diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1b46a355c2be9f1f3781c49b2a1c051cdf77ef02 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.classpath +.project +.settings +*.jardesc +*.jar +*.7z +bin/ +target/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..8199f4f684d34d0dabd77a7ac46b3a1f24cc539d --- /dev/null +++ b/pom.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>pom-icy</artifactId> + <groupId>org.bioimageanalysis.icy</groupId> + <version>1.0.4</version> + </parent> + + <artifactId>icy-jython</artifactId> + <version>2.8.0</version> + + <packaging>jar</packaging> + + <name>Jython for Icy</name> + <description> + Jython library for Icy + </description> + + <dependencies> + <dependency> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>icy-ezplug</artifactId> + <version>3.15.13</version> + </dependency> + </dependencies> + + <repositories> + <repository> + <id>icy-prod</id> + <url>https://icy-nexus.pasteur.fr/repository/Icy/</url> + </repository> + </repositories> +</project> \ No newline at end of file diff --git a/src/main/java/plugins/tlecomte/jythonForIcy/ExtractionHelper.java b/src/main/java/plugins/tlecomte/jythonForIcy/ExtractionHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..e976e6162ccee619a2032f639da3fc038cebeaff --- /dev/null +++ b/src/main/java/plugins/tlecomte/jythonForIcy/ExtractionHelper.java @@ -0,0 +1,301 @@ +package plugins.tlecomte.jythonForIcy; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.JarURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.python.core.PySystemState; + +import icy.file.FileUtil; +import icy.plugin.PluginDescriptor; +import icy.plugin.PluginLoader; +import icy.plugin.abstract_.Plugin; + +class ExtractionHelper +{ + final static String pythonDirName = "PythonLibs"; + final static String extractionDir = pythonDirName; + + /** + * Walk the plugin list to look for plugins that contain py files + * and extract them. + * + * @return the list of dirs whose contents have been extracted + */ + static void extractPyFiles(ExtractionTimestamps timestamps) + { + ArrayList<PluginDescriptor> pluginList = PluginLoader.getPlugins(); + + String destDir = getPythonLibDir(); + if (destDir == null) + { + System.err.println("Failed to extract python library files because sys.prefix is not set"); + return; + } + + // extract Python files + for (PluginDescriptor plugin : pluginList) + { + if (plugin.getPluginClass().getAnnotation(PythonLibraries.class) != null) + { + try + { + extractPyFiles(plugin, destDir, timestamps); + } + catch (IOException e) + { + System.err.println("Failed to extract python library files for plugin " + plugin); + e.printStackTrace(); + } + catch (URISyntaxException e) + { + System.err.println("Failed to extract python library files for plugin " + plugin); + e.printStackTrace(); + } + } + } + } + + static String getPythonLibDir() + { + // Note: this is done in a thread, otherwise ThreadLocal variables in Jython + // prevents the whole classloader from being garbage-collected. + ExecutorService executor = Executors.newSingleThreadExecutor(); + Callable<String> callable = new Callable<String>() + { + @Override + public String call() + { + // create a new PySystemState (will initialize Jython state if not done already) + PySystemState sys = new PySystemState(); + // retrieve Python prefix (i.e. where the 'Lib' folder will be looked for) + String sys_prefix = PySystemState.prefix.asString(); + // cleanup immediately to remove shutdown hooks that prevent the classloader from being garbage-collected + sys.cleanup(); + return sys_prefix; + } + }; + Future<String> future = executor.submit(callable); + executor.shutdown(); + executor = null; + + String sys_prefix; + try + { + sys_prefix = future.get(); + } + catch (InterruptedException e) + { + System.err.println("Failed to retrieve Python prefix"); + sys_prefix = null; + } + catch (ExecutionException e) + { + System.err.println("Failed to retrieve Python prefix"); + sys_prefix = null; + } + + String Lib_prefix = null; + if (sys_prefix == null) + { + System.err.println("Error: sys.prefix is None."); + System.err.println("If you are developing in Eclipse, please set the 'python.home' property"); + System.err.println("on the Java command-line. For example:"); + System.err.println(" -Dpython.home=plugins"); + } + else + { + Lib_prefix = sys_prefix + File.separator + "Lib"; + } + + return Lib_prefix; + } + + static void extractPyFiles(PluginDescriptor plugin, String destDir, ExtractionTimestamps timestamps) + throws IOException, URISyntaxException + { + + // Jython can use python files that are actually on disk + // or files that are inside a jar. + // However, files inside a jar will not be found by modules + // like 'inspect' that are actively working on the source + // code. This is preventing the interpreter from displaying + // complete backtraces whenever they go through a file in a jar. + // Additionally, it prevents execnet from correctly bootstrapping + // itself. + + // To overcome this, we choose to make sure that all python files + // provided by Icy are extracted to an actual folder on disk. + + // This will work on files provided by all plugins implementing PythonLibrariesBundle + // JythonExtrasForIcy and JythonExecnetForIcy are first users of this interface. + + Class<? extends Plugin> klass = plugin.getPluginClass(); + + URL classUrl = klass.getResource(klass.getSimpleName() + ".class"); + + URLConnection connection = classUrl.openConnection(); + + if (connection instanceof JarURLConnection) + { + JarURLConnection jarConnection = (JarURLConnection) connection; + + extractPyFilesFromJarIfNewer(jarConnection, plugin, destDir, timestamps); + } + else + { + // the files are already on disk ! + // (this happens when developing the plugins in Eclipse) + + System.out.println("Extracting Python files from disk for plugin " + plugin); + String srcDir = findPythonFilesFromDisk(classUrl); + FileUtil.copy(srcDir, destDir, true, true); // force and recursive + } + } + + static void extractPyFilesFromJarIfNewer(JarURLConnection jarConnection, PluginDescriptor plugin, String destDir, + ExtractionTimestamps timestamps) throws IOException, URISyntaxException + { + URL jarUrl = jarConnection.getJarFileURL(); + + URI jarURI = jarUrl.toURI(); + + JarFile jarFile = new JarFile(new File(jarURI)); + + long jarLastModified = new File(jarFile.getName()).lastModified(); + + // retrieve the lastModified info of the last time we extracted + Long extractionTimestamp = timestamps.getTimestamp(plugin); + + if (extractionTimestamp.longValue() == jarLastModified) + { + // no need to extract anything, the proper version exists + return; + } + + // the bundled version is newer, extract ! + System.out.println("Extracting Python files from plugin " + plugin); + extractPyFilesFromJar(jarFile, destDir); + + // store the extracted version + timestamps.setTimestamp(plugin, new Long(jarLastModified)); + } + + static void extractPyFilesFromJar(JarFile jarFile, String destDir) throws IOException + { + Enumeration<JarEntry> entries = jarFile.entries(); + while (entries.hasMoreElements()) + { + JarEntry jarEntry = entries.nextElement(); + + String name = jarEntry.getName(); + + // extract all files contained in a dir named $pythonDirName + if (!jarEntry.isDirectory() && name.startsWith(pythonDirName)) + { + String strippedName = name.substring(pythonDirName.length() + 1); + String outName = destDir + File.separator + strippedName; + + InputStream inputStream = jarFile.getInputStream(jarEntry); + File destFile = new File(outName); + FileOutputStream fileOutputStream; + try + { + fileOutputStream = new FileOutputStream(destFile); + } + catch (FileNotFoundException e) + { + destFile.getParentFile().mkdirs(); + fileOutputStream = new FileOutputStream(destFile); + } + byte[] b = new byte[16384]; + int bytes; + while ((bytes = inputStream.read(b)) > 0) + { + fileOutputStream.write(b, 0, bytes); + } + fileOutputStream.close(); + inputStream.close(); + } + } + } + + /** + * Given a directory, walk the sub-directories until it finds + * one that is named "PythonLibs" + * If no directory with that name is found, reset the starting + * directory with its parent and start again + * + * @param connection + * @return the "PythonLibs" directory as a File object, null if none is found + * @throws URISyntaxException + */ + static String findPythonFilesFromDisk(URL classUrl) throws URISyntaxException + { + // the URL needs to be converted to an URI to handle spaces in paths + File classFile = new File(classUrl.toURI()); + + File pythonParent = null; + File leaf = classFile; + + while (pythonParent == null) + { + leaf = leaf.getParentFile(); + pythonParent = findPythonFilesInSubDirs(leaf); + } + + return pythonParent.getAbsolutePath(); + } + + /** + * Given a root directory, walk the sub-directories until it finds + * one that is named "PythonLibs" + * + * @param connection + * @return the "PythonLibs" directory as a File object, null if none is found + */ + static File findPythonFilesInSubDirs(File root) + { + if (!root.isDirectory()) + { + return null; + } + + for (File file : root.listFiles()) + { + if (file.isDirectory()) + { + if (file.getName().endsWith(pythonDirName)) + { + return file; + } + else + { + File res = findPythonFilesInSubDirs(file); // recursive ! + if (res != null) + { + return res; + } + } + } + } + + return null; + } +} diff --git a/src/main/java/plugins/tlecomte/jythonForIcy/ExtractionTimestamps.java b/src/main/java/plugins/tlecomte/jythonForIcy/ExtractionTimestamps.java new file mode 100644 index 0000000000000000000000000000000000000000..956e9bbd0bf0b8fec3a90caa42cb1cd01cdaf159 --- /dev/null +++ b/src/main/java/plugins/tlecomte/jythonForIcy/ExtractionTimestamps.java @@ -0,0 +1,85 @@ +package plugins.tlecomte.jythonForIcy; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Hashtable; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import icy.file.xml.XMLPersistent; +import icy.plugin.PluginDescriptor; +import icy.util.XMLUtil; + +public class ExtractionTimestamps implements XMLPersistent { + + Hashtable<String, Long> timestamps; + + static final String ID_PLUGINS = "plugins"; + static final String ID_PLUGIN = "plugin"; + static final String ID_CLASSNAME = "className"; + static final String ID_TIMESTAMP = "timestamp"; + + ExtractionTimestamps() { + timestamps = new Hashtable<String, Long>(); + } + + public Long getTimestamp(PluginDescriptor plugin) { + Long timestamp = timestamps.get(plugin.getClassName()); + if (timestamp == null) { + timestamp = new Long(0); + } + return timestamp; + } + + public void setTimestamp(PluginDescriptor plugin, Long timestamp) { + timestamps.put(plugin.getClassName(), timestamp); + } + + @Override + public boolean loadFromXML(Node node) { + if (node == null) + return false; + + final Node pluginsNode = XMLUtil.getElement(node, ID_PLUGINS); + + if (pluginsNode != null) + { + final ArrayList<Node> pluginNodes = XMLUtil.getChildren(pluginsNode, ID_PLUGIN); + + for (Node n : pluginNodes) + { + String pluginName = XMLUtil.getElementValue(n, ID_CLASSNAME, "noClassName"); + Long timestamp = XMLUtil.getElementLongValue(n, ID_TIMESTAMP, 0); + timestamps.put(pluginName, timestamp); + } + } + + return true; + } + + @Override + public boolean saveToXML(Node node) { + if (node == null) + return false; + + final Element pluginsNode = XMLUtil.setElement(node, ID_PLUGINS); + + if (pluginsNode != null) + { + XMLUtil.removeAllChildren(pluginsNode); + + Enumeration<String> enumKey = timestamps.keys(); + while(enumKey.hasMoreElements()) { + String key = enumKey.nextElement(); + Long timestamp = timestamps.get(key); + Element n = XMLUtil.addElement(pluginsNode, ID_PLUGIN); + XMLUtil.setElementValue(n, ID_CLASSNAME, key); + XMLUtil.setElementLongValue(n, ID_TIMESTAMP, timestamp); + } + } + + return true; + } + +} diff --git a/src/main/java/plugins/tlecomte/jythonForIcy/JythonForIcy.java b/src/main/java/plugins/tlecomte/jythonForIcy/JythonForIcy.java new file mode 100644 index 0000000000000000000000000000000000000000..bc40caea94e178c3a2154c025cf1c34579a5ac48 --- /dev/null +++ b/src/main/java/plugins/tlecomte/jythonForIcy/JythonForIcy.java @@ -0,0 +1,107 @@ +package plugins.tlecomte.jythonForIcy; + +import java.io.File; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.python.core.Py; +import org.python.core.PySystemState; + +import icy.file.xml.XMLPersistentHelper; +import icy.plugin.abstract_.Plugin; +import icy.plugin.interface_.PluginDaemon; +import icy.plugin.interface_.PluginLibrary; +import icy.util.ClassUtil; +import icy.util.XMLUtil; + +@PythonLibraries +public class JythonForIcy extends Plugin implements PluginDaemon, PluginLibrary +{ + final String TIMESTAMPS_FILENAME = "ExtractDescriptor"; + + @Override + public void init() + { + // allow to avoid warning on jython loading + System.setProperty("python.console.encoding", "UTF-8"); + + // load timestamps of last extraction from XML file + ExtractionTimestamps timestamps = new ExtractionTimestamps(); + + String qualifiedDir = new File(ClassUtil.getPathFromQualifiedName(getDescriptor().getClassName())).getParent(); + String timestampsFile = qualifiedDir + File.separator + TIMESTAMPS_FILENAME + XMLUtil.FILE_DOT_EXTENSION; + boolean loadSuccess = XMLPersistentHelper.loadFromXML(timestamps, timestampsFile); + + if (!loadSuccess) + { + File file = new File(timestampsFile); + // if the file does not exist, the failure is normal + if (file.exists()) + { + System.err.println("Failed to load the Python extraction timestamp file from " + timestampsFile); + } + } + + // do the hard work here + ExtractionHelper.extractPyFiles(timestamps); + + // save timestamps + boolean saveSucess = XMLPersistentHelper.saveToXML(timestamps, timestampsFile); + + if (!saveSucess) + { + System.err.println("Failed to save the Python extraction timestamp file to " + timestampsFile); + } + } + + @Override + public void run() + { + // nothing to do here + } + + @Override + public void stop() + { + // This is our last chance of cleanup before a classloader reload + // If we do not ask for a cleanup, the registered shutdown hooks will + // prevent the whole classloader from being garbage collected, + // utlimately leading to a PermGenSpace error. + + // Note that we need to do that in a thread to prevent ThreadLocal variables from + // being kept forever and preventing the classloader from being collected. + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Runnable runnable = new Runnable() + { + @Override + public void run() + { + // Cleanup to remove shutdown hooks that prevent the classloader from being garbage-collected. + // Note: instantiating a new PySystemState will cleanup those that have been marked as garbage previously + // and this new one must be cleaned up too immediately. + new PySystemState().cleanup(); + + // the defaultSystemState is defined static, so it is never marked as garbage. + // We must clean it up manually. + Py.defaultSystemState.cleanup(); + } + }; + Future<?> future = executor.submit(runnable); + executor.shutdown(); + try + { + future.get(); + } + catch (InterruptedException e) + { + // ignore + } + catch (ExecutionException e) + { + // ignore + } + } +} diff --git a/src/main/java/plugins/tlecomte/jythonForIcy/PythonExtractorManager.java b/src/main/java/plugins/tlecomte/jythonForIcy/PythonExtractorManager.java new file mode 100644 index 0000000000000000000000000000000000000000..1e41efe4e0bcad6545b7adbe5752e350d53b7b93 --- /dev/null +++ b/src/main/java/plugins/tlecomte/jythonForIcy/PythonExtractorManager.java @@ -0,0 +1,111 @@ +package plugins.tlecomte.jythonForIcy; + +/* + * Copyright 2013 Institut Pasteur. + * + * This file is part of ICY. + * + * ICY is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ICY is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ICY. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +import icy.plugin.interface_.PluginBundled; +import plugins.adufour.ezplug.EzButton; +import plugins.adufour.ezplug.EzLabel; +import plugins.adufour.ezplug.EzPlug; +import plugins.adufour.ezplug.EzVarText; + +public class PythonExtractorManager extends EzPlug implements PluginBundled, ActionListener +{ + + EzLabel description = new EzLabel("The Python Extractor walks the plugins list" + + " to extract all the Python scripts packaged inside the plugins." + + "\n\nThis operation is done automatically each time Icy starts and each" + + " time the plugins list is reloaded (after an update for example)." + + "\n\nIn some cases, you may want to force this operation manually." + + " This is useful when developping your own Python plugins inside" + " Eclipse for example."); + EzButton startButton = null; + + EzLabel folderDescription = new EzLabel( + "\nFor your information, the Python files" + " are extracted to the following folder:"); + EzVarText folder = new EzVarText("Extraction path", ""); + + EzLabel customizeDescription = new EzLabel( + "\nYou can customize your Python installation" + " by creating or editing the following file:"); + EzVarText sitecustomizePath = new EzVarText("Site customization script", ""); + EzLabel customizeDescription2 = new EzLabel("If it exists, this file is executed automatically" + + " each time the Python interpreter is launched. This file is a good place to extend the Python import" + + " path with the directories containing your own Python modules." + "\n" + "\n" + + "Please note that the embedded Python interpreter inside Icy also offers the" + + " other customization mechanisms offered by Python 2.7 (USERS_SITE, usercustomize.py, etc.)." + + " Look at http://docs.python.org/2/library/site.html for more information."); + + public PythonExtractorManager() + { + startButton = new EzButton("Force extraction", this); + description.setNumberOfColumns(20); + description.setNumberOfRows(0); + String pythonlibDir = ExtractionHelper.getPythonLibDir(); + folder.setValue(pythonlibDir); + sitecustomizePath + .setValue(pythonlibDir + File.separator + "site-packages" + File.separator + "sitecustomize.py"); + } + + @Override + public void actionPerformed(ActionEvent arg0) + { + // Launch the extraction with an empty timestamps object, + // so that every plugin will be extracted again + ExtractionHelper.extractPyFiles(new ExtractionTimestamps()); + } + + @Override + public void clean() + { + // TODO Auto-generated method stub + + } + + @Override + protected void execute() + { + // TODO Auto-generated method stub + + } + + @Override + protected void initialize() + { + getUI().setActionPanelVisible(false); + + addEzComponent(description); + addEzComponent(startButton); + addEzComponent(folderDescription); + addEzComponent(folder); + addEzComponent(customizeDescription); + addEzComponent(sitecustomizePath); + addEzComponent(customizeDescription2); + + getUI().repack(true); + } + + @Override + public String getMainPluginClassName() + { + return JythonForIcy.class.getName(); + } +} diff --git a/src/main/java/plugins/tlecomte/jythonForIcy/PythonLibraries.java b/src/main/java/plugins/tlecomte/jythonForIcy/PythonLibraries.java new file mode 100644 index 0000000000000000000000000000000000000000..53f2d356407a6959abd7efb1e4e775b4a611d93b --- /dev/null +++ b/src/main/java/plugins/tlecomte/jythonForIcy/PythonLibraries.java @@ -0,0 +1,18 @@ +package plugins.tlecomte.jythonForIcy; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.ElementType; + +/** + * Annotation used to mark that a plugin contains Python scripts. + * In turn Icy will extract these files from the jar to to the disk. + * + * @author Timothee Lecomte + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface PythonLibraries { + +} diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7 --- /dev/null +++ b/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..d76a648ee8cd95f9f35b02976ad26f9264375032 --- /dev/null +++ b/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Ant-Version: Apache Ant 1.8.4 +Built-By: tlecomte +Created-By: 1.6.0_65-b14-462-10M4609 (Apple Inc.) +Main-Class: org.python.util.jython + +Name: Build-Info +informix: ${informix.present} +build-compiler: modern +debug: true +oracle: ${oracle.present} +jdk-target-version: 1.6 +version: 2.7b1+ + diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000000000000000000000000000000000000..85e6e4eeeaeb491b088e73c9ee36a4ad76925d83 --- /dev/null +++ b/src/main/resources/META-INF/NOTICE @@ -0,0 +1,17 @@ + ========================================================================= + == NOTICE file corresponding to section 4(d) of the Apache License, == + == Version 2.0, in this case for the Apache Xerces Java distribution. == + ========================================================================= + + Apache Xerces Java + Copyright 1999-2010 The Apache Software Foundation + + This product includes software developed at + The Apache Software Foundation (http://www.apache.org/). + + Portions of this software were originally based on the following: + - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. + - software copyright (c) 1999, Sun Microsystems., http://www.sun.com. + - voluntary contributions made by Paul Eng on behalf of the + Apache Software Foundation that were originally developed at iClick, Inc., + software copyright (c) 1999. \ No newline at end of file diff --git a/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory b/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory new file mode 100644 index 0000000000000000000000000000000000000000..5f6c08eb062a3912d857f4a16d060c545db9ce27 --- /dev/null +++ b/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory @@ -0,0 +1 @@ +org.python.jsr223.PyScriptEngineFactory diff --git a/src/main/resources/ProxyDeserialization.class b/src/main/resources/ProxyDeserialization.class new file mode 100644 index 0000000000000000000000000000000000000000..e7a506acb80e24422b0210367eddc121d414725b Binary files /dev/null and b/src/main/resources/ProxyDeserialization.class differ diff --git a/src/main/resources/PythonLibs/BaseHTTPServer.py b/src/main/resources/PythonLibs/BaseHTTPServer.py new file mode 100644 index 0000000000000000000000000000000000000000..deaf2f960b83c76b38b0c494db91202c70886833 --- /dev/null +++ b/src/main/resources/PythonLibs/BaseHTTPServer.py @@ -0,0 +1,603 @@ +"""HTTP server base class. + +Note: the class in this module doesn't implement any HTTP request; see +SimpleHTTPServer for simple implementations of GET, HEAD and POST +(including CGI scripts). It does, however, optionally implement HTTP/1.1 +persistent connections, as of version 0.3. + +Contents: + +- BaseHTTPRequestHandler: HTTP request handler base class +- test: test function + +XXX To do: + +- log requests even later (to capture byte count) +- log user-agent header and other interesting goodies +- send error log to separate file +""" + + +# See also: +# +# HTTP Working Group T. Berners-Lee +# INTERNET-DRAFT R. T. Fielding +# <draft-ietf-http-v10-spec-00.txt> H. Frystyk Nielsen +# Expires September 8, 1995 March 8, 1995 +# +# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt +# +# and +# +# Network Working Group R. Fielding +# Request for Comments: 2616 et al +# Obsoletes: 2068 June 1999 +# Category: Standards Track +# +# URL: http://www.faqs.org/rfcs/rfc2616.html + +# Log files +# --------- +# +# Here's a quote from the NCSA httpd docs about log file format. +# +# | The logfile format is as follows. Each line consists of: +# | +# | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb +# | +# | host: Either the DNS name or the IP number of the remote client +# | rfc931: Any information returned by identd for this person, +# | - otherwise. +# | authuser: If user sent a userid for authentication, the user name, +# | - otherwise. +# | DD: Day +# | Mon: Month (calendar name) +# | YYYY: Year +# | hh: hour (24-hour format, the machine's timezone) +# | mm: minutes +# | ss: seconds +# | request: The first line of the HTTP request as sent by the client. +# | ddd: the status code returned by the server, - if not available. +# | bbbb: the total number of bytes sent, +# | *not including the HTTP/1.0 header*, - if not available +# | +# | You can determine the name of the file accessed through request. +# +# (Actually, the latter is only true if you know the server configuration +# at the time the request was made!) + +__version__ = "0.3" + +__all__ = ["HTTPServer", "BaseHTTPRequestHandler"] + +import sys +import time +import socket # For gethostbyaddr() +from warnings import filterwarnings, catch_warnings +with catch_warnings(): + if sys.py3kwarning: + filterwarnings("ignore", ".*mimetools has been removed", + DeprecationWarning) + import mimetools +import SocketServer + +# Default error message template +DEFAULT_ERROR_MESSAGE = """\ +<head> +<title>Error response</title> +</head> +<body> +<h1>Error response</h1> +<p>Error code %(code)d. +<p>Message: %(message)s. +<p>Error code explanation: %(code)s = %(explain)s. +</body> +""" + +DEFAULT_ERROR_CONTENT_TYPE = "text/html" + +def _quote_html(html): + return html.replace("&", "&").replace("<", "<").replace(">", ">") + +class HTTPServer(SocketServer.TCPServer): + + allow_reuse_address = 1 # Seems to make sense in testing environment + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.TCPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port + + +class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): + + """HTTP request handler base class. + + The following explanation of HTTP serves to guide you through the + code as well as to expose any misunderstandings I may have about + HTTP (so you don't need to read the code to figure out I'm wrong + :-). + + HTTP (HyperText Transfer Protocol) is an extensible protocol on + top of a reliable stream transport (e.g. TCP/IP). The protocol + recognizes three parts to a request: + + 1. One line identifying the request type and path + 2. An optional set of RFC-822-style headers + 3. An optional data part + + The headers and data are separated by a blank line. + + The first line of the request has the form + + <command> <path> <version> + + where <command> is a (case-sensitive) keyword such as GET or POST, + <path> is a string containing path information for the request, + and <version> should be the string "HTTP/1.0" or "HTTP/1.1". + <path> is encoded using the URL encoding scheme (using %xx to signify + the ASCII character with hex code xx). + + The specification specifies that lines are separated by CRLF but + for compatibility with the widest range of clients recommends + servers also handle LF. Similarly, whitespace in the request line + is treated sensibly (allowing multiple spaces between components + and allowing trailing whitespace). + + Similarly, for output, lines ought to be separated by CRLF pairs + but most clients grok LF characters just fine. + + If the first line of the request has the form + + <command> <path> + + (i.e. <version> is left out) then this is assumed to be an HTTP + 0.9 request; this form has no optional headers and data part and + the reply consists of just the data. + + The reply form of the HTTP 1.x protocol again has three parts: + + 1. One line giving the response code + 2. An optional set of RFC-822-style headers + 3. The data + + Again, the headers and data are separated by a blank line. + + The response code line has the form + + <version> <responsecode> <responsestring> + + where <version> is the protocol version ("HTTP/1.0" or "HTTP/1.1"), + <responsecode> is a 3-digit response code indicating success or + failure of the request, and <responsestring> is an optional + human-readable string explaining what the response code means. + + This server parses the request and the headers, and then calls a + function specific to the request type (<command>). Specifically, + a request SPAM will be handled by a method do_SPAM(). If no + such method exists the server sends an error response to the + client. If it exists, it is called with no arguments: + + do_SPAM() + + Note that the request name is case sensitive (i.e. SPAM and spam + are different requests). + + The various request details are stored in instance variables: + + - client_address is the client IP address in the form (host, + port); + + - command, path and version are the broken-down request line; + + - headers is an instance of mimetools.Message (or a derived + class) containing the header information; + + - rfile is a file object open for reading positioned at the + start of the optional input data part; + + - wfile is a file object open for writing. + + IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING! + + The first thing to be written must be the response line. Then + follow 0 or more header lines, then a blank line, and then the + actual data (if any). The meaning of the header lines depends on + the command executed by the server; in most cases, when data is + returned, there should be at least one header line of the form + + Content-type: <type>/<subtype> + + where <type> and <subtype> should be registered MIME types, + e.g. "text/html" or "text/plain". + + """ + + # The Python system version, truncated to its first component. + sys_version = "Python/" + sys.version.split()[0] + + # The server software version. You may want to override this. + # The format is multiple whitespace-separated strings, + # where each string is of the form name[/version]. + server_version = "BaseHTTP/" + __version__ + + # The default request version. This only affects responses up until + # the point where the request line is parsed, so it mainly decides what + # the client gets back when sending a malformed request line. + # Most web servers default to HTTP 0.9, i.e. don't send a status line. + default_request_version = "HTTP/0.9" + + def parse_request(self): + """Parse a request (internal). + + The request should be stored in self.raw_requestline; the results + are in self.command, self.path, self.request_version and + self.headers. + + Return True for success, False for failure; on failure, an + error is sent back. + + """ + self.command = None # set in case of error on the first line + self.request_version = version = self.default_request_version + self.close_connection = 1 + requestline = self.raw_requestline + requestline = requestline.rstrip('\r\n') + self.requestline = requestline + words = requestline.split() + if len(words) == 3: + command, path, version = words + if version[:5] != 'HTTP/': + self.send_error(400, "Bad request version (%r)" % version) + return False + try: + base_version_number = version.split('/', 1)[1] + version_number = base_version_number.split(".") + # RFC 2145 section 3.1 says there can be only one "." and + # - major and minor numbers MUST be treated as + # separate integers; + # - HTTP/2.4 is a lower version than HTTP/2.13, which in + # turn is lower than HTTP/12.3; + # - Leading zeros MUST be ignored by recipients. + if len(version_number) != 2: + raise ValueError + version_number = int(version_number[0]), int(version_number[1]) + except (ValueError, IndexError): + self.send_error(400, "Bad request version (%r)" % version) + return False + if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": + self.close_connection = 0 + if version_number >= (2, 0): + self.send_error(505, + "Invalid HTTP Version (%s)" % base_version_number) + return False + elif len(words) == 2: + command, path = words + self.close_connection = 1 + if command != 'GET': + self.send_error(400, + "Bad HTTP/0.9 request type (%r)" % command) + return False + elif not words: + return False + else: + self.send_error(400, "Bad request syntax (%r)" % requestline) + return False + self.command, self.path, self.request_version = command, path, version + + # Examine the headers and look for a Connection directive + self.headers = self.MessageClass(self.rfile, 0) + + conntype = self.headers.get('Connection', "") + if conntype.lower() == 'close': + self.close_connection = 1 + elif (conntype.lower() == 'keep-alive' and + self.protocol_version >= "HTTP/1.1"): + self.close_connection = 0 + return True + + def handle_one_request(self): + """Handle a single HTTP request. + + You normally don't need to override this method; see the class + __doc__ string for information on how to handle specific HTTP + commands such as GET and POST. + + """ + try: + self.raw_requestline = self.rfile.readline(65537) + if len(self.raw_requestline) > 65536: + self.requestline = '' + self.request_version = '' + self.command = '' + self.send_error(414) + return + if not self.raw_requestline: + self.close_connection = 1 + return + if not self.parse_request(): + # An error code has been sent, just exit + return + mname = 'do_' + self.command + if not hasattr(self, mname): + self.send_error(501, "Unsupported method (%r)" % self.command) + return + method = getattr(self, mname) + method() + self.wfile.flush() #actually send the response if not already done. + except socket.timeout, e: + #a read or a write timed out. Discard this connection + self.log_error("Request timed out: %r", e) + self.close_connection = 1 + return + + def handle(self): + """Handle multiple requests if necessary.""" + self.close_connection = 1 + + self.handle_one_request() + while not self.close_connection: + self.handle_one_request() + + def send_error(self, code, message=None): + """Send and log an error reply. + + Arguments are the error code, and a detailed message. + The detailed message defaults to the short entry matching the + response code. + + This sends an error response (so it must be called before any + output has been generated), logs the error, and finally sends + a piece of HTML explaining the error to the user. + + """ + + try: + short, long = self.responses[code] + except KeyError: + short, long = '???', '???' + if message is None: + message = short + explain = long + self.log_error("code %d, message %s", code, message) + # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201) + content = (self.error_message_format % + {'code': code, 'message': _quote_html(message), 'explain': explain}) + self.send_response(code, message) + self.send_header("Content-Type", self.error_content_type) + self.send_header('Connection', 'close') + self.end_headers() + if self.command != 'HEAD' and code >= 200 and code not in (204, 304): + self.wfile.write(content) + + error_message_format = DEFAULT_ERROR_MESSAGE + error_content_type = DEFAULT_ERROR_CONTENT_TYPE + + def send_response(self, code, message=None): + """Send the response header and log the response code. + + Also send two standard headers with the server software + version and the current date. + + """ + self.log_request(code) + if message is None: + if code in self.responses: + message = self.responses[code][0] + else: + message = '' + if self.request_version != 'HTTP/0.9': + self.wfile.write("%s %d %s\r\n" % + (self.protocol_version, code, message)) + # print (self.protocol_version, code, message) + self.send_header('Server', self.version_string()) + self.send_header('Date', self.date_time_string()) + + def send_header(self, keyword, value): + """Send a MIME header.""" + if self.request_version != 'HTTP/0.9': + self.wfile.write("%s: %s\r\n" % (keyword, value)) + + if keyword.lower() == 'connection': + if value.lower() == 'close': + self.close_connection = 1 + elif value.lower() == 'keep-alive': + self.close_connection = 0 + + def end_headers(self): + """Send the blank line ending the MIME headers.""" + if self.request_version != 'HTTP/0.9': + self.wfile.write("\r\n") + + def log_request(self, code='-', size='-'): + """Log an accepted request. + + This is called by send_response(). + + """ + + self.log_message('"%s" %s %s', + self.requestline, str(code), str(size)) + + def log_error(self, format, *args): + """Log an error. + + This is called when a request cannot be fulfilled. By + default it passes the message on to log_message(). + + Arguments are the same as for log_message(). + + XXX This should go to the separate error log. + + """ + + self.log_message(format, *args) + + def log_message(self, format, *args): + """Log an arbitrary message. + + This is used by all other logging functions. Override + it if you have specific logging wishes. + + The first argument, FORMAT, is a format string for the + message to be logged. If the format string contains + any % escapes requiring parameters, they should be + specified as subsequent arguments (it's just like + printf!). + + The client ip address and current date/time are prefixed to every + message. + + """ + + sys.stderr.write("%s - - [%s] %s\n" % + (self.client_address[0], + self.log_date_time_string(), + format%args)) + + def version_string(self): + """Return the server software version string.""" + return self.server_version + ' ' + self.sys_version + + def date_time_string(self, timestamp=None): + """Return the current date and time formatted for a message header.""" + if timestamp is None: + timestamp = time.time() + year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp) + s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( + self.weekdayname[wd], + day, self.monthname[month], year, + hh, mm, ss) + return s + + def log_date_time_string(self): + """Return the current time formatted for logging.""" + now = time.time() + year, month, day, hh, mm, ss, x, y, z = time.localtime(now) + s = "%02d/%3s/%04d %02d:%02d:%02d" % ( + day, self.monthname[month], year, hh, mm, ss) + return s + + weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + + monthname = [None, + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + + def address_string(self): + """Return the client address formatted for logging. + + This version looks up the full hostname using gethostbyaddr(), + and tries to find a name that contains at least one dot. + + """ + + host, port = self.client_address[:2] + return socket.getfqdn(host) + + # Essentially static class variables + + # The version of the HTTP protocol we support. + # Set this to HTTP/1.1 to enable automatic keepalive + protocol_version = "HTTP/1.0" + + # The Message-like class used to parse headers + MessageClass = mimetools.Message + + # Table mapping response codes to messages; entries have the + # form {code: (shortmessage, longmessage)}. + # See RFC 2616. + responses = { + 100: ('Continue', 'Request received, please continue'), + 101: ('Switching Protocols', + 'Switching to new protocol; obey Upgrade header'), + + 200: ('OK', 'Request fulfilled, document follows'), + 201: ('Created', 'Document created, URL follows'), + 202: ('Accepted', + 'Request accepted, processing continues off-line'), + 203: ('Non-Authoritative Information', 'Request fulfilled from cache'), + 204: ('No Content', 'Request fulfilled, nothing follows'), + 205: ('Reset Content', 'Clear input form for further input.'), + 206: ('Partial Content', 'Partial content follows.'), + + 300: ('Multiple Choices', + 'Object has several resources -- see URI list'), + 301: ('Moved Permanently', 'Object moved permanently -- see URI list'), + 302: ('Found', 'Object moved temporarily -- see URI list'), + 303: ('See Other', 'Object moved -- see Method and URL list'), + 304: ('Not Modified', + 'Document has not changed since given time'), + 305: ('Use Proxy', + 'You must use proxy specified in Location to access this ' + 'resource.'), + 307: ('Temporary Redirect', + 'Object moved temporarily -- see URI list'), + + 400: ('Bad Request', + 'Bad request syntax or unsupported method'), + 401: ('Unauthorized', + 'No permission -- see authorization schemes'), + 402: ('Payment Required', + 'No payment -- see charging schemes'), + 403: ('Forbidden', + 'Request forbidden -- authorization will not help'), + 404: ('Not Found', 'Nothing matches the given URI'), + 405: ('Method Not Allowed', + 'Specified method is invalid for this resource.'), + 406: ('Not Acceptable', 'URI not available in preferred format.'), + 407: ('Proxy Authentication Required', 'You must authenticate with ' + 'this proxy before proceeding.'), + 408: ('Request Timeout', 'Request timed out; try again later.'), + 409: ('Conflict', 'Request conflict.'), + 410: ('Gone', + 'URI no longer exists and has been permanently removed.'), + 411: ('Length Required', 'Client must specify Content-Length.'), + 412: ('Precondition Failed', 'Precondition in headers is false.'), + 413: ('Request Entity Too Large', 'Entity is too large.'), + 414: ('Request-URI Too Long', 'URI is too long.'), + 415: ('Unsupported Media Type', 'Entity body in unsupported format.'), + 416: ('Requested Range Not Satisfiable', + 'Cannot satisfy request range.'), + 417: ('Expectation Failed', + 'Expect condition could not be satisfied.'), + + 500: ('Internal Server Error', 'Server got itself in trouble'), + 501: ('Not Implemented', + 'Server does not support this operation'), + 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'), + 503: ('Service Unavailable', + 'The server cannot process the request due to a high load'), + 504: ('Gateway Timeout', + 'The gateway server did not receive a timely response'), + 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'), + } + + +def test(HandlerClass = BaseHTTPRequestHandler, + ServerClass = HTTPServer, protocol="HTTP/1.0"): + """Test the HTTP request handler class. + + This runs an HTTP server on port 8000 (or the first command line + argument). + + """ + + if sys.argv[1:]: + port = int(sys.argv[1]) + else: + port = 8000 + server_address = ('', port) + + HandlerClass.protocol_version = protocol + httpd = ServerClass(server_address, HandlerClass) + + sa = httpd.socket.getsockname() + print "Serving HTTP on", sa[0], "port", sa[1], "..." + httpd.serve_forever() + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/CGIHTTPServer.py b/src/main/resources/PythonLibs/CGIHTTPServer.py new file mode 100644 index 0000000000000000000000000000000000000000..47a994cab1fe90850dcecf79fd4a2ccbe46ba1f2 --- /dev/null +++ b/src/main/resources/PythonLibs/CGIHTTPServer.py @@ -0,0 +1,378 @@ +"""CGI-savvy HTTP Server. + +This module builds on SimpleHTTPServer by implementing GET and POST +requests to cgi-bin scripts. + +If the os.fork() function is not present (e.g. on Windows), +os.popen2() is used as a fallback, with slightly altered semantics; if +that function is not present either (e.g. on Macintosh), only Python +scripts are supported, and they are executed by the current process. + +In all cases, the implementation is intentionally naive -- all +requests are executed sychronously. + +SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL +-- it may execute arbitrary Python code or external programs. + +Note that status code 200 is sent prior to execution of a CGI script, so +scripts cannot send other status codes such as 302 (redirect). +""" + + +__version__ = "0.4" + +__all__ = ["CGIHTTPRequestHandler"] + +import os +import sys +import urllib +import BaseHTTPServer +import SimpleHTTPServer +import select +import copy + + +class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): + + """Complete HTTP server with GET, HEAD and POST commands. + + GET and HEAD also support running CGI scripts. + + The POST command is *only* implemented for CGI scripts. + + """ + + # Determine platform specifics + have_fork = hasattr(os, 'fork') + have_popen2 = hasattr(os, 'popen2') + have_popen3 = hasattr(os, 'popen3') + + # Make rfile unbuffered -- we need to read one line and then pass + # the rest to a subprocess, so we can't use buffered input. + rbufsize = 0 + + def do_POST(self): + """Serve a POST request. + + This is only implemented for CGI scripts. + + """ + + if self.is_cgi(): + self.run_cgi() + else: + self.send_error(501, "Can only POST to CGI scripts") + + def send_head(self): + """Version of send_head that support CGI scripts""" + if self.is_cgi(): + return self.run_cgi() + else: + return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self) + + def is_cgi(self): + """Test whether self.path corresponds to a CGI script. + + Returns True and updates the cgi_info attribute to the tuple + (dir, rest) if self.path requires running a CGI script. + Returns False otherwise. + + If any exception is raised, the caller should assume that + self.path was rejected as invalid and act accordingly. + + The default implementation tests whether the normalized url + path begins with one of the strings in self.cgi_directories + (and the next character is a '/' or the end of the string). + """ + collapsed_path = _url_collapse_path(self.path) + dir_sep = collapsed_path.find('/', 1) + head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:] + if head in self.cgi_directories: + self.cgi_info = head, tail + return True + return False + + cgi_directories = ['/cgi-bin', '/htbin'] + + def is_executable(self, path): + """Test whether argument path is an executable file.""" + return executable(path) + + def is_python(self, path): + """Test whether argument path is a Python script.""" + head, tail = os.path.splitext(path) + return tail.lower() in (".py", ".pyw") + + def run_cgi(self): + """Execute a CGI script.""" + path = self.path + dir, rest = self.cgi_info + + i = path.find('/', len(dir) + 1) + while i >= 0: + nextdir = path[:i] + nextrest = path[i+1:] + + scriptdir = self.translate_path(nextdir) + if os.path.isdir(scriptdir): + dir, rest = nextdir, nextrest + i = path.find('/', len(dir) + 1) + else: + break + + # find an explicit query string, if present. + i = rest.rfind('?') + if i >= 0: + rest, query = rest[:i], rest[i+1:] + else: + query = '' + + # dissect the part after the directory name into a script name & + # a possible additional path, to be stored in PATH_INFO. + i = rest.find('/') + if i >= 0: + script, rest = rest[:i], rest[i:] + else: + script, rest = rest, '' + + scriptname = dir + '/' + script + scriptfile = self.translate_path(scriptname) + if not os.path.exists(scriptfile): + self.send_error(404, "No such CGI script (%r)" % scriptname) + return + if not os.path.isfile(scriptfile): + self.send_error(403, "CGI script is not a plain file (%r)" % + scriptname) + return + ispy = self.is_python(scriptname) + if not ispy: + if not (self.have_fork or self.have_popen2 or self.have_popen3): + self.send_error(403, "CGI script is not a Python script (%r)" % + scriptname) + return + if not self.is_executable(scriptfile): + self.send_error(403, "CGI script is not executable (%r)" % + scriptname) + return + + # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html + # XXX Much of the following could be prepared ahead of time! + env = copy.deepcopy(os.environ) + env['SERVER_SOFTWARE'] = self.version_string() + env['SERVER_NAME'] = self.server.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PROTOCOL'] = self.protocol_version + env['SERVER_PORT'] = str(self.server.server_port) + env['REQUEST_METHOD'] = self.command + uqrest = urllib.unquote(rest) + env['PATH_INFO'] = uqrest + env['PATH_TRANSLATED'] = self.translate_path(uqrest) + env['SCRIPT_NAME'] = scriptname + if query: + env['QUERY_STRING'] = query + host = self.address_string() + if host != self.client_address[0]: + env['REMOTE_HOST'] = host + env['REMOTE_ADDR'] = self.client_address[0] + authorization = self.headers.getheader("authorization") + if authorization: + authorization = authorization.split() + if len(authorization) == 2: + import base64, binascii + env['AUTH_TYPE'] = authorization[0] + if authorization[0].lower() == "basic": + try: + authorization = base64.decodestring(authorization[1]) + except binascii.Error: + pass + else: + authorization = authorization.split(':') + if len(authorization) == 2: + env['REMOTE_USER'] = authorization[0] + # XXX REMOTE_IDENT + if self.headers.typeheader is None: + env['CONTENT_TYPE'] = self.headers.type + else: + env['CONTENT_TYPE'] = self.headers.typeheader + length = self.headers.getheader('content-length') + if length: + env['CONTENT_LENGTH'] = length + referer = self.headers.getheader('referer') + if referer: + env['HTTP_REFERER'] = referer + accept = [] + for line in self.headers.getallmatchingheaders('accept'): + if line[:1] in "\t\n\r ": + accept.append(line.strip()) + else: + accept = accept + line[7:].split(',') + env['HTTP_ACCEPT'] = ','.join(accept) + ua = self.headers.getheader('user-agent') + if ua: + env['HTTP_USER_AGENT'] = ua + co = filter(None, self.headers.getheaders('cookie')) + if co: + env['HTTP_COOKIE'] = ', '.join(co) + # XXX Other HTTP_* headers + # Since we're setting the env in the parent, provide empty + # values to override previously set values + for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH', + 'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'): + env.setdefault(k, "") + + self.send_response(200, "Script output follows") + + decoded_query = query.replace('+', ' ') + + if self.have_fork: + # Unix -- fork as we should + args = [script] + if '=' not in decoded_query: + args.append(decoded_query) + nobody = nobody_uid() + self.wfile.flush() # Always flush before forking + pid = os.fork() + if pid != 0: + # Parent + pid, sts = os.waitpid(pid, 0) + # throw away additional data [see bug #427345] + while select.select([self.rfile], [], [], 0)[0]: + if not self.rfile.read(1): + break + if sts: + self.log_error("CGI script exit status %#x", sts) + return + # Child + try: + try: + os.setuid(nobody) + except os.error: + pass + os.dup2(self.rfile.fileno(), 0) + os.dup2(self.wfile.fileno(), 1) + os.execve(scriptfile, args, env) + except: + self.server.handle_error(self.request, self.client_address) + os._exit(127) + + else: + # Non Unix - use subprocess + import subprocess + cmdline = [scriptfile] + if self.is_python(scriptfile): + interp = sys.executable + if interp.lower().endswith("w.exe"): + # On Windows, use python.exe, not pythonw.exe + interp = interp[:-5] + interp[-4:] + cmdline = [interp, '-u'] + cmdline + if '=' not in query: + cmdline.append(query) + + self.log_message("command: %s", subprocess.list2cmdline(cmdline)) + try: + nbytes = int(length) + except (TypeError, ValueError): + nbytes = 0 + p = subprocess.Popen(cmdline, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + env = env + ) + if self.command.lower() == "post" and nbytes > 0: + data = self.rfile.read(nbytes) + else: + data = None + # throw away additional data [see bug #427345] + while select.select([self.rfile._sock], [], [], 0)[0]: + if not self.rfile._sock.recv(1): + break + stdout, stderr = p.communicate(data) + self.wfile.write(stdout) + if stderr: + self.log_error('%s', stderr) + p.stderr.close() + p.stdout.close() + status = p.returncode + if status: + self.log_error("CGI script exit status %#x", status) + else: + self.log_message("CGI script exited OK") + + +def _url_collapse_path(path): + """ + Given a URL path, remove extra '/'s and '.' path elements and collapse + any '..' references and returns a colllapsed path. + + Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. + The utility of this function is limited to is_cgi method and helps + preventing some security attacks. + + Returns: A tuple of (head, tail) where tail is everything after the final / + and head is everything before it. Head will always start with a '/' and, + if it contains anything else, never have a trailing '/'. + + Raises: IndexError if too many '..' occur within the path. + + """ + # Similar to os.path.split(os.path.normpath(path)) but specific to URL + # path semantics rather than local operating system semantics. + path_parts = path.split('/') + head_parts = [] + for part in path_parts[:-1]: + if part == '..': + head_parts.pop() # IndexError if more '..' than prior parts + elif part and part != '.': + head_parts.append( part ) + if path_parts: + tail_part = path_parts.pop() + if tail_part: + if tail_part == '..': + head_parts.pop() + tail_part = '' + elif tail_part == '.': + tail_part = '' + else: + tail_part = '' + + splitpath = ('/' + '/'.join(head_parts), tail_part) + collapsed_path = "/".join(splitpath) + + return collapsed_path + + +nobody = None + +def nobody_uid(): + """Internal routine to get nobody's uid""" + global nobody + if nobody: + return nobody + try: + import pwd + except ImportError: + return -1 + try: + nobody = pwd.getpwnam('nobody')[2] + except KeyError: + nobody = 1 + max(map(lambda x: x[2], pwd.getpwall())) + return nobody + + +def executable(path): + """Test for executable file.""" + try: + st = os.stat(path) + except os.error: + return False + return st.st_mode & 0111 != 0 + + +def test(HandlerClass = CGIHTTPRequestHandler, + ServerClass = BaseHTTPServer.HTTPServer): + SimpleHTTPServer.test(HandlerClass, ServerClass) + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/ConfigParser.py b/src/main/resources/PythonLibs/ConfigParser.py new file mode 100644 index 0000000000000000000000000000000000000000..7e6cdbc30a766f55933cca102afd564522a50806 --- /dev/null +++ b/src/main/resources/PythonLibs/ConfigParser.py @@ -0,0 +1,753 @@ +"""Configuration file parser. + +A setup file consists of sections, lead by a "[section]" header, +and followed by "name: value" entries, with continuations and such in +the style of RFC 822. + +The option values can contain format strings which refer to other values in +the same section, or values in a special [DEFAULT] section. + +For example: + + something: %(dir)s/whatever + +would resolve the "%(dir)s" to the value of dir. All reference +expansions are done late, on demand. + +Intrinsic defaults can be specified by passing them into the +ConfigParser constructor as a dictionary. + +class: + +ConfigParser -- responsible for parsing a list of + configuration files, and managing the parsed database. + + methods: + + __init__(defaults=None) + create the parser and specify a dictionary of intrinsic defaults. The + keys must be strings, the values must be appropriate for %()s string + interpolation. Note that `__name__' is always an intrinsic default; + its value is the section's name. + + sections() + return all the configuration section names, sans DEFAULT + + has_section(section) + return whether the given section exists + + has_option(section, option) + return whether the given option exists in the given section + + options(section) + return list of configuration options for the named section + + read(filenames) + read and parse the list of named configuration files, given by + name. A single filename is also allowed. Non-existing files + are ignored. Return list of successfully read files. + + readfp(fp, filename=None) + read and parse one configuration file, given as a file object. + The filename defaults to fp.name; it is only used in error + messages (if fp has no `name' attribute, the string `<???>' is used). + + get(section, option, raw=False, vars=None) + return a string value for the named option. All % interpolations are + expanded in the return values, based on the defaults passed into the + constructor and the DEFAULT section. Additional substitutions may be + provided using the `vars' argument, which must be a dictionary whose + contents override any pre-existing defaults. + + getint(section, options) + like get(), but convert value to an integer + + getfloat(section, options) + like get(), but convert value to a float + + getboolean(section, options) + like get(), but convert value to a boolean (currently case + insensitively defined as 0, false, no, off for False, and 1, true, + yes, on for True). Returns False or True. + + items(section, raw=False, vars=None) + return a list of tuples with (name, value) for each option + in the section. + + remove_section(section) + remove the given file section and all its options + + remove_option(section, option) + remove the given option from the given section + + set(section, option, value) + set the given option + + write(fp) + write the configuration state in .ini format +""" + +try: + from collections import OrderedDict as _default_dict +except ImportError: + # fallback for setup.py which hasn't yet built _collections + _default_dict = dict + +import re + +__all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError", + "InterpolationError", "InterpolationDepthError", + "InterpolationSyntaxError", "ParsingError", + "MissingSectionHeaderError", + "ConfigParser", "SafeConfigParser", "RawConfigParser", + "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] + +DEFAULTSECT = "DEFAULT" + +MAX_INTERPOLATION_DEPTH = 10 + + + +# exception classes +class Error(Exception): + """Base class for ConfigParser exceptions.""" + + def _get_message(self): + """Getter for 'message'; needed only to override deprecation in + BaseException.""" + return self.__message + + def _set_message(self, value): + """Setter for 'message'; needed only to override deprecation in + BaseException.""" + self.__message = value + + # BaseException.message has been deprecated since Python 2.6. To prevent + # DeprecationWarning from popping up over this pre-existing attribute, use + # a new property that takes lookup precedence. + message = property(_get_message, _set_message) + + def __init__(self, msg=''): + self.message = msg + Exception.__init__(self, msg) + + def __repr__(self): + return self.message + + __str__ = __repr__ + +class NoSectionError(Error): + """Raised when no section matches a requested option.""" + + def __init__(self, section): + Error.__init__(self, 'No section: %r' % (section,)) + self.section = section + self.args = (section, ) + +class DuplicateSectionError(Error): + """Raised when a section is multiply-created.""" + + def __init__(self, section): + Error.__init__(self, "Section %r already exists" % section) + self.section = section + self.args = (section, ) + +class NoOptionError(Error): + """A requested option was not found.""" + + def __init__(self, option, section): + Error.__init__(self, "No option %r in section: %r" % + (option, section)) + self.option = option + self.section = section + self.args = (option, section) + +class InterpolationError(Error): + """Base class for interpolation-related exceptions.""" + + def __init__(self, option, section, msg): + Error.__init__(self, msg) + self.option = option + self.section = section + self.args = (option, section, msg) + +class InterpolationMissingOptionError(InterpolationError): + """A string substitution required a setting which was not available.""" + + def __init__(self, option, section, rawval, reference): + msg = ("Bad value substitution:\n" + "\tsection: [%s]\n" + "\toption : %s\n" + "\tkey : %s\n" + "\trawval : %s\n" + % (section, option, reference, rawval)) + InterpolationError.__init__(self, option, section, msg) + self.reference = reference + self.args = (option, section, rawval, reference) + +class InterpolationSyntaxError(InterpolationError): + """Raised when the source text into which substitutions are made + does not conform to the required syntax.""" + +class InterpolationDepthError(InterpolationError): + """Raised when substitutions are nested too deeply.""" + + def __init__(self, option, section, rawval): + msg = ("Value interpolation too deeply recursive:\n" + "\tsection: [%s]\n" + "\toption : %s\n" + "\trawval : %s\n" + % (section, option, rawval)) + InterpolationError.__init__(self, option, section, msg) + self.args = (option, section, rawval) + +class ParsingError(Error): + """Raised when a configuration file does not follow legal syntax.""" + + def __init__(self, filename): + Error.__init__(self, 'File contains parsing errors: %s' % filename) + self.filename = filename + self.errors = [] + self.args = (filename, ) + + def append(self, lineno, line): + self.errors.append((lineno, line)) + self.message += '\n\t[line %2d]: %s' % (lineno, line) + +class MissingSectionHeaderError(ParsingError): + """Raised when a key-value pair is found before any section header.""" + + def __init__(self, filename, lineno, line): + Error.__init__( + self, + 'File contains no section headers.\nfile: %s, line: %d\n%r' % + (filename, lineno, line)) + self.filename = filename + self.lineno = lineno + self.line = line + self.args = (filename, lineno, line) + + +class RawConfigParser: + def __init__(self, defaults=None, dict_type=_default_dict, + allow_no_value=False): + self._dict = dict_type + self._sections = self._dict() + self._defaults = self._dict() + if allow_no_value: + self._optcre = self.OPTCRE_NV + else: + self._optcre = self.OPTCRE + if defaults: + for key, value in defaults.items(): + self._defaults[self.optionxform(key)] = value + + def defaults(self): + return self._defaults + + def sections(self): + """Return a list of section names, excluding [DEFAULT]""" + # self._sections will never have [DEFAULT] in it + return self._sections.keys() + + def add_section(self, section): + """Create a new section in the configuration. + + Raise DuplicateSectionError if a section by the specified name + already exists. Raise ValueError if name is DEFAULT or any of it's + case-insensitive variants. + """ + if section.lower() == "default": + raise ValueError, 'Invalid section name: %s' % section + + if section in self._sections: + raise DuplicateSectionError(section) + self._sections[section] = self._dict() + + def has_section(self, section): + """Indicate whether the named section is present in the configuration. + + The DEFAULT section is not acknowledged. + """ + return section in self._sections + + def options(self, section): + """Return a list of option names for the given section name.""" + try: + opts = self._sections[section].copy() + except KeyError: + raise NoSectionError(section) + opts.update(self._defaults) + if '__name__' in opts: + del opts['__name__'] + return opts.keys() + + def read(self, filenames): + """Read and parse a filename or a list of filenames. + + Files that cannot be opened are silently ignored; this is + designed so that you can specify a list of potential + configuration file locations (e.g. current directory, user's + home directory, systemwide directory), and all existing + configuration files in the list will be read. A single + filename may also be given. + + Return list of successfully read files. + """ + if isinstance(filenames, basestring): + filenames = [filenames] + read_ok = [] + for filename in filenames: + try: + fp = open(filename) + except IOError: + continue + self._read(fp, filename) + fp.close() + read_ok.append(filename) + return read_ok + + def readfp(self, fp, filename=None): + """Like read() but the argument must be a file-like object. + + The `fp' argument must have a `readline' method. Optional + second argument is the `filename', which if not given, is + taken from fp.name. If fp has no `name' attribute, `<???>' is + used. + + """ + if filename is None: + try: + filename = fp.name + except AttributeError: + filename = '<???>' + self._read(fp, filename) + + def get(self, section, option): + opt = self.optionxform(option) + if section not in self._sections: + if section != DEFAULTSECT: + raise NoSectionError(section) + if opt in self._defaults: + return self._defaults[opt] + else: + raise NoOptionError(option, section) + elif opt in self._sections[section]: + return self._sections[section][opt] + elif opt in self._defaults: + return self._defaults[opt] + else: + raise NoOptionError(option, section) + + def items(self, section): + try: + d2 = self._sections[section] + except KeyError: + if section != DEFAULTSECT: + raise NoSectionError(section) + d2 = self._dict() + d = self._defaults.copy() + d.update(d2) + if "__name__" in d: + del d["__name__"] + return d.items() + + def _get(self, section, conv, option): + return conv(self.get(section, option)) + + def getint(self, section, option): + return self._get(section, int, option) + + def getfloat(self, section, option): + return self._get(section, float, option) + + _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True, + '0': False, 'no': False, 'false': False, 'off': False} + + def getboolean(self, section, option): + v = self.get(section, option) + if v.lower() not in self._boolean_states: + raise ValueError, 'Not a boolean: %s' % v + return self._boolean_states[v.lower()] + + def optionxform(self, optionstr): + return optionstr.lower() + + def has_option(self, section, option): + """Check for the existence of a given option in a given section.""" + if not section or section == DEFAULTSECT: + option = self.optionxform(option) + return option in self._defaults + elif section not in self._sections: + return False + else: + option = self.optionxform(option) + return (option in self._sections[section] + or option in self._defaults) + + def set(self, section, option, value=None): + """Set an option.""" + if not section or section == DEFAULTSECT: + sectdict = self._defaults + else: + try: + sectdict = self._sections[section] + except KeyError: + raise NoSectionError(section) + sectdict[self.optionxform(option)] = value + + def write(self, fp): + """Write an .ini-format representation of the configuration state.""" + if self._defaults: + fp.write("[%s]\n" % DEFAULTSECT) + for (key, value) in self._defaults.items(): + fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) + fp.write("\n") + for section in self._sections: + fp.write("[%s]\n" % section) + for (key, value) in self._sections[section].items(): + if key == "__name__": + continue + if (value is not None) or (self._optcre == self.OPTCRE): + key = " = ".join((key, str(value).replace('\n', '\n\t'))) + fp.write("%s\n" % (key)) + fp.write("\n") + + def remove_option(self, section, option): + """Remove an option.""" + if not section or section == DEFAULTSECT: + sectdict = self._defaults + else: + try: + sectdict = self._sections[section] + except KeyError: + raise NoSectionError(section) + option = self.optionxform(option) + existed = option in sectdict + if existed: + del sectdict[option] + return existed + + def remove_section(self, section): + """Remove a file section.""" + existed = section in self._sections + if existed: + del self._sections[section] + return existed + + # + # Regular expressions for parsing section headers and options. + # + SECTCRE = re.compile( + r'\[' # [ + r'(?P<header>[^]]+)' # very permissive! + r'\]' # ] + ) + OPTCRE = re.compile( + r'(?P<option>[^:=\s][^:=]*)' # very permissive! + r'\s*(?P<vi>[:=])\s*' # any number of space/tab, + # followed by separator + # (either : or =), followed + # by any # space/tab + r'(?P<value>.*)$' # everything up to eol + ) + OPTCRE_NV = re.compile( + r'(?P<option>[^:=\s][^:=]*)' # very permissive! + r'\s*(?:' # any number of space/tab, + r'(?P<vi>[:=])\s*' # optionally followed by + # separator (either : or + # =), followed by any # + # space/tab + r'(?P<value>.*))?$' # everything up to eol + ) + + def _read(self, fp, fpname): + """Parse a sectioned setup file. + + The sections in setup file contains a title line at the top, + indicated by a name in square brackets (`[]'), plus key/value + options lines, indicated by `name: value' format lines. + Continuations are represented by an embedded newline then + leading whitespace. Blank lines, lines beginning with a '#', + and just about everything else are ignored. + """ + cursect = None # None, or a dictionary + optname = None + lineno = 0 + e = None # None, or an exception + while True: + line = fp.readline() + if not line: + break + lineno = lineno + 1 + # comment or blank line? + if line.strip() == '' or line[0] in '#;': + continue + if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": + # no leading whitespace + continue + # continuation line? + if line[0].isspace() and cursect is not None and optname: + value = line.strip() + if value: + cursect[optname].append(value) + # a section header or option header? + else: + # is it a section header? + mo = self.SECTCRE.match(line) + if mo: + sectname = mo.group('header') + if sectname in self._sections: + cursect = self._sections[sectname] + elif sectname == DEFAULTSECT: + cursect = self._defaults + else: + cursect = self._dict() + cursect['__name__'] = sectname + self._sections[sectname] = cursect + # So sections can't start with a continuation line + optname = None + # no section header in the file? + elif cursect is None: + raise MissingSectionHeaderError(fpname, lineno, line) + # an option line? + else: + mo = self._optcre.match(line) + if mo: + optname, vi, optval = mo.group('option', 'vi', 'value') + optname = self.optionxform(optname.rstrip()) + # This check is fine because the OPTCRE cannot + # match if it would set optval to None + if optval is not None: + if vi in ('=', ':') and ';' in optval: + # ';' is a comment delimiter only if it follows + # a spacing character + pos = optval.find(';') + if pos != -1 and optval[pos-1].isspace(): + optval = optval[:pos] + optval = optval.strip() + # allow empty values + if optval == '""': + optval = '' + cursect[optname] = [optval] + else: + # valueless option handling + cursect[optname] = optval + else: + # a non-fatal parsing error occurred. set up the + # exception but keep going. the exception will be + # raised at the end of the file and will contain a + # list of all bogus lines + if not e: + e = ParsingError(fpname) + e.append(lineno, repr(line)) + # if any parsing errors occurred, raise an exception + if e: + raise e + + # join the multi-line values collected while reading + all_sections = [self._defaults] + all_sections.extend(self._sections.values()) + for options in all_sections: + for name, val in options.items(): + if isinstance(val, list): + options[name] = '\n'.join(val) + +import UserDict as _UserDict + +class _Chainmap(_UserDict.DictMixin): + """Combine multiple mappings for successive lookups. + + For example, to emulate Python's normal lookup sequence: + + import __builtin__ + pylookup = _Chainmap(locals(), globals(), vars(__builtin__)) + """ + + def __init__(self, *maps): + self._maps = maps + + def __getitem__(self, key): + for mapping in self._maps: + try: + return mapping[key] + except KeyError: + pass + raise KeyError(key) + + def keys(self): + result = [] + seen = set() + for mapping in self._maps: + for key in mapping: + if key not in seen: + result.append(key) + seen.add(key) + return result + +class ConfigParser(RawConfigParser): + + def get(self, section, option, raw=False, vars=None): + """Get an option value for a given section. + + If `vars' is provided, it must be a dictionary. The option is looked up + in `vars' (if provided), `section', and in `defaults' in that order. + + All % interpolations are expanded in the return values, unless the + optional argument `raw' is true. Values for interpolation keys are + looked up in the same manner as the option. + + The section DEFAULT is special. + """ + sectiondict = {} + try: + sectiondict = self._sections[section] + except KeyError: + if section != DEFAULTSECT: + raise NoSectionError(section) + # Update with the entry specific variables + vardict = {} + if vars: + for key, value in vars.items(): + vardict[self.optionxform(key)] = value + d = _Chainmap(vardict, sectiondict, self._defaults) + option = self.optionxform(option) + try: + value = d[option] + except KeyError: + raise NoOptionError(option, section) + + if raw or value is None: + return value + else: + return self._interpolate(section, option, value, d) + + def items(self, section, raw=False, vars=None): + """Return a list of tuples with (name, value) for each option + in the section. + + All % interpolations are expanded in the return values, based on the + defaults passed into the constructor, unless the optional argument + `raw' is true. Additional substitutions may be provided using the + `vars' argument, which must be a dictionary whose contents overrides + any pre-existing defaults. + + The section DEFAULT is special. + """ + d = self._defaults.copy() + try: + d.update(self._sections[section]) + except KeyError: + if section != DEFAULTSECT: + raise NoSectionError(section) + # Update with the entry specific variables + if vars: + for key, value in vars.items(): + d[self.optionxform(key)] = value + options = d.keys() + if "__name__" in options: + options.remove("__name__") + if raw: + return [(option, d[option]) + for option in options] + else: + return [(option, self._interpolate(section, option, d[option], d)) + for option in options] + + def _interpolate(self, section, option, rawval, vars): + # do the string interpolation + value = rawval + depth = MAX_INTERPOLATION_DEPTH + while depth: # Loop through this until it's done + depth -= 1 + if value and "%(" in value: + value = self._KEYCRE.sub(self._interpolation_replace, value) + try: + value = value % vars + except KeyError, e: + raise InterpolationMissingOptionError( + option, section, rawval, e.args[0]) + else: + break + if value and "%(" in value: + raise InterpolationDepthError(option, section, rawval) + return value + + _KEYCRE = re.compile(r"%\(([^)]*)\)s|.") + + def _interpolation_replace(self, match): + s = match.group(1) + if s is None: + return match.group() + else: + return "%%(%s)s" % self.optionxform(s) + + +class SafeConfigParser(ConfigParser): + + def _interpolate(self, section, option, rawval, vars): + # do the string interpolation + L = [] + self._interpolate_some(option, L, rawval, section, vars, 1) + return ''.join(L) + + _interpvar_re = re.compile(r"%\(([^)]+)\)s") + + def _interpolate_some(self, option, accum, rest, section, map, depth): + if depth > MAX_INTERPOLATION_DEPTH: + raise InterpolationDepthError(option, section, rest) + while rest: + p = rest.find("%") + if p < 0: + accum.append(rest) + return + if p > 0: + accum.append(rest[:p]) + rest = rest[p:] + # p is no longer used + c = rest[1:2] + if c == "%": + accum.append("%") + rest = rest[2:] + elif c == "(": + m = self._interpvar_re.match(rest) + if m is None: + raise InterpolationSyntaxError(option, section, + "bad interpolation variable reference %r" % rest) + var = self.optionxform(m.group(1)) + rest = rest[m.end():] + try: + v = map[var] + except KeyError: + raise InterpolationMissingOptionError( + option, section, rest, var) + if "%" in v: + self._interpolate_some(option, accum, v, + section, map, depth + 1) + else: + accum.append(v) + else: + raise InterpolationSyntaxError( + option, section, + "'%%' must be followed by '%%' or '(', found: %r" % (rest,)) + + def set(self, section, option, value=None): + """Set an option. Extend ConfigParser.set: check for string values.""" + # The only legal non-string value if we allow valueless + # options is None, so we need to check if the value is a + # string if: + # - we do not allow valueless options, or + # - we allow valueless options but the value is not None + if self._optcre is self.OPTCRE or value: + if not isinstance(value, basestring): + raise TypeError("option values must be strings") + if value is not None: + # check for bad percent signs: + # first, replace all "good" interpolations + tmp_value = value.replace('%%', '') + tmp_value = self._interpvar_re.sub('', tmp_value) + # then, check if there's a lone percent sign left + if '%' in tmp_value: + raise ValueError("invalid interpolation syntax in %r at " + "position %d" % (value, tmp_value.find('%'))) + ConfigParser.set(self, section, option, value) diff --git a/src/main/resources/PythonLibs/Cookie.py b/src/main/resources/PythonLibs/Cookie.py new file mode 100644 index 0000000000000000000000000000000000000000..2eda48c0bb156c12c07ab1ac761b346e77c727db --- /dev/null +++ b/src/main/resources/PythonLibs/Cookie.py @@ -0,0 +1,761 @@ +#!/usr/bin/env python +# + +#### +# Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu> +# +# 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 +# Timothy O'Malley not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley 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. +# +#### +# +# Id: Cookie.py,v 2.29 2000/08/23 05:28:49 timo Exp +# by Timothy O'Malley <timo@alum.mit.edu> +# +# Cookie.py is a Python module for the handling of HTTP +# cookies as a Python dictionary. See RFC 2109 for more +# information on cookies. +# +# The original idea to treat Cookies as a dictionary came from +# Dave Mitchell (davem@magnet.com) in 1995, when he released the +# first version of nscookie.py. +# +#### + +r""" +Here's a sample session to show how to use this module. +At the moment, this is the only documentation. + +The Basics +---------- + +Importing is easy.. + + >>> import Cookie + +Most of the time you start by creating a cookie. Cookies come in +three flavors, each with slightly different encoding semantics, but +more on that later. + + >>> C = Cookie.SimpleCookie() + >>> C = Cookie.SerialCookie() + >>> C = Cookie.SmartCookie() + +[Note: Long-time users of Cookie.py will remember using +Cookie.Cookie() to create an Cookie object. Although deprecated, it +is still supported by the code. See the Backward Compatibility notes +for more information.] + +Once you've created your Cookie, you can add values just as if it were +a dictionary. + + >>> C = Cookie.SmartCookie() + >>> C["fig"] = "newton" + >>> C["sugar"] = "wafer" + >>> C.output() + 'Set-Cookie: fig=newton\r\nSet-Cookie: sugar=wafer' + +Notice that the printable representation of a Cookie is the +appropriate format for a Set-Cookie: header. This is the +default behavior. You can change the header and printed +attributes by using the .output() function + + >>> C = Cookie.SmartCookie() + >>> C["rocky"] = "road" + >>> C["rocky"]["path"] = "/cookie" + >>> print C.output(header="Cookie:") + Cookie: rocky=road; Path=/cookie + >>> print C.output(attrs=[], header="Cookie:") + Cookie: rocky=road + +The load() method of a Cookie extracts cookies from a string. In a +CGI script, you would use this method to extract the cookies from the +HTTP_COOKIE environment variable. + + >>> C = Cookie.SmartCookie() + >>> C.load("chips=ahoy; vienna=finger") + >>> C.output() + 'Set-Cookie: chips=ahoy\r\nSet-Cookie: vienna=finger' + +The load() method is darn-tootin smart about identifying cookies +within a string. Escaped quotation marks, nested semicolons, and other +such trickeries do not confuse it. + + >>> C = Cookie.SmartCookie() + >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";') + >>> print C + Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;" + +Each element of the Cookie also supports all of the RFC 2109 +Cookie attributes. Here's an example which sets the Path +attribute. + + >>> C = Cookie.SmartCookie() + >>> C["oreo"] = "doublestuff" + >>> C["oreo"]["path"] = "/" + >>> print C + Set-Cookie: oreo=doublestuff; Path=/ + +Each dictionary element has a 'value' attribute, which gives you +back the value associated with the key. + + >>> C = Cookie.SmartCookie() + >>> C["twix"] = "none for you" + >>> C["twix"].value + 'none for you' + + +A Bit More Advanced +------------------- + +As mentioned before, there are three different flavors of Cookie +objects, each with different encoding/decoding semantics. This +section briefly discusses the differences. + +SimpleCookie + +The SimpleCookie expects that all values should be standard strings. +Just to be sure, SimpleCookie invokes the str() builtin to convert +the value to a string, when the values are set dictionary-style. + + >>> C = Cookie.SimpleCookie() + >>> C["number"] = 7 + >>> C["string"] = "seven" + >>> C["number"].value + '7' + >>> C["string"].value + 'seven' + >>> C.output() + 'Set-Cookie: number=7\r\nSet-Cookie: string=seven' + + +SerialCookie + +The SerialCookie expects that all values should be serialized using +cPickle (or pickle, if cPickle isn't available). As a result of +serializing, SerialCookie can save almost any Python object to a +value, and recover the exact same object when the cookie has been +returned. (SerialCookie can yield some strange-looking cookie +values, however.) + + >>> C = Cookie.SerialCookie() + >>> C["number"] = 7 + >>> C["string"] = "seven" + >>> C["number"].value + 7 + >>> C["string"].value + 'seven' + >>> C.output() + 'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string="S\'seven\'\\012p1\\012."' + +Be warned, however, if SerialCookie cannot de-serialize a value (because +it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION. + + +SmartCookie + +The SmartCookie combines aspects of each of the other two flavors. +When setting a value in a dictionary-fashion, the SmartCookie will +serialize (ala cPickle) the value *if and only if* it isn't a +Python string. String objects are *not* serialized. Similarly, +when the load() method parses out values, it attempts to de-serialize +the value. If it fails, then it fallsback to treating the value +as a string. + + >>> C = Cookie.SmartCookie() + >>> C["number"] = 7 + >>> C["string"] = "seven" + >>> C["number"].value + 7 + >>> C["string"].value + 'seven' + >>> C.output() + 'Set-Cookie: number="I7\\012."\r\nSet-Cookie: string=seven' + + +Backwards Compatibility +----------------------- + +In order to keep compatibilty with earlier versions of Cookie.py, +it is still possible to use Cookie.Cookie() to create a Cookie. In +fact, this simply returns a SmartCookie. + + >>> C = Cookie.Cookie() + >>> print C.__class__.__name__ + SmartCookie + + +Finis. +""" #" +# ^ +# |----helps out font-lock + +# +# Import our required modules +# +import string + +try: + from cPickle import dumps, loads +except ImportError: + from pickle import dumps, loads + +import re, warnings + +__all__ = ["CookieError","BaseCookie","SimpleCookie","SerialCookie", + "SmartCookie","Cookie"] + +_nulljoin = ''.join +_semispacejoin = '; '.join +_spacejoin = ' '.join + +# +# Define an exception visible to External modules +# +class CookieError(Exception): + pass + + +# These quoting routines conform to the RFC2109 specification, which in +# turn references the character definitions from RFC2068. They provide +# a two-way quoting algorithm. Any non-text character is translated +# into a 4 character sequence: a forward-slash followed by the +# three-digit octal equivalent of the character. Any '\' or '"' is +# quoted with a preceeding '\' slash. +# +# These are taken from RFC2068 and RFC2109. +# _LegalChars is the list of chars which don't require "'s +# _Translator hash-table for fast quoting +# +_LegalChars = string.ascii_letters + string.digits + "!#$%&'*+-.^_`|~" +_Translator = { + '\000' : '\\000', '\001' : '\\001', '\002' : '\\002', + '\003' : '\\003', '\004' : '\\004', '\005' : '\\005', + '\006' : '\\006', '\007' : '\\007', '\010' : '\\010', + '\011' : '\\011', '\012' : '\\012', '\013' : '\\013', + '\014' : '\\014', '\015' : '\\015', '\016' : '\\016', + '\017' : '\\017', '\020' : '\\020', '\021' : '\\021', + '\022' : '\\022', '\023' : '\\023', '\024' : '\\024', + '\025' : '\\025', '\026' : '\\026', '\027' : '\\027', + '\030' : '\\030', '\031' : '\\031', '\032' : '\\032', + '\033' : '\\033', '\034' : '\\034', '\035' : '\\035', + '\036' : '\\036', '\037' : '\\037', + + # Because of the way browsers really handle cookies (as opposed + # to what the RFC says) we also encode , and ; + + ',' : '\\054', ';' : '\\073', + + '"' : '\\"', '\\' : '\\\\', + + '\177' : '\\177', '\200' : '\\200', '\201' : '\\201', + '\202' : '\\202', '\203' : '\\203', '\204' : '\\204', + '\205' : '\\205', '\206' : '\\206', '\207' : '\\207', + '\210' : '\\210', '\211' : '\\211', '\212' : '\\212', + '\213' : '\\213', '\214' : '\\214', '\215' : '\\215', + '\216' : '\\216', '\217' : '\\217', '\220' : '\\220', + '\221' : '\\221', '\222' : '\\222', '\223' : '\\223', + '\224' : '\\224', '\225' : '\\225', '\226' : '\\226', + '\227' : '\\227', '\230' : '\\230', '\231' : '\\231', + '\232' : '\\232', '\233' : '\\233', '\234' : '\\234', + '\235' : '\\235', '\236' : '\\236', '\237' : '\\237', + '\240' : '\\240', '\241' : '\\241', '\242' : '\\242', + '\243' : '\\243', '\244' : '\\244', '\245' : '\\245', + '\246' : '\\246', '\247' : '\\247', '\250' : '\\250', + '\251' : '\\251', '\252' : '\\252', '\253' : '\\253', + '\254' : '\\254', '\255' : '\\255', '\256' : '\\256', + '\257' : '\\257', '\260' : '\\260', '\261' : '\\261', + '\262' : '\\262', '\263' : '\\263', '\264' : '\\264', + '\265' : '\\265', '\266' : '\\266', '\267' : '\\267', + '\270' : '\\270', '\271' : '\\271', '\272' : '\\272', + '\273' : '\\273', '\274' : '\\274', '\275' : '\\275', + '\276' : '\\276', '\277' : '\\277', '\300' : '\\300', + '\301' : '\\301', '\302' : '\\302', '\303' : '\\303', + '\304' : '\\304', '\305' : '\\305', '\306' : '\\306', + '\307' : '\\307', '\310' : '\\310', '\311' : '\\311', + '\312' : '\\312', '\313' : '\\313', '\314' : '\\314', + '\315' : '\\315', '\316' : '\\316', '\317' : '\\317', + '\320' : '\\320', '\321' : '\\321', '\322' : '\\322', + '\323' : '\\323', '\324' : '\\324', '\325' : '\\325', + '\326' : '\\326', '\327' : '\\327', '\330' : '\\330', + '\331' : '\\331', '\332' : '\\332', '\333' : '\\333', + '\334' : '\\334', '\335' : '\\335', '\336' : '\\336', + '\337' : '\\337', '\340' : '\\340', '\341' : '\\341', + '\342' : '\\342', '\343' : '\\343', '\344' : '\\344', + '\345' : '\\345', '\346' : '\\346', '\347' : '\\347', + '\350' : '\\350', '\351' : '\\351', '\352' : '\\352', + '\353' : '\\353', '\354' : '\\354', '\355' : '\\355', + '\356' : '\\356', '\357' : '\\357', '\360' : '\\360', + '\361' : '\\361', '\362' : '\\362', '\363' : '\\363', + '\364' : '\\364', '\365' : '\\365', '\366' : '\\366', + '\367' : '\\367', '\370' : '\\370', '\371' : '\\371', + '\372' : '\\372', '\373' : '\\373', '\374' : '\\374', + '\375' : '\\375', '\376' : '\\376', '\377' : '\\377' + } + +_idmap = ''.join(chr(x) for x in xrange(256)) + +def _quote(str, LegalChars=_LegalChars, + idmap=_idmap, translate=string.translate): + # + # If the string does not need to be double-quoted, + # then just return the string. Otherwise, surround + # the string in doublequotes and precede quote (with a \) + # special characters. + # + if "" == translate(str, idmap, LegalChars): + return str + else: + return '"' + _nulljoin( map(_Translator.get, str, str) ) + '"' +# end _quote + + +_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]") +_QuotePatt = re.compile(r"[\\].") + +def _unquote(str): + # If there aren't any doublequotes, + # then there can't be any special characters. See RFC 2109. + if len(str) < 2: + return str + if str[0] != '"' or str[-1] != '"': + return str + + # We have to assume that we must decode this string. + # Down to work. + + # Remove the "s + str = str[1:-1] + + # Check for special sequences. Examples: + # \012 --> \n + # \" --> " + # + i = 0 + n = len(str) + res = [] + while 0 <= i < n: + Omatch = _OctalPatt.search(str, i) + Qmatch = _QuotePatt.search(str, i) + if not Omatch and not Qmatch: # Neither matched + res.append(str[i:]) + break + # else: + j = k = -1 + if Omatch: j = Omatch.start(0) + if Qmatch: k = Qmatch.start(0) + if Qmatch and ( not Omatch or k < j ): # QuotePatt matched + res.append(str[i:k]) + res.append(str[k+1]) + i = k+2 + else: # OctalPatt matched + res.append(str[i:j]) + res.append( chr( int(str[j+1:j+4], 8) ) ) + i = j+4 + return _nulljoin(res) +# end _unquote + +# The _getdate() routine is used to set the expiration time in +# the cookie's HTTP header. By default, _getdate() returns the +# current time in the appropriate "expires" format for a +# Set-Cookie header. The one optional argument is an offset from +# now, in seconds. For example, an offset of -3600 means "one hour ago". +# The offset may be a floating point number. +# + +_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + +_monthname = [None, + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + +def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname): + from time import gmtime, time + now = time() + year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future) + return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % \ + (weekdayname[wd], day, monthname[month], year, hh, mm, ss) + + +# +# A class to hold ONE key,value pair. +# In a cookie, each such pair may have several attributes. +# so this class is used to keep the attributes associated +# with the appropriate key,value pair. +# This class also includes a coded_value attribute, which +# is used to hold the network representation of the +# value. This is most useful when Python objects are +# pickled for network transit. +# + +class Morsel(dict): + # RFC 2109 lists these attributes as reserved: + # path comment domain + # max-age secure version + # + # For historical reasons, these attributes are also reserved: + # expires + # + # This is an extension from Microsoft: + # httponly + # + # This dictionary provides a mapping from the lowercase + # variant on the left to the appropriate traditional + # formatting on the right. + _reserved = { "expires" : "expires", + "path" : "Path", + "comment" : "Comment", + "domain" : "Domain", + "max-age" : "Max-Age", + "secure" : "secure", + "httponly" : "httponly", + "version" : "Version", + } + + def __init__(self): + # Set defaults + self.key = self.value = self.coded_value = None + + # Set default attributes + for K in self._reserved: + dict.__setitem__(self, K, "") + # end __init__ + + def __setitem__(self, K, V): + K = K.lower() + if not K in self._reserved: + raise CookieError("Invalid Attribute %s" % K) + dict.__setitem__(self, K, V) + # end __setitem__ + + def isReservedKey(self, K): + return K.lower() in self._reserved + # end isReservedKey + + def set(self, key, val, coded_val, + LegalChars=_LegalChars, + idmap=_idmap, translate=string.translate): + # First we verify that the key isn't a reserved word + # Second we make sure it only contains legal characters + if key.lower() in self._reserved: + raise CookieError("Attempt to set a reserved key: %s" % key) + if "" != translate(key, idmap, LegalChars): + raise CookieError("Illegal key value: %s" % key) + + # It's a good key, so save it. + self.key = key + self.value = val + self.coded_value = coded_val + # end set + + def output(self, attrs=None, header = "Set-Cookie:"): + return "%s %s" % ( header, self.OutputString(attrs) ) + + __str__ = output + + def __repr__(self): + return '<%s: %s=%s>' % (self.__class__.__name__, + self.key, repr(self.value) ) + + def js_output(self, attrs=None): + # Print javascript + return """ + <script type="text/javascript"> + <!-- begin hiding + document.cookie = \"%s\"; + // end hiding --> + </script> + """ % ( self.OutputString(attrs).replace('"',r'\"'), ) + # end js_output() + + def OutputString(self, attrs=None): + # Build up our result + # + result = [] + RA = result.append + + # First, the key=value pair + RA("%s=%s" % (self.key, self.coded_value)) + + # Now add any defined attributes + if attrs is None: + attrs = self._reserved + items = self.items() + items.sort() + for K,V in items: + if V == "": continue + if K not in attrs: continue + if K == "expires" and type(V) == type(1): + RA("%s=%s" % (self._reserved[K], _getdate(V))) + elif K == "max-age" and type(V) == type(1): + RA("%s=%d" % (self._reserved[K], V)) + elif K == "secure": + RA(str(self._reserved[K])) + elif K == "httponly": + RA(str(self._reserved[K])) + else: + RA("%s=%s" % (self._reserved[K], V)) + + # Return the result + return _semispacejoin(result) + # end OutputString +# end Morsel class + + + +# +# Pattern for finding cookie +# +# This used to be strict parsing based on the RFC2109 and RFC2068 +# specifications. I have since discovered that MSIE 3.0x doesn't +# follow the character rules outlined in those specs. As a +# result, the parsing rules here are less strict. +# + +_LegalCharsPatt = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=]" +_CookiePattern = re.compile( + r"(?x)" # This is a Verbose pattern + r"(?P<key>" # Start of group 'key' + ""+ _LegalCharsPatt +"+?" # Any word of at least one letter, nongreedy + r")" # End of group 'key' + r"\s*=\s*" # Equal Sign + r"(?P<val>" # Start of group 'val' + r'"(?:[^\\"]|\\.)*"' # Any doublequoted string + r"|" # or + r"\w{3},\s[\s\w\d-]{9,11}\s[\d:]{8}\sGMT" # Special case for "expires" attr + r"|" # or + ""+ _LegalCharsPatt +"*" # Any word or empty string + r")" # End of group 'val' + r"\s*;?" # Probably ending in a semi-colon + ) + + +# At long last, here is the cookie class. +# Using this class is almost just like using a dictionary. +# See this module's docstring for example usage. +# +class BaseCookie(dict): + # A container class for a set of Morsels + # + + def value_decode(self, val): + """real_value, coded_value = value_decode(STRING) + Called prior to setting a cookie's value from the network + representation. The VALUE is the value read from HTTP + header. + Override this function to modify the behavior of cookies. + """ + return val, val + # end value_encode + + def value_encode(self, val): + """real_value, coded_value = value_encode(VALUE) + Called prior to setting a cookie's value from the dictionary + representation. The VALUE is the value being assigned. + Override this function to modify the behavior of cookies. + """ + strval = str(val) + return strval, strval + # end value_encode + + def __init__(self, input=None): + if input: self.load(input) + # end __init__ + + def __set(self, key, real_value, coded_value): + """Private method for setting a cookie's value""" + M = self.get(key, Morsel()) + M.set(key, real_value, coded_value) + dict.__setitem__(self, key, M) + # end __set + + def __setitem__(self, key, value): + """Dictionary style assignment.""" + rval, cval = self.value_encode(value) + self.__set(key, rval, cval) + # end __setitem__ + + def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"): + """Return a string suitable for HTTP.""" + result = [] + items = self.items() + items.sort() + for K,V in items: + result.append( V.output(attrs, header) ) + return sep.join(result) + # end output + + __str__ = output + + def __repr__(self): + L = [] + items = self.items() + items.sort() + for K,V in items: + L.append( '%s=%s' % (K,repr(V.value) ) ) + return '<%s: %s>' % (self.__class__.__name__, _spacejoin(L)) + + def js_output(self, attrs=None): + """Return a string suitable for JavaScript.""" + result = [] + items = self.items() + items.sort() + for K,V in items: + result.append( V.js_output(attrs) ) + return _nulljoin(result) + # end js_output + + def load(self, rawdata): + """Load cookies from a string (presumably HTTP_COOKIE) or + from a dictionary. Loading cookies from a dictionary 'd' + is equivalent to calling: + map(Cookie.__setitem__, d.keys(), d.values()) + """ + if type(rawdata) == type(""): + self.__ParseString(rawdata) + else: + # self.update() wouldn't call our custom __setitem__ + for k, v in rawdata.items(): + self[k] = v + return + # end load() + + def __ParseString(self, str, patt=_CookiePattern): + i = 0 # Our starting point + n = len(str) # Length of string + M = None # current morsel + + while 0 <= i < n: + # Start looking for a cookie + match = patt.search(str, i) + if not match: break # No more cookies + + K,V = match.group("key"), match.group("val") + i = match.end(0) + + # Parse the key, value in case it's metainfo + if K[0] == "$": + # We ignore attributes which pertain to the cookie + # mechanism as a whole. See RFC 2109. + # (Does anyone care?) + if M: + M[ K[1:] ] = V + elif K.lower() in Morsel._reserved: + if M: + M[ K ] = _unquote(V) + else: + rval, cval = self.value_decode(V) + self.__set(K, rval, cval) + M = self[K] + # end __ParseString +# end BaseCookie class + +class SimpleCookie(BaseCookie): + """SimpleCookie + SimpleCookie supports strings as cookie values. When setting + the value using the dictionary assignment notation, SimpleCookie + calls the builtin str() to convert the value to a string. Values + received from HTTP are kept as strings. + """ + def value_decode(self, val): + return _unquote( val ), val + def value_encode(self, val): + strval = str(val) + return strval, _quote( strval ) +# end SimpleCookie + +class SerialCookie(BaseCookie): + """SerialCookie + SerialCookie supports arbitrary objects as cookie values. All + values are serialized (using cPickle) before being sent to the + client. All incoming values are assumed to be valid Pickle + representations. IF AN INCOMING VALUE IS NOT IN A VALID PICKLE + FORMAT, THEN AN EXCEPTION WILL BE RAISED. + + Note: Large cookie values add overhead because they must be + retransmitted on every HTTP transaction. + + Note: HTTP has a 2k limit on the size of a cookie. This class + does not check for this limit, so be careful!!! + """ + def __init__(self, input=None): + warnings.warn("SerialCookie class is insecure; do not use it", + DeprecationWarning) + BaseCookie.__init__(self, input) + # end __init__ + def value_decode(self, val): + # This could raise an exception! + return loads( _unquote(val) ), val + def value_encode(self, val): + return val, _quote( dumps(val) ) +# end SerialCookie + +class SmartCookie(BaseCookie): + """SmartCookie + SmartCookie supports arbitrary objects as cookie values. If the + object is a string, then it is quoted. If the object is not a + string, however, then SmartCookie will use cPickle to serialize + the object into a string representation. + + Note: Large cookie values add overhead because they must be + retransmitted on every HTTP transaction. + + Note: HTTP has a 2k limit on the size of a cookie. This class + does not check for this limit, so be careful!!! + """ + def __init__(self, input=None): + warnings.warn("Cookie/SmartCookie class is insecure; do not use it", + DeprecationWarning) + BaseCookie.__init__(self, input) + # end __init__ + def value_decode(self, val): + strval = _unquote(val) + try: + return loads(strval), val + except: + return strval, val + def value_encode(self, val): + if type(val) == type(""): + return val, _quote(val) + else: + return val, _quote( dumps(val) ) +# end SmartCookie + + +########################################################### +# Backwards Compatibility: Don't break any existing code! + +# We provide Cookie() as an alias for SmartCookie() +Cookie = SmartCookie + +# +########################################################### + +def _test(): + import doctest, Cookie + return doctest.testmod(Cookie) + +if __name__ == "__main__": + _test() + + +#Local Variables: +#tab-width: 4 +#end: diff --git a/src/main/resources/PythonLibs/DocXMLRPCServer.py b/src/main/resources/PythonLibs/DocXMLRPCServer.py new file mode 100644 index 0000000000000000000000000000000000000000..4064ec2e48d4ddcb5cfd5f9663cb5c143c7dd568 --- /dev/null +++ b/src/main/resources/PythonLibs/DocXMLRPCServer.py @@ -0,0 +1,279 @@ +"""Self documenting XML-RPC Server. + +This module can be used to create XML-RPC servers that +serve pydoc-style documentation in response to HTTP +GET requests. This documentation is dynamically generated +based on the functions and methods registered with the +server. + +This module is built upon the pydoc and SimpleXMLRPCServer +modules. +""" + +import pydoc +import inspect +import re +import sys + +from SimpleXMLRPCServer import (SimpleXMLRPCServer, + SimpleXMLRPCRequestHandler, + CGIXMLRPCRequestHandler, + resolve_dotted_attribute) + +class ServerHTMLDoc(pydoc.HTMLDoc): + """Class used to generate pydoc HTML document for a server""" + + 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 + + # XXX Note that this regular expression does not allow for the + # hyperlinking of arbitrary strings being used as method + # names. Only methods with names consisting of word characters + # and '.'s are hyperlinked. + pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|' + r'RFC[- ]?(\d+)|' + r'PEP[- ]?(\d+)|' + r'(self\.)?((?:\w|\.)+))\b') + while 1: + 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('"', '"') + 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 text[end:end+1] == '(': + results.append(self.namelink(name, methods, funcs, classes)) + elif selfdot: + results.append('self.<strong>%s</strong>' % name) + else: + results.append(self.namelink(name, classes)) + here = end + results.append(escape(text[here:])) + return ''.join(results) + + def docroutine(self, object, name, mod=None, + funcs={}, classes={}, methods={}, cl=None): + """Produce HTML documentation for a function or method object.""" + + anchor = (cl and cl.__name__ or '') + '-' + name + note = '' + + title = '<a name="%s"><strong>%s</strong></a>' % ( + self.escape(anchor), self.escape(name)) + + if inspect.ismethod(object): + args, varargs, varkw, defaults = inspect.getargspec(object.im_func) + # exclude the argument bound to the instance, it will be + # confusing to the non-Python user + argspec = inspect.formatargspec ( + args[1:], + varargs, + varkw, + defaults, + formatvalue=self.formatvalue + ) + elif inspect.isfunction(object): + args, varargs, varkw, defaults = inspect.getargspec(object) + argspec = inspect.formatargspec( + args, varargs, varkw, defaults, formatvalue=self.formatvalue) + else: + argspec = '(...)' + + if isinstance(object, tuple): + argspec = object[0] or argspec + docstring = object[1] or "" + else: + docstring = pydoc.getdoc(object) + + decl = title + argspec + (note and self.grey( + '<font face="helvetica, arial">%s</font>' % note)) + + doc = self.markup( + docstring, 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 docserver(self, server_name, package_documentation, methods): + """Produce HTML documentation for an XML-RPC server.""" + + fdict = {} + for key, value in methods.items(): + fdict[key] = '#-' + key + fdict[value] = fdict[key] + + server_name = self.escape(server_name) + head = '<big><big><strong>%s</strong></big></big>' % server_name + result = self.heading(head, '#ffffff', '#7799ee') + + doc = self.markup(package_documentation, self.preformat, fdict) + doc = doc and '<tt>%s</tt>' % doc + result = result + '<p>%s</p>\n' % doc + + contents = [] + method_items = sorted(methods.items()) + for key, value in method_items: + contents.append(self.docroutine(value, key, funcs=fdict)) + result = result + self.bigsection( + 'Methods', '#ffffff', '#eeaa77', pydoc.join(contents)) + + return result + +class XMLRPCDocGenerator: + """Generates documentation for an XML-RPC server. + + This class is designed as mix-in and should not + be constructed directly. + """ + + def __init__(self): + # setup variables used for HTML documentation + self.server_name = 'XML-RPC Server Documentation' + self.server_documentation = \ + "This server exports the following methods through the XML-RPC "\ + "protocol." + self.server_title = 'XML-RPC Server Documentation' + + def set_server_title(self, server_title): + """Set the HTML title of the generated server documentation""" + + self.server_title = server_title + + def set_server_name(self, server_name): + """Set the name of the generated HTML server documentation""" + + self.server_name = server_name + + def set_server_documentation(self, server_documentation): + """Set the documentation string for the entire server.""" + + self.server_documentation = server_documentation + + def generate_html_documentation(self): + """generate_html_documentation() => html documentation for the server + + Generates HTML documentation for the server using introspection for + installed functions and instances that do not implement the + _dispatch method. Alternatively, instances can choose to implement + the _get_method_argstring(method_name) method to provide the + argument string used in the documentation and the + _methodHelp(method_name) method to provide the help text used + in the documentation.""" + + methods = {} + + for method_name in self.system_listMethods(): + if method_name in self.funcs: + method = self.funcs[method_name] + elif self.instance is not None: + method_info = [None, None] # argspec, documentation + if hasattr(self.instance, '_get_method_argstring'): + method_info[0] = self.instance._get_method_argstring(method_name) + if hasattr(self.instance, '_methodHelp'): + method_info[1] = self.instance._methodHelp(method_name) + + method_info = tuple(method_info) + if method_info != (None, None): + method = method_info + elif not hasattr(self.instance, '_dispatch'): + try: + method = resolve_dotted_attribute( + self.instance, + method_name + ) + except AttributeError: + method = method_info + else: + method = method_info + else: + assert 0, "Could not find method in self.functions and no "\ + "instance installed" + + methods[method_name] = method + + documenter = ServerHTMLDoc() + documentation = documenter.docserver( + self.server_name, + self.server_documentation, + methods + ) + + return documenter.page(self.server_title, documentation) + +class DocXMLRPCRequestHandler(SimpleXMLRPCRequestHandler): + """XML-RPC and documentation request handler class. + + Handles all HTTP POST requests and attempts to decode them as + XML-RPC requests. + + Handles all HTTP GET requests and interprets them as requests + for documentation. + """ + + def do_GET(self): + """Handles the HTTP GET request. + + Interpret all HTTP GET requests as requests for server + documentation. + """ + # Check that the path is legal + if not self.is_rpc_path_valid(): + self.report_404() + return + + response = self.server.generate_html_documentation() + self.send_response(200) + self.send_header("Content-type", "text/html") + self.send_header("Content-length", str(len(response))) + self.end_headers() + self.wfile.write(response) + +class DocXMLRPCServer( SimpleXMLRPCServer, + XMLRPCDocGenerator): + """XML-RPC and HTML documentation server. + + Adds the ability to serve server documentation to the capabilities + of SimpleXMLRPCServer. + """ + + def __init__(self, addr, requestHandler=DocXMLRPCRequestHandler, + logRequests=1, allow_none=False, encoding=None, + bind_and_activate=True): + SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests, + allow_none, encoding, bind_and_activate) + XMLRPCDocGenerator.__init__(self) + +class DocCGIXMLRPCRequestHandler( CGIXMLRPCRequestHandler, + XMLRPCDocGenerator): + """Handler for XML-RPC data and documentation requests passed through + CGI""" + + def handle_get(self): + """Handles the HTTP GET request. + + Interpret all HTTP GET requests as requests for server + documentation. + """ + + response = self.generate_html_documentation() + + print 'Content-Type: text/html' + print 'Content-Length: %d' % len(response) + print + sys.stdout.write(response) + + def __init__(self): + CGIXMLRPCRequestHandler.__init__(self) + XMLRPCDocGenerator.__init__(self) diff --git a/src/main/resources/PythonLibs/HTMLParser.py b/src/main/resources/PythonLibs/HTMLParser.py new file mode 100644 index 0000000000000000000000000000000000000000..b336a4c31df64988f41f094cd9cb3912ff939d59 --- /dev/null +++ b/src/main/resources/PythonLibs/HTMLParser.py @@ -0,0 +1,472 @@ +"""A parser for HTML and XHTML.""" + +# This file is based on sgmllib.py, but the API is slightly different. + +# XXX There should be a way to distinguish between PCDATA (parsed +# character data -- the normal case), RCDATA (replaceable character +# data -- only char and entity references and end tags are special) +# and CDATA (character data -- only end tags are special). + + +import markupbase +import re + +# Regular expressions used for parsing + +interesting_normal = re.compile('[&<]') +incomplete = re.compile('&[a-zA-Z#]') + +entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') +charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]') + +starttagopen = re.compile('<[a-zA-Z]') +piclose = re.compile('>') +commentclose = re.compile(r'--\s*>') +tagfind = re.compile('([a-zA-Z][-.a-zA-Z0-9:_]*)(?:\s|/(?!>))*') +# see http://www.w3.org/TR/html5/tokenization.html#tag-open-state +# and http://www.w3.org/TR/html5/tokenization.html#tag-name-state +tagfind_tolerant = re.compile('[a-zA-Z][^\t\n\r\f />\x00]*') + +attrfind = re.compile( + r'((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' + r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') + +locatestarttagend = re.compile(r""" + <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name + (?:[\s/]* # optional whitespace before attribute name + (?:(?<=['"\s/])[^\s/>][^\s/=>]* # attribute name + (?:\s*=+\s* # value indicator + (?:'[^']*' # LITA-enclosed value + |"[^"]*" # LIT-enclosed value + |(?!['"])[^>\s]* # bare value + ) + )?(?:\s|/(?!>))* + )* + )? + \s* # trailing whitespace +""", re.VERBOSE) +endendtag = re.compile('>') +# the HTML 5 spec, section 8.1.2.2, doesn't allow spaces between +# </ and the tag name, so maybe this should be fixed +endtagfind = re.compile('</\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\s*>') + + +class HTMLParseError(Exception): + """Exception raised for all parse errors.""" + + def __init__(self, msg, position=(None, None)): + assert msg + self.msg = msg + self.lineno = position[0] + self.offset = position[1] + + def __str__(self): + result = self.msg + if self.lineno is not None: + result = result + ", at line %d" % self.lineno + if self.offset is not None: + result = result + ", column %d" % (self.offset + 1) + return result + + +class HTMLParser(markupbase.ParserBase): + """Find tags and other markup and call handler functions. + + Usage: + p = HTMLParser() + p.feed(data) + ... + p.close() + + Start tags are handled by calling self.handle_starttag() or + self.handle_startendtag(); end tags by self.handle_endtag(). The + data between tags is passed from the parser to the derived class + by calling self.handle_data() with the data as argument (the data + may be split up in arbitrary chunks). Entity references are + passed by calling self.handle_entityref() with the entity + reference as the argument. Numeric character references are + passed to self.handle_charref() with the string containing the + reference as the argument. + """ + + CDATA_CONTENT_ELEMENTS = ("script", "style") + + + def __init__(self): + """Initialize and reset this instance.""" + self.reset() + + def reset(self): + """Reset this instance. Loses all unprocessed data.""" + self.rawdata = '' + self.lasttag = '???' + self.interesting = interesting_normal + self.cdata_elem = None + markupbase.ParserBase.reset(self) + + def feed(self, data): + r"""Feed data to the parser. + + Call this as often as you want, with as little or as much text + as you want (may include '\n'). + """ + self.rawdata = self.rawdata + data + self.goahead(0) + + def close(self): + """Handle any buffered data.""" + self.goahead(1) + + def error(self, message): + raise HTMLParseError(message, self.getpos()) + + __starttag_text = None + + def get_starttag_text(self): + """Return full source of start tag: '<...>'.""" + return self.__starttag_text + + def set_cdata_mode(self, elem): + self.cdata_elem = elem.lower() + self.interesting = re.compile(r'</\s*%s\s*>' % self.cdata_elem, re.I) + + def clear_cdata_mode(self): + self.interesting = interesting_normal + self.cdata_elem = None + + # Internal -- handle data as far as reasonable. May leave state + # and data to be processed by a subsequent call. If 'end' is + # true, force handling all data as if followed by EOF marker. + def goahead(self, end): + rawdata = self.rawdata + i = 0 + n = len(rawdata) + while i < n: + match = self.interesting.search(rawdata, i) # < or & + if match: + j = match.start() + else: + if self.cdata_elem: + break + j = n + if i < j: self.handle_data(rawdata[i:j]) + i = self.updatepos(i, j) + if i == n: break + startswith = rawdata.startswith + if startswith('<', i): + if starttagopen.match(rawdata, i): # < + letter + k = self.parse_starttag(i) + elif startswith("</", i): + k = self.parse_endtag(i) + elif startswith("<!--", i): + k = self.parse_comment(i) + elif startswith("<?", i): + k = self.parse_pi(i) + elif startswith("<!", i): + k = self.parse_html_declaration(i) + elif (i + 1) < n: + self.handle_data("<") + k = i + 1 + else: + break + if k < 0: + if not end: + break + k = rawdata.find('>', i + 1) + if k < 0: + k = rawdata.find('<', i + 1) + if k < 0: + k = i + 1 + else: + k += 1 + self.handle_data(rawdata[i:k]) + i = self.updatepos(i, k) + elif startswith("&#", i): + match = charref.match(rawdata, i) + if match: + name = match.group()[2:-1] + self.handle_charref(name) + k = match.end() + if not startswith(';', k-1): + k = k - 1 + i = self.updatepos(i, k) + continue + else: + if ";" in rawdata[i:]: #bail by consuming &# + self.handle_data(rawdata[0:2]) + i = self.updatepos(i, 2) + break + elif startswith('&', i): + match = entityref.match(rawdata, i) + if match: + name = match.group(1) + self.handle_entityref(name) + k = match.end() + if not startswith(';', k-1): + k = k - 1 + i = self.updatepos(i, k) + continue + match = incomplete.match(rawdata, i) + if match: + # match.group() will contain at least 2 chars + if end and match.group() == rawdata[i:]: + self.error("EOF in middle of entity or char ref") + # incomplete + break + elif (i + 1) < n: + # not the end of the buffer, and can't be confused + # with some other construct + self.handle_data("&") + i = self.updatepos(i, i + 1) + else: + break + else: + assert 0, "interesting.search() lied" + # end while + if end and i < n and not self.cdata_elem: + self.handle_data(rawdata[i:n]) + i = self.updatepos(i, n) + self.rawdata = rawdata[i:] + + # Internal -- parse html declarations, return length or -1 if not terminated + # See w3.org/TR/html5/tokenization.html#markup-declaration-open-state + # See also parse_declaration in _markupbase + def parse_html_declaration(self, i): + rawdata = self.rawdata + if rawdata[i:i+2] != '<!': + self.error('unexpected call to parse_html_declaration()') + if rawdata[i:i+4] == '<!--': + # this case is actually already handled in goahead() + return self.parse_comment(i) + elif rawdata[i:i+3] == '<![': + return self.parse_marked_section(i) + elif rawdata[i:i+9].lower() == '<!doctype': + # find the closing > + gtpos = rawdata.find('>', i+9) + if gtpos == -1: + return -1 + self.handle_decl(rawdata[i+2:gtpos]) + return gtpos+1 + else: + return self.parse_bogus_comment(i) + + # Internal -- parse bogus comment, return length or -1 if not terminated + # see http://www.w3.org/TR/html5/tokenization.html#bogus-comment-state + def parse_bogus_comment(self, i, report=1): + rawdata = self.rawdata + if rawdata[i:i+2] not in ('<!', '</'): + self.error('unexpected call to parse_comment()') + pos = rawdata.find('>', i+2) + if pos == -1: + return -1 + if report: + self.handle_comment(rawdata[i+2:pos]) + return pos + 1 + + # Internal -- parse processing instr, return end or -1 if not terminated + def parse_pi(self, i): + rawdata = self.rawdata + assert rawdata[i:i+2] == '<?', 'unexpected call to parse_pi()' + match = piclose.search(rawdata, i+2) # > + if not match: + return -1 + j = match.start() + self.handle_pi(rawdata[i+2: j]) + j = match.end() + return j + + # Internal -- handle starttag, return end or -1 if not terminated + def parse_starttag(self, i): + self.__starttag_text = None + endpos = self.check_for_whole_start_tag(i) + if endpos < 0: + return endpos + rawdata = self.rawdata + self.__starttag_text = rawdata[i:endpos] + + # Now parse the data between i+1 and j into a tag and attrs + attrs = [] + match = tagfind.match(rawdata, i+1) + assert match, 'unexpected call to parse_starttag()' + k = match.end() + self.lasttag = tag = match.group(1).lower() + + while k < endpos: + m = attrfind.match(rawdata, k) + if not m: + break + attrname, rest, attrvalue = m.group(1, 2, 3) + if not rest: + attrvalue = None + elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ + attrvalue[:1] == '"' == attrvalue[-1:]: + attrvalue = attrvalue[1:-1] + if attrvalue: + attrvalue = self.unescape(attrvalue) + attrs.append((attrname.lower(), attrvalue)) + k = m.end() + + end = rawdata[k:endpos].strip() + if end not in (">", "/>"): + lineno, offset = self.getpos() + if "\n" in self.__starttag_text: + lineno = lineno + self.__starttag_text.count("\n") + offset = len(self.__starttag_text) \ + - self.__starttag_text.rfind("\n") + else: + offset = offset + len(self.__starttag_text) + self.handle_data(rawdata[i:endpos]) + return endpos + if end.endswith('/>'): + # XHTML-style empty tag: <span attr="value" /> + self.handle_startendtag(tag, attrs) + else: + self.handle_starttag(tag, attrs) + if tag in self.CDATA_CONTENT_ELEMENTS: + self.set_cdata_mode(tag) + return endpos + + # Internal -- check to see if we have a complete starttag; return end + # or -1 if incomplete. + def check_for_whole_start_tag(self, i): + rawdata = self.rawdata + m = locatestarttagend.match(rawdata, i) + if m: + j = m.end() + next = rawdata[j:j+1] + if next == ">": + return j + 1 + if next == "/": + if rawdata.startswith("/>", j): + return j + 2 + if rawdata.startswith("/", j): + # buffer boundary + return -1 + # else bogus input + self.updatepos(i, j + 1) + self.error("malformed empty start tag") + if next == "": + # end of input + return -1 + if next in ("abcdefghijklmnopqrstuvwxyz=/" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"): + # end of input in or before attribute value, or we have the + # '/' from a '/>' ending + return -1 + if j > i: + return j + else: + return i + 1 + raise AssertionError("we should not get here!") + + # Internal -- parse endtag, return end or -1 if incomplete + def parse_endtag(self, i): + rawdata = self.rawdata + assert rawdata[i:i+2] == "</", "unexpected call to parse_endtag" + match = endendtag.search(rawdata, i+1) # > + if not match: + return -1 + gtpos = match.end() + match = endtagfind.match(rawdata, i) # </ + tag + > + if not match: + if self.cdata_elem is not None: + self.handle_data(rawdata[i:gtpos]) + return gtpos + # find the name: w3.org/TR/html5/tokenization.html#tag-name-state + namematch = tagfind_tolerant.match(rawdata, i+2) + if not namematch: + # w3.org/TR/html5/tokenization.html#end-tag-open-state + if rawdata[i:i+3] == '</>': + return i+3 + else: + return self.parse_bogus_comment(i) + tagname = namematch.group().lower() + # consume and ignore other stuff between the name and the > + # Note: this is not 100% correct, since we might have things like + # </tag attr=">">, but looking for > after tha name should cover + # most of the cases and is much simpler + gtpos = rawdata.find('>', namematch.end()) + self.handle_endtag(tagname) + return gtpos+1 + + elem = match.group(1).lower() # script or style + if self.cdata_elem is not None: + if elem != self.cdata_elem: + self.handle_data(rawdata[i:gtpos]) + return gtpos + + self.handle_endtag(elem) + self.clear_cdata_mode() + return gtpos + + # Overridable -- finish processing of start+end tag: <tag.../> + def handle_startendtag(self, tag, attrs): + self.handle_starttag(tag, attrs) + self.handle_endtag(tag) + + # Overridable -- handle start tag + def handle_starttag(self, tag, attrs): + pass + + # Overridable -- handle end tag + def handle_endtag(self, tag): + pass + + # Overridable -- handle character reference + def handle_charref(self, name): + pass + + # Overridable -- handle entity reference + def handle_entityref(self, name): + pass + + # Overridable -- handle data + def handle_data(self, data): + pass + + # Overridable -- handle comment + def handle_comment(self, data): + pass + + # Overridable -- handle declaration + def handle_decl(self, decl): + pass + + # Overridable -- handle processing instruction + def handle_pi(self, data): + pass + + def unknown_decl(self, data): + pass + + # Internal -- helper to remove special character quoting + entitydefs = None + def unescape(self, s): + if '&' not in s: + return s + def replaceEntities(s): + s = s.groups()[0] + try: + if s[0] == "#": + s = s[1:] + if s[0] in ['x','X']: + c = int(s[1:], 16) + else: + c = int(s) + return unichr(c) + except ValueError: + return '&#'+s+';' + else: + # Cannot use name2codepoint directly, because HTMLParser supports apos, + # which is not part of HTML 4 + import htmlentitydefs + if HTMLParser.entitydefs is None: + entitydefs = HTMLParser.entitydefs = {'apos':u"'"} + for k, v in htmlentitydefs.name2codepoint.iteritems(): + entitydefs[k] = unichr(v) + try: + return self.entitydefs[s] + except KeyError: + return '&'+s+';' + + return re.sub(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));", replaceEntities, s) diff --git a/src/main/resources/PythonLibs/MimeWriter.py b/src/main/resources/PythonLibs/MimeWriter.py new file mode 100644 index 0000000000000000000000000000000000000000..e898f9ff231793672ae281c770666be8953be6ec --- /dev/null +++ b/src/main/resources/PythonLibs/MimeWriter.py @@ -0,0 +1,186 @@ +"""Generic MIME writer. + +This module defines the class MimeWriter. The MimeWriter class implements +a basic formatter for creating MIME multi-part files. It doesn't seek around +the output file nor does it use large amounts of buffer space. You must write +the parts out in the order that they should occur in the final file. +MimeWriter does buffer the headers you add, allowing you to rearrange their +order. + +""" + + +import mimetools + +__all__ = ["MimeWriter"] + +import warnings + +warnings.warn("the MimeWriter module is deprecated; use the email package instead", + DeprecationWarning, 2) + +class MimeWriter: + + """Generic MIME writer. + + Methods: + + __init__() + addheader() + flushheaders() + startbody() + startmultipartbody() + nextpart() + lastpart() + + A MIME writer is much more primitive than a MIME parser. It + doesn't seek around on the output file, and it doesn't use large + amounts of buffer space, so you have to write the parts in the + order they should occur on the output file. It does buffer the + headers you add, allowing you to rearrange their order. + + General usage is: + + f = <open the output file> + w = MimeWriter(f) + ...call w.addheader(key, value) 0 or more times... + + followed by either: + + f = w.startbody(content_type) + ...call f.write(data) for body data... + + or: + + w.startmultipartbody(subtype) + for each part: + subwriter = w.nextpart() + ...use the subwriter's methods to create the subpart... + w.lastpart() + + The subwriter is another MimeWriter instance, and should be + treated in the same way as the toplevel MimeWriter. This way, + writing recursive body parts is easy. + + Warning: don't forget to call lastpart()! + + XXX There should be more state so calls made in the wrong order + are detected. + + Some special cases: + + - startbody() just returns the file passed to the constructor; + but don't use this knowledge, as it may be changed. + + - startmultipartbody() actually returns a file as well; + this can be used to write the initial 'if you can read this your + mailer is not MIME-aware' message. + + - If you call flushheaders(), the headers accumulated so far are + written out (and forgotten); this is useful if you don't need a + body part at all, e.g. for a subpart of type message/rfc822 + that's (mis)used to store some header-like information. + + - Passing a keyword argument 'prefix=<flag>' to addheader(), + start*body() affects where the header is inserted; 0 means + append at the end, 1 means insert at the start; default is + append for addheader(), but insert for start*body(), which use + it to determine where the Content-Type header goes. + + """ + + def __init__(self, fp): + self._fp = fp + self._headers = [] + + def addheader(self, key, value, prefix=0): + """Add a header line to the MIME message. + + The key is the name of the header, where the value obviously provides + the value of the header. The optional argument prefix determines + where the header is inserted; 0 means append at the end, 1 means + insert at the start. The default is to append. + + """ + lines = value.split("\n") + while lines and not lines[-1]: del lines[-1] + while lines and not lines[0]: del lines[0] + for i in range(1, len(lines)): + lines[i] = " " + lines[i].strip() + value = "\n".join(lines) + "\n" + line = key + ": " + value + if prefix: + self._headers.insert(0, line) + else: + self._headers.append(line) + + def flushheaders(self): + """Writes out and forgets all headers accumulated so far. + + This is useful if you don't need a body part at all; for example, + for a subpart of type message/rfc822 that's (mis)used to store some + header-like information. + + """ + self._fp.writelines(self._headers) + self._headers = [] + + def startbody(self, ctype, plist=[], prefix=1): + """Returns a file-like object for writing the body of the message. + + The content-type is set to the provided ctype, and the optional + parameter, plist, provides additional parameters for the + content-type declaration. The optional argument prefix determines + where the header is inserted; 0 means append at the end, 1 means + insert at the start. The default is to insert at the start. + + """ + for name, value in plist: + ctype = ctype + ';\n %s=\"%s\"' % (name, value) + self.addheader("Content-Type", ctype, prefix=prefix) + self.flushheaders() + self._fp.write("\n") + return self._fp + + def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1): + """Returns a file-like object for writing the body of the message. + + Additionally, this method initializes the multi-part code, where the + subtype parameter provides the multipart subtype, the boundary + parameter may provide a user-defined boundary specification, and the + plist parameter provides optional parameters for the subtype. The + optional argument, prefix, determines where the header is inserted; + 0 means append at the end, 1 means insert at the start. The default + is to insert at the start. Subparts should be created using the + nextpart() method. + + """ + self._boundary = boundary or mimetools.choose_boundary() + return self.startbody("multipart/" + subtype, + [("boundary", self._boundary)] + plist, + prefix=prefix) + + def nextpart(self): + """Returns a new instance of MimeWriter which represents an + individual part in a multipart message. + + This may be used to write the part as well as used for creating + recursively complex multipart messages. The message must first be + initialized with the startmultipartbody() method before using the + nextpart() method. + + """ + self._fp.write("\n--" + self._boundary + "\n") + return self.__class__(self._fp) + + def lastpart(self): + """This is used to designate the last part of a multipart message. + + It should always be used when writing multipart messages. + + """ + self._fp.write("\n--" + self._boundary + "--\n") + + +if __name__ == '__main__': + import test.test_MimeWriter diff --git a/src/main/resources/PythonLibs/Queue.py b/src/main/resources/PythonLibs/Queue.py new file mode 100644 index 0000000000000000000000000000000000000000..2db8d76966535ac458d5f21ab5533dd4aca8297b --- /dev/null +++ b/src/main/resources/PythonLibs/Queue.py @@ -0,0 +1,244 @@ +"""A multi-producer, multi-consumer queue.""" + +from time import time as _time +try: + import threading as _threading +except ImportError: + import dummy_threading as _threading +from collections import deque +import heapq + +__all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue'] + +class Empty(Exception): + "Exception raised by Queue.get(block=0)/get_nowait()." + pass + +class Full(Exception): + "Exception raised by Queue.put(block=0)/put_nowait()." + pass + +class Queue: + """Create a queue object with a given maximum size. + + If maxsize is <= 0, the queue size is infinite. + """ + def __init__(self, maxsize=0): + self.maxsize = maxsize + self._init(maxsize) + # mutex must be held whenever the queue is mutating. All methods + # that acquire mutex must release it before returning. mutex + # is shared between the three conditions, so acquiring and + # releasing the conditions also acquires and releases mutex. + self.mutex = _threading.Lock() + # Notify not_empty whenever an item is added to the queue; a + # thread waiting to get is notified then. + self.not_empty = _threading.Condition(self.mutex) + # Notify not_full whenever an item is removed from the queue; + # a thread waiting to put is notified then. + self.not_full = _threading.Condition(self.mutex) + # Notify all_tasks_done whenever the number of unfinished tasks + # drops to zero; thread waiting to join() is notified to resume + self.all_tasks_done = _threading.Condition(self.mutex) + self.unfinished_tasks = 0 + + def task_done(self): + """Indicate that a formerly enqueued task is complete. + + Used by Queue consumer threads. For each get() used to fetch a task, + a subsequent call to task_done() tells the queue that the processing + on the task is complete. + + If a join() is currently blocking, it will resume when all items + have been processed (meaning that a task_done() call was received + for every item that had been put() into the queue). + + Raises a ValueError if called more times than there were items + placed in the queue. + """ + self.all_tasks_done.acquire() + try: + unfinished = self.unfinished_tasks - 1 + if unfinished <= 0: + if unfinished < 0: + raise ValueError('task_done() called too many times') + self.all_tasks_done.notify_all() + self.unfinished_tasks = unfinished + finally: + self.all_tasks_done.release() + + def join(self): + """Blocks until all items in the Queue have been gotten and processed. + + The count of unfinished tasks goes up whenever an item is added to the + queue. The count goes down whenever a consumer thread calls task_done() + to indicate the item was retrieved and all work on it is complete. + + When the count of unfinished tasks drops to zero, join() unblocks. + """ + self.all_tasks_done.acquire() + try: + while self.unfinished_tasks: + self.all_tasks_done.wait() + finally: + self.all_tasks_done.release() + + def qsize(self): + """Return the approximate size of the queue (not reliable!).""" + self.mutex.acquire() + n = self._qsize() + self.mutex.release() + return n + + def empty(self): + """Return True if the queue is empty, False otherwise (not reliable!).""" + self.mutex.acquire() + n = not self._qsize() + self.mutex.release() + return n + + def full(self): + """Return True if the queue is full, False otherwise (not reliable!).""" + self.mutex.acquire() + n = 0 < self.maxsize == self._qsize() + self.mutex.release() + return n + + def put(self, item, block=True, timeout=None): + """Put an item into the queue. + + If optional args 'block' is true and 'timeout' is None (the default), + block if necessary until a free slot is available. If 'timeout' is + a positive number, it blocks at most 'timeout' seconds and raises + the Full exception if no free slot was available within that time. + Otherwise ('block' is false), put an item on the queue if a free slot + is immediately available, else raise the Full exception ('timeout' + is ignored in that case). + """ + self.not_full.acquire() + try: + if self.maxsize > 0: + if not block: + if self._qsize() == self.maxsize: + raise Full + elif timeout is None: + while self._qsize() == self.maxsize: + self.not_full.wait() + elif timeout < 0: + raise ValueError("'timeout' must be a positive number") + else: + endtime = _time() + timeout + while self._qsize() == self.maxsize: + remaining = endtime - _time() + if remaining <= 0.0: + raise Full + self.not_full.wait(remaining) + self._put(item) + self.unfinished_tasks += 1 + self.not_empty.notify() + finally: + self.not_full.release() + + def put_nowait(self, item): + """Put an item into the queue without blocking. + + Only enqueue the item if a free slot is immediately available. + Otherwise raise the Full exception. + """ + return self.put(item, False) + + def get(self, block=True, timeout=None): + """Remove and return an item from the queue. + + If optional args 'block' is true and 'timeout' is None (the default), + block if necessary until an item is available. If 'timeout' is + a positive number, it blocks at most 'timeout' seconds and raises + the Empty exception if no item was available within that time. + Otherwise ('block' is false), return an item if one is immediately + available, else raise the Empty exception ('timeout' is ignored + in that case). + """ + self.not_empty.acquire() + try: + if not block: + if not self._qsize(): + raise Empty + elif timeout is None: + while not self._qsize(): + self.not_empty.wait() + elif timeout < 0: + raise ValueError("'timeout' must be a positive number") + else: + endtime = _time() + timeout + while not self._qsize(): + remaining = endtime - _time() + if remaining <= 0.0: + raise Empty + self.not_empty.wait(remaining) + item = self._get() + self.not_full.notify() + return item + finally: + self.not_empty.release() + + def get_nowait(self): + """Remove and return an item from the queue without blocking. + + Only get an item if one is immediately available. Otherwise + raise the Empty exception. + """ + return self.get(False) + + # Override these methods to implement other queue organizations + # (e.g. stack or priority queue). + # These will only be called with appropriate locks held + + # Initialize the queue representation + def _init(self, maxsize): + self.queue = deque() + + def _qsize(self, len=len): + return len(self.queue) + + # Put a new item in the queue + def _put(self, item): + self.queue.append(item) + + # Get an item from the queue + def _get(self): + return self.queue.popleft() + + +class PriorityQueue(Queue): + '''Variant of Queue that retrieves open entries in priority order (lowest first). + + Entries are typically tuples of the form: (priority number, data). + ''' + + def _init(self, maxsize): + self.queue = [] + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item, heappush=heapq.heappush): + heappush(self.queue, item) + + def _get(self, heappop=heapq.heappop): + return heappop(self.queue) + + +class LifoQueue(Queue): + '''Variant of Queue that retrieves most recently added entries first.''' + + def _init(self, maxsize): + self.queue = [] + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item): + self.queue.append(item) + + def _get(self): + return self.queue.pop() diff --git a/src/main/resources/PythonLibs/SimpleHTTPServer.py b/src/main/resources/PythonLibs/SimpleHTTPServer.py new file mode 100644 index 0000000000000000000000000000000000000000..c015742d19441da69c9b76f09af45877fa604018 --- /dev/null +++ b/src/main/resources/PythonLibs/SimpleHTTPServer.py @@ -0,0 +1,221 @@ +"""Simple HTTP Server. + +This module builds on BaseHTTPServer by implementing the standard GET +and HEAD requests in a fairly straightforward manner. + +""" + + +__version__ = "0.6" + +__all__ = ["SimpleHTTPRequestHandler"] + +import os +import posixpath +import BaseHTTPServer +import urllib +import cgi +import sys +import shutil +import mimetypes +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + + +class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + + """Simple HTTP request handler with GET and HEAD commands. + + This serves files from the current directory and any of its + subdirectories. The MIME type for files is determined by + calling the .guess_type() method. + + The GET and HEAD requests are identical except that the HEAD + request omits the actual contents of the file. + + """ + + server_version = "SimpleHTTP/" + __version__ + + def do_GET(self): + """Serve a GET request.""" + f = self.send_head() + if f: + self.copyfile(f, self.wfile) + f.close() + + def do_HEAD(self): + """Serve a HEAD request.""" + f = self.send_head() + if f: + f.close() + + def send_head(self): + """Common code for GET and HEAD commands. + + This sends the response code and MIME headers. + + Return value is either a file object (which has to be copied + to the outputfile by the caller unless the command was HEAD, + and must be closed by the caller under all circumstances), or + None, in which case the caller has nothing further to do. + + """ + path = self.translate_path(self.path) + f = None + if os.path.isdir(path): + if not self.path.endswith('/'): + # redirect browser - doing basically what apache does + self.send_response(301) + self.send_header("Location", self.path + "/") + self.end_headers() + return None + for index in "index.html", "index.htm": + index = os.path.join(path, index) + if os.path.exists(index): + path = index + break + else: + return self.list_directory(path) + ctype = self.guess_type(path) + try: + # Always read in binary mode. Opening files in text mode may cause + # newline translations, making the actual size of the content + # transmitted *less* than the content-length! + f = open(path, 'rb') + except IOError: + self.send_error(404, "File not found") + return None + self.send_response(200) + self.send_header("Content-type", ctype) + fs = os.fstat(f.fileno()) if hasattr(os, 'fstat') else os.stat(path) + self.send_header("Content-Length", str(fs[6])) + self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) + self.end_headers() + return f + + def list_directory(self, path): + """Helper to produce a directory listing (absent index.html). + + Return value is either a file object, or None (indicating an + error). In either case, the headers are sent, making the + interface the same as for send_head(). + + """ + try: + list = os.listdir(path) + except os.error: + self.send_error(404, "No permission to list directory") + return None + list.sort(key=lambda a: a.lower()) + f = StringIO() + displaypath = cgi.escape(urllib.unquote(self.path)) + f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">') + f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath) + f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath) + f.write("<hr>\n<ul>\n") + for name in list: + fullname = os.path.join(path, name) + displayname = linkname = name + # Append / for directories or @ for symbolic links + if os.path.isdir(fullname): + displayname = name + "/" + linkname = name + "/" + if os.path.islink(fullname): + displayname = name + "@" + # Note: a link to a directory displays with @ and links with / + f.write('<li><a href="%s">%s</a>\n' + % (urllib.quote(linkname), cgi.escape(displayname))) + f.write("</ul>\n<hr>\n</body>\n</html>\n") + length = f.tell() + f.seek(0) + self.send_response(200) + if not sys.platform.startswith("java"): + encoding = sys.getfilesystemencoding() + self.send_header("Content-type", "text/html; charset=%s" % encoding) + self.send_header("Content-Length", str(length)) + self.end_headers() + return f + + def translate_path(self, path): + """Translate a /-separated PATH to the local filename syntax. + + Components that mean special things to the local file system + (e.g. drive or directory names) are ignored. (XXX They should + probably be diagnosed.) + + """ + # abandon query parameters + path = path.split('?',1)[0] + path = path.split('#',1)[0] + path = posixpath.normpath(urllib.unquote(path)) + words = path.split('/') + words = filter(None, words) + path = os.getcwd() + for word in words: + drive, word = os.path.splitdrive(word) + head, word = os.path.split(word) + if word in (os.curdir, os.pardir): continue + path = os.path.join(path, word) + return path + + def copyfile(self, source, outputfile): + """Copy all data between two file objects. + + The SOURCE argument is a file object open for reading + (or anything with a read() method) and the DESTINATION + argument is a file object open for writing (or + anything with a write() method). + + The only reason for overriding this would be to change + the block size or perhaps to replace newlines by CRLF + -- note however that this the default server uses this + to copy binary data as well. + + """ + shutil.copyfileobj(source, outputfile) + + def guess_type(self, path): + """Guess the type of a file. + + Argument is a PATH (a filename). + + Return value is a string of the form type/subtype, + usable for a MIME Content-type header. + + The default implementation looks the file's extension + up in the table self.extensions_map, using application/octet-stream + as a default; however it would be permissible (if + slow) to look inside the data to make a better guess. + + """ + + base, ext = posixpath.splitext(path) + if ext in self.extensions_map: + return self.extensions_map[ext] + ext = ext.lower() + if ext in self.extensions_map: + return self.extensions_map[ext] + else: + return self.extensions_map[''] + + if not mimetypes.inited: + mimetypes.init() # try to read system mime.types + extensions_map = mimetypes.types_map.copy() + extensions_map.update({ + '': 'application/octet-stream', # Default + '.py': 'text/plain', + '.c': 'text/plain', + '.h': 'text/plain', + }) + + +def test(HandlerClass = SimpleHTTPRequestHandler, + ServerClass = BaseHTTPServer.HTTPServer): + BaseHTTPServer.test(HandlerClass, ServerClass) + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/SimpleXMLRPCServer.py b/src/main/resources/PythonLibs/SimpleXMLRPCServer.py new file mode 100644 index 0000000000000000000000000000000000000000..f15cd62f4cfb676502a574857cc80c934bc7ba3c --- /dev/null +++ b/src/main/resources/PythonLibs/SimpleXMLRPCServer.py @@ -0,0 +1,707 @@ +r"""Simple XML-RPC Server. + +This module can be used to create simple XML-RPC servers +by creating a server and either installing functions, a +class instance, or by extending the SimpleXMLRPCServer +class. + +It can also be used to handle XML-RPC requests in a CGI +environment using CGIXMLRPCRequestHandler. + +A list of possible usage patterns follows: + +1. Install functions: + +server = SimpleXMLRPCServer(("localhost", 8000)) +server.register_function(pow) +server.register_function(lambda x,y: x+y, 'add') +server.serve_forever() + +2. Install an instance: + +class MyFuncs: + def __init__(self): + # make all of the string functions available through + # string.func_name + import string + self.string = string + def _listMethods(self): + # implement this method so that system.listMethods + # knows to advertise the strings methods + return list_public_methods(self) + \ + ['string.' + method for method in list_public_methods(self.string)] + def pow(self, x, y): return pow(x, y) + def add(self, x, y) : return x + y + +server = SimpleXMLRPCServer(("localhost", 8000)) +server.register_introspection_functions() +server.register_instance(MyFuncs()) +server.serve_forever() + +3. Install an instance with custom dispatch method: + +class Math: + def _listMethods(self): + # this method must be present for system.listMethods + # to work + return ['add', 'pow'] + def _methodHelp(self, method): + # this method must be present for system.methodHelp + # to work + if method == 'add': + return "add(2,3) => 5" + elif method == 'pow': + return "pow(x, y[, z]) => number" + else: + # By convention, return empty + # string if no help is available + return "" + def _dispatch(self, method, params): + if method == 'pow': + return pow(*params) + elif method == 'add': + return params[0] + params[1] + else: + raise 'bad method' + +server = SimpleXMLRPCServer(("localhost", 8000)) +server.register_introspection_functions() +server.register_instance(Math()) +server.serve_forever() + +4. Subclass SimpleXMLRPCServer: + +class MathServer(SimpleXMLRPCServer): + def _dispatch(self, method, params): + try: + # We are forcing the 'export_' prefix on methods that are + # callable through XML-RPC to prevent potential security + # problems + func = getattr(self, 'export_' + method) + except AttributeError: + raise Exception('method "%s" is not supported' % method) + else: + return func(*params) + + def export_add(self, x, y): + return x + y + +server = MathServer(("localhost", 8000)) +server.serve_forever() + +5. CGI script: + +server = CGIXMLRPCRequestHandler() +server.register_function(pow) +server.handle_request() +""" + +# Written by Brian Quinlan (brian@sweetapp.com). +# Based on code written by Fredrik Lundh. + +import xmlrpclib +from xmlrpclib import Fault +import SocketServer +import BaseHTTPServer +import sys +import os +import traceback +import re +try: + import fcntl +except ImportError: + fcntl = None + +def resolve_dotted_attribute(obj, attr, allow_dotted_names=True): + """resolve_dotted_attribute(a, 'b.c.d') => a.b.c.d + + Resolves a dotted attribute name to an object. Raises + an AttributeError if any attribute in the chain starts with a '_'. + + If the optional allow_dotted_names argument is false, dots are not + supported and this function operates similar to getattr(obj, attr). + """ + + if allow_dotted_names: + attrs = attr.split('.') + else: + attrs = [attr] + + for i in attrs: + if i.startswith('_'): + raise AttributeError( + 'attempt to access private attribute "%s"' % i + ) + else: + obj = getattr(obj,i) + return obj + +def list_public_methods(obj): + """Returns a list of attribute strings, found in the specified + object, which represent callable attributes""" + + return [member for member in dir(obj) + if not member.startswith('_') and + hasattr(getattr(obj, member), '__call__')] + +def remove_duplicates(lst): + """remove_duplicates([2,2,2,1,3,3]) => [3,1,2] + + Returns a copy of a list without duplicates. Every list + item must be hashable and the order of the items in the + resulting list is not defined. + """ + u = {} + for x in lst: + u[x] = 1 + + return u.keys() + +class SimpleXMLRPCDispatcher: + """Mix-in class that dispatches XML-RPC requests. + + This class is used to register XML-RPC method handlers + and then to dispatch them. This class doesn't need to be + instanced directly when used by SimpleXMLRPCServer but it + can be instanced when used by the MultiPathXMLRPCServer. + """ + + def __init__(self, allow_none=False, encoding=None): + self.funcs = {} + self.instance = None + self.allow_none = allow_none + self.encoding = encoding + + def register_instance(self, instance, allow_dotted_names=False): + """Registers an instance to respond to XML-RPC requests. + + Only one instance can be installed at a time. + + If the registered instance has a _dispatch method then that + method will be called with the name of the XML-RPC method and + its parameters as a tuple + e.g. instance._dispatch('add',(2,3)) + + If the registered instance does not have a _dispatch method + then the instance will be searched to find a matching method + and, if found, will be called. Methods beginning with an '_' + are considered private and will not be called by + SimpleXMLRPCServer. + + If a registered function matches a XML-RPC request, then it + will be called instead of the registered instance. + + If the optional allow_dotted_names argument is true and the + instance does not have a _dispatch method, method names + containing dots are supported and resolved, as long as none of + the name segments start with an '_'. + + *** SECURITY WARNING: *** + + Enabling the allow_dotted_names options allows intruders + to access your module's global variables and may allow + intruders to execute arbitrary code on your machine. Only + use this option on a secure, closed network. + + """ + + self.instance = instance + self.allow_dotted_names = allow_dotted_names + + def register_function(self, function, name = None): + """Registers a function to respond to XML-RPC requests. + + The optional name argument can be used to set a Unicode name + for the function. + """ + + if name is None: + name = function.__name__ + self.funcs[name] = function + + def register_introspection_functions(self): + """Registers the XML-RPC introspection methods in the system + namespace. + + see http://xmlrpc.usefulinc.com/doc/reserved.html + """ + + self.funcs.update({'system.listMethods' : self.system_listMethods, + 'system.methodSignature' : self.system_methodSignature, + 'system.methodHelp' : self.system_methodHelp}) + + def register_multicall_functions(self): + """Registers the XML-RPC multicall method in the system + namespace. + + see http://www.xmlrpc.com/discuss/msgReader$1208""" + + self.funcs.update({'system.multicall' : self.system_multicall}) + + def _marshaled_dispatch(self, data, dispatch_method = None, path = None): + """Dispatches an XML-RPC method from marshalled (XML) data. + + XML-RPC methods are dispatched from the marshalled (XML) data + using the _dispatch method and the result is returned as + marshalled data. For backwards compatibility, a dispatch + function can be provided as an argument (see comment in + SimpleXMLRPCRequestHandler.do_POST) but overriding the + existing method through subclassing is the preferred means + of changing method dispatch behavior. + """ + + try: + params, method = xmlrpclib.loads(data) + + # generate response + if dispatch_method is not None: + response = dispatch_method(method, params) + else: + response = self._dispatch(method, params) + # wrap response in a singleton tuple + response = (response,) + response = xmlrpclib.dumps(response, methodresponse=1, + allow_none=self.allow_none, encoding=self.encoding) + except Fault, fault: + response = xmlrpclib.dumps(fault, allow_none=self.allow_none, + encoding=self.encoding) + except: + # report exception back to server + exc_type, exc_value, exc_tb = sys.exc_info() + response = xmlrpclib.dumps( + xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)), + encoding=self.encoding, allow_none=self.allow_none, + ) + + return response + + def system_listMethods(self): + """system.listMethods() => ['add', 'subtract', 'multiple'] + + Returns a list of the methods supported by the server.""" + + methods = self.funcs.keys() + if self.instance is not None: + # Instance can implement _listMethod to return a list of + # methods + if hasattr(self.instance, '_listMethods'): + methods = remove_duplicates( + methods + self.instance._listMethods() + ) + # if the instance has a _dispatch method then we + # don't have enough information to provide a list + # of methods + elif not hasattr(self.instance, '_dispatch'): + methods = remove_duplicates( + methods + list_public_methods(self.instance) + ) + methods.sort() + return methods + + def system_methodSignature(self, method_name): + """system.methodSignature('add') => [double, int, int] + + Returns a list describing the signature of the method. In the + above example, the add method takes two integers as arguments + and returns a double result. + + This server does NOT support system.methodSignature.""" + + # See http://xmlrpc.usefulinc.com/doc/sysmethodsig.html + + return 'signatures not supported' + + def system_methodHelp(self, method_name): + """system.methodHelp('add') => "Adds two integers together" + + Returns a string containing documentation for the specified method.""" + + method = None + if method_name in self.funcs: + method = self.funcs[method_name] + elif self.instance is not None: + # Instance can implement _methodHelp to return help for a method + if hasattr(self.instance, '_methodHelp'): + return self.instance._methodHelp(method_name) + # if the instance has a _dispatch method then we + # don't have enough information to provide help + elif not hasattr(self.instance, '_dispatch'): + try: + method = resolve_dotted_attribute( + self.instance, + method_name, + self.allow_dotted_names + ) + except AttributeError: + pass + + # Note that we aren't checking that the method actually + # be a callable object of some kind + if method is None: + return "" + else: + import pydoc + return pydoc.getdoc(method) + + def system_multicall(self, call_list): + """system.multicall([{'methodName': 'add', 'params': [2, 2]}, ...]) => \ +[[4], ...] + + Allows the caller to package multiple XML-RPC calls into a single + request. + + See http://www.xmlrpc.com/discuss/msgReader$1208 + """ + + results = [] + for call in call_list: + method_name = call['methodName'] + params = call['params'] + + try: + # XXX A marshalling error in any response will fail the entire + # multicall. If someone cares they should fix this. + results.append([self._dispatch(method_name, params)]) + except Fault, fault: + results.append( + {'faultCode' : fault.faultCode, + 'faultString' : fault.faultString} + ) + except: + exc_type, exc_value, exc_tb = sys.exc_info() + results.append( + {'faultCode' : 1, + 'faultString' : "%s:%s" % (exc_type, exc_value)} + ) + return results + + def _dispatch(self, method, params): + """Dispatches the XML-RPC method. + + XML-RPC calls are forwarded to a registered function that + matches the called XML-RPC method name. If no such function + exists then the call is forwarded to the registered instance, + if available. + + If the registered instance has a _dispatch method then that + method will be called with the name of the XML-RPC method and + its parameters as a tuple + e.g. instance._dispatch('add',(2,3)) + + If the registered instance does not have a _dispatch method + then the instance will be searched to find a matching method + and, if found, will be called. + + Methods beginning with an '_' are considered private and will + not be called. + """ + + func = None + try: + # check to see if a matching function has been registered + func = self.funcs[method] + except KeyError: + if self.instance is not None: + # check for a _dispatch method + if hasattr(self.instance, '_dispatch'): + return self.instance._dispatch(method, params) + else: + # call instance method directly + try: + func = resolve_dotted_attribute( + self.instance, + method, + self.allow_dotted_names + ) + except AttributeError: + pass + + if func is not None: + return func(*params) + else: + raise Exception('method "%s" is not supported' % method) + +class SimpleXMLRPCRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): + """Simple XML-RPC request handler class. + + Handles all HTTP POST requests and attempts to decode them as + XML-RPC requests. + """ + + # Class attribute listing the accessible path components; + # paths not on this list will result in a 404 error. + rpc_paths = ('/', '/RPC2') + + #if not None, encode responses larger than this, if possible + encode_threshold = 1400 #a common MTU + + #Override form StreamRequestHandler: full buffering of output + #and no Nagle. + wbufsize = -1 + disable_nagle_algorithm = True + + # a re to match a gzip Accept-Encoding + aepattern = re.compile(r""" + \s* ([^\s;]+) \s* #content-coding + (;\s* q \s*=\s* ([0-9\.]+))? #q + """, re.VERBOSE | re.IGNORECASE) + + def accept_encodings(self): + r = {} + ae = self.headers.get("Accept-Encoding", "") + for e in ae.split(","): + match = self.aepattern.match(e) + if match: + v = match.group(3) + v = float(v) if v else 1.0 + r[match.group(1)] = v + return r + + def is_rpc_path_valid(self): + if self.rpc_paths: + return self.path in self.rpc_paths + else: + # If .rpc_paths is empty, just assume all paths are legal + return True + + def do_POST(self): + """Handles the HTTP POST request. + + Attempts to interpret all HTTP POST requests as XML-RPC calls, + which are forwarded to the server's _dispatch method for handling. + """ + + # Check that the path is legal + if not self.is_rpc_path_valid(): + self.report_404() + return + + try: + # Get arguments by reading body of request. + # We read this in chunks to avoid straining + # socket.read(); around the 10 or 15Mb mark, some platforms + # begin to have problems (bug #792570). + max_chunk_size = 10*1024*1024 + size_remaining = int(self.headers["content-length"]) + L = [] + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + chunk = self.rfile.read(chunk_size) + if not chunk: + break + L.append(chunk) + size_remaining -= len(L[-1]) + data = ''.join(L) + + data = self.decode_request_content(data) + if data is None: + return #response has been sent + + # In previous versions of SimpleXMLRPCServer, _dispatch + # could be overridden in this class, instead of in + # SimpleXMLRPCDispatcher. To maintain backwards compatibility, + # check to see if a subclass implements _dispatch and dispatch + # using that method if present. + response = self.server._marshaled_dispatch( + data, getattr(self, '_dispatch', None), self.path + ) + except Exception, e: # This should only happen if the module is buggy + # internal error, report as HTTP server error + self.send_response(500) + + # Send information about the exception if requested + if hasattr(self.server, '_send_traceback_header') and \ + self.server._send_traceback_header: + self.send_header("X-exception", str(e)) + self.send_header("X-traceback", traceback.format_exc()) + + self.send_header("Content-length", "0") + self.end_headers() + else: + # got a valid XML RPC response + self.send_response(200) + self.send_header("Content-type", "text/xml") + if self.encode_threshold is not None: + if len(response) > self.encode_threshold: + q = self.accept_encodings().get("gzip", 0) + if q: + try: + response = xmlrpclib.gzip_encode(response) + self.send_header("Content-Encoding", "gzip") + except NotImplementedError: + pass + self.send_header("Content-length", str(len(response))) + self.end_headers() + self.wfile.write(response) + + def decode_request_content(self, data): + #support gzip encoding of request + encoding = self.headers.get("content-encoding", "identity").lower() + if encoding == "identity": + return data + if encoding == "gzip": + try: + return xmlrpclib.gzip_decode(data) + except NotImplementedError: + self.send_response(501, "encoding %r not supported" % encoding) + except ValueError: + self.send_response(400, "error decoding gzip content") + else: + self.send_response(501, "encoding %r not supported" % encoding) + self.send_header("Content-length", "0") + self.end_headers() + + def report_404 (self): + # Report a 404 error + self.send_response(404) + response = 'No such page' + self.send_header("Content-type", "text/plain") + self.send_header("Content-length", str(len(response))) + self.end_headers() + self.wfile.write(response) + + def log_request(self, code='-', size='-'): + """Selectively log an accepted request.""" + + if self.server.logRequests: + BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size) + +class SimpleXMLRPCServer(SocketServer.TCPServer, + SimpleXMLRPCDispatcher): + """Simple XML-RPC server. + + Simple XML-RPC server that allows functions and a single instance + to be installed to handle requests. The default implementation + attempts to dispatch XML-RPC calls to the functions or instance + installed in the server. Override the _dispatch method inhereted + from SimpleXMLRPCDispatcher to change this behavior. + """ + + allow_reuse_address = True + + # Warning: this is for debugging purposes only! Never set this to True in + # production code, as will be sending out sensitive information (exception + # and stack trace details) when exceptions are raised inside + # SimpleXMLRPCRequestHandler.do_POST + _send_traceback_header = False + + def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler, + logRequests=True, allow_none=False, encoding=None, bind_and_activate=True): + self.logRequests = logRequests + + SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding) + SocketServer.TCPServer.__init__(self, addr, requestHandler, bind_and_activate) + + # [Bug #1222790] If possible, set close-on-exec flag; if a + # method spawns a subprocess, the subprocess shouldn't have + # the listening socket open. + if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'): + flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD) + flags |= fcntl.FD_CLOEXEC + fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags) + +class MultiPathXMLRPCServer(SimpleXMLRPCServer): + """Multipath XML-RPC Server + This specialization of SimpleXMLRPCServer allows the user to create + multiple Dispatcher instances and assign them to different + HTTP request paths. This makes it possible to run two or more + 'virtual XML-RPC servers' at the same port. + Make sure that the requestHandler accepts the paths in question. + """ + def __init__(self, addr, requestHandler=SimpleXMLRPCRequestHandler, + logRequests=True, allow_none=False, encoding=None, bind_and_activate=True): + + SimpleXMLRPCServer.__init__(self, addr, requestHandler, logRequests, allow_none, + encoding, bind_and_activate) + self.dispatchers = {} + self.allow_none = allow_none + self.encoding = encoding + + def add_dispatcher(self, path, dispatcher): + self.dispatchers[path] = dispatcher + return dispatcher + + def get_dispatcher(self, path): + return self.dispatchers[path] + + def _marshaled_dispatch(self, data, dispatch_method = None, path = None): + try: + response = self.dispatchers[path]._marshaled_dispatch( + data, dispatch_method, path) + except: + # report low level exception back to server + # (each dispatcher should have handled their own + # exceptions) + exc_type, exc_value = sys.exc_info()[:2] + response = xmlrpclib.dumps( + xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)), + encoding=self.encoding, allow_none=self.allow_none) + return response + +class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): + """Simple handler for XML-RPC data passed through CGI.""" + + def __init__(self, allow_none=False, encoding=None): + SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding) + + def handle_xmlrpc(self, request_text): + """Handle a single XML-RPC request""" + + response = self._marshaled_dispatch(request_text) + + print 'Content-Type: text/xml' + print 'Content-Length: %d' % len(response) + print + sys.stdout.write(response) + + def handle_get(self): + """Handle a single HTTP GET request. + + Default implementation indicates an error because + XML-RPC uses the POST method. + """ + + code = 400 + message, explain = \ + BaseHTTPServer.BaseHTTPRequestHandler.responses[code] + + response = BaseHTTPServer.DEFAULT_ERROR_MESSAGE % \ + { + 'code' : code, + 'message' : message, + 'explain' : explain + } + print 'Status: %d %s' % (code, message) + print 'Content-Type: %s' % BaseHTTPServer.DEFAULT_ERROR_CONTENT_TYPE + print 'Content-Length: %d' % len(response) + print + sys.stdout.write(response) + + def handle_request(self, request_text = None): + """Handle a single XML-RPC request passed through a CGI post method. + + If no XML data is given then it is read from stdin. The resulting + XML-RPC response is printed to stdout along with the correct HTTP + headers. + """ + + if request_text is None and \ + os.environ.get('REQUEST_METHOD', None) == 'GET': + self.handle_get() + else: + # POST data is normally available through stdin + try: + length = int(os.environ.get('CONTENT_LENGTH', None)) + except (TypeError, ValueError): + length = -1 + if request_text is None: + request_text = sys.stdin.read(length) + + self.handle_xmlrpc(request_text) + +if __name__ == '__main__': + print 'Running XML-RPC server on port 8000' + server = SimpleXMLRPCServer(("localhost", 8000)) + server.register_function(pow) + server.register_function(lambda x,y: x+y, 'add') + server.serve_forever() diff --git a/src/main/resources/PythonLibs/SocketServer.py b/src/main/resources/PythonLibs/SocketServer.py new file mode 100644 index 0000000000000000000000000000000000000000..fab03ac0f7d28b81d8faf85241fd39da85c2776c --- /dev/null +++ b/src/main/resources/PythonLibs/SocketServer.py @@ -0,0 +1,723 @@ +"""Generic socket server classes. + +This module tries to capture the various aspects of defining a server: + +For socket-based servers: + +- address family: + - AF_INET{,6}: IP (Internet Protocol) sockets (default) + - AF_UNIX: Unix domain sockets + - others, e.g. AF_DECNET are conceivable (see <socket.h> +- socket type: + - SOCK_STREAM (reliable stream, e.g. TCP) + - SOCK_DGRAM (datagrams, e.g. UDP) + +For request-based servers (including socket-based): + +- client address verification before further looking at the request + (This is actually a hook for any processing that needs to look + at the request before anything else, e.g. logging) +- how to handle multiple requests: + - synchronous (one request is handled at a time) + - forking (each request is handled by a new process) + - threading (each request is handled by a new thread) + +The classes in this module favor the server type that is simplest to +write: a synchronous TCP/IP server. This is bad class design, but +save some typing. (There's also the issue that a deep class hierarchy +slows down method lookups.) + +There are five classes in an inheritance diagram, four of which represent +synchronous servers of four types: + + +------------+ + | BaseServer | + +------------+ + | + v + +-----------+ +------------------+ + | TCPServer |------->| UnixStreamServer | + +-----------+ +------------------+ + | + v + +-----------+ +--------------------+ + | UDPServer |------->| UnixDatagramServer | + +-----------+ +--------------------+ + +Note that UnixDatagramServer derives from UDPServer, not from +UnixStreamServer -- the only difference between an IP and a Unix +stream server is the address family, which is simply repeated in both +unix server classes. + +Forking and threading versions of each type of server can be created +using the ForkingMixIn and ThreadingMixIn mix-in classes. For +instance, a threading UDP server class is created as follows: + + class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass + +The Mix-in class must come first, since it overrides a method defined +in UDPServer! Setting the various member variables also changes +the behavior of the underlying server mechanism. + +To implement a service, you must derive a class from +BaseRequestHandler and redefine its handle() method. You can then run +various versions of the service by combining one of the server classes +with your request handler class. + +The request handler class must be different for datagram or stream +services. This can be hidden by using the request handler +subclasses StreamRequestHandler or DatagramRequestHandler. + +Of course, you still have to use your head! + +For instance, it makes no sense to use a forking server if the service +contains state in memory that can be modified by requests (since the +modifications in the child process would never reach the initial state +kept in the parent process and passed to each child). In this case, +you can use a threading server, but you will probably have to use +locks to avoid two requests that come in nearly simultaneous to apply +conflicting changes to the server state. + +On the other hand, if you are building e.g. an HTTP server, where all +data is stored externally (e.g. in the file system), a synchronous +class will essentially render the service "deaf" while one request is +being handled -- which may be for a very long time if a client is slow +to reqd all the data it has requested. Here a threading or forking +server is appropriate. + +In some cases, it may be appropriate to process part of a request +synchronously, but to finish processing in a forked child depending on +the request data. This can be implemented by using a synchronous +server and doing an explicit fork in the request handler class +handle() method. + +Another approach to handling multiple simultaneous requests in an +environment that supports neither threads nor fork (or where these are +too expensive or inappropriate for the service) is to maintain an +explicit table of partially finished requests and to use select() to +decide which request to work on next (or whether to handle a new +incoming request). This is particularly important for stream services +where each client can potentially be connected for a long time (if +threads or subprocesses cannot be used). + +Future work: +- Standard classes for Sun RPC (which uses either UDP or TCP) +- Standard mix-in classes to implement various authentication + and encryption schemes +- Standard framework for select-based multiplexing + +XXX Open problems: +- What to do with out-of-band data? + +BaseServer: +- split generic "request" functionality out into BaseServer class. + Copyright (C) 2000 Luke Kenneth Casson Leighton <lkcl@samba.org> + + example: read entries from a SQL database (requires overriding + get_request() to return a table entry from the database). + entry is processed by a RequestHandlerClass. + +""" + +# Author of the BaseServer patch: Luke Kenneth Casson Leighton + +# XXX Warning! +# There is a test suite for this module, but it cannot be run by the +# standard regression test. +# To run it manually, run Lib/test/test_socketserver.py. + +__version__ = "0.4" + + +import socket +import select +import sys +import os +try: + import threading +except ImportError: + import dummy_threading as threading + +select_fn = select.select +if sys.platform.startswith('java'): + select_fn = select.cpython_compatible_select + +__all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", + "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", + "StreamRequestHandler","DatagramRequestHandler", + "ThreadingMixIn", "ForkingMixIn"] +if hasattr(socket, "AF_UNIX"): + __all__.extend(["UnixStreamServer","UnixDatagramServer", + "ThreadingUnixStreamServer", + "ThreadingUnixDatagramServer"]) + +class BaseServer: + + """Base class for server classes. + + Methods for the caller: + + - __init__(server_address, RequestHandlerClass) + - serve_forever(poll_interval=0.5) + - shutdown() + - handle_request() # if you do not use serve_forever() + - fileno() -> int # for select() + + Methods that may be overridden: + + - server_bind() + - server_activate() + - get_request() -> request, client_address + - handle_timeout() + - verify_request(request, client_address) + - server_close() + - process_request(request, client_address) + - shutdown_request(request) + - close_request(request) + - handle_error() + + Methods for derived classes: + + - finish_request(request, client_address) + + Class variables that may be overridden by derived classes or + instances: + + - timeout + - address_family + - socket_type + - allow_reuse_address + + Instance variables: + + - RequestHandlerClass + - socket + + """ + + timeout = None + + def __init__(self, server_address, RequestHandlerClass): + """Constructor. May be extended, do not override.""" + self.server_address = server_address + self.RequestHandlerClass = RequestHandlerClass + self.__is_shut_down = threading.Event() + self.__shutdown_request = False + + def server_activate(self): + """Called by constructor to activate the server. + + May be overridden. + + """ + pass + + def serve_forever(self, poll_interval=0.5): + """Handle one request at a time until shutdown. + + Polls for shutdown every poll_interval seconds. Ignores + self.timeout. If you need to do periodic tasks, do them in + another thread. + """ + self.__is_shut_down.clear() + try: + while not self.__shutdown_request: + # XXX: Consider using another file descriptor or + # connecting to the socket to wake this up instead of + # polling. Polling reduces our responsiveness to a + # shutdown request and wastes cpu at all other times. + r, w, e = select_fn([self], [], [], poll_interval) + if self in r: + self._handle_request_noblock() + finally: + self.__shutdown_request = False + self.__is_shut_down.set() + + def shutdown(self): + """Stops the serve_forever loop. + + Blocks until the loop has finished. This must be called while + serve_forever() is running in another thread, or it will + deadlock. + """ + self.__shutdown_request = True + self.__is_shut_down.wait() + + # The distinction between handling, getting, processing and + # finishing a request is fairly arbitrary. Remember: + # + # - handle_request() is the top-level call. It calls + # select, get_request(), verify_request() and process_request() + # - get_request() is different for stream or datagram sockets + # - process_request() is the place that may fork a new process + # or create a new thread to finish the request + # - finish_request() instantiates the request handler class; + # this constructor will handle the request all by itself + + def handle_request(self): + """Handle one request, possibly blocking. + + Respects self.timeout. + """ + # Support people who used socket.settimeout() to escape + # handle_request before self.timeout was available. + timeout = self.socket.gettimeout() + if timeout is None: + timeout = self.timeout + elif self.timeout is not None: + timeout = min(timeout, self.timeout) + fd_sets = select_fn([self], [], [], timeout) + if not fd_sets[0]: + self.handle_timeout() + return + self._handle_request_noblock() + + def _handle_request_noblock(self): + """Handle one request, without blocking. + + I assume that select_fn has returned that the socket is + readable before this function was called, so there should be + no risk of blocking in get_request(). + """ + try: + request, client_address = self.get_request() + except socket.error: + return + if self.verify_request(request, client_address): + try: + self.process_request(request, client_address) + except: + self.handle_error(request, client_address) + self.shutdown_request(request) + + def handle_timeout(self): + """Called if no new request arrives within self.timeout. + + Overridden by ForkingMixIn. + """ + pass + + def verify_request(self, request, client_address): + """Verify the request. May be overridden. + + Return True if we should proceed with this request. + + """ + return True + + def process_request(self, request, client_address): + """Call finish_request. + + Overridden by ForkingMixIn and ThreadingMixIn. + + """ + self.finish_request(request, client_address) + self.shutdown_request(request) + + def server_close(self): + """Called to clean-up the server. + + May be overridden. + + """ + pass + + def finish_request(self, request, client_address): + """Finish one request by instantiating RequestHandlerClass.""" + self.RequestHandlerClass(request, client_address, self) + + def shutdown_request(self, request): + """Called to shutdown and close an individual request.""" + self.close_request(request) + + def close_request(self, request): + """Called to clean up an individual request.""" + pass + + def handle_error(self, request, client_address): + """Handle an error gracefully. May be overridden. + + The default is to print a traceback and continue. + + """ + print '-'*40 + print 'Exception happened during processing of request from', + print client_address + import traceback + traceback.print_exc() # XXX But this goes to stderr! + print '-'*40 + + +class TCPServer(BaseServer): + + """Base class for various socket-based server classes. + + Defaults to synchronous IP stream (i.e., TCP). + + Methods for the caller: + + - __init__(server_address, RequestHandlerClass, bind_and_activate=True) + - serve_forever(poll_interval=0.5) + - shutdown() + - handle_request() # if you don't use serve_forever() + - fileno() -> int # for select() + + Methods that may be overridden: + + - server_bind() + - server_activate() + - get_request() -> request, client_address + - handle_timeout() + - verify_request(request, client_address) + - process_request(request, client_address) + - shutdown_request(request) + - close_request(request) + - handle_error() + + Methods for derived classes: + + - finish_request(request, client_address) + + Class variables that may be overridden by derived classes or + instances: + + - timeout + - address_family + - socket_type + - request_queue_size (only for stream sockets) + - allow_reuse_address + + Instance variables: + + - server_address + - RequestHandlerClass + - socket + + """ + + address_family = socket.AF_INET + + socket_type = socket.SOCK_STREAM + + request_queue_size = 5 + + allow_reuse_address = False + + def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): + """Constructor. May be extended, do not override.""" + BaseServer.__init__(self, server_address, RequestHandlerClass) + self.socket = socket.socket(self.address_family, + self.socket_type) + if bind_and_activate: + self.server_bind() + self.server_activate() + + def server_bind(self): + """Called by constructor to bind the socket. + + May be overridden. + + """ + if self.allow_reuse_address: + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.socket.bind(self.server_address) + self.server_address = self.socket.getsockname() + + def server_activate(self): + """Called by constructor to activate the server. + + May be overridden. + + """ + self.socket.listen(self.request_queue_size) + # Adding a second call to getsockname() because of this issue + # http://wiki.python.org/jython/NewSocketModule#Deferredsocketcreationonjython + self.server_address = self.socket.getsockname() + + def server_close(self): + """Called to clean-up the server. + + May be overridden. + + """ + self.socket.close() + + def fileno(self): + """Return socket file number. + + Interface required by select(). + + """ + return self.socket.fileno() + + def get_request(self): + """Get the request and client address from the socket. + + May be overridden. + + """ + return self.socket.accept() + + def shutdown_request(self, request): + """Called to shutdown and close an individual request.""" + try: + #explicitly shutdown. socket.close() merely releases + #the socket and waits for GC to perform the actual close. + request.shutdown(socket.SHUT_WR) + except socket.error: + pass #some platforms may raise ENOTCONN here + self.close_request(request) + + def close_request(self, request): + """Called to clean up an individual request.""" + request.close() + + +class UDPServer(TCPServer): + + """UDP server class.""" + + allow_reuse_address = False + + socket_type = socket.SOCK_DGRAM + + max_packet_size = 8192 + + def get_request(self): + data, client_addr = self.socket.recvfrom(self.max_packet_size) + return (data, self.socket), client_addr + + def server_activate(self): + # No need to call listen() for UDP. + pass + + def shutdown_request(self, request): + # No need to shutdown anything. + self.close_request(request) + + def close_request(self, request): + # No need to close anything. + pass + +class ForkingMixIn: + + """Mix-in class to handle each request in a new process.""" + + timeout = 300 + active_children = None + max_children = 40 + + def collect_children(self): + """Internal routine to wait for children that have exited.""" + if self.active_children is None: return + while len(self.active_children) >= self.max_children: + # XXX: This will wait for any child process, not just ones + # spawned by this library. This could confuse other + # libraries that expect to be able to wait for their own + # children. + try: + pid, status = os.waitpid(0, 0) + except os.error: + pid = None + if pid not in self.active_children: continue + self.active_children.remove(pid) + + # XXX: This loop runs more system calls than it ought + # to. There should be a way to put the active_children into a + # process group and then use os.waitpid(-pgid) to wait for any + # of that set, but I couldn't find a way to allocate pgids + # that couldn't collide. + for child in self.active_children: + try: + pid, status = os.waitpid(child, os.WNOHANG) + except os.error: + pid = None + if not pid: continue + try: + self.active_children.remove(pid) + except ValueError, e: + raise ValueError('%s. x=%d and list=%r' % (e.message, pid, + self.active_children)) + + def handle_timeout(self): + """Wait for zombies after self.timeout seconds of inactivity. + + May be extended, do not override. + """ + self.collect_children() + + def process_request(self, request, client_address): + """Fork a new subprocess to process the request.""" + self.collect_children() + pid = os.fork() + if pid: + # Parent process + if self.active_children is None: + self.active_children = [] + self.active_children.append(pid) + self.close_request(request) #close handle in parent process + return + else: + # Child process. + # This must never return, hence os._exit()! + try: + self.finish_request(request, client_address) + self.shutdown_request(request) + os._exit(0) + except: + try: + self.handle_error(request, client_address) + self.shutdown_request(request) + finally: + os._exit(1) + + +class ThreadingMixIn: + """Mix-in class to handle each request in a new thread.""" + + # Decides how threads will act upon termination of the + # main process + daemon_threads = False + + def process_request_thread(self, request, client_address): + """Same as in BaseServer but as a thread. + + In addition, exception handling is done here. + + """ + try: + self.finish_request(request, client_address) + self.shutdown_request(request) + except: + self.handle_error(request, client_address) + self.shutdown_request(request) + + def process_request(self, request, client_address): + """Start a new thread to process the request.""" + t = threading.Thread(target = self.process_request_thread, + args = (request, client_address)) + if self.daemon_threads: + t.setDaemon (1) + t.start() + + +class ForkingUDPServer(ForkingMixIn, UDPServer): pass +class ForkingTCPServer(ForkingMixIn, TCPServer): pass + +class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass +class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass + +if hasattr(socket, 'AF_UNIX'): + + class UnixStreamServer(TCPServer): + address_family = socket.AF_UNIX + + class UnixDatagramServer(UDPServer): + address_family = socket.AF_UNIX + + class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer): pass + + class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass + +class BaseRequestHandler: + + """Base class for request handler classes. + + This class is instantiated for each request to be handled. The + constructor sets the instance variables request, client_address + and server, and then calls the handle() method. To implement a + specific service, all you need to do is to derive a class which + defines a handle() method. + + The handle() method can find the request as self.request, the + client address as self.client_address, and the server (in case it + needs access to per-server information) as self.server. Since a + separate instance is created for each request, the handle() method + can define arbitrary other instance variariables. + + """ + + def __init__(self, request, client_address, server): + self.request = request + self.client_address = client_address + self.server = server + self.setup() + try: + self.handle() + finally: + self.finish() + + def setup(self): + pass + + def handle(self): + pass + + def finish(self): + pass + + +# The following two classes make it possible to use the same service +# class for stream or datagram servers. +# Each class sets up these instance variables: +# - rfile: a file object from which receives the request is read +# - wfile: a file object to which the reply is written +# When the handle() method returns, wfile is flushed properly + + +class StreamRequestHandler(BaseRequestHandler): + + """Define self.rfile and self.wfile for stream sockets.""" + + # Default buffer sizes for rfile, wfile. + # We default rfile to buffered because otherwise it could be + # really slow for large data (a getc() call per byte); we make + # wfile unbuffered because (a) often after a write() we want to + # read and we need to flush the line; (b) big writes to unbuffered + # files are typically optimized by stdio even when big reads + # aren't. + rbufsize = -1 + wbufsize = 0 + + # A timeout to apply to the request socket, if not None. + timeout = None + + # Disable nagle algorithm for this socket, if True. + # Use only when wbufsize != 0, to avoid small packets. + disable_nagle_algorithm = False + + def setup(self): + self.connection = self.request + if self.timeout is not None: + self.connection.settimeout(self.timeout) + if self.disable_nagle_algorithm: + self.connection.setsockopt(socket.IPPROTO_TCP, + socket.TCP_NODELAY, True) + self.rfile = self.connection.makefile('rb', self.rbufsize) + self.wfile = self.connection.makefile('wb', self.wbufsize) + + def finish(self): + if not self.wfile.closed: + self.wfile.flush() + self.wfile.close() + self.rfile.close() + + +class DatagramRequestHandler(BaseRequestHandler): + + # XXX Regrettably, I cannot get this working on Linux; + # s.recvfrom() doesn't return a meaningful client address. + + """Define self.rfile and self.wfile for datagram sockets.""" + + def setup(self): + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + self.packet, self.socket = self.request + self.rfile = StringIO(self.packet) + self.wfile = StringIO() + + def finish(self): + self.socket.sendto(self.wfile.getvalue(), self.client_address) diff --git a/src/main/resources/PythonLibs/StringIO.py b/src/main/resources/PythonLibs/StringIO.py new file mode 100644 index 0000000000000000000000000000000000000000..b63525b9bfdcef6a146dea47cfd61d8683bfeb31 --- /dev/null +++ b/src/main/resources/PythonLibs/StringIO.py @@ -0,0 +1,324 @@ +r"""File-like objects that read from or write to a string buffer. + +This implements (nearly) all stdio methods. + +f = StringIO() # ready for writing +f = StringIO(buf) # ready for reading +f.close() # explicitly release resources held +flag = f.isatty() # always false +pos = f.tell() # get current position +f.seek(pos) # set current position +f.seek(pos, mode) # mode 0: absolute; 1: relative; 2: relative to EOF +buf = f.read() # read until EOF +buf = f.read(n) # read up to n bytes +buf = f.readline() # read until end of line ('\n') or EOF +list = f.readlines()# list of f.readline() results until EOF +f.truncate([size]) # truncate file at to at most size (default: current pos) +f.write(buf) # write at current position +f.writelines(list) # for line in list: f.write(line) +f.getvalue() # return whole file's contents as a string + +Notes: +- Using a real file is often faster (but less convenient). +- There's also a much faster implementation in C, called cStringIO, but + it's not subclassable. +- fileno() is left unimplemented so that code which uses it triggers + an exception early. +- Seeking far beyond EOF and then writing will insert real null + bytes that occupy space in the buffer. +- There's a simple test set (see end of this file). +""" +try: + from errno import EINVAL +except ImportError: + EINVAL = 22 + +__all__ = ["StringIO"] + +def _complain_ifclosed(closed): + if closed: + raise ValueError, "I/O operation on closed file" + +class StringIO: + """class StringIO([buffer]) + + When a StringIO object is created, it can be initialized to an existing + string by passing the string to the constructor. If no string is given, + the StringIO will start empty. + + The StringIO object can accept either Unicode or 8-bit strings, but + mixing the two may take some care. If both are used, 8-bit strings that + cannot be interpreted as 7-bit ASCII (that use the 8th bit) will cause + a UnicodeError to be raised when getvalue() is called. + """ + def __init__(self, buf = ''): + # Force self.buf to be a string or unicode + if not isinstance(buf, basestring): + buf = str(buf) + self.buf = buf + self.len = len(buf) + self.buflist = [] + self.pos = 0 + self.closed = False + self.softspace = 0 + + def __iter__(self): + return self + + def next(self): + """A file object is its own iterator, for example iter(f) returns f + (unless f is closed). When a file is used as an iterator, typically + in a for loop (for example, for line in f: print line), the next() + method is called repeatedly. This method returns the next input line, + or raises StopIteration when EOF is hit. + """ + _complain_ifclosed(self.closed) + r = self.readline() + if not r: + raise StopIteration + return r + + def close(self): + """Free the memory buffer. + """ + if not self.closed: + self.closed = True + del self.buf, self.pos + + def isatty(self): + """Returns False because StringIO objects are not connected to a + tty-like device. + """ + _complain_ifclosed(self.closed) + return False + + def seek(self, pos, mode = 0): + """Set the file's current position. + + The mode argument is optional and defaults to 0 (absolute file + positioning); other values are 1 (seek relative to the current + position) and 2 (seek relative to the file's end). + + There is no return value. + """ + _complain_ifclosed(self.closed) + if self.buflist: + self.buf += ''.join(self.buflist) + self.buflist = [] + if mode == 1: + pos += self.pos + elif mode == 2: + pos += self.len + self.pos = max(0, pos) + + def tell(self): + """Return the file's current position.""" + _complain_ifclosed(self.closed) + return self.pos + + def read(self, n = -1): + """Read at most size bytes from the file + (less if the read hits EOF before obtaining size bytes). + + If the size argument is negative or omitted, read all data until EOF + is reached. The bytes are returned as a string object. An empty + string is returned when EOF is encountered immediately. + """ + _complain_ifclosed(self.closed) + if self.buflist: + self.buf += ''.join(self.buflist) + self.buflist = [] + if n is None or n < 0: + newpos = self.len + else: + newpos = min(self.pos+n, self.len) + r = self.buf[self.pos:newpos] + self.pos = newpos + return r + + def readline(self, length=None): + r"""Read one entire line from the file. + + A trailing newline character is kept in the string (but may be absent + when a file ends with an incomplete line). If the size argument is + present and non-negative, it is a maximum byte count (including the + trailing newline) and an incomplete line may be returned. + + An empty string is returned only when EOF is encountered immediately. + + Note: Unlike stdio's fgets(), the returned string contains null + characters ('\0') if they occurred in the input. + """ + _complain_ifclosed(self.closed) + if self.buflist: + self.buf += ''.join(self.buflist) + self.buflist = [] + i = self.buf.find('\n', self.pos) + if i < 0: + newpos = self.len + else: + newpos = i+1 + if length is not None and length >= 0: + if self.pos + length < newpos: + newpos = self.pos + length + r = self.buf[self.pos:newpos] + self.pos = newpos + return r + + def readlines(self, sizehint = 0): + """Read until EOF using readline() and return a list containing the + lines thus read. + + If the optional sizehint argument is present, instead of reading up + to EOF, whole lines totalling approximately sizehint bytes (or more + to accommodate a final whole line). + """ + total = 0 + lines = [] + line = self.readline() + while line: + lines.append(line) + total += len(line) + if 0 < sizehint <= total: + break + line = self.readline() + return lines + + def truncate(self, size=None): + """Truncate the file's size. + + If the optional size argument is present, the file is truncated to + (at most) that size. The size defaults to the current position. + The current file position is not changed unless the position + is beyond the new file size. + + If the specified size exceeds the file's current size, the + file remains unchanged. + """ + _complain_ifclosed(self.closed) + if size is None: + size = self.pos + elif size < 0: + raise IOError(EINVAL, "Negative size not allowed") + elif size < self.pos: + self.pos = size + self.buf = self.getvalue()[:size] + self.len = size + + def write(self, s): + """Write a string to the file. + + There is no return value. + """ + _complain_ifclosed(self.closed) + if not s: return + # Force s to be a string or unicode + if not isinstance(s, basestring): + s = str(s) + spos = self.pos + slen = self.len + if spos == slen: + self.buflist.append(s) + self.len = self.pos = spos + len(s) + return + if spos > slen: + self.buflist.append('\0'*(spos - slen)) + slen = spos + newpos = spos + len(s) + if spos < slen: + if self.buflist: + self.buf += ''.join(self.buflist) + self.buflist = [self.buf[:spos], s, self.buf[newpos:]] + self.buf = '' + if newpos > slen: + slen = newpos + else: + self.buflist.append(s) + slen = newpos + self.len = slen + self.pos = newpos + + def writelines(self, iterable): + """Write a sequence of strings to the file. The sequence can be any + iterable object producing strings, typically a list of strings. There + is no return value. + + (The name is intended to match readlines(); writelines() does not add + line separators.) + """ + write = self.write + for line in iterable: + write(line) + + def flush(self): + """Flush the internal buffer + """ + _complain_ifclosed(self.closed) + + def getvalue(self): + """ + Retrieve the entire contents of the "file" at any time before + the StringIO object's close() method is called. + + The StringIO object can accept either Unicode or 8-bit strings, + but mixing the two may take some care. If both are used, 8-bit + strings that cannot be interpreted as 7-bit ASCII (that use the + 8th bit) will cause a UnicodeError to be raised when getvalue() + is called. + """ + _complain_ifclosed(self.closed) + if self.buflist: + self.buf += ''.join(self.buflist) + self.buflist = [] + return self.buf + + +# A little test suite + +def test(): + import sys + if sys.argv[1:]: + file = sys.argv[1] + else: + file = '/etc/passwd' + lines = open(file, 'r').readlines() + text = open(file, 'r').read() + f = StringIO() + for line in lines[:-2]: + f.write(line) + f.writelines(lines[-2:]) + if f.getvalue() != text: + raise RuntimeError, 'write failed' + length = f.tell() + print 'File length =', length + f.seek(len(lines[0])) + f.write(lines[1]) + f.seek(0) + print 'First line =', repr(f.readline()) + print 'Position =', f.tell() + line = f.readline() + print 'Second line =', repr(line) + f.seek(-len(line), 1) + line2 = f.read(len(line)) + if line != line2: + raise RuntimeError, 'bad result after seek back' + f.seek(len(line2), 1) + list = f.readlines() + line = list[-1] + f.seek(f.tell() - len(line)) + line2 = f.read() + if line != line2: + raise RuntimeError, 'bad result after seek back from EOF' + print 'Read', len(list), 'more lines' + print 'File length =', f.tell() + if f.tell() != length: + raise RuntimeError, 'bad length' + f.truncate(length/2) + f.seek(0, 2) + print 'Truncated length =', f.tell() + if f.tell() != length/2: + raise RuntimeError, 'truncate did not adjust length' + f.close() + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/UserDict.py b/src/main/resources/PythonLibs/UserDict.py new file mode 100644 index 0000000000000000000000000000000000000000..bb2218ab6ce5d808a4016105d69b7b637d1252a6 --- /dev/null +++ b/src/main/resources/PythonLibs/UserDict.py @@ -0,0 +1,180 @@ +"""A more or less complete user-defined wrapper around dictionary objects.""" + +class UserDict: + def __init__(self, dict=None, **kwargs): + self.data = {} + if dict is not None: + self.update(dict) + if len(kwargs): + self.update(kwargs) + def __repr__(self): return repr(self.data) + def __cmp__(self, dict): + if isinstance(dict, UserDict): + return cmp(self.data, dict.data) + else: + return cmp(self.data, dict) + __hash__ = None # Avoid Py3k warning + def __len__(self): return len(self.data) + def __getitem__(self, key): + if key in self.data: + return self.data[key] + if hasattr(self.__class__, "__missing__"): + return self.__class__.__missing__(self, key) + raise KeyError(key) + def __setitem__(self, key, item): self.data[key] = item + def __delitem__(self, key): del self.data[key] + def clear(self): self.data.clear() + def copy(self): + if self.__class__ is UserDict: + return UserDict(self.data.copy()) + import copy + data = self.data + try: + self.data = {} + c = copy.copy(self) + finally: + self.data = data + c.update(self) + return c + def keys(self): return self.data.keys() + def items(self): return self.data.items() + def iteritems(self): return self.data.iteritems() + def iterkeys(self): return self.data.iterkeys() + def itervalues(self): return self.data.itervalues() + def values(self): return self.data.values() + def has_key(self, key): return key in self.data + def update(self, dict=None, **kwargs): + if dict is None: + pass + elif isinstance(dict, UserDict): + self.data.update(dict.data) + elif isinstance(dict, type({})) or not hasattr(dict, 'items'): + self.data.update(dict) + else: + for k, v in dict.items(): + self[k] = v + if len(kwargs): + self.data.update(kwargs) + def get(self, key, failobj=None): + if key not in self: + return failobj + return self[key] + def setdefault(self, key, failobj=None): + if key not in self: + self[key] = failobj + return self[key] + def pop(self, key, *args): + return self.data.pop(key, *args) + def popitem(self): + return self.data.popitem() + def __contains__(self, key): + return key in self.data + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + +class IterableUserDict(UserDict): + def __iter__(self): + return iter(self.data) + +import _abcoll +_abcoll.MutableMapping.register(IterableUserDict) + + +class DictMixin: + # Mixin defining all dictionary methods for classes that already have + # a minimum dictionary interface including getitem, setitem, delitem, + # and keys. Without knowledge of the subclass constructor, the mixin + # does not define __init__() or copy(). In addition to the four base + # methods, progressively more efficiency comes with defining + # __contains__(), __iter__(), and iteritems(). + + # second level definitions support higher levels + def __iter__(self): + for k in self.keys(): + yield k + def has_key(self, key): + try: + self[key] + except KeyError: + return False + return True + def __contains__(self, key): + return self.has_key(key) + + # third level takes advantage of second level definitions + def iteritems(self): + for k in self: + yield (k, self[k]) + def iterkeys(self): + return self.__iter__() + + # fourth level uses definitions from lower levels + def itervalues(self): + for _, v in self.iteritems(): + yield v + def values(self): + return [v for _, v in self.iteritems()] + def items(self): + return list(self.iteritems()) + def clear(self): + for key in self.keys(): + del self[key] + def setdefault(self, key, default=None): + try: + return self[key] + except KeyError: + self[key] = default + return default + def pop(self, key, *args): + if len(args) > 1: + raise TypeError, "pop expected at most 2 arguments, got "\ + + repr(1 + len(args)) + try: + value = self[key] + except KeyError: + if args: + return args[0] + raise + del self[key] + return value + def popitem(self): + try: + k, v = self.iteritems().next() + except StopIteration: + raise KeyError, 'container is empty' + del self[k] + return (k, v) + def update(self, other=None, **kwargs): + # Make progressively weaker assumptions about "other" + if other is None: + pass + elif hasattr(other, 'iteritems'): # iteritems saves memory and lookups + for k, v in other.iteritems(): + self[k] = v + elif hasattr(other, 'keys'): + for k in other.keys(): + self[k] = other[k] + else: + for k, v in other: + self[k] = v + if kwargs: + self.update(kwargs) + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + def __repr__(self): + return repr(dict(self.iteritems())) + def __cmp__(self, other): + if other is None: + return 1 + if isinstance(other, DictMixin): + other = dict(other.iteritems()) + return cmp(dict(self.iteritems()), other) + def __len__(self): + return len(self.keys()) diff --git a/src/main/resources/PythonLibs/UserList.py b/src/main/resources/PythonLibs/UserList.py new file mode 100644 index 0000000000000000000000000000000000000000..b44598570790f42374623b357780bd6b131b4089 --- /dev/null +++ b/src/main/resources/PythonLibs/UserList.py @@ -0,0 +1,88 @@ +"""A more or less complete user-defined wrapper around list objects.""" + +import collections + +class UserList(collections.MutableSequence): + def __init__(self, initlist=None): + self.data = [] + if initlist is not None: + # XXX should this accept an arbitrary sequence? + if type(initlist) == type(self.data): + self.data[:] = initlist + elif isinstance(initlist, UserList): + self.data[:] = initlist.data[:] + else: + self.data = list(initlist) + def __repr__(self): return repr(self.data) + def __lt__(self, other): return self.data < self.__cast(other) + def __le__(self, other): return self.data <= self.__cast(other) + def __eq__(self, other): return self.data == self.__cast(other) + def __ne__(self, other): return self.data != self.__cast(other) + def __gt__(self, other): return self.data > self.__cast(other) + def __ge__(self, other): return self.data >= self.__cast(other) + def __cast(self, other): + if isinstance(other, UserList): return other.data + else: return other + def __cmp__(self, other): + return cmp(self.data, self.__cast(other)) + __hash__ = None # Mutable sequence, so not hashable + def __contains__(self, item): return item in self.data + def __len__(self): return len(self.data) + def __getitem__(self, i): return self.data[i] + def __setitem__(self, i, item): self.data[i] = item + def __delitem__(self, i): del self.data[i] + def __getslice__(self, i, j): + i = max(i, 0); j = max(j, 0) + return self.__class__(self.data[i:j]) + def __setslice__(self, i, j, other): + i = max(i, 0); j = max(j, 0) + if isinstance(other, UserList): + self.data[i:j] = other.data + elif isinstance(other, type(self.data)): + self.data[i:j] = other + else: + self.data[i:j] = list(other) + def __delslice__(self, i, j): + i = max(i, 0); j = max(j, 0) + del self.data[i:j] + def __add__(self, other): + if isinstance(other, UserList): + return self.__class__(self.data + other.data) + elif isinstance(other, type(self.data)): + return self.__class__(self.data + other) + else: + return self.__class__(self.data + list(other)) + def __radd__(self, other): + if isinstance(other, UserList): + return self.__class__(other.data + self.data) + elif isinstance(other, type(self.data)): + return self.__class__(other + self.data) + else: + return self.__class__(list(other) + self.data) + def __iadd__(self, other): + if isinstance(other, UserList): + self.data += other.data + elif isinstance(other, type(self.data)): + self.data += other + else: + self.data += list(other) + return self + def __mul__(self, n): + return self.__class__(self.data*n) + __rmul__ = __mul__ + def __imul__(self, n): + self.data *= n + return self + def append(self, item): self.data.append(item) + def insert(self, i, item): self.data.insert(i, item) + def pop(self, i=-1): return self.data.pop(i) + def remove(self, item): self.data.remove(item) + def count(self, item): return self.data.count(item) + def index(self, item, *args): return self.data.index(item, *args) + def reverse(self): self.data.reverse() + def sort(self, *args, **kwds): self.data.sort(*args, **kwds) + def extend(self, other): + if isinstance(other, UserList): + self.data.extend(other.data) + else: + self.data.extend(other) diff --git a/src/main/resources/PythonLibs/UserString.py b/src/main/resources/PythonLibs/UserString.py new file mode 100644 index 0000000000000000000000000000000000000000..726b3f7d3c81f75a8529a4e60e265817736f1d86 --- /dev/null +++ b/src/main/resources/PythonLibs/UserString.py @@ -0,0 +1,228 @@ +#!/usr/bin/env python +## vim:ts=4:et:nowrap +"""A user-defined wrapper around string objects + +Note: string objects have grown methods in Python 1.6 +This module requires Python 1.6 or later. +""" +import sys +import collections + +__all__ = ["UserString","MutableString"] + +class UserString(collections.Sequence): + def __init__(self, seq): + if isinstance(seq, basestring): + self.data = seq + elif isinstance(seq, UserString): + self.data = seq.data[:] + else: + self.data = str(seq) + def __str__(self): return str(self.data) + def __repr__(self): return repr(self.data) + def __int__(self): return int(self.data) + def __long__(self): return long(self.data) + def __float__(self): return float(self.data) + def __complex__(self): return complex(self.data) + def __hash__(self): return hash(self.data) + + def __cmp__(self, string): + if isinstance(string, UserString): + return cmp(self.data, string.data) + else: + return cmp(self.data, string) + def __contains__(self, char): + return char in self.data + + def __len__(self): return len(self.data) + def __getitem__(self, index): return self.__class__(self.data[index]) + def __getslice__(self, start, end): + start = max(start, 0); end = max(end, 0) + return self.__class__(self.data[start:end]) + + def __add__(self, other): + if isinstance(other, UserString): + return self.__class__(self.data + other.data) + elif isinstance(other, basestring): + return self.__class__(self.data + other) + else: + return self.__class__(self.data + str(other)) + def __radd__(self, other): + if isinstance(other, basestring): + return self.__class__(other + self.data) + else: + return self.__class__(str(other) + self.data) + def __mul__(self, n): + return self.__class__(self.data*n) + __rmul__ = __mul__ + def __mod__(self, args): + return self.__class__(self.data % args) + + # the following methods are defined in alphabetical order: + def capitalize(self): return self.__class__(self.data.capitalize()) + def center(self, width, *args): + return self.__class__(self.data.center(width, *args)) + def count(self, sub, start=0, end=sys.maxint): + return self.data.count(sub, start, end) + def decode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.decode(encoding, errors)) + else: + return self.__class__(self.data.decode(encoding)) + else: + return self.__class__(self.data.decode()) + def encode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.encode(encoding, errors)) + else: + return self.__class__(self.data.encode(encoding)) + else: + return self.__class__(self.data.encode()) + def endswith(self, suffix, start=0, end=sys.maxint): + return self.data.endswith(suffix, start, end) + def expandtabs(self, tabsize=8): + return self.__class__(self.data.expandtabs(tabsize)) + def find(self, sub, start=0, end=sys.maxint): + return self.data.find(sub, start, end) + def index(self, sub, start=0, end=sys.maxint): + return self.data.index(sub, start, end) + def isalpha(self): return self.data.isalpha() + def isalnum(self): return self.data.isalnum() + def isdecimal(self): return self.data.isdecimal() + def isdigit(self): return self.data.isdigit() + def islower(self): return self.data.islower() + def isnumeric(self): return self.data.isnumeric() + def isspace(self): return self.data.isspace() + def istitle(self): return self.data.istitle() + def isupper(self): return self.data.isupper() + def join(self, seq): return self.data.join(seq) + def ljust(self, width, *args): + return self.__class__(self.data.ljust(width, *args)) + def lower(self): return self.__class__(self.data.lower()) + def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) + def partition(self, sep): + return self.data.partition(sep) + def replace(self, old, new, maxsplit=-1): + return self.__class__(self.data.replace(old, new, maxsplit)) + def rfind(self, sub, start=0, end=sys.maxint): + return self.data.rfind(sub, start, end) + def rindex(self, sub, start=0, end=sys.maxint): + return self.data.rindex(sub, start, end) + def rjust(self, width, *args): + return self.__class__(self.data.rjust(width, *args)) + def rpartition(self, sep): + return self.data.rpartition(sep) + def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars)) + def split(self, sep=None, maxsplit=-1): + return self.data.split(sep, maxsplit) + def rsplit(self, sep=None, maxsplit=-1): + return self.data.rsplit(sep, maxsplit) + def splitlines(self, keepends=0): return self.data.splitlines(keepends) + def startswith(self, prefix, start=0, end=sys.maxint): + return self.data.startswith(prefix, start, end) + def strip(self, chars=None): return self.__class__(self.data.strip(chars)) + def swapcase(self): return self.__class__(self.data.swapcase()) + def title(self): return self.__class__(self.data.title()) + def translate(self, *args): + return self.__class__(self.data.translate(*args)) + def upper(self): return self.__class__(self.data.upper()) + def zfill(self, width): return self.__class__(self.data.zfill(width)) + +class MutableString(UserString, collections.MutableSequence): + """mutable string objects + + Python strings are immutable objects. This has the advantage, that + strings may be used as dictionary keys. If this property isn't needed + and you insist on changing string values in place instead, you may cheat + and use MutableString. + + But the purpose of this class is an educational one: to prevent + people from inventing their own mutable string class derived + from UserString and than forget thereby to remove (override) the + __hash__ method inherited from UserString. This would lead to + errors that would be very hard to track down. + + A faster and better solution is to rewrite your program using lists.""" + def __init__(self, string=""): + from warnings import warnpy3k + warnpy3k('the class UserString.MutableString has been removed in ' + 'Python 3.0', stacklevel=2) + self.data = string + + # We inherit object.__hash__, so we must deny this explicitly + __hash__ = None + + def __setitem__(self, index, sub): + if isinstance(index, slice): + if isinstance(sub, UserString): + sub = sub.data + elif not isinstance(sub, basestring): + sub = str(sub) + start, stop, step = index.indices(len(self.data)) + if step == -1: + start, stop = stop+1, start+1 + sub = sub[::-1] + elif step != 1: + # XXX(twouters): I guess we should be reimplementing + # the extended slice assignment/deletion algorithm here... + raise TypeError, "invalid step in slicing assignment" + start = min(start, stop) + self.data = self.data[:start] + sub + self.data[stop:] + else: + if index < 0: + index += len(self.data) + if index < 0 or index >= len(self.data): raise IndexError + self.data = self.data[:index] + sub + self.data[index+1:] + def __delitem__(self, index): + if isinstance(index, slice): + start, stop, step = index.indices(len(self.data)) + if step == -1: + start, stop = stop+1, start+1 + elif step != 1: + # XXX(twouters): see same block in __setitem__ + raise TypeError, "invalid step in slicing deletion" + start = min(start, stop) + self.data = self.data[:start] + self.data[stop:] + else: + if index < 0: + index += len(self.data) + if index < 0 or index >= len(self.data): raise IndexError + self.data = self.data[:index] + self.data[index+1:] + def __setslice__(self, start, end, sub): + start = max(start, 0); end = max(end, 0) + if isinstance(sub, UserString): + self.data = self.data[:start]+sub.data+self.data[end:] + elif isinstance(sub, basestring): + self.data = self.data[:start]+sub+self.data[end:] + else: + self.data = self.data[:start]+str(sub)+self.data[end:] + def __delslice__(self, start, end): + start = max(start, 0); end = max(end, 0) + self.data = self.data[:start] + self.data[end:] + def immutable(self): + return UserString(self.data) + def __iadd__(self, other): + if isinstance(other, UserString): + self.data += other.data + elif isinstance(other, basestring): + self.data += other + else: + self.data += str(other) + return self + def __imul__(self, n): + self.data *= n + return self + def insert(self, index, value): + self[index:index] = value + +if __name__ == "__main__": + # execute the regression test to stdout, if called as a script: + import os + called_in_dir, called_as = os.path.split(sys.argv[0]) + called_as, py = os.path.splitext(called_as) + if '-q' in sys.argv: + from test import test_support + test_support.verbose = 0 + __import__('test.test_' + called_as.lower()) diff --git a/src/main/resources/PythonLibs/_LWPCookieJar.py b/src/main/resources/PythonLibs/_LWPCookieJar.py new file mode 100644 index 0000000000000000000000000000000000000000..90cc633d53164d02a3bb1fbbb059cf8c9004732a --- /dev/null +++ b/src/main/resources/PythonLibs/_LWPCookieJar.py @@ -0,0 +1,170 @@ +"""Load / save to libwww-perl (LWP) format files. + +Actually, the format is slightly extended from that used by LWP's +(libwww-perl's) HTTP::Cookies, to avoid losing some RFC 2965 information +not recorded by LWP. + +It uses the version string "2.0", though really there isn't an LWP Cookies +2.0 format. This indicates that there is extra information in here +(domain_dot and # port_spec) while still being compatible with +libwww-perl, I hope. + +""" + +import time, re +from cookielib import (_warn_unhandled_exception, FileCookieJar, LoadError, + Cookie, MISSING_FILENAME_TEXT, + join_header_words, split_header_words, + iso2time, time2isoz) + +def lwp_cookie_str(cookie): + """Return string representation of Cookie in an the LWP cookie file format. + + Actually, the format is extended a bit -- see module docstring. + + """ + h = [(cookie.name, cookie.value), + ("path", cookie.path), + ("domain", cookie.domain)] + if cookie.port is not None: h.append(("port", cookie.port)) + if cookie.path_specified: h.append(("path_spec", None)) + if cookie.port_specified: h.append(("port_spec", None)) + if cookie.domain_initial_dot: h.append(("domain_dot", None)) + if cookie.secure: h.append(("secure", None)) + if cookie.expires: h.append(("expires", + time2isoz(float(cookie.expires)))) + if cookie.discard: h.append(("discard", None)) + if cookie.comment: h.append(("comment", cookie.comment)) + if cookie.comment_url: h.append(("commenturl", cookie.comment_url)) + + keys = cookie._rest.keys() + keys.sort() + for k in keys: + h.append((k, str(cookie._rest[k]))) + + h.append(("version", str(cookie.version))) + + return join_header_words([h]) + +class LWPCookieJar(FileCookieJar): + """ + The LWPCookieJar saves a sequence of "Set-Cookie3" lines. + "Set-Cookie3" is the format used by the libwww-perl libary, not known + to be compatible with any browser, but which is easy to read and + doesn't lose information about RFC 2965 cookies. + + Additional methods + + as_lwp_str(ignore_discard=True, ignore_expired=True) + + """ + + def as_lwp_str(self, ignore_discard=True, ignore_expires=True): + """Return cookies as a string of "\\n"-separated "Set-Cookie3" headers. + + ignore_discard and ignore_expires: see docstring for FileCookieJar.save + + """ + now = time.time() + r = [] + for cookie in self: + if not ignore_discard and cookie.discard: + continue + if not ignore_expires and cookie.is_expired(now): + continue + r.append("Set-Cookie3: %s" % lwp_cookie_str(cookie)) + return "\n".join(r+[""]) + + def save(self, filename=None, ignore_discard=False, ignore_expires=False): + if filename is None: + if self.filename is not None: filename = self.filename + else: raise ValueError(MISSING_FILENAME_TEXT) + + f = open(filename, "w") + try: + # There really isn't an LWP Cookies 2.0 format, but this indicates + # that there is extra information in here (domain_dot and + # port_spec) while still being compatible with libwww-perl, I hope. + f.write("#LWP-Cookies-2.0\n") + f.write(self.as_lwp_str(ignore_discard, ignore_expires)) + finally: + f.close() + + def _really_load(self, f, filename, ignore_discard, ignore_expires): + magic = f.readline() + if not re.search(self.magic_re, magic): + msg = ("%r does not look like a Set-Cookie3 (LWP) format " + "file" % filename) + raise LoadError(msg) + + now = time.time() + + header = "Set-Cookie3:" + boolean_attrs = ("port_spec", "path_spec", "domain_dot", + "secure", "discard") + value_attrs = ("version", + "port", "path", "domain", + "expires", + "comment", "commenturl") + + try: + while 1: + line = f.readline() + if line == "": break + if not line.startswith(header): + continue + line = line[len(header):].strip() + + for data in split_header_words([line]): + name, value = data[0] + standard = {} + rest = {} + for k in boolean_attrs: + standard[k] = False + for k, v in data[1:]: + if k is not None: + lc = k.lower() + else: + lc = None + # don't lose case distinction for unknown fields + if (lc in value_attrs) or (lc in boolean_attrs): + k = lc + if k in boolean_attrs: + if v is None: v = True + standard[k] = v + elif k in value_attrs: + standard[k] = v + else: + rest[k] = v + + h = standard.get + expires = h("expires") + discard = h("discard") + if expires is not None: + expires = iso2time(expires) + if expires is None: + discard = True + domain = h("domain") + domain_specified = domain.startswith(".") + c = Cookie(h("version"), name, value, + h("port"), h("port_spec"), + domain, domain_specified, h("domain_dot"), + h("path"), h("path_spec"), + h("secure"), + expires, + discard, + h("comment"), + h("commenturl"), + rest) + if not ignore_discard and c.discard: + continue + if not ignore_expires and c.is_expired(now): + continue + self.set_cookie(c) + + except IOError: + raise + except Exception: + _warn_unhandled_exception() + raise LoadError("invalid Set-Cookie3 format file %r: %r" % + (filename, line)) diff --git a/src/main/resources/PythonLibs/_MozillaCookieJar.py b/src/main/resources/PythonLibs/_MozillaCookieJar.py new file mode 100644 index 0000000000000000000000000000000000000000..00e8bcf981911e24d1d67c739c517148b301bdef --- /dev/null +++ b/src/main/resources/PythonLibs/_MozillaCookieJar.py @@ -0,0 +1,149 @@ +"""Mozilla / Netscape cookie loading / saving.""" + +import re, time + +from cookielib import (_warn_unhandled_exception, FileCookieJar, LoadError, + Cookie, MISSING_FILENAME_TEXT) + +class MozillaCookieJar(FileCookieJar): + """ + + WARNING: you may want to backup your browser's cookies file if you use + this class to save cookies. I *think* it works, but there have been + bugs in the past! + + This class differs from CookieJar only in the format it uses to save and + load cookies to and from a file. This class uses the Mozilla/Netscape + `cookies.txt' format. lynx uses this file format, too. + + Don't expect cookies saved while the browser is running to be noticed by + the browser (in fact, Mozilla on unix will overwrite your saved cookies if + you change them on disk while it's running; on Windows, you probably can't + save at all while the browser is running). + + Note that the Mozilla/Netscape format will downgrade RFC2965 cookies to + Netscape cookies on saving. + + In particular, the cookie version and port number information is lost, + together with information about whether or not Path, Port and Discard were + specified by the Set-Cookie2 (or Set-Cookie) header, and whether or not the + domain as set in the HTTP header started with a dot (yes, I'm aware some + domains in Netscape files start with a dot and some don't -- trust me, you + really don't want to know any more about this). + + Note that though Mozilla and Netscape use the same format, they use + slightly different headers. The class saves cookies using the Netscape + header by default (Mozilla can cope with that). + + """ + magic_re = "#( Netscape)? HTTP Cookie File" + header = """\ +# Netscape HTTP Cookie File +# http://www.netscape.com/newsref/std/cookie_spec.html +# This is a generated file! Do not edit. + +""" + + def _really_load(self, f, filename, ignore_discard, ignore_expires): + now = time.time() + + magic = f.readline() + if not re.search(self.magic_re, magic): + f.close() + raise LoadError( + "%r does not look like a Netscape format cookies file" % + filename) + + try: + while 1: + line = f.readline() + if line == "": break + + # last field may be absent, so keep any trailing tab + if line.endswith("\n"): line = line[:-1] + + # skip comments and blank lines XXX what is $ for? + if (line.strip().startswith(("#", "$")) or + line.strip() == ""): + continue + + domain, domain_specified, path, secure, expires, name, value = \ + line.split("\t") + secure = (secure == "TRUE") + domain_specified = (domain_specified == "TRUE") + if name == "": + # cookies.txt regards 'Set-Cookie: foo' as a cookie + # with no name, whereas cookielib regards it as a + # cookie with no value. + name = value + value = None + + initial_dot = domain.startswith(".") + assert domain_specified == initial_dot + + discard = False + if expires == "": + expires = None + discard = True + + # assume path_specified is false + c = Cookie(0, name, value, + None, False, + domain, domain_specified, initial_dot, + path, False, + secure, + expires, + discard, + None, + None, + {}) + if not ignore_discard and c.discard: + continue + if not ignore_expires and c.is_expired(now): + continue + self.set_cookie(c) + + except IOError: + raise + except Exception: + _warn_unhandled_exception() + raise LoadError("invalid Netscape format cookies file %r: %r" % + (filename, line)) + + def save(self, filename=None, ignore_discard=False, ignore_expires=False): + if filename is None: + if self.filename is not None: filename = self.filename + else: raise ValueError(MISSING_FILENAME_TEXT) + + f = open(filename, "w") + try: + f.write(self.header) + now = time.time() + for cookie in self: + if not ignore_discard and cookie.discard: + continue + if not ignore_expires and cookie.is_expired(now): + continue + if cookie.secure: secure = "TRUE" + else: secure = "FALSE" + if cookie.domain.startswith("."): initial_dot = "TRUE" + else: initial_dot = "FALSE" + if cookie.expires is not None: + expires = str(cookie.expires) + else: + expires = "" + if cookie.value is None: + # cookies.txt regards 'Set-Cookie: foo' as a cookie + # with no name, whereas cookielib regards it as a + # cookie with no value. + name = "" + value = cookie.name + else: + name = cookie.name + value = cookie.value + f.write( + "\t".join([cookie.domain, initial_dot, cookie.path, + secure, expires, name, value])+ + "\n") + finally: + f.close() diff --git a/src/main/resources/PythonLibs/__future__.py b/src/main/resources/PythonLibs/__future__.py new file mode 100644 index 0000000000000000000000000000000000000000..e0996eb007bf2673dd253b71a336127777353183 --- /dev/null +++ b/src/main/resources/PythonLibs/__future__.py @@ -0,0 +1,128 @@ +"""Record of phased-in incompatible language changes. + +Each line is of the form: + + FeatureName = "_Feature(" OptionalRelease "," MandatoryRelease "," + CompilerFlag ")" + +where, normally, OptionalRelease < MandatoryRelease, and both are 5-tuples +of the same form as sys.version_info: + + (PY_MAJOR_VERSION, # the 2 in 2.1.0a3; an int + PY_MINOR_VERSION, # the 1; an int + PY_MICRO_VERSION, # the 0; an int + PY_RELEASE_LEVEL, # "alpha", "beta", "candidate" or "final"; string + PY_RELEASE_SERIAL # the 3; an int + ) + +OptionalRelease records the first release in which + + from __future__ import FeatureName + +was accepted. + +In the case of MandatoryReleases that have not yet occurred, +MandatoryRelease predicts the release in which the feature will become part +of the language. + +Else MandatoryRelease records when the feature became part of the language; +in releases at or after that, modules no longer need + + from __future__ import FeatureName + +to use the feature in question, but may continue to use such imports. + +MandatoryRelease may also be None, meaning that a planned feature got +dropped. + +Instances of class _Feature have two corresponding methods, +.getOptionalRelease() and .getMandatoryRelease(). + +CompilerFlag is the (bitfield) flag that should be passed in the fourth +argument to the builtin function compile() to enable the feature in +dynamically compiled code. This flag is stored in the .compiler_flag +attribute on _Future instances. These values must match the appropriate +#defines of CO_xxx flags in Include/compile.h. + +No feature line is ever to be deleted from this file. +""" + +all_feature_names = [ + "nested_scopes", + "generators", + "division", + "absolute_import", + "with_statement", + "print_function", + "unicode_literals", +] + +__all__ = ["all_feature_names"] + all_feature_names + +# The CO_xxx symbols are defined here under the same names used by +# compile.h, so that an editor search will find them here. However, +# they're not exported in __all__, because they don't really belong to +# this module. +CO_NESTED = 0x0010 # nested_scopes +CO_GENERATOR_ALLOWED = 0 # generators (obsolete, was 0x1000) +CO_FUTURE_DIVISION = 0x2000 # division +CO_FUTURE_ABSOLUTE_IMPORT = 0x4000 # perform absolute imports by default +CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement +CO_FUTURE_PRINT_FUNCTION = 0x10000 # print function +CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals + +class _Feature: + def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): + self.optional = optionalRelease + self.mandatory = mandatoryRelease + self.compiler_flag = compiler_flag + + def getOptionalRelease(self): + """Return first release in which this feature was recognized. + + This is a 5-tuple, of the same form as sys.version_info. + """ + + return self.optional + + def getMandatoryRelease(self): + """Return release in which this feature will become mandatory. + + This is a 5-tuple, of the same form as sys.version_info, or, if + the feature was dropped, is None. + """ + + return self.mandatory + + def __repr__(self): + return "_Feature" + repr((self.optional, + self.mandatory, + self.compiler_flag)) + +nested_scopes = _Feature((2, 1, 0, "beta", 1), + (2, 2, 0, "alpha", 0), + CO_NESTED) + +generators = _Feature((2, 2, 0, "alpha", 1), + (2, 3, 0, "final", 0), + CO_GENERATOR_ALLOWED) + +division = _Feature((2, 2, 0, "alpha", 2), + (3, 0, 0, "alpha", 0), + CO_FUTURE_DIVISION) + +absolute_import = _Feature((2, 5, 0, "alpha", 1), + (3, 0, 0, "alpha", 0), + CO_FUTURE_ABSOLUTE_IMPORT) + +with_statement = _Feature((2, 5, 0, "alpha", 1), + (2, 6, 0, "alpha", 0), + CO_FUTURE_WITH_STATEMENT) + +print_function = _Feature((2, 6, 0, "alpha", 2), + (3, 0, 0, "alpha", 0), + CO_FUTURE_PRINT_FUNCTION) + +unicode_literals = _Feature((2, 6, 0, "alpha", 2), + (3, 0, 0, "alpha", 0), + CO_FUTURE_UNICODE_LITERALS) diff --git a/src/main/resources/PythonLibs/_abcoll.py b/src/main/resources/PythonLibs/_abcoll.py new file mode 100644 index 0000000000000000000000000000000000000000..c59ccaaa0bd4b60277f1aca00bde3472724a89d4 --- /dev/null +++ b/src/main/resources/PythonLibs/_abcoll.py @@ -0,0 +1,602 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Abstract Base Classes (ABCs) for collections, according to PEP 3119. + +DON'T USE THIS MODULE DIRECTLY! The classes here should be imported +via collections; they are defined here only to alleviate certain +bootstrapping issues. Unit tests are in test_collections. +""" + +from abc import ABCMeta, abstractmethod +import sys + +__all__ = ["Hashable", "Iterable", "Iterator", + "Sized", "Container", "Callable", + "Set", "MutableSet", + "Mapping", "MutableMapping", + "MappingView", "KeysView", "ItemsView", "ValuesView", + "Sequence", "MutableSequence", + ] + +### ONE-TRICK PONIES ### + +def _hasattr(C, attr): + try: + return any(attr in B.__dict__ for B in C.__mro__) + except AttributeError: + # Old-style class + return hasattr(C, attr) + + +class Hashable: + __metaclass__ = ABCMeta + + @abstractmethod + def __hash__(self): + return 0 + + @classmethod + def __subclasshook__(cls, C): + if cls is Hashable: + try: + for B in C.__mro__: + if "__hash__" in B.__dict__: + if B.__dict__["__hash__"]: + return True + break + except AttributeError: + # Old-style class + if getattr(C, "__hash__", None): + return True + return NotImplemented + + +class Iterable: + __metaclass__ = ABCMeta + + @abstractmethod + def __iter__(self): + while False: + yield None + + @classmethod + def __subclasshook__(cls, C): + if cls is Iterable: + if _hasattr(C, "__iter__"): + return True + return NotImplemented + +Iterable.register(str) + + +class Iterator(Iterable): + + @abstractmethod + def next(self): + raise StopIteration + + def __iter__(self): + return self + + @classmethod + def __subclasshook__(cls, C): + if cls is Iterator: + if _hasattr(C, "next"): + return True + return NotImplemented + + +class Sized: + __metaclass__ = ABCMeta + + @abstractmethod + def __len__(self): + return 0 + + @classmethod + def __subclasshook__(cls, C): + if cls is Sized: + if _hasattr(C, "__len__"): + return True + return NotImplemented + + +class Container: + __metaclass__ = ABCMeta + + @abstractmethod + def __contains__(self, x): + return False + + @classmethod + def __subclasshook__(cls, C): + if cls is Container: + if _hasattr(C, "__contains__"): + return True + return NotImplemented + + +class Callable: + __metaclass__ = ABCMeta + + @abstractmethod + def __call__(self, *args, **kwds): + return False + + @classmethod + def __subclasshook__(cls, C): + if cls is Callable: + if _hasattr(C, "__call__"): + return True + return NotImplemented + + +### SETS ### + + +class Set(Sized, Iterable, Container): + """A set is a finite, iterable container. + + This class provides concrete generic implementations of all + methods except for __contains__, __iter__ and __len__. + + To override the comparisons (presumably for speed, as the + semantics are fixed), all you have to do is redefine __le__ and + then the other operations will automatically follow suit. + """ + + def __le__(self, other): + if not isinstance(other, Set): + return NotImplemented + if len(self) > len(other): + return False + for elem in self: + if elem not in other: + return False + return True + + def __lt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) < len(other) and self.__le__(other) + + def __gt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return other < self + + def __ge__(self, other): + if not isinstance(other, Set): + return NotImplemented + return other <= self + + def __eq__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) == len(other) and self.__le__(other) + + def __ne__(self, other): + return not (self == other) + + @classmethod + def _from_iterable(cls, it): + '''Construct an instance of the class from any iterable input. + + Must override this method if the class constructor signature + does not accept an iterable for an input. + ''' + return cls(it) + + def __and__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + return self._from_iterable(value for value in other if value in self) + + def isdisjoint(self, other): + for value in other: + if value in self: + return False + return True + + def __or__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + chain = (e for s in (self, other) for e in s) + return self._from_iterable(chain) + + def __sub__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return self._from_iterable(value for value in self + if value not in other) + + def __xor__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return (self - other) | (other - self) + + # Sets are not hashable by default, but subclasses can change this + __hash__ = None + + def _hash(self): + """Compute the hash value of a set. + + Note that we don't define __hash__: not all sets are hashable. + But if you define a hashable set type, its __hash__ should + call this function. + + This must be compatible __eq__. + + All sets ought to compare equal if they contain the same + elements, regardless of how they are implemented, and + regardless of the order of the elements; so there's not much + freedom for __eq__ or __hash__. We match the algorithm used + by the built-in frozenset type. + """ + MAX = sys.maxint + MASK = 2 * MAX + 1 + n = len(self) + h = 1927868237 * (n + 1) + h &= MASK + for x in self: + hx = hash(x) + h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 + h &= MASK + h = h * 69069 + 907133923 + h &= MASK + if h > MAX: + h -= MASK + 1 + if h == -1: + h = 590923713 + return h + +Set.register(frozenset) + + +class MutableSet(Set): + + @abstractmethod + def add(self, value): + """Add an element.""" + raise NotImplementedError + + @abstractmethod + def discard(self, value): + """Remove an element. Do not raise an exception if absent.""" + raise NotImplementedError + + def remove(self, value): + """Remove an element. If not a member, raise a KeyError.""" + if value not in self: + raise KeyError(value) + self.discard(value) + + def pop(self): + """Return the popped value. Raise KeyError if empty.""" + it = iter(self) + try: + value = next(it) + except StopIteration: + raise KeyError + self.discard(value) + return value + + def clear(self): + """This is slow (creates N new iterators!) but effective.""" + try: + while True: + self.pop() + except KeyError: + pass + + def __ior__(self, it): + for value in it: + self.add(value) + return self + + def __iand__(self, it): + for value in (self - it): + self.discard(value) + return self + + def __ixor__(self, it): + if it is self: + self.clear() + else: + if not isinstance(it, Set): + it = self._from_iterable(it) + for value in it: + if value in self: + self.discard(value) + else: + self.add(value) + return self + + def __isub__(self, it): + if it is self: + self.clear() + else: + for value in it: + self.discard(value) + return self + +MutableSet.register(set) + + +### MAPPINGS ### + + +class Mapping(Sized, Iterable, Container): + + @abstractmethod + def __getitem__(self, key): + raise KeyError + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def __contains__(self, key): + try: + self[key] + except KeyError: + return False + else: + return True + + def iterkeys(self): + return iter(self) + + def itervalues(self): + for key in self: + yield self[key] + + def iteritems(self): + for key in self: + yield (key, self[key]) + + def keys(self): + return list(self) + + def items(self): + return [(key, self[key]) for key in self] + + def values(self): + return [self[key] for key in self] + + # Mappings are not hashable by default, but subclasses can change this + __hash__ = None + + def __eq__(self, other): + if not isinstance(other, Mapping): + return NotImplemented + return dict(self.items()) == dict(other.items()) + + def __ne__(self, other): + return not (self == other) + +class MappingView(Sized): + + def __init__(self, mapping): + self._mapping = mapping + + def __len__(self): + return len(self._mapping) + + def __repr__(self): + return '{0.__class__.__name__}({0._mapping!r})'.format(self) + + +class KeysView(MappingView, Set): + + @classmethod + def _from_iterable(self, it): + return set(it) + + def __contains__(self, key): + return key in self._mapping + + def __iter__(self): + for key in self._mapping: + yield key + + +class ItemsView(MappingView, Set): + + @classmethod + def _from_iterable(self, it): + return set(it) + + def __contains__(self, item): + key, value = item + try: + v = self._mapping[key] + except KeyError: + return False + else: + return v == value + + def __iter__(self): + for key in self._mapping: + yield (key, self._mapping[key]) + + +class ValuesView(MappingView): + + def __contains__(self, value): + for key in self._mapping: + if value == self._mapping[key]: + return True + return False + + def __iter__(self): + for key in self._mapping: + yield self._mapping[key] + + +class MutableMapping(Mapping): + + @abstractmethod + def __setitem__(self, key, value): + raise KeyError + + @abstractmethod + def __delitem__(self, key): + raise KeyError + + __marker = object() + + def pop(self, key, default=__marker): + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def popitem(self): + try: + key = next(iter(self)) + except StopIteration: + raise KeyError + value = self[key] + del self[key] + return key, value + + def clear(self): + try: + while True: + self.popitem() + except KeyError: + pass + + def update(*args, **kwds): + if len(args) > 2: + raise TypeError("update() takes at most 2 positional " + "arguments ({} given)".format(len(args))) + elif not args: + raise TypeError("update() takes at least 1 argument (0 given)") + self = args[0] + other = args[1] if len(args) >= 2 else () + + if isinstance(other, Mapping): + for key in other: + self[key] = other[key] + elif hasattr(other, "keys"): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + def setdefault(self, key, default=None): + try: + return self[key] + except KeyError: + self[key] = default + return default + +MutableMapping.register(dict) + + +### SEQUENCES ### + + +class Sequence(Sized, Iterable, Container): + """All the operations on a read-only sequence. + + Concrete subclasses must override __new__ or __init__, + __getitem__, and __len__. + """ + + @abstractmethod + def __getitem__(self, index): + raise IndexError + + def __iter__(self): + i = 0 + try: + while True: + v = self[i] + yield v + i += 1 + except IndexError: + return + + def __contains__(self, value): + for v in self: + if v == value: + return True + return False + + def __reversed__(self): + for i in reversed(range(len(self))): + yield self[i] + + def index(self, value): + for i, v in enumerate(self): + if v == value: + return i + raise ValueError + + def count(self, value): + return sum(1 for v in self if v == value) + +Sequence.register(tuple) +Sequence.register(basestring) +if sys.platform[:4] != "java": + Sequence.register(buffer) +Sequence.register(xrange) + + +class MutableSequence(Sequence): + + @abstractmethod + def __setitem__(self, index, value): + raise IndexError + + @abstractmethod + def __delitem__(self, index): + raise IndexError + + @abstractmethod + def insert(self, index, value): + raise IndexError + + def append(self, value): + self.insert(len(self), value) + + def reverse(self): + n = len(self) + for i in range(n//2): + self[i], self[n-i-1] = self[n-i-1], self[i] + + def extend(self, values): + for v in values: + self.append(v) + + def pop(self, index=-1): + v = self[index] + del self[index] + return v + + def remove(self, value): + del self[self.index(value)] + + def __iadd__(self, values): + self.extend(values) + return self + +MutableSequence.register(list) diff --git a/src/main/resources/PythonLibs/_fsum.py b/src/main/resources/PythonLibs/_fsum.py new file mode 100644 index 0000000000000000000000000000000000000000..9d58363e15e236d6c1724bcd718de06576d09fd2 --- /dev/null +++ b/src/main/resources/PythonLibs/_fsum.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python + +from sys import float_info +import math + + +mant_dig = float_info.mant_dig +etiny = float_info.min_exp - mant_dig + +def fsum(iterable): + """Full precision summation. Compute sum(iterable) without any + intermediate accumulation of error. Based on the 'lsum' function + at http://code.activestate.com/recipes/393090/ + + """ + tmant, texp = 0, 0 + for x in iterable: + mant, exp = math.frexp(x) + mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig + if texp > exp: + tmant <<= texp-exp + texp = exp + else: + mant <<= exp-texp + tmant += mant + + # Round tmant * 2**texp to a float. The original recipe + # used float(str(tmant)) * 2.0**texp for this, but that's + # a little unsafe because str -> float conversion can't be + # relied upon to do correct rounding on all platforms. + tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp) + if tail > 0: + h = 1 << (tail-1) + tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1) + texp += tail + return math.ldexp(tmant, texp) diff --git a/src/main/resources/PythonLibs/_google_ipaddr_r234.py b/src/main/resources/PythonLibs/_google_ipaddr_r234.py new file mode 100644 index 0000000000000000000000000000000000000000..a89298a315ddcfa3aa6cc89027e9c93d5afb909d --- /dev/null +++ b/src/main/resources/PythonLibs/_google_ipaddr_r234.py @@ -0,0 +1,1907 @@ +#!/usr/bin/python +# +# Copyright 2007 Google Inc. +# Licensed to PSF under a Contributor Agreement. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing +# permissions and limitations under the License. + +"""A fast, lightweight IPv4/IPv6 manipulation library in Python. + +This library is used to create/poke/manipulate IPv4 and IPv6 addresses +and networks. + +""" + +__version__ = 'trunk' + +import struct + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def IPAddress(address, version=None): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + version: An Integer, 4 or 6. If set, don't try to automatically + determine what the IP address type is. important for things + like IPAddress(1), which could be IPv4, '0.0.0.1', or IPv6, + '::1'. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + """ + if version: + if version == 4: + return IPv4Address(address) + elif version == 6: + return IPv6Address(address) + + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def IPNetwork(address, version=None, strict=False): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + version: An Integer, if set, don't try to automatically + determine what the IP address type is. important for things + like IPNetwork(1), which could be IPv4, '0.0.0.1/32', or IPv6, + '::1/128'. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if a strict network was requested and a strict + network wasn't given. + + """ + if version: + if version == 4: + return IPv4Network(address, strict) + elif version == 6: + return IPv6Network(address, strict) + + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def v4_int_to_packed(address): + """The binary representation of this address. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The binary representation of this address. + + Raises: + ValueError: If the integer is too large to be an IPv4 IP + address. + """ + if address > _BaseV4._ALL_ONES: + raise ValueError('Address too large for IPv4') + return struct.pack('!I', address) + + +def v6_int_to_packed(address): + """The binary representation of this address. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The binary representation of this address. + """ + return struct.pack('!QQ', address >> 64, address & (2**64 - 1)) + + +def _find_address_range(addresses): + """Find a sequence of addresses. + + Args: + addresses: a list of IPv4 or IPv6 addresses. + + Returns: + A tuple containing the first and last IP addresses in the sequence. + + """ + first = last = addresses[0] + for ip in addresses[1:]: + if ip._ip == last._ip + 1: + last = ip + else: + break + return (first, last) + +def _get_prefix_length(number1, number2, bits): + """Get the number of leading bits that are same for two numbers. + + Args: + number1: an integer. + number2: another integer. + bits: the maximum number of bits to compare. + + Returns: + The number of leading bits that are the same for two numbers. + + """ + for i in range(bits): + if number1 >> i == number2 >> i: + return bits - i + return 0 + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + for i in range(bits): + if (number >> i) % 2: + return i + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> summarize_address_range(IPv4Address('1.1.1.0'), + IPv4Address('1.1.1.130')) + [IPv4Network('1.1.1.0/25'), IPv4Network('1.1.1.128/31'), + IPv4Network('1.1.1.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + The address range collapsed to a list of IPv4Network's or + IPv6Network's. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version is not 4 or 6. + + """ + if not (isinstance(first, _BaseIP) and isinstance(last, _BaseIP)): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + str(first), str(last))) + if first > last: + raise ValueError('last IP address must be greater than first') + + networks = [] + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = _count_righthand_zero_bits(first_int, ip_bits) + current = None + while nbits >= 0: + addend = 2**nbits - 1 + current = first_int + addend + nbits -= 1 + if current <= last_int: + break + prefix = _get_prefix_length(first_int, current, ip_bits) + net = ip('%s/%d' % (str(first), prefix)) + networks.append(net) + if current == ip._ALL_ONES: + break + first_int = current + 1 + first = IPAddress(first_int, version=first._version) + return networks + +def _collapse_address_list_recursive(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('1.1.0.0/24') + ip2 = IPv4Network('1.1.1.0/24') + ip3 = IPv4Network('1.1.2.0/24') + ip4 = IPv4Network('1.1.3.0/24') + ip5 = IPv4Network('1.1.4.0/24') + ip6 = IPv4Network('1.1.0.1/22') + + _collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) -> + [IPv4Network('1.1.0.0/22'), IPv4Network('1.1.4.0/24')] + + This shouldn't be called directly; it is called via + collapse_address_list([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + ret_array = [] + optimized = False + + for cur_addr in addresses: + if not ret_array: + ret_array.append(cur_addr) + continue + if cur_addr in ret_array[-1]: + optimized = True + elif cur_addr == ret_array[-1].supernet().subnet()[1]: + ret_array.append(ret_array.pop().supernet()) + optimized = True + else: + ret_array.append(cur_addr) + + if optimized: + return _collapse_address_list_recursive(ret_array) + + return ret_array + + +def collapse_address_list(addresses): + """Collapse a list of IP objects. + + Example: + collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) -> + [IPv4('1.1.0.0/23')] + + Args: + addresses: A list of IPv4Network or IPv6Network objects. + + Returns: + A list of IPv4Network or IPv6Network objects depending on what we + were passed. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + i = 0 + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseIP): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + str(ip), str(ips[-1]))) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + str(ip), str(ips[-1]))) + ips.append(ip.ip) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + str(ip), str(ips[-1]))) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + nets = sorted(set(nets)) + + while i < len(ips): + (first, last) = _find_address_range(ips[i:]) + i = ips.index(last) + 1 + addrs.extend(summarize_address_range(first, last)) + + return _collapse_address_list_recursive(sorted( + addrs + nets, key=_BaseNet._get_networks_key)) + +# backwards compatibility +CollapseAddrList = collapse_address_list + +# Test whether this Python implementation supports byte objects that +# are not identical to str ones. +# We need to exclude platforms where bytes == str so that we can +# distinguish between packed representations and strings, for example +# b'12::' (the IPv4 address 49.50.58.58) and '12::' (an IPv6 address). +try: + _compat_has_real_bytes = bytes is not str +except NameError: # <Python2.6 + _compat_has_real_bytes = False + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('1.1.1.1') <= IPv4Network('1.1.1.1/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddr sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNet): + return obj._get_networks_key() + elif isinstance(obj, _BaseIP): + return obj._get_address_key() + return NotImplemented + +class _IPAddrBase(object): + + """The mother class.""" + + def __index__(self): + return self._ip + + def __int__(self): + return self._ip + + def __hex__(self): + return hex(self._ip) + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return str(self) + + +class _BaseIP(_IPAddrBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + + """ + + def __init__(self, address): + if (not (_compat_has_real_bytes and isinstance(address, bytes)) + and '/' in str(address)): + raise AddressValueError(address) + + def __eq__(self, other): + try: + return (self._ip == other._ip + and self._version == other._version) + except AttributeError: + return NotImplemented + + def __ne__(self, other): + eq = self.__eq__(other) + if eq is NotImplemented: + return NotImplemented + return not eq + + def __le__(self, other): + gt = self.__gt__(other) + if gt is NotImplemented: + return NotImplemented + return not gt + + def __ge__(self, other): + lt = self.__lt__(other) + if lt is NotImplemented: + return NotImplemented + return not lt + + def __lt__(self, other): + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + str(self), str(other))) + if not isinstance(other, _BaseIP): + raise TypeError('%s and %s are not of the same type' % ( + str(self), str(other))) + if self._ip != other._ip: + return self._ip < other._ip + return False + + def __gt__(self, other): + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + str(self), str(other))) + if not isinstance(other, _BaseIP): + raise TypeError('%s and %s are not of the same type' % ( + str(self), str(other))) + if self._ip != other._ip: + return self._ip > other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, int): + return NotImplemented + return IPAddress(int(self) + other, version=self._version) + + def __sub__(self, other): + if not isinstance(other, int): + return NotImplemented + return IPAddress(int(self) - other, version=self._version) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, str(self)) + + def __str__(self): + return '%s' % self._string_from_ip_int(self._ip) + + def __hash__(self): + return hash(hex(long(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + @property + def version(self): + raise NotImplementedError('BaseIP has no version') + + +class _BaseNet(_IPAddrBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by networks. + + """ + + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, str(self)) + + def iterhosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + cur = int(self.network) + 1 + bcast = int(self.broadcast) - 1 + while cur <= bcast: + cur += 1 + yield IPAddress(cur - 1, version=self._version) + + def __iter__(self): + cur = int(self.network) + bcast = int(self.broadcast) + while cur <= bcast: + cur += 1 + yield IPAddress(cur - 1, version=self._version) + + def __getitem__(self, n): + network = int(self.network) + broadcast = int(self.broadcast) + if n >= 0: + if network + n > broadcast: + raise IndexError + return IPAddress(network + n, version=self._version) + else: + n += 1 + if broadcast + n < network: + raise IndexError + return IPAddress(broadcast + n, version=self._version) + + def __lt__(self, other): + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + str(self), str(other))) + if not isinstance(other, _BaseNet): + raise TypeError('%s and %s are not of the same type' % ( + str(self), str(other))) + if self.network != other.network: + return self.network < other.network + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __gt__(self, other): + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + str(self), str(other))) + if not isinstance(other, _BaseNet): + raise TypeError('%s and %s are not of the same type' % ( + str(self), str(other))) + if self.network != other.network: + return self.network > other.network + if self.netmask != other.netmask: + return self.netmask > other.netmask + return False + + def __le__(self, other): + gt = self.__gt__(other) + if gt is NotImplemented: + return NotImplemented + return not gt + + def __ge__(self, other): + lt = self.__lt__(other) + if lt is NotImplemented: + return NotImplemented + return not lt + + def __eq__(self, other): + try: + return (self._version == other._version + and self.network == other.network + and int(self.netmask) == int(other.netmask)) + except AttributeError: + if isinstance(other, _BaseIP): + return (self._version == other._version + and self._ip == other._ip) + + def __ne__(self, other): + eq = self.__eq__(other) + if eq is NotImplemented: + return NotImplemented + return not eq + + def __str__(self): + return '%s/%s' % (str(self.ip), + str(self._prefixlen)) + + def __hash__(self): + return hash(int(self.network) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNet): + return (self.network <= other.network and + self.broadcast >= other.broadcast) + # dealing with another address + else: + return (int(self.network) <= int(other._ip) <= + int(self.broadcast)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network in other or self.broadcast in other or ( + other.network in self or other.broadcast in self) + + @property + def network(self): + x = self._cache.get('network') + if x is None: + x = IPAddress(self._ip & int(self.netmask), version=self._version) + self._cache['network'] = x + return x + + @property + def broadcast(self): + x = self._cache.get('broadcast') + if x is None: + x = IPAddress(self._ip | int(self.hostmask), version=self._version) + self._cache['broadcast'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = IPAddress(int(self.netmask) ^ self._ALL_ONES, + version=self._version) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (str(self.ip), self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (str(self.ip), str(self.netmask)) + + @property + def with_hostmask(self): + return '%s/%s' % (str(self.ip), str(self.hostmask)) + + @property + def numhosts(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast) - int(self.network) + 1 + + @property + def version(self): + raise NotImplementedError('BaseNet has no version') + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = IPNetwork('10.1.1.0/24') + addr2 = IPNetwork('10.1.1.0/26') + addr1.address_exclude(addr2) = + [IPNetwork('10.1.1.64/26'), IPNetwork('10.1.1.128/25')] + + or IPv6: + + addr1 = IPNetwork('::1/32') + addr2 = IPNetwork('::1/128') + addr1.address_exclude(addr2) = [IPNetwork('::0/128'), + IPNetwork('::2/127'), + IPNetwork('::4/126'), + IPNetwork('::8/125'), + ... + IPNetwork('0:0:8000::/33')] + + Args: + other: An IPvXNetwork object of the same type. + + Returns: + A sorted list of IPvXNetwork objects addresses which is self + minus other. + + Raises: + TypeError: If self and other are of difffering address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + str(self), str(other))) + + if not isinstance(other, _BaseNet): + raise TypeError("%s is not a network object" % str(other)) + + if other not in self: + raise ValueError('%s not contained in %s' % (str(other), + str(self))) + if other == self: + return [] + + ret_addrs = [] + + # Make sure we're comparing the network of other. + other = IPNetwork('%s/%s' % (str(other.network), str(other.prefixlen)), + version=other._version) + + s1, s2 = self.subnet() + while s1 != other and s2 != other: + if other in s1: + ret_addrs.append(s2) + s1, s2 = s1.subnet() + elif other in s2: + ret_addrs.append(s1) + s1, s2 = s2.subnet() + else: + # If we got here, there's a bug somewhere. + assert True == False, ('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (str(s1), str(s2), str(other))) + if s1 == other: + ret_addrs.append(s2) + elif s2 == other: + ret_addrs.append(s1) + else: + # If we got here, there's a bug somewhere. + assert True == False, ('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (str(s1), str(s2), str(other))) + + return sorted(ret_addrs, key=_BaseNet._get_networks_key) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4('1.1.1.0/24') < IPv4('1.1.2.0/24') + IPv6('1080::200C:417A') < IPv6('1080::200B:417B') + 0 if self == other + eg: IPv4('1.1.1.1/24') == IPv4('1.1.1.2/24') + IPv6('1080::200C:417A/96') == IPv6('1080::200C:417B/96') + 1 if self > other + eg: IPv4('1.1.1.0/24') > IPv4('1.1.0.0/24') + IPv6('1080::1:200C:417A/112') > + IPv6('1080::0:200C:417A/112') + + If the IP versions of self and other are different, returns: + + -1 if self._version < other._version + eg: IPv4('10.0.0.1/24') < IPv6('::1/128') + 1 if self._version > other._version + eg: IPv6('::1/128') > IPv4('255.255.255.0/24') + + """ + if self._version < other._version: + return -1 + if self._version > other._version: + return 1 + # self._version == other._version below here: + if self.network < other.network: + return -1 + if self.network > other.network: + return 1 + # self.network == other.network below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + # self.network == other.network and self.netmask == other.netmask + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network, self.netmask) + + def _ip_int_from_prefix(self, prefixlen=None): + """Turn the prefix length netmask into a int for comparison. + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + if not prefixlen and prefixlen != 0: + prefixlen = self._prefixlen + return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen) + + def _prefix_from_ip_int(self, ip_int, mask=32): + """Return prefix length from the decimal netmask. + + Args: + ip_int: An integer, the IP address. + mask: The netmask. Defaults to 32. + + Returns: + An integer, the prefix length. + + """ + while mask: + if ip_int & 1 == 1: + break + ip_int >>= 1 + mask -= 1 + + return mask + + def _ip_string_from_prefix(self, prefixlen=None): + """Turn a prefix length into a dotted decimal string. + + Args: + prefixlen: An integer, the netmask prefix length. + + Returns: + A string, the dotted decimal netmask string. + + """ + if not prefixlen: + prefixlen = self._prefixlen + return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen)) + + def iter_subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), return a list with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if not self._is_valid_netmask(str(new_prefixlen)): + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, str(self))) + + first = IPNetwork('%s/%s' % (str(self.network), + str(self._prefixlen + prefixlen_diff)), + version=self._version) + + yield first + current = first + while True: + broadcast = current.broadcast + if broadcast == self.broadcast: + return + new_addr = IPAddress(int(broadcast) + 1, version=self._version) + current = IPNetwork('%s/%s' % (str(new_addr), str(new_prefixlen)), + version=self._version) + + yield current + + def masked(self): + """Return the network object with the host bits masked out.""" + return IPNetwork('%s/%d' % (self.network, self._prefixlen), + version=self._version) + + def subnet(self, prefixlen_diff=1, new_prefix=None): + """Return a list of subnets, rather than an iterator.""" + return list(self.iter_subnets(prefixlen_diff, new_prefix)) + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have a + negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + + if self.prefixlen - prefixlen_diff < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return IPNetwork('%s/%s' % (str(self.network), + str(self.prefixlen - prefixlen_diff)), + version=self._version) + + # backwards compatibility + Subnet = subnet + Supernet = supernet + AddressExclude = address_exclude + CompareNetworks = compare_networks + Contains = __contains__ + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2**IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + def __init__(self, address): + self._version = 4 + self._max_prefixlen = IPV4LENGTH + + def _explode_shorthand_ip_string(self, ip_str=None): + if not ip_str: + ip_str = str(self) + return ip_str + + def _ip_int_from_string(self, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError(ip_str) + + packed_ip = 0 + for oc in octets: + try: + packed_ip = (packed_ip << 8) | self._parse_octet(oc) + except ValueError: + raise AddressValueError(ip_str) + return packed_ip + + def _parse_octet(self, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not self._DECIMAL_DIGITS.issuperset(octet_str): + raise ValueError + octet_int = int(octet_str, 10) + # Disallow leading zeroes, because no clear standard exists on + # whether these should be interpreted as decimal or octal. + if octet_int > 255 or (octet_str[0] == '0' and len(octet_str) > 1): + raise ValueError + return octet_int + + def _string_from_ip_int(self, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + octets = [] + for _ in xrange(4): + octets.insert(0, str(ip_int & 0xFF)) + ip_int >>= 8 + return '.'.join(octets) + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def version(self): + return self._version + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in IPv4Network('240.0.0.0/4') + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per RFC 1918. + + """ + return (self in IPv4Network('10.0.0.0/8') or + self in IPv4Network('172.16.0.0/12') or + self in IPv4Network('192.168.0.0/16')) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in IPv4Network('224.0.0.0/4') + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self in IPv4Network('0.0.0.0') + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in IPv4Network('127.0.0.0/8') + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in IPv4Network('169.254.0.0/16') + + +class IPv4Address(_BaseV4, _BaseIP): + + """Represent and manipulate single IPv4 Addresses.""" + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + '192.168.1.1' + + Additionally, an integer can be passed, so + IPv4Address('192.168.1.1') == IPv4Address(3232235777). + or, more generally + IPv4Address(int(IPv4Address('192.168.1.1'))) == + IPv4Address('192.168.1.1') + + Raises: + AddressValueError: If ipaddr isn't a valid IPv4 address. + + """ + _BaseIP.__init__(self, address) + _BaseV4.__init__(self, address) + + # Efficient constructor from integer. + if isinstance(address, (int, long)): + self._ip = address + if address < 0 or address > self._ALL_ONES: + raise AddressValueError(address) + return + + # Constructing from a packed address + if _compat_has_real_bytes: + if isinstance(address, bytes) and len(address) == 4: + self._ip = struct.unpack('!I', address)[0] + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = str(address) + self._ip = self._ip_int_from_string(addr_str) + + +class IPv4Network(_BaseV4, _BaseNet): + + """This class represents and manipulates 32-bit IPv4 networks. + + Attributes: [examples for IPv4Network('1.2.3.4/27')] + ._ip: 16909060 + .ip: IPv4Address('1.2.3.4') + .network: IPv4Address('1.2.3.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast: IPv4Address('1.2.3.31') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0)) + + def __init__(self, address, strict=False): + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.168.1.1/24' + '192.168.1.1/255.255.255.0' + '192.168.1.1/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.168.1.1' + '192.168.1.1/255.255.255.255' + '192.168.1.1/32' + are also functionaly equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.168.1.1') == IPv4Network(3232235777). + or, more generally + IPv4Network(int(IPv4Network('192.168.1.1'))) == + IPv4Network('192.168.1.1') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 192.168.1.0/24 and not an + IP address on a network, eg, 192.168.1.1/24. + + Raises: + AddressValueError: If ipaddr isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNet.__init__(self, address) + _BaseV4.__init__(self, address) + + # Efficient constructor from integer. + if isinstance(address, (int, long)): + self._ip = address + self.ip = IPv4Address(self._ip) + self._prefixlen = self._max_prefixlen + self.netmask = IPv4Address(self._ALL_ONES) + if address < 0 or address > self._ALL_ONES: + raise AddressValueError(address) + return + + # Constructing from a packed address + if _compat_has_real_bytes: + if isinstance(address, bytes) and len(address) == 4: + self._ip = struct.unpack('!I', address)[0] + self.ip = IPv4Address(self._ip) + self._prefixlen = self._max_prefixlen + self.netmask = IPv4Address(self._ALL_ONES) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = str(address).split('/') + + if len(addr) > 2: + raise AddressValueError(address) + + self._ip = self._ip_int_from_string(addr[0]) + self.ip = IPv4Address(self._ip) + + if len(addr) == 2: + mask = addr[1].split('.') + if len(mask) == 4: + # We have dotted decimal netmask. + if self._is_valid_netmask(addr[1]): + self.netmask = IPv4Address(self._ip_int_from_string( + addr[1])) + elif self._is_hostmask(addr[1]): + self.netmask = IPv4Address( + self._ip_int_from_string(addr[1]) ^ self._ALL_ONES) + else: + raise NetmaskValueError('%s is not a valid netmask' + % addr[1]) + + self._prefixlen = self._prefix_from_ip_int(int(self.netmask)) + else: + # We have a netmask in prefix length form. + if not self._is_valid_netmask(addr[1]): + raise NetmaskValueError(addr[1]) + self._prefixlen = int(addr[1]) + self.netmask = IPv4Address(self._ip_int_from_prefix( + self._prefixlen)) + else: + self._prefixlen = self._max_prefixlen + self.netmask = IPv4Address(self._ip_int_from_prefix( + self._prefixlen)) + if strict: + if self.ip != self.network: + raise ValueError('%s has host bits set' % + self.ip) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [int(x) for x in bits if int(x) in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _is_valid_netmask(self, netmask): + """Verify that the netmask is valid. + + Args: + netmask: A string, either a prefix or dotted decimal + netmask. + + Returns: + A boolean, True if the prefix represents a valid IPv4 + netmask. + + """ + mask = netmask.split('.') + if len(mask) == 4: + if [x for x in mask if int(x) not in self._valid_mask_octets]: + return False + if [y for idx, y in enumerate(mask) if idx > 0 and + y > mask[idx - 1]]: + return False + return True + try: + netmask = int(netmask) + except ValueError: + return False + return 0 <= netmask <= self._max_prefixlen + + # backwards compatibility + IsRFC1918 = lambda self: self.is_private + IsMulticast = lambda self: self.is_multicast + IsLoopback = lambda self: self.is_loopback + IsLinkLocal = lambda self: self.is_link_local + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + _ALL_ONES = (2**IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + + def __init__(self, address): + self._version = 6 + self._max_prefixlen = IPV6LENGTH + + def _ip_int_from_string(self, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + A long, the IPv6 ip_str. + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + if len(parts) < 3: + raise AddressValueError(ip_str) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + ipv4_int = IPv4Address(parts.pop())._ip + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + if len(parts) > self._HEXTET_COUNT + 1: + raise AddressValueError(ip_str) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + try: + skip_index, = ( + [i for i in xrange(1, len(parts) - 1) if not parts[i]] or + [None]) + except ValueError: + # Can't have more than one '::' + raise AddressValueError(ip_str) + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + raise AddressValueError(ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + raise AddressValueError(ip_str) # :$ requires ::$ + parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + raise AddressValueError(ip_str) + else: + # Otherwise, allocate the entire address to parts_hi. The endpoints + # could still be empty, but _parse_hextet() will check for that. + if len(parts) != self._HEXTET_COUNT: + raise AddressValueError(ip_str) + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0L + for i in xrange(parts_hi): + ip_int <<= 16 + ip_int |= self._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in xrange(-parts_lo, 0): + ip_int <<= 16 + ip_int |= self._parse_hextet(parts[i]) + return ip_int + except ValueError: + raise AddressValueError(ip_str) + + def _parse_hextet(self, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not self._HEX_DIGITS.issuperset(hextet_str): + raise ValueError + hextet_int = int(hextet_str, 16) + if hextet_int > 0xFFFF: + raise ValueError + return hextet_int + + def _compress_hextets(self, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index in range(len(hextets)): + if hextets[index] == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + def _string_from_ip_int(self, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if not ip_int and ip_int != 0: + ip_int = int(self._ip) + + if ip_int > self._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = [] + for x in range(0, 32, 4): + hextets.append('%x' % int(hex_str[x:x+4], 16)) + + hextets = self._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self, ip_str=None): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if not ip_str: + ip_str = str(self) + if isinstance(self, _BaseNet): + ip_str = str(self.ip) + + ip_int = self._ip_int_from_string(ip_str) + parts = [] + for i in xrange(self._HEXTET_COUNT): + parts.append('%04x' % (ip_int & 0xFFFF)) + ip_int >>= 16 + parts.reverse() + return ':'.join(parts) + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def version(self): + return self._version + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in IPv6Network('ff00::/8') + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self in IPv6Network('::/8') or + self in IPv6Network('100::/8') or + self in IPv6Network('200::/7') or + self in IPv6Network('400::/6') or + self in IPv6Network('800::/5') or + self in IPv6Network('1000::/4') or + self in IPv6Network('4000::/3') or + self in IPv6Network('6000::/3') or + self in IPv6Network('8000::/3') or + self in IPv6Network('A000::/3') or + self in IPv6Network('C000::/3') or + self in IPv6Network('E000::/4') or + self in IPv6Network('F000::/5') or + self in IPv6Network('F800::/6') or + self in IPv6Network('FE00::/9')) + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 and getattr(self, '_prefixlen', 128) == 128 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 and getattr(self, '_prefixlen', 128) == 128 + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in IPv6Network('fe80::/10') + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in IPv6Network('fec0::/10') + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per RFC 4193. + + """ + return self in IPv6Network('fc00::/7') + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Address(_BaseV6, _BaseIP): + + """Represent and manipulate single IPv6 Addresses. + """ + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:4860::') == + IPv6Address(42541956101370907050197289607612071936L). + or, more generally + IPv6Address(IPv6Address('2001:4860::')._ip) == + IPv6Address('2001:4860::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + _BaseIP.__init__(self, address) + _BaseV6.__init__(self, address) + + # Efficient constructor from integer. + if isinstance(address, (int, long)): + self._ip = address + if address < 0 or address > self._ALL_ONES: + raise AddressValueError(address) + return + + # Constructing from a packed address + if _compat_has_real_bytes: + if isinstance(address, bytes) and len(address) == 16: + tmp = struct.unpack('!QQ', address) + self._ip = (tmp[0] << 64) | tmp[1] + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = str(address) + if not addr_str: + raise AddressValueError('') + + self._ip = self._ip_int_from_string(addr_str) + + +class IPv6Network(_BaseV6, _BaseNet): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')] + .ip: IPv6Address('2001:658:22a:cafe:200::1') + .network: IPv6Address('2001:658:22a:cafe::') + .hostmask: IPv6Address('::ffff:ffff:ffff:ffff') + .broadcast: IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff') + .netmask: IPv6Address('ffff:ffff:ffff:ffff::') + .prefixlen: 64 + + """ + + + def __init__(self, address, strict=False): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the IP + and prefix/netmask. + '2001:4860::/128' + '2001:4860:0000:0000:0000:0000:0000:0000/128' + '2001:4860::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:4860::') == + IPv6Network(42541956101370907050197289607612071936L). + or, more generally + IPv6Network(IPv6Network('2001:4860::')._ip) == + IPv6Network('2001:4860::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 192.168.1.0/24 and not an + IP address on a network, eg, 192.168.1.1/24. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNet.__init__(self, address) + _BaseV6.__init__(self, address) + + # Efficient constructor from integer. + if isinstance(address, (int, long)): + self._ip = address + self.ip = IPv6Address(self._ip) + self._prefixlen = self._max_prefixlen + self.netmask = IPv6Address(self._ALL_ONES) + if address < 0 or address > self._ALL_ONES: + raise AddressValueError(address) + return + + # Constructing from a packed address + if _compat_has_real_bytes: + if isinstance(address, bytes) and len(address) == 16: + tmp = struct.unpack('!QQ', address) + self._ip = (tmp[0] << 64) | tmp[1] + self.ip = IPv6Address(self._ip) + self._prefixlen = self._max_prefixlen + self.netmask = IPv6Address(self._ALL_ONES) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = str(address).split('/') + + if len(addr) > 2: + raise AddressValueError(address) + + self._ip = self._ip_int_from_string(addr[0]) + self.ip = IPv6Address(self._ip) + + if len(addr) == 2: + if self._is_valid_netmask(addr[1]): + self._prefixlen = int(addr[1]) + else: + raise NetmaskValueError(addr[1]) + else: + self._prefixlen = self._max_prefixlen + + self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen)) + + if strict: + if self.ip != self.network: + raise ValueError('%s has host bits set' % + self.ip) + + def _is_valid_netmask(self, prefixlen): + """Verify that the netmask/prefixlen is valid. + + Args: + prefixlen: A string, the netmask in prefix length format. + + Returns: + A boolean, True if the prefix represents a valid IPv6 + netmask. + + """ + try: + prefixlen = int(prefixlen) + except ValueError: + return False + return 0 <= prefixlen <= self._max_prefixlen + + @property + def with_netmask(self): + return self.with_prefixlen diff --git a/src/main/resources/PythonLibs/_jyio.py b/src/main/resources/PythonLibs/_jyio.py new file mode 100644 index 0000000000000000000000000000000000000000..1f595f17a432e10bcd847cca46f56d8870a70d96 --- /dev/null +++ b/src/main/resources/PythonLibs/_jyio.py @@ -0,0 +1,1646 @@ +""" +This is based on _pyio.py from CPython 2.7 which is Python implementation of +the io module. The upgrade from a 2.6-ish version accounts for the large +number of changes made all at once. + +It is here to stand in for classes that should be provided by the _io module. +In CPython 2.7, when client code imports io, that module imports a set of +classes from _io and re-exports them as its own. In Jython, io.py imports +those things from _jyio, which in turn imports from _io those so far +implemented in Java. _jyio implements the rest here using nearly the same +code as _pyio. + +Some classes have gained an underscore to match their _io module names: +_IOBase, _RawIOBase, _BufferedIOBase, _TextIOBase. + +As Jython implements more and more of _io in Java, the Python implementations here +will progressively be replaced with imports from _io. Eventually we should implement +all this in Java, remove this module and revert io.py to its CPython original. +""" + +from __future__ import (print_function, unicode_literals) + +import _io # Java implementations to replace this module + +import os +import abc +import codecs +import warnings +import errno +import array +# Import thread instead of threading to reduce startup cost +try: + from thread import allocate_lock as Lock +except ImportError: + from dummy_thread import allocate_lock as Lock + +#import io +#from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END) +from errno import EINTR + +__metaclass__ = type + +# open() uses st_blksize whenever we can +from _io import DEFAULT_BUFFER_SIZE + +# NOTE: Base classes defined here are registered with the "official" ABCs +# defined in io.py. + + +class BlockingIOError(IOError): + + """Exception raised when I/O would block on a non-blocking I/O stream.""" + + def __init__(self, errno, strerror, characters_written=0): + super(IOError, self).__init__(errno, strerror) + if not isinstance(characters_written, (int, long)): + raise TypeError("characters_written must be a integer") + self.characters_written = characters_written + + +from _io import (open, UnsupportedOperation, _IOBase, _RawIOBase, FileIO) + + +class _BufferedIOBase(_IOBase): + + """Base class for buffered IO objects. + + The main difference with _RawIOBase is that the read() method + supports omitting the size argument, and does not have a default + implementation that defers to readinto(). + + In addition, read(), readinto() and write() may raise + BlockingIOError if the underlying raw stream is in non-blocking + mode and not ready; unlike their raw counterparts, they will never + return None. + + A typical implementation should not inherit from a _RawIOBase + implementation, but wrap one. + """ + + def read(self, n=None): + """Read and return up to n bytes. + + If the argument is omitted, None, or negative, reads and + returns all data until EOF. + + If the argument is positive, and the underlying raw stream is + not 'interactive', multiple raw reads may be issued to satisfy + the byte count (unless EOF is reached first). But for + interactive raw streams (XXX and for pipes?), at most one raw + read will be issued, and a short result does not imply that + EOF is imminent. + + Returns an empty bytes array on EOF. + + Raises BlockingIOError if the underlying raw stream has no + data at the moment. + """ + self._unsupported("read") + + def read1(self, n=None): + """Read up to n bytes with at most one read() system call.""" + self._unsupported("read1") + + def readinto(self, b): + """Read up to len(b) bytes into b. + + Like read(), this may issue multiple reads to the underlying raw + stream, unless the latter is 'interactive'. + + Returns the number of bytes read (0 for EOF). + + Raises BlockingIOError if the underlying raw stream has no + data at the moment. + """ + # XXX This ought to work with anything that supports the buffer API + data = self.read(len(b)) + n = len(data) + try: + b[:n] = data + except TypeError as err: + import array + if not isinstance(b, array.array): + raise err + b[:n] = array.array(b'b', data) + return n + + def write(self, b): + """Write the given buffer to the IO stream. + + Return the number of bytes written, which is never less than + len(b). + + Raises BlockingIOError if the buffer is full and the + underlying raw stream cannot accept more data at the moment. + """ + self._unsupported("write") + + def detach(self): + """ + Separate the underlying raw stream from the buffer and return it. + + After the raw stream has been detached, the buffer is in an unusable + state. + """ + self._unsupported("detach") + + +class _BufferedIOMixin(_BufferedIOBase): + + """A mixin implementation of _BufferedIOBase with an underlying raw stream. + + This passes most requests on to the underlying raw stream. It + does *not* provide implementations of read(), readinto() or + write(). + """ + + def __init__(self, raw): + self._ok = False # Jython: subclass __init__ must set when state valid + self._raw = raw + + ### Positioning ### + + def seek(self, pos, whence=0): + new_position = self.raw.seek(pos, whence) + if new_position < 0: + raise IOError("seek() returned an invalid position") + return new_position + + def tell(self): + pos = self.raw.tell() + if pos < 0: + raise IOError("tell() returned an invalid position") + return pos + + def truncate(self, pos=None): + # Flush the stream. We're mixing buffered I/O with lower-level I/O, + # and a flush may be necessary to synch both views of the current + # file state. + self.flush() + + if pos is None: + pos = self.tell() + # XXX: Should seek() be used, instead of passing the position + # XXX directly to truncate? + return self.raw.truncate(pos) + + ### Flush and close ### + + def flush(self): + if self.closed: + raise ValueError("flush of closed file") + self.raw.flush() + + def close(self): + if self.raw is not None and not self.closed: + try: + # Jython difference: call super.close() which manages "closed to client" state, + # and calls flush(), which may raise BlockingIOError or BrokenPipeError etc. + super(_BufferedIOBase, self).close() + finally: + self.raw.close() + + def detach(self): + if self.raw is None: + raise ValueError("raw stream already detached") + self.flush() + raw = self._raw + self._raw = None + return raw + + ### Inquiries ### + + def seekable(self): + self._checkInitialized() # Jython: to forbid use in an invalid state + return self.raw.seekable() + + def readable(self): + self._checkInitialized() # Jython: to forbid use in an invalid state + return self.raw.readable() + + def writable(self): + self._checkInitialized() # Jython: to forbid use in an invalid state + return self.raw.writable() + + @property + def raw(self): + return self._raw + + @property + def closed(self): + return self.raw.closed + + # Jython difference: emulate C implementation CHECK_INITIALIZED. This is for + # compatibility, to pass test.test_io.CTextIOWrapperTest.test_initialization. + def _checkInitialized(self): + if not self._ok: + if self.raw is None: + raise ValueError("raw stream has been detached") + else: + raise ValueError("I/O operation on uninitialized object") + + @property + def name(self): + return self.raw.name + + @property + def mode(self): + return self.raw.mode + + def __repr__(self): + clsname = self.__class__.__name__ + try: + name = self.name + except AttributeError: + return "<_jyio.{0}>".format(clsname) + else: + return "<_jyio.{0} name={1!r}>".format(clsname, name) + + ### Lower-level APIs ### + + def fileno(self): + return self.raw.fileno() + + def isatty(self): + return self.raw.isatty() + + +class BytesIO(_BufferedIOBase): + + """Buffered I/O implementation using an in-memory bytes buffer.""" + + def __init__(self, initial_bytes=None): + buf = bytearray() + if initial_bytes is not None: + buf.extend(initial_bytes) + self._buffer = buf + self._pos = 0 + + # Jython: modelled after bytesio.c::bytesio_getstate + def __getstate__(self): + d = getattr(self, '__dict__', None) + if d is not None : + d = d.copy() + return (self.getvalue(), self._pos, d) + + # Jython: modelled after bytesio.c::bytesio_setstate + def __setstate__(self, state): + + if not isinstance(state, tuple) or len(state) < 3 : + fmt = "%s.__setstate__ argument should be 3-tuple got %s" + raise TypeError( fmt % (type(self), type(state)) ) + + # Reset the object to its default state. This is only needed to handle + # the case of repeated calls to __setstate__. */ + self._buffer = bytearray() + self._pos = 0 + + # Set the value of the internal buffer. If state[0] does not support the + # buffer protocol, bytesio_write will raise the appropriate TypeError. */ + self.write(state[0]); + + # Carefully set the position value. Alternatively, we could use the seek + # method instead of modifying self._pos directly to better protect the + # object internal state against erroneous (or malicious) inputs. */ + p = state[1] + if not isinstance(p, (int, long)) : + fmt = "second item of state must be an integer, got %s" + raise TypeError( fmt % type(p) ) + elif p < 0 : + raise ValueError("position value cannot be negative") + self._pos = p + + # Set the dictionary of the instance variables. */ + d = state[2] + if not d is None : + if isinstance(d, dict) : + self.__dict__ = d + else : + fmt = "third item of state should be a dict, got %s" + raise TypeError( fmt % type(d) ) + + def getvalue(self): + """Return the bytes value (contents) of the buffer + """ + if self.closed: + raise ValueError("getvalue on closed file") + return bytes(self._buffer) + + def read(self, n=None): + if self.closed: + raise ValueError("read from closed file") + if n is None: + n = -1 + if not isinstance(n, (int, long)): + raise TypeError("integer argument expected, got {0!r}".format( + type(n))) + if n < 0: + n = len(self._buffer) + if len(self._buffer) <= self._pos: + return b"" + newpos = min(len(self._buffer), self._pos + n) + b = self._buffer[self._pos : newpos] + self._pos = newpos + return bytes(b) + + def read1(self, n): + """This is the same as read. + """ + return self.read(n) + + def write(self, b): + if self.closed: + raise ValueError("write to closed file") + if isinstance(b, unicode): + raise TypeError("can't write unicode to binary stream") + n = len(b) + if n == 0: + return 0 + pos = self._pos + if pos > len(self._buffer): + # Inserts null bytes between the current end of the file + # and the new write position. + padding = b'\x00' * (pos - len(self._buffer)) + self._buffer += padding + self._buffer[pos:pos + n] = b + self._pos += n + return n + + def seek(self, pos, whence=0): + if self.closed: + raise ValueError("seek on closed file") + try: + pos.__index__ + except AttributeError: + raise TypeError("an integer is required") + if whence == 0: + if pos < 0: + raise ValueError("negative seek position %r" % (pos,)) + self._pos = pos + elif whence == 1: + self._pos = max(0, self._pos + pos) + elif whence == 2: + self._pos = max(0, len(self._buffer) + pos) + else: + raise ValueError("invalid whence value") + return self._pos + + def tell(self): + if self.closed: + raise ValueError("tell on closed file") + return self._pos + + def truncate(self, pos=None): + if self.closed: + raise ValueError("truncate on closed file") + if pos is None: + pos = self._pos + else: + try: + pos.__index__ + except AttributeError: + raise TypeError("an integer is required") + if pos < 0: + raise ValueError("negative truncate position %r" % (pos,)) + del self._buffer[pos:] + return pos + + def readable(self): + self._checkClosed() + return True + + def writable(self): + self._checkClosed() + return True + + def seekable(self): + self._checkClosed() + return True + + +class BufferedReader(_BufferedIOMixin): + + """BufferedReader(raw[, buffer_size]) + + A buffer for a readable, sequential BaseRawIO object. + + The constructor creates a BufferedReader for the given readable raw + stream and buffer_size. If buffer_size is omitted, DEFAULT_BUFFER_SIZE + is used. + """ + + def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE): + """Create a new buffered reader using the given readable raw IO object. + """ + if not raw.readable(): + raise IOError('"raw" argument must be readable.') + + _BufferedIOMixin.__init__(self, raw) + if buffer_size <= 0: + raise ValueError("invalid buffer size") + self.buffer_size = buffer_size + self._reset_read_buf() + self._read_lock = Lock() + self._ok = True # Jython: to enable use now in a valid state + + def _reset_read_buf(self): + self._read_buf = b"" + self._read_pos = 0 + + def read(self, n=None): + """Read n bytes. + + Returns exactly n bytes of data unless the underlying raw IO + stream reaches EOF or if the call would block in non-blocking + mode. If n is negative, read until EOF or until read() would + block. + """ + self._checkReadable() # Jython: to forbid use in an invalid state + if n is not None and n < -1: + raise ValueError("invalid number of bytes to read") + with self._read_lock: + return self._read_unlocked(n) + + def _read_unlocked(self, n=None): + nodata_val = b"" + empty_values = (b"", None) + buf = self._read_buf + pos = self._read_pos + + # Special case for when the number of bytes to read is unspecified. + if n is None or n == -1: + self._reset_read_buf() + chunks = [buf[pos:]] # Strip the consumed bytes. + current_size = 0 + while True: + # Read until EOF or until read() would block. + try: + chunk = self.raw.read() + except IOError as e: + if e.errno != EINTR: + raise + continue + if chunk in empty_values: + nodata_val = chunk + break + current_size += len(chunk) + chunks.append(chunk) + return b"".join(chunks) or nodata_val + + # The number of bytes to read is specified, return at most n bytes. + avail = len(buf) - pos # Length of the available buffered data. + if n <= avail: + # Fast path: the data to read is fully buffered. + self._read_pos += n + return buf[pos:pos+n] + # Slow path: read from the stream until enough bytes are read, + # or until an EOF occurs or until read() would block. + chunks = [buf[pos:]] + wanted = max(self.buffer_size, n) + while avail < n: + try: + chunk = self.raw.read(wanted) + except IOError as e: + if e.errno != EINTR: + raise + continue + if chunk in empty_values: + nodata_val = chunk + break + avail += len(chunk) + chunks.append(chunk) + # n is more then avail only when an EOF occurred or when + # read() would have blocked. + n = min(n, avail) + out = b"".join(chunks) + self._read_buf = out[n:] # Save the extra data in the buffer. + self._read_pos = 0 + return out[:n] if out else nodata_val + + def peek(self, n=0): + """Returns buffered bytes without advancing the position. + + The argument indicates a desired minimal number of bytes; we + do at most one raw read to satisfy it. We never return more + than self.buffer_size. + """ + with self._read_lock: + return self._peek_unlocked(n) + + def _peek_unlocked(self, n=0): + want = min(n, self.buffer_size) + have = len(self._read_buf) - self._read_pos + if have < want or have <= 0: + to_read = self.buffer_size - have + while True: + try: + current = self.raw.read(to_read) + except IOError as e: + if e.errno != EINTR: + raise + continue + break + if current: + self._read_buf = self._read_buf[self._read_pos:] + current + self._read_pos = 0 + return self._read_buf[self._read_pos:] + + def read1(self, n): + """Reads up to n bytes, with at most one read() system call.""" + # Returns up to n bytes. If at least one byte is buffered, we + # only return buffered bytes. Otherwise, we do one raw read. + self._checkReadable() # Jython: to forbid use in an invalid state + if n < 0: + raise ValueError("number of bytes to read must be positive") + if n == 0: + return b"" + with self._read_lock: + self._peek_unlocked(1) + return self._read_unlocked( + min(n, len(self._read_buf) - self._read_pos)) + + def tell(self): + return _BufferedIOMixin.tell(self) - len(self._read_buf) + self._read_pos + + def seek(self, pos, whence=0): + if not (0 <= whence <= 2): + raise ValueError("invalid whence value") + with self._read_lock: + if whence == 1: + pos -= len(self._read_buf) - self._read_pos + pos = _BufferedIOMixin.seek(self, pos, whence) + self._reset_read_buf() + return pos + + +class BufferedWriter(_BufferedIOMixin): + + """A buffer for a writeable sequential RawIO object. + + The constructor creates a BufferedWriter for the given writeable raw + stream. If the buffer_size is not given, it defaults to + DEFAULT_BUFFER_SIZE. + """ + + _warning_stack_offset = 2 + + def __init__(self, raw, + buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=None): + if not raw.writable(): + raise IOError('"raw" argument must be writable.') + + _BufferedIOMixin.__init__(self, raw) + if buffer_size <= 0: + raise ValueError("invalid buffer size") + if max_buffer_size is not None: + warnings.warn("max_buffer_size is deprecated", DeprecationWarning, + self._warning_stack_offset) + self.buffer_size = buffer_size + self._write_buf = bytearray() + self._write_lock = Lock() + self._ok = True # Jython: to enable use now in a valid state + + def write(self, b): + self._checkWritable() # Jython: to forbid use in an invalid state + if self.closed: + raise ValueError("write to closed file") + if isinstance(b, unicode): + raise TypeError("can't write unicode to binary stream") + with self._write_lock: + # XXX we can implement some more tricks to try and avoid + # partial writes + if len(self._write_buf) > self.buffer_size: + # We're full, so let's pre-flush the buffer. (This may + # raise BlockingIOError with characters_written == 0.) + self._flush_unlocked() + before = len(self._write_buf) + if isinstance(b, array.array): # _pyio.py version fails on array.array + self._write_buf.extend(b.tostring()) # Jython version works (while needed) + else: + self._write_buf.extend(b) + written = len(self._write_buf) - before + if len(self._write_buf) > self.buffer_size: + try: + self._flush_unlocked() + except BlockingIOError as e: + if len(self._write_buf) > self.buffer_size: + # We've hit the buffer_size. We have to accept a partial + # write and cut back our buffer. + overage = len(self._write_buf) - self.buffer_size + written -= overage + self._write_buf = self._write_buf[:self.buffer_size] + raise BlockingIOError(e.errno, e.strerror, written) + return written + + def truncate(self, pos=None): + with self._write_lock: + self._flush_unlocked() + if pos is None: + pos = self.raw.tell() + return self.raw.truncate(pos) + + def flush(self): + with self._write_lock: + self._flush_unlocked() + + def _flush_unlocked(self): + if self.closed: + raise ValueError("flush of closed file") + self._checkWritable() # Jython: to forbid use in an invalid state + while self._write_buf: + try: + n = self.raw.write(self._write_buf) + except BlockingIOError: + raise RuntimeError("self.raw should implement _RawIOBase: it " + "should not raise BlockingIOError") + except IOError as e: + if e.errno != EINTR: + raise + continue + if n is None: + raise BlockingIOError( + errno.EAGAIN, + "write could not complete without blocking", 0) + if n > len(self._write_buf) or n < 0: + raise IOError("write() returned incorrect number of bytes") + del self._write_buf[:n] + + def tell(self): + return _BufferedIOMixin.tell(self) + len(self._write_buf) + + def seek(self, pos, whence=0): + if not (0 <= whence <= 2): + raise ValueError("invalid whence") + with self._write_lock: + self._flush_unlocked() + return _BufferedIOMixin.seek(self, pos, whence) + + +class BufferedRWPair(_BufferedIOBase): + + """A buffered reader and writer object together. + + A buffered reader object and buffered writer object put together to + form a sequential IO object that can read and write. This is typically + used with a socket or two-way pipe. + + reader and writer are _RawIOBase objects that are readable and + writeable respectively. If the buffer_size is omitted it defaults to + DEFAULT_BUFFER_SIZE. + """ + + # XXX The usefulness of this (compared to having two separate IO + # objects) is questionable. + + def __init__(self, reader, writer, + buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=None): + """Constructor. + + The arguments are two RawIO instances. + """ + if max_buffer_size is not None: + warnings.warn("max_buffer_size is deprecated", DeprecationWarning, 2) + + if not reader.readable(): + raise IOError('"reader" argument must be readable.') + + if not writer.writable(): + raise IOError('"writer" argument must be writable.') + + self.reader = BufferedReader(reader, buffer_size) + self.writer = BufferedWriter(writer, buffer_size) + + def read(self, n=None): + if n is None: + n = -1 + return self.reader.read(n) + + def readinto(self, b): + return self.reader.readinto(b) + + def write(self, b): + return self.writer.write(b) + + def peek(self, n=0): + return self.reader.peek(n) + + def read1(self, n): + return self.reader.read1(n) + + def readable(self): + return self.reader.readable() + + def writable(self): + return self.writer.writable() + + def flush(self): + return self.writer.flush() + + def close(self): + self.writer.close() + self.reader.close() + + def isatty(self): + return self.reader.isatty() or self.writer.isatty() + + @property + def closed(self): + return self.writer.closed + + +class BufferedRandom(BufferedWriter, BufferedReader): + + """A buffered interface to random access streams. + + The constructor creates a reader and writer for a seekable stream, + raw, given in the first argument. If the buffer_size is omitted it + defaults to DEFAULT_BUFFER_SIZE. + """ + + _warning_stack_offset = 3 + + def __init__(self, raw, + buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=None): + raw._checkSeekable() + BufferedReader.__init__(self, raw, buffer_size) + BufferedWriter.__init__(self, raw, buffer_size, max_buffer_size) + + def seek(self, pos, whence=0): + if not (0 <= whence <= 2): + raise ValueError("invalid whence") + self.flush() + if self._read_buf: + # Undo read ahead. + with self._read_lock: + self.raw.seek(self._read_pos - len(self._read_buf), 1) + # First do the raw seek, then empty the read buffer, so that + # if the raw seek fails, we don't lose buffered data forever. + pos = self.raw.seek(pos, whence) + with self._read_lock: + self._reset_read_buf() + if pos < 0: + raise IOError("seek() returned invalid position") + return pos + + def tell(self): + if self._write_buf: + return BufferedWriter.tell(self) + else: + return BufferedReader.tell(self) + + def truncate(self, pos=None): + if pos is None: + pos = self.tell() + # Use seek to flush the read buffer. + return BufferedWriter.truncate(self, pos) + + def read(self, n=None): + if n is None: + n = -1 + self.flush() + return BufferedReader.read(self, n) + + def readinto(self, b): + self.flush() + return BufferedReader.readinto(self, b) + + def peek(self, n=0): + self.flush() + return BufferedReader.peek(self, n) + + def read1(self, n): + self.flush() + return BufferedReader.read1(self, n) + + def write(self, b): + if self._read_buf: + # Undo readahead + with self._read_lock: + self.raw.seek(self._read_pos - len(self._read_buf), 1) + self._reset_read_buf() + return BufferedWriter.write(self, b) + + +class _TextIOBase(_IOBase): + + """Base class for text I/O. + + This class provides a character and line based interface to stream + I/O. There is no readinto method because Python's character strings + are immutable. There is no public constructor. + """ + + def read(self, n=-1): + """Read at most n characters from stream. + + Read from underlying buffer until we have n characters or we hit EOF. + If n is negative or omitted, read until EOF. + """ + self._unsupported("read") + + def write(self, s): + """Write string s to stream.""" + self._unsupported("write") + + def truncate(self, pos=None): + """Truncate size to pos.""" + self._unsupported("truncate") + + def readline(self): + """Read until newline or EOF. + + Returns an empty string if EOF is hit immediately. + """ + self._unsupported("readline") + + def detach(self): + """ + Separate the underlying buffer from the _TextIOBase and return it. + + After the underlying buffer has been detached, the TextIO is in an + unusable state. + """ + self._unsupported("detach") + + @property + def encoding(self): + """Subclasses should override.""" + return None + + @property + def newlines(self): + """Line endings translated so far. + + Only line endings translated during reading are considered. + + Subclasses should override. + """ + return None + + @property + def errors(self): + """Error setting of the decoder or encoder. + + Subclasses should override.""" + return None + + +class IncrementalNewlineDecoder(codecs.IncrementalDecoder): + r"""Codec used when reading a file in universal newlines mode. It wraps + another incremental decoder, translating \r\n and \r into \n. It also + records the types of newlines encountered. When used with + translate=False, it ensures that the newline sequence is returned in + one piece. + """ + def __init__(self, decoder, translate, errors='strict'): + codecs.IncrementalDecoder.__init__(self, errors=errors) + self.translate = translate + self.decoder = decoder + self.seennl = 0 + self.pendingcr = False + + def decode(self, input, final=False): + # decode input (with the eventual \r from a previous pass) + if self.decoder is None: + output = input + else: + output = self.decoder.decode(input, final=final) + if self.pendingcr and (output or final): + output = "\r" + output + self.pendingcr = False + + # retain last \r even when not translating data: + # then readline() is sure to get \r\n in one pass + if output.endswith("\r") and not final: + output = output[:-1] + self.pendingcr = True + + # Record which newlines are read + crlf = output.count('\r\n') + cr = output.count('\r') - crlf + lf = output.count('\n') - crlf + self.seennl |= (lf and self._LF) | (cr and self._CR) \ + | (crlf and self._CRLF) + + if self.translate: + if crlf: + output = output.replace("\r\n", "\n") + if cr: + output = output.replace("\r", "\n") + + return output + + def getstate(self): + if self.decoder is None: + buf = b"" + flag = 0 + else: + buf, flag = self.decoder.getstate() + flag <<= 1 + if self.pendingcr: + flag |= 1 + return buf, flag + + def setstate(self, state): + buf, flag = state + self.pendingcr = bool(flag & 1) + if self.decoder is not None: + self.decoder.setstate((buf, flag >> 1)) + + def reset(self): + self.seennl = 0 + self.pendingcr = False + if self.decoder is not None: + self.decoder.reset() + + _LF = 1 + _CR = 2 + _CRLF = 4 + + @property + def newlines(self): + return (None, + "\n", + "\r", + ("\r", "\n"), + "\r\n", + ("\n", "\r\n"), + ("\r", "\r\n"), + ("\r", "\n", "\r\n") + )[self.seennl] + + +def _check_decoded_chars(chars): + """Check decoder output is unicode""" + if not isinstance(chars, unicode): + raise TypeError("decoder should return a string result, not '%s'" % + type(chars)) + +def _check_buffered_bytes(b, context="read"): + """Check buffer has returned bytes""" + if not isinstance(b, str): + raise TypeError("underlying %s() should have returned a bytes object, not '%s'" % + (context, type(b))) + + + +class TextIOWrapper(_TextIOBase): + + r"""Character and line based layer over a _BufferedIOBase object, buffer. + + encoding gives the name of the encoding that the stream will be + decoded or encoded with. It defaults to locale.getpreferredencoding. + + errors determines the strictness of encoding and decoding (see the + codecs.register) and defaults to "strict". + + newline can be None, '', '\n', '\r', or '\r\n'. It controls the + handling of line endings. If it is None, universal newlines is + enabled. With this enabled, on input, the lines endings '\n', '\r', + or '\r\n' are translated to '\n' before being returned to the + caller. Conversely, on output, '\n' is translated to the system + default line separator, os.linesep. If newline is any other of its + legal values, that newline becomes the newline when the file is read + and it is returned untranslated. On output, '\n' is converted to the + newline. + + If line_buffering is True, a call to flush is implied when a call to + write contains a newline character. + """ + + _CHUNK_SIZE = 2048 + + def __init__(self, buffer, encoding=None, errors=None, newline=None, + line_buffering=False): + self._ok = False # Jython: to forbid use in an invalid state + if newline is not None and not isinstance(newline, basestring): + raise TypeError("illegal newline type: %r" % (type(newline),)) + if newline not in (None, "", "\n", "\r", "\r\n"): + raise ValueError("illegal newline value: %r" % (newline,)) + if encoding is None: + try: + import locale + except ImportError: + # Importing locale may fail if Python is being built + encoding = "ascii" + else: + encoding = locale.getpreferredencoding() + + if not isinstance(encoding, basestring): + raise ValueError("invalid encoding: %r" % encoding) + + if errors is None: + errors = "strict" + else: + if not isinstance(errors, basestring): + raise ValueError("invalid errors: %r" % errors) + + self._buffer = buffer + self._line_buffering = line_buffering + self._encoding = encoding + self._errors = errors + self._readuniversal = not newline + self._readtranslate = newline is None + self._readnl = newline + self._writetranslate = newline != '' + self._writenl = newline or os.linesep + self._encoder = None + self._decoder = None + self._decoded_chars = '' # buffer for text returned from decoder + self._decoded_chars_used = 0 # offset into _decoded_chars for read() + self._snapshot = None # info for reconstructing decoder state + self._seekable = self._telling = self.buffer.seekable() + + self._ok = True # Jython: to enable use now in a valid state + + if self._seekable and self.writable(): + position = self.buffer.tell() + if position != 0: + try: + self._get_encoder().setstate(0) + except LookupError: + # Sometimes the encoder doesn't exist + pass + + # self._snapshot is either None, or a tuple (dec_flags, next_input) + # where dec_flags is the second (integer) item of the decoder state + # and next_input is the chunk of input bytes that comes next after the + # snapshot point. We use this to reconstruct decoder states in tell(). + + # Naming convention: + # - "bytes_..." for integer variables that count input bytes + # - "chars_..." for integer variables that count decoded characters + + def __repr__(self): + try: + name = self.name + except AttributeError: + return "<_jyio.TextIOWrapper encoding='{0}'>".format(self.encoding) + else: + return "<_jyio.TextIOWrapper name={0!r} encoding='{1}'>".format( + name, self.encoding) + + @property + def encoding(self): + return self._encoding + + @property + def errors(self): + return self._errors + + @property + def line_buffering(self): + return self._line_buffering + + @property + def buffer(self): + return self._buffer + + def seekable(self): + self._checkInitialized() # Jython: to forbid use in an invalid state + self._checkClosed() + return self._seekable + + def readable(self): + self._checkInitialized() # Jython: to forbid use in an invalid state + return self.buffer.readable() + + def writable(self): + self._checkInitialized() # Jython: to forbid use in an invalid state + return self.buffer.writable() + + def flush(self): + self._checkInitialized() # Jython: to forbid use in an invalid state + self.buffer.flush() + self._telling = self._seekable + + def close(self): + if self.buffer is not None and not self.closed: + try: + # Jython difference: flush and close via super. + # Sets __closed for quick _checkClosed(). + super(TextIOWrapper, self).close() + finally: + self.buffer.close() + + @property + def closed(self): + return self.buffer.closed + + # Jython difference: emulate C implementation CHECK_INITIALIZED. This is for + # compatibility, to pass test.test_io.CTextIOWrapperTest.test_initialization. + def _checkInitialized(self): + if not self._ok: + if self.buffer is None: + raise ValueError("underlying buffer has been detached") + else: + raise ValueError("I/O operation on uninitialized object") + + @property + def name(self): + return self.buffer.name + + def fileno(self): + return self.buffer.fileno() + + def isatty(self): + return self.buffer.isatty() + + def write(self, s): + self._checkWritable() # Jython: to forbid use in an invalid state + if self.closed: + raise ValueError("write to closed file") + if not isinstance(s, unicode): + raise TypeError("can't write %s to text stream" % + s.__class__.__name__) + length = len(s) + haslf = (self._writetranslate or self._line_buffering) and "\n" in s + if haslf and self._writetranslate and self._writenl != "\n": + s = s.replace("\n", self._writenl) + encoder = self._encoder or self._get_encoder() + # XXX What if we were just reading? + b = encoder.encode(s) + self.buffer.write(b) + if self._line_buffering and (haslf or "\r" in s): + self.flush() + self._snapshot = None + if self._decoder: + self._decoder.reset() + return length + + def _get_encoder(self): + make_encoder = codecs.getincrementalencoder(self._encoding) + self._encoder = make_encoder(self._errors) + return self._encoder + + def _get_decoder(self): + make_decoder = codecs.getincrementaldecoder(self._encoding) + decoder = make_decoder(self._errors) + if self._readuniversal: + decoder = IncrementalNewlineDecoder(decoder, self._readtranslate) + self._decoder = decoder + return decoder + + # The following three methods implement an ADT for _decoded_chars. + # Text returned from the decoder is buffered here until the client + # requests it by calling our read() or readline() method. + def _set_decoded_chars(self, chars): + """Set the _decoded_chars buffer.""" + self._decoded_chars = chars + self._decoded_chars_used = 0 + + def _get_decoded_chars(self, n=None): + """Advance into the _decoded_chars buffer.""" + offset = self._decoded_chars_used + if n is None: + chars = self._decoded_chars[offset:] + else: + chars = self._decoded_chars[offset:offset + n] + self._decoded_chars_used += len(chars) + return chars + + def _rewind_decoded_chars(self, n): + """Rewind the _decoded_chars buffer.""" + if self._decoded_chars_used < n: + raise AssertionError("rewind decoded_chars out of bounds") + self._decoded_chars_used -= n + + def _read_chunk(self): + """ + Read and decode the next chunk of data from the BufferedReader. + """ + + # The return value is True unless EOF was reached. The decoded + # string is placed in self._decoded_chars (replacing its previous + # value). The entire input chunk is sent to the decoder, though + # some of it may remain buffered in the decoder, yet to be + # converted. + + if self._decoder is None: + raise ValueError("no decoder") + + if self._telling: + # To prepare for tell(), we need to snapshot a point in the + # file where the decoder's input buffer is empty. + + dec_buffer, dec_flags = self._decoder.getstate() + # Given this, we know there was a valid snapshot point + # len(dec_buffer) bytes ago with decoder state (b'', dec_flags). + + # Read a chunk, decode it, and put the result in self._decoded_chars. + input_chunk = self.buffer.read1(self._CHUNK_SIZE) + _check_buffered_bytes(input_chunk, "read1") + + eof = not input_chunk + decoded_chunk = self._decoder.decode(input_chunk, eof) + _check_decoded_chars(decoded_chunk) + self._set_decoded_chars(decoded_chunk) + + if self._telling: + # At the snapshot point, len(dec_buffer) bytes before the read, + # the next input to be decoded is dec_buffer + input_chunk. + self._snapshot = (dec_flags, dec_buffer + input_chunk) + + return not eof + + def _pack_cookie(self, position, dec_flags=0, + bytes_to_feed=0, need_eof=0, chars_to_skip=0): + # The meaning of a tell() cookie is: seek to position, set the + # decoder flags to dec_flags, read bytes_to_feed bytes, feed them + # into the decoder with need_eof as the EOF flag, then skip + # chars_to_skip characters of the decoded result. For most simple + # decoders, tell() will often just give a byte offset in the file. + return (position | (dec_flags<<64) | (bytes_to_feed<<128) | + (chars_to_skip<<192) | bool(need_eof)<<256) + + def _unpack_cookie(self, bigint): + rest, position = divmod(bigint, 1<<64) + rest, dec_flags = divmod(rest, 1<<64) + rest, bytes_to_feed = divmod(rest, 1<<64) + need_eof, chars_to_skip = divmod(rest, 1<<64) + return position, dec_flags, bytes_to_feed, need_eof, chars_to_skip + + def tell(self): + if not self._seekable: + raise IOError("underlying stream is not seekable") + if not self._telling: + raise IOError("telling position disabled by next() call") + self.flush() + position = self.buffer.tell() + decoder = self._decoder + if decoder is None or self._snapshot is None: + if self._decoded_chars: + # This should never happen. + raise AssertionError("pending decoded text") + return position + + # Skip backward to the snapshot point (see _read_chunk). + dec_flags, next_input = self._snapshot + position -= len(next_input) + + # How many decoded characters have been used up since the snapshot? + chars_to_skip = self._decoded_chars_used + if chars_to_skip == 0: + # We haven't moved from the snapshot point. + return self._pack_cookie(position, dec_flags) + + # Starting from the snapshot position, we will walk the decoder + # forward until it gives us enough decoded characters. + saved_state = decoder.getstate() + try: + # Note our initial start point. + decoder.setstate((b'', dec_flags)) + start_pos = position + start_flags, bytes_fed, chars_decoded = dec_flags, 0, 0 + need_eof = 0 + + # Feed the decoder one byte at a time. As we go, note the + # nearest "safe start point" before the current location + # (a point where the decoder has nothing buffered, so seek() + # can safely start from there and advance to this location). + for next_byte in next_input: + bytes_fed += 1 + chars_decoded += len(decoder.decode(next_byte)) + dec_buffer, dec_flags = decoder.getstate() + if not dec_buffer and chars_decoded <= chars_to_skip: + # Decoder buffer is empty, so this is a safe start point. + start_pos += bytes_fed + chars_to_skip -= chars_decoded + start_flags, bytes_fed, chars_decoded = dec_flags, 0, 0 + if chars_decoded >= chars_to_skip: + break + else: + # We didn't get enough decoded data; signal EOF to get more. + chars_decoded += len(decoder.decode(b'', final=True)) + need_eof = 1 + if chars_decoded < chars_to_skip: + raise IOError("can't reconstruct logical file position") + + # The returned cookie corresponds to the last safe start point. + return self._pack_cookie( + start_pos, start_flags, bytes_fed, need_eof, chars_to_skip) + finally: + decoder.setstate(saved_state) + + def truncate(self, pos=None): + self.flush() + if pos is None: + pos = self.tell() + return self.buffer.truncate(pos) + + def detach(self): + if self.buffer is None: + raise ValueError("buffer is already detached") + self.flush() + self._ok = False # Jython: to forbid use in an invalid state + buffer = self._buffer + self._buffer = None + return buffer + + def seek(self, cookie, whence=0): + if self.closed: + raise ValueError("tell on closed file") + if not self._seekable: + raise IOError("underlying stream is not seekable") + if whence == 1: # seek relative to current position + if cookie != 0: + raise IOError("can't do nonzero cur-relative seeks") + # Seeking to the current position should attempt to + # sync the underlying buffer with the current position. + whence = 0 + cookie = self.tell() + if whence == 2: # seek relative to end of file + if cookie != 0: + raise IOError("can't do nonzero end-relative seeks") + self.flush() + position = self.buffer.seek(0, 2) + self._set_decoded_chars('') + self._snapshot = None + if self._decoder: + self._decoder.reset() + return position + if whence != 0: + raise ValueError("invalid whence (%r, should be 0, 1 or 2)" % + (whence,)) + if cookie < 0: + raise ValueError("negative seek position %r" % (cookie,)) + self.flush() + + # The strategy of seek() is to go back to the safe start point + # and replay the effect of read(chars_to_skip) from there. + start_pos, dec_flags, bytes_to_feed, need_eof, chars_to_skip = \ + self._unpack_cookie(cookie) + + # Seek back to the safe start point. + self.buffer.seek(start_pos) + self._set_decoded_chars('') + self._snapshot = None + + # Restore the decoder to its state from the safe start point. + if cookie == 0 and self._decoder: + self._decoder.reset() + elif self._decoder or dec_flags or chars_to_skip: + self._decoder = self._decoder or self._get_decoder() + self._decoder.setstate((b'', dec_flags)) + self._snapshot = (dec_flags, b'') + + if chars_to_skip: + # Just like _read_chunk, feed the decoder and save a snapshot. + input_chunk = self.buffer.read(bytes_to_feed) + _check_buffered_bytes(input_chunk) + decoded_chunk = self._decoder.decode(input_chunk, need_eof) + _check_decoded_chars(decoded_chunk) + self._set_decoded_chars(decoded_chunk) + + self._snapshot = (dec_flags, input_chunk) + + # Skip chars_to_skip of the decoded characters. + if len(self._decoded_chars) < chars_to_skip: + raise IOError("can't restore logical file position") + self._decoded_chars_used = chars_to_skip + + # Finally, reset the encoder (merely useful for proper BOM handling) + try: + encoder = self._encoder or self._get_encoder() + except LookupError: + # Sometimes the encoder doesn't exist + pass + else: + if cookie != 0: + encoder.setstate(0) + else: + encoder.reset() + return cookie + + def read(self, n=None): + self._checkReadable() + if n is None: + n = -1 + decoder = self._decoder or self._get_decoder() + try: + n.__index__ + except AttributeError: + raise TypeError("an integer is required") + if n < 0: + # Read everything. + input_chunk = self.buffer.read() + # Jython difference: CPython textio.c omits: + _check_buffered_bytes(input_chunk) + decoded_chunk = decoder.decode(input_chunk, final=True) + _check_decoded_chars(decoded_chunk) + result = self._get_decoded_chars() + decoded_chunk + self._set_decoded_chars('') + self._snapshot = None + return result + else: + # Keep reading chunks until we have n characters to return. + eof = False + result = self._get_decoded_chars(n) + while len(result) < n and not eof: + eof = not self._read_chunk() + result += self._get_decoded_chars(n - len(result)) + return result + + def next(self): + self._telling = False + line = self.readline() + if not line: + self._snapshot = None + self._telling = self._seekable + raise StopIteration + return line + + def readline(self, limit=None): + if self.closed: + raise ValueError("read from closed file") + if limit is None: + limit = -1 + elif not isinstance(limit, (int, long)): + raise TypeError("limit must be an integer") + + # Grab all the decoded text (we will rewind any extra bits later). + line = self._get_decoded_chars() + + start = 0 + # Make the decoder if it doesn't already exist. + if not self._decoder: + self._get_decoder() + + pos = endpos = None + while True: + if self._readtranslate: + # Newlines are already translated, only search for \n + pos = line.find('\n', start) + if pos >= 0: + endpos = pos + 1 + break + else: + start = len(line) + + elif self._readuniversal: + # Universal newline search. Find any of \r, \r\n, \n + # The decoder ensures that \r\n are not split in two pieces + + # In C we'd look for these in parallel of course. + nlpos = line.find("\n", start) + crpos = line.find("\r", start) + if crpos == -1: + if nlpos == -1: + # Nothing found + start = len(line) + else: + # Found \n + endpos = nlpos + 1 + break + elif nlpos == -1: + # Found lone \r + endpos = crpos + 1 + break + elif nlpos < crpos: + # Found \n + endpos = nlpos + 1 + break + elif nlpos == crpos + 1: + # Found \r\n + endpos = crpos + 2 + break + else: + # Found \r + endpos = crpos + 1 + break + else: + # non-universal + pos = line.find(self._readnl) + if pos >= 0: + endpos = pos + len(self._readnl) + break + + if limit >= 0 and len(line) >= limit: + endpos = limit # reached length limit + break + + # No line ending seen yet - get more data' + while self._read_chunk(): + if self._decoded_chars: + break + if self._decoded_chars: + line += self._get_decoded_chars() + else: + # end of file + self._set_decoded_chars('') + self._snapshot = None + return line + + if limit >= 0 and endpos > limit: + endpos = limit # don't exceed limit + + # Rewind _decoded_chars to just after the line ending we found. + self._rewind_decoded_chars(len(line) - endpos) + return line[:endpos] + + @property + def newlines(self): + return self._decoder.newlines if self._decoder else None + + +class StringIO(TextIOWrapper): + """Text I/O implementation using an in-memory buffer. + + The initial_value argument sets the value of object. The newline + argument is like the one of TextIOWrapper's constructor. + """ + + def __init__(self, initial_value="", newline="\n"): + + # Newline mark needs to be in bytes: convert if not already so + if isinstance(newline, unicode) : + newline = newline.encode("utf-8") + + super(StringIO, self).__init__(BytesIO(), + encoding="utf-8", + errors="strict", + newline=newline) + # Issue #5645: make universal newlines semantics the same as in the + # C version, even under Windows. + if newline is None: + self._writetranslate = False + # An initial value may have been supplied (and must be unicode) + if initial_value is not None: + if not isinstance(initial_value, unicode) : + fmt = "initial value should be unicode or None, got %s" + raise TypeError( fmt % type(initial_value) ) + if initial_value: + self.write(initial_value) + self.seek(0) + + # Jython: modelled after stringio.c::stringio_getstate + def __getstate__(self): + d = getattr(self, '__dict__', None) + if d is not None : + d = d.copy() + return (self.getvalue(), self._readnl, self.tell(), d) + + # Jython: modelled after stringio.c:stringio_setstate + def __setstate__(self, state): + self._checkClosed() + + if not isinstance(state, tuple) or len(state) < 4 : + fmt = "%s.__setstate__ argument should be 4-tuple got %s" + raise TypeError( fmt % (type(self), type(state)) ) + + # Initialize the object's state, but empty + self.__init__(None, state[1]) + + # Write the buffer, bypassing end-of-line translation. + value = state[0] + if value is not None: + if not isinstance(value, unicode) : + fmt = "ivalue should be unicode or None, got %s" + raise TypeError( fmt % type(value) ) + encoder = self._encoder or self._get_encoder() + b = encoder.encode(state[0]) + self.buffer.write(b) + + # Reset the object to its default state. This is only needed to handle + # the case of repeated calls to __setstate__. + self.seek(0) + + # Set the position value using seek. A long is tolerated (e.g from pickle). + p = state[2] + if not isinstance(p, (int, long)) : + fmt = "third item of state must be an integer, got %s" + raise TypeError( fmt % type(p) ) + elif p < 0 : + raise ValueError("position value cannot be negative") + self.seek(p) + + # Set the dictionary of the instance variables. */ + d = state[3] + if not d is None : + if isinstance(d, dict) : + self.__dict__ = d + else : + fmt = "fourth item of state should be a dict, got %s" + raise TypeError( fmt % type(d) ) + + def getvalue(self): + self.flush() + return self.buffer.getvalue().decode(self._encoding, self._errors) + + def __repr__(self): + # TextIOWrapper tells the encoding in its repr. In StringIO, + # that's a implementation detail. + return object.__repr__(self) + + @property + def errors(self): + return None + + @property + def encoding(self): + return None + + def detach(self): + # This doesn't make sense on StringIO. + self._unsupported("detach") diff --git a/src/main/resources/PythonLibs/_pyio.py b/src/main/resources/PythonLibs/_pyio.py new file mode 100644 index 0000000000000000000000000000000000000000..ac7832e1bda34e8279ab3c99355fa3a747cd449c --- /dev/null +++ b/src/main/resources/PythonLibs/_pyio.py @@ -0,0 +1,2017 @@ +""" +Python implementation of the io module. +""" + +from __future__ import (print_function, unicode_literals) + +import os +import abc +import codecs +import warnings +import errno +# Import thread instead of threading to reduce startup cost +try: + from thread import allocate_lock as Lock +except ImportError: + from dummy_thread import allocate_lock as Lock + +import io +from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END) +from errno import EINTR + +__metaclass__ = type + +# open() uses st_blksize whenever we can +DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes + +# NOTE: Base classes defined here are registered with the "official" ABCs +# defined in io.py. We don't use real inheritance though, because we don't +# want to inherit the C implementations. + + +class BlockingIOError(IOError): + + """Exception raised when I/O would block on a non-blocking I/O stream.""" + + def __init__(self, errno, strerror, characters_written=0): + super(IOError, self).__init__(errno, strerror) + if not isinstance(characters_written, (int, long)): + raise TypeError("characters_written must be a integer") + self.characters_written = characters_written + + +def open(file, mode="r", buffering=-1, + encoding=None, errors=None, + newline=None, closefd=True): + + r"""Open file and return a stream. Raise IOError upon failure. + + file is either a text or byte string giving the name (and the path + if the file isn't in the current working directory) of the file to + be opened or an integer file descriptor of the file to be + wrapped. (If a file descriptor is given, it is closed when the + returned I/O object is closed, unless closefd is set to False.) + + mode is an optional string that specifies the mode in which the file + is opened. It defaults to 'r' which means open for reading in text + mode. Other common values are 'w' for writing (truncating the file if + it already exists), and 'a' for appending (which on some Unix systems, + means that all writes append to the end of the file regardless of the + current seek position). In text mode, if encoding is not specified the + encoding used is platform dependent. (For reading and writing raw + bytes use binary mode and leave encoding unspecified.) The available + modes are: + + ========= =============================================================== + Character Meaning + --------- --------------------------------------------------------------- + 'r' open for reading (default) + 'w' open for writing, truncating the file first + 'a' open for writing, appending to the end of the file if it exists + 'b' binary mode + 't' text mode (default) + '+' open a disk file for updating (reading and writing) + 'U' universal newline mode (for backwards compatibility; unneeded + for new code) + ========= =============================================================== + + The default mode is 'rt' (open for reading text). For binary random + access, the mode 'w+b' opens and truncates the file to 0 bytes, while + 'r+b' opens the file without truncation. + + Python distinguishes between files opened in binary and text modes, + even when the underlying operating system doesn't. Files opened in + binary mode (appending 'b' to the mode argument) return contents as + bytes objects without any decoding. In text mode (the default, or when + 't' is appended to the mode argument), the contents of the file are + returned as strings, the bytes having been first decoded using a + platform-dependent encoding or using the specified encoding if given. + + buffering is an optional integer used to set the buffering policy. + Pass 0 to switch buffering off (only allowed in binary mode), 1 to select + line buffering (only usable in text mode), and an integer > 1 to indicate + the size of a fixed-size chunk buffer. When no buffering argument is + given, the default buffering policy works as follows: + + * Binary files are buffered in fixed-size chunks; the size of the buffer + is chosen using a heuristic trying to determine the underlying device's + "block size" and falling back on `io.DEFAULT_BUFFER_SIZE`. + On many systems, the buffer will typically be 4096 or 8192 bytes long. + + * "Interactive" text files (files for which isatty() returns True) + use line buffering. Other text files use the policy described above + for binary files. + + encoding is the name of the encoding used to decode or encode the + file. This should only be used in text mode. The default encoding is + platform dependent, but any encoding supported by Python can be + passed. See the codecs module for the list of supported encodings. + + errors is an optional string that specifies how encoding errors are to + be handled---this argument should not be used in binary mode. Pass + 'strict' to raise a ValueError exception if there is an encoding error + (the default of None has the same effect), or pass 'ignore' to ignore + errors. (Note that ignoring encoding errors can lead to data loss.) + See the documentation for codecs.register for a list of the permitted + encoding error strings. + + newline controls how universal newlines works (it only applies to text + mode). It can be None, '', '\n', '\r', and '\r\n'. It works as + follows: + + * On input, if newline is None, universal newlines mode is + enabled. Lines in the input can end in '\n', '\r', or '\r\n', and + these are translated into '\n' before being returned to the + caller. If it is '', universal newline mode is enabled, but line + endings are returned to the caller untranslated. If it has any of + the other legal values, input lines are only terminated by the given + string, and the line ending is returned to the caller untranslated. + + * On output, if newline is None, any '\n' characters written are + translated to the system default line separator, os.linesep. If + newline is '', no translation takes place. If newline is any of the + other legal values, any '\n' characters written are translated to + the given string. + + If closefd is False, the underlying file descriptor will be kept open + when the file is closed. This does not work when a file name is given + and must be True in that case. + + open() returns a file object whose type depends on the mode, and + through which the standard file operations such as reading and writing + are performed. When open() is used to open a file in a text mode ('w', + 'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open + a file in a binary mode, the returned class varies: in read binary + mode, it returns a BufferedReader; in write binary and append binary + modes, it returns a BufferedWriter, and in read/write mode, it returns + a BufferedRandom. + + It is also possible to use a string or bytearray as a file for both + reading and writing. For strings StringIO can be used like a file + opened in a text mode, and for bytes a BytesIO can be used like a file + opened in a binary mode. + """ + if not isinstance(file, (basestring, int, long)): + raise TypeError("invalid file: %r" % file) + if not isinstance(mode, basestring): + raise TypeError("invalid mode: %r" % mode) + if not isinstance(buffering, (int, long)): + raise TypeError("invalid buffering: %r" % buffering) + if encoding is not None and not isinstance(encoding, basestring): + raise TypeError("invalid encoding: %r" % encoding) + if errors is not None and not isinstance(errors, basestring): + raise TypeError("invalid errors: %r" % errors) + modes = set(mode) + if modes - set("arwb+tU") or len(mode) > len(modes): + raise ValueError("invalid mode: %r" % mode) + reading = "r" in modes + writing = "w" in modes + appending = "a" in modes + updating = "+" in modes + text = "t" in modes + binary = "b" in modes + if "U" in modes: + if writing or appending: + raise ValueError("can't use U and writing mode at once") + reading = True + if text and binary: + raise ValueError("can't have text and binary mode at once") + if reading + writing + appending > 1: + raise ValueError("can't have read/write/append mode at once") + if not (reading or writing or appending): + raise ValueError("must have exactly one of read/write/append mode") + if binary and encoding is not None: + raise ValueError("binary mode doesn't take an encoding argument") + if binary and errors is not None: + raise ValueError("binary mode doesn't take an errors argument") + if binary and newline is not None: + raise ValueError("binary mode doesn't take a newline argument") + raw = FileIO(file, + (reading and "r" or "") + + (writing and "w" or "") + + (appending and "a" or "") + + (updating and "+" or ""), + closefd) + line_buffering = False + if buffering == 1 or buffering < 0 and raw.isatty(): + buffering = -1 + line_buffering = True + if buffering < 0: + buffering = DEFAULT_BUFFER_SIZE + try: + bs = os.fstat(raw.fileno()).st_blksize + except (os.error, AttributeError): + pass + else: + if bs > 1: + buffering = bs + if buffering < 0: + raise ValueError("invalid buffering size") + if buffering == 0: + if binary: + return raw + raise ValueError("can't have unbuffered text I/O") + if updating: + buffer = BufferedRandom(raw, buffering) + elif writing or appending: + buffer = BufferedWriter(raw, buffering) + elif reading: + buffer = BufferedReader(raw, buffering) + else: + raise ValueError("unknown mode: %r" % mode) + if binary: + return buffer + text = TextIOWrapper(buffer, encoding, errors, newline, line_buffering) + text.mode = mode + return text + + +class DocDescriptor: + """Helper for builtins.open.__doc__ + """ + def __get__(self, obj, typ): + return ( + "open(file, mode='r', buffering=-1, encoding=None, " + "errors=None, newline=None, closefd=True)\n\n" + + open.__doc__) + +class OpenWrapper: + """Wrapper for builtins.open + + Trick so that open won't become a bound method when stored + as a class variable (as dbm.dumb does). + + See initstdio() in Python/pythonrun.c. + """ + __doc__ = DocDescriptor() + + def __new__(cls, *args, **kwargs): + return open(*args, **kwargs) + + +class UnsupportedOperation(ValueError, IOError): + pass + + +class IOBase: + __metaclass__ = abc.ABCMeta + + """The abstract base class for all I/O classes, acting on streams of + bytes. There is no public constructor. + + This class provides dummy implementations for many methods that + derived classes can override selectively; the default implementations + represent a file that cannot be read, written or seeked. + + Even though IOBase does not declare read, readinto, or write because + their signatures will vary, implementations and clients should + consider those methods part of the interface. Also, implementations + may raise a IOError when operations they do not support are called. + + The basic type used for binary data read from or written to a file is + bytes. bytearrays are accepted too, and in some cases (such as + readinto) needed. Text I/O classes work with str data. + + Note that calling any method (even inquiries) on a closed stream is + undefined. Implementations may raise IOError in this case. + + IOBase (and its subclasses) support the iterator protocol, meaning + that an IOBase object can be iterated over yielding the lines in a + stream. + + IOBase also supports the :keyword:`with` statement. In this example, + fp is closed after the suite of the with statement is complete: + + with open('spam.txt', 'r') as fp: + fp.write('Spam and eggs!') + """ + + ### Internal ### + + def _unsupported(self, name): + """Internal: raise an exception for unsupported operations.""" + raise UnsupportedOperation("%s.%s() not supported" % + (self.__class__.__name__, name)) + + ### Positioning ### + + def seek(self, pos, whence=0): + """Change stream position. + + Change the stream position to byte offset offset. offset is + interpreted relative to the position indicated by whence. Values + for whence are: + + * 0 -- start of stream (the default); offset should be zero or positive + * 1 -- current stream position; offset may be negative + * 2 -- end of stream; offset is usually negative + + Return the new absolute position. + """ + self._unsupported("seek") + + def tell(self): + """Return current stream position.""" + return self.seek(0, 1) + + def truncate(self, pos=None): + """Truncate file to size bytes. + + Size defaults to the current IO position as reported by tell(). Return + the new size. + """ + self._unsupported("truncate") + + ### Flush and close ### + + def flush(self): + """Flush write buffers, if applicable. + + This is not implemented for read-only and non-blocking streams. + """ + self._checkClosed() + # XXX Should this return the number of bytes written??? + + __closed = False + + def close(self): + """Flush and close the IO object. + + This method has no effect if the file is already closed. + """ + if not self.__closed: + try: + self.flush() + finally: + self.__closed = True + + def __del__(self): + """Destructor. Calls close().""" + # The try/except block is in case this is called at program + # exit time, when it's possible that globals have already been + # deleted, and then the close() call might fail. Since + # there's nothing we can do about such failures and they annoy + # the end users, we suppress the traceback. + try: + self.close() + except: + pass + + ### Inquiries ### + + def seekable(self): + """Return whether object supports random access. + + If False, seek(), tell() and truncate() will raise IOError. + This method may need to do a test seek(). + """ + return False + + def _checkSeekable(self, msg=None): + """Internal: raise an IOError if file is not seekable + """ + if not self.seekable(): + raise IOError("File or stream is not seekable." + if msg is None else msg) + + + def readable(self): + """Return whether object was opened for reading. + + If False, read() will raise IOError. + """ + return False + + def _checkReadable(self, msg=None): + """Internal: raise an IOError if file is not readable + """ + if not self.readable(): + raise IOError("File or stream is not readable." + if msg is None else msg) + + def writable(self): + """Return whether object was opened for writing. + + If False, write() and truncate() will raise IOError. + """ + return False + + def _checkWritable(self, msg=None): + """Internal: raise an IOError if file is not writable + """ + if not self.writable(): + raise IOError("File or stream is not writable." + if msg is None else msg) + + @property + def closed(self): + """closed: bool. True iff the file has been closed. + + For backwards compatibility, this is a property, not a predicate. + """ + return self.__closed + + def _checkClosed(self, msg=None): + """Internal: raise an ValueError if file is closed + """ + if self.closed: + raise ValueError("I/O operation on closed file." + if msg is None else msg) + + ### Context manager ### + + def __enter__(self): + """Context management protocol. Returns self.""" + self._checkClosed() + return self + + def __exit__(self, *args): + """Context management protocol. Calls close()""" + self.close() + + ### Lower-level APIs ### + + # XXX Should these be present even if unimplemented? + + def fileno(self): + """Returns underlying file descriptor if one exists. + + An IOError is raised if the IO object does not use a file descriptor. + """ + self._unsupported("fileno") + + def isatty(self): + """Return whether this is an 'interactive' stream. + + Return False if it can't be determined. + """ + self._checkClosed() + return False + + ### Readline[s] and writelines ### + + def readline(self, limit=-1): + r"""Read and return a line from the stream. + + If limit is specified, at most limit bytes will be read. + + The line terminator is always b'\n' for binary files; for text + files, the newlines argument to open can be used to select the line + terminator(s) recognized. + """ + # For backwards compatibility, a (slowish) readline(). + if hasattr(self, "peek"): + def nreadahead(): + readahead = self.peek(1) + if not readahead: + return 1 + n = (readahead.find(b"\n") + 1) or len(readahead) + if limit >= 0: + n = min(n, limit) + return n + else: + def nreadahead(): + return 1 + if limit is None: + limit = -1 + elif not isinstance(limit, (int, long)): + raise TypeError("limit must be an integer") + res = bytearray() + while limit < 0 or len(res) < limit: + b = self.read(nreadahead()) + if not b: + break + res += b + if res.endswith(b"\n"): + break + return bytes(res) + + def __iter__(self): + self._checkClosed() + return self + + def next(self): + line = self.readline() + if not line: + raise StopIteration + return line + + def readlines(self, hint=None): + """Return a list of lines from the stream. + + hint can be specified to control the number of lines read: no more + lines will be read if the total size (in bytes/characters) of all + lines so far exceeds hint. + """ + if hint is not None and not isinstance(hint, (int, long)): + raise TypeError("integer or None expected") + if hint is None or hint <= 0: + return list(self) + n = 0 + lines = [] + for line in self: + lines.append(line) + n += len(line) + if n >= hint: + break + return lines + + def writelines(self, lines): + self._checkClosed() + for line in lines: + self.write(line) + +io.IOBase.register(IOBase) + + +class RawIOBase(IOBase): + + """Base class for raw binary I/O.""" + + # The read() method is implemented by calling readinto(); derived + # classes that want to support read() only need to implement + # readinto() as a primitive operation. In general, readinto() can be + # more efficient than read(). + + # (It would be tempting to also provide an implementation of + # readinto() in terms of read(), in case the latter is a more suitable + # primitive operation, but that would lead to nasty recursion in case + # a subclass doesn't implement either.) + + def read(self, n=-1): + """Read and return up to n bytes. + + Returns an empty bytes object on EOF, or None if the object is + set not to block and has no data to read. + """ + if n is None: + n = -1 + if n < 0: + return self.readall() + b = bytearray(n.__index__()) + n = self.readinto(b) + if n is None: + return None + del b[n:] + return bytes(b) + + def readall(self): + """Read until EOF, using multiple read() call.""" + res = bytearray() + while True: + data = self.read(DEFAULT_BUFFER_SIZE) + if not data: + break + res += data + if res: + return bytes(res) + else: + # b'' or None + return data + + def readinto(self, b): + """Read up to len(b) bytes into b. + + Returns number of bytes read (0 for EOF), or None if the object + is set not to block and has no data to read. + """ + self._unsupported("readinto") + + def write(self, b): + """Write the given buffer to the IO stream. + + Returns the number of bytes written, which may be less than len(b). + """ + self._unsupported("write") + +io.RawIOBase.register(RawIOBase) +from _io import FileIO +RawIOBase.register(FileIO) + + +class BufferedIOBase(IOBase): + + """Base class for buffered IO objects. + + The main difference with RawIOBase is that the read() method + supports omitting the size argument, and does not have a default + implementation that defers to readinto(). + + In addition, read(), readinto() and write() may raise + BlockingIOError if the underlying raw stream is in non-blocking + mode and not ready; unlike their raw counterparts, they will never + return None. + + A typical implementation should not inherit from a RawIOBase + implementation, but wrap one. + """ + + def read(self, n=None): + """Read and return up to n bytes. + + If the argument is omitted, None, or negative, reads and + returns all data until EOF. + + If the argument is positive, and the underlying raw stream is + not 'interactive', multiple raw reads may be issued to satisfy + the byte count (unless EOF is reached first). But for + interactive raw streams (XXX and for pipes?), at most one raw + read will be issued, and a short result does not imply that + EOF is imminent. + + Returns an empty bytes array on EOF. + + Raises BlockingIOError if the underlying raw stream has no + data at the moment. + """ + self._unsupported("read") + + def read1(self, n=None): + """Read up to n bytes with at most one read() system call.""" + self._unsupported("read1") + + def readinto(self, b): + """Read up to len(b) bytes into b. + + Like read(), this may issue multiple reads to the underlying raw + stream, unless the latter is 'interactive'. + + Returns the number of bytes read (0 for EOF). + + Raises BlockingIOError if the underlying raw stream has no + data at the moment. + """ + # XXX This ought to work with anything that supports the buffer API + data = self.read(len(b)) + n = len(data) + try: + b[:n] = data + except TypeError as err: + import array + if not isinstance(b, array.array): + raise err + b[:n] = array.array(b'b', data) + return n + + def write(self, b): + """Write the given buffer to the IO stream. + + Return the number of bytes written, which is never less than + len(b). + + Raises BlockingIOError if the buffer is full and the + underlying raw stream cannot accept more data at the moment. + """ + self._unsupported("write") + + def detach(self): + """ + Separate the underlying raw stream from the buffer and return it. + + After the raw stream has been detached, the buffer is in an unusable + state. + """ + self._unsupported("detach") + +io.BufferedIOBase.register(BufferedIOBase) + + +class _BufferedIOMixin(BufferedIOBase): + + """A mixin implementation of BufferedIOBase with an underlying raw stream. + + This passes most requests on to the underlying raw stream. It + does *not* provide implementations of read(), readinto() or + write(). + """ + + def __init__(self, raw): + self._raw = raw + + ### Positioning ### + + def seek(self, pos, whence=0): + new_position = self.raw.seek(pos, whence) + if new_position < 0: + raise IOError("seek() returned an invalid position") + return new_position + + def tell(self): + pos = self.raw.tell() + if pos < 0: + raise IOError("tell() returned an invalid position") + return pos + + def truncate(self, pos=None): + # Flush the stream. We're mixing buffered I/O with lower-level I/O, + # and a flush may be necessary to synch both views of the current + # file state. + self.flush() + + if pos is None: + pos = self.tell() + # XXX: Should seek() be used, instead of passing the position + # XXX directly to truncate? + return self.raw.truncate(pos) + + ### Flush and close ### + + def flush(self): + if self.closed: + raise ValueError("flush of closed file") + self.raw.flush() + + def close(self): + if self.raw is not None and not self.closed: + try: + # may raise BlockingIOError or BrokenPipeError etc + self.flush() + finally: + self.raw.close() + + def detach(self): + if self.raw is None: + raise ValueError("raw stream already detached") + self.flush() + raw = self._raw + self._raw = None + return raw + + ### Inquiries ### + + def seekable(self): + return self.raw.seekable() + + def readable(self): + return self.raw.readable() + + def writable(self): + return self.raw.writable() + + @property + def raw(self): + return self._raw + + @property + def closed(self): + return self.raw.closed + + @property + def name(self): + return self.raw.name + + @property + def mode(self): + return self.raw.mode + + def __repr__(self): + clsname = self.__class__.__name__ + try: + name = self.name + except AttributeError: + return "<_pyio.{0}>".format(clsname) + else: + return "<_pyio.{0} name={1!r}>".format(clsname, name) + + ### Lower-level APIs ### + + def fileno(self): + return self.raw.fileno() + + def isatty(self): + return self.raw.isatty() + + +class BytesIO(BufferedIOBase): + + """Buffered I/O implementation using an in-memory bytes buffer.""" + + def __init__(self, initial_bytes=None): + buf = bytearray() + if initial_bytes is not None: + buf.extend(initial_bytes) + self._buffer = buf + self._pos = 0 + + def __getstate__(self): + if self.closed: + raise ValueError("__getstate__ on closed file") + return self.__dict__.copy() + + def getvalue(self): + """Return the bytes value (contents) of the buffer + """ + if self.closed: + raise ValueError("getvalue on closed file") + return bytes(self._buffer) + + def read(self, n=None): + if self.closed: + raise ValueError("read from closed file") + if n is None: + n = -1 + if not isinstance(n, (int, long)): + raise TypeError("integer argument expected, got {0!r}".format( + type(n))) + if n < 0: + n = len(self._buffer) + if len(self._buffer) <= self._pos: + return b"" + newpos = min(len(self._buffer), self._pos + n) + b = self._buffer[self._pos : newpos] + self._pos = newpos + return bytes(b) + + def read1(self, n): + """This is the same as read. + """ + return self.read(n) + + def write(self, b): + if self.closed: + raise ValueError("write to closed file") + if isinstance(b, unicode): + raise TypeError("can't write unicode to binary stream") + n = len(b) + if n == 0: + return 0 + pos = self._pos + if pos > len(self._buffer): + # Inserts null bytes between the current end of the file + # and the new write position. + padding = b'\x00' * (pos - len(self._buffer)) + self._buffer += padding + self._buffer[pos:pos + n] = b + self._pos += n + return n + + def seek(self, pos, whence=0): + if self.closed: + raise ValueError("seek on closed file") + try: + pos.__index__ + except AttributeError: + raise TypeError("an integer is required") + if whence == 0: + if pos < 0: + raise ValueError("negative seek position %r" % (pos,)) + self._pos = pos + elif whence == 1: + self._pos = max(0, self._pos + pos) + elif whence == 2: + self._pos = max(0, len(self._buffer) + pos) + else: + raise ValueError("invalid whence value") + return self._pos + + def tell(self): + if self.closed: + raise ValueError("tell on closed file") + return self._pos + + def truncate(self, pos=None): + if self.closed: + raise ValueError("truncate on closed file") + if pos is None: + pos = self._pos + else: + try: + pos.__index__ + except AttributeError: + raise TypeError("an integer is required") + if pos < 0: + raise ValueError("negative truncate position %r" % (pos,)) + del self._buffer[pos:] + return pos + + def readable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") + return True + + def writable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") + return True + + def seekable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") + return True + + +class BufferedReader(_BufferedIOMixin): + + """BufferedReader(raw[, buffer_size]) + + A buffer for a readable, sequential BaseRawIO object. + + The constructor creates a BufferedReader for the given readable raw + stream and buffer_size. If buffer_size is omitted, DEFAULT_BUFFER_SIZE + is used. + """ + + def __init__(self, raw, buffer_size=DEFAULT_BUFFER_SIZE): + """Create a new buffered reader using the given readable raw IO object. + """ + if not raw.readable(): + raise IOError('"raw" argument must be readable.') + + _BufferedIOMixin.__init__(self, raw) + if buffer_size <= 0: + raise ValueError("invalid buffer size") + self.buffer_size = buffer_size + self._reset_read_buf() + self._read_lock = Lock() + + def _reset_read_buf(self): + self._read_buf = b"" + self._read_pos = 0 + + def read(self, n=None): + """Read n bytes. + + Returns exactly n bytes of data unless the underlying raw IO + stream reaches EOF or if the call would block in non-blocking + mode. If n is negative, read until EOF or until read() would + block. + """ + if n is not None and n < -1: + raise ValueError("invalid number of bytes to read") + with self._read_lock: + return self._read_unlocked(n) + + def _read_unlocked(self, n=None): + nodata_val = b"" + empty_values = (b"", None) + buf = self._read_buf + pos = self._read_pos + + # Special case for when the number of bytes to read is unspecified. + if n is None or n == -1: + self._reset_read_buf() + chunks = [buf[pos:]] # Strip the consumed bytes. + current_size = 0 + while True: + # Read until EOF or until read() would block. + try: + chunk = self.raw.read() + except IOError as e: + if e.errno != EINTR: + raise + continue + if chunk in empty_values: + nodata_val = chunk + break + current_size += len(chunk) + chunks.append(chunk) + return b"".join(chunks) or nodata_val + + # The number of bytes to read is specified, return at most n bytes. + avail = len(buf) - pos # Length of the available buffered data. + if n <= avail: + # Fast path: the data to read is fully buffered. + self._read_pos += n + return buf[pos:pos+n] + # Slow path: read from the stream until enough bytes are read, + # or until an EOF occurs or until read() would block. + chunks = [buf[pos:]] + wanted = max(self.buffer_size, n) + while avail < n: + try: + chunk = self.raw.read(wanted) + except IOError as e: + if e.errno != EINTR: + raise + continue + if chunk in empty_values: + nodata_val = chunk + break + avail += len(chunk) + chunks.append(chunk) + # n is more then avail only when an EOF occurred or when + # read() would have blocked. + n = min(n, avail) + out = b"".join(chunks) + self._read_buf = out[n:] # Save the extra data in the buffer. + self._read_pos = 0 + return out[:n] if out else nodata_val + + def peek(self, n=0): + """Returns buffered bytes without advancing the position. + + The argument indicates a desired minimal number of bytes; we + do at most one raw read to satisfy it. We never return more + than self.buffer_size. + """ + with self._read_lock: + return self._peek_unlocked(n) + + def _peek_unlocked(self, n=0): + want = min(n, self.buffer_size) + have = len(self._read_buf) - self._read_pos + if have < want or have <= 0: + to_read = self.buffer_size - have + while True: + try: + current = self.raw.read(to_read) + except IOError as e: + if e.errno != EINTR: + raise + continue + break + if current: + self._read_buf = self._read_buf[self._read_pos:] + current + self._read_pos = 0 + return self._read_buf[self._read_pos:] + + def read1(self, n): + """Reads up to n bytes, with at most one read() system call.""" + # Returns up to n bytes. If at least one byte is buffered, we + # only return buffered bytes. Otherwise, we do one raw read. + if n < 0: + raise ValueError("number of bytes to read must be positive") + if n == 0: + return b"" + with self._read_lock: + self._peek_unlocked(1) + return self._read_unlocked( + min(n, len(self._read_buf) - self._read_pos)) + + def tell(self): + return _BufferedIOMixin.tell(self) - len(self._read_buf) + self._read_pos + + def seek(self, pos, whence=0): + if not (0 <= whence <= 2): + raise ValueError("invalid whence value") + with self._read_lock: + if whence == 1: + pos -= len(self._read_buf) - self._read_pos + pos = _BufferedIOMixin.seek(self, pos, whence) + self._reset_read_buf() + return pos + +class BufferedWriter(_BufferedIOMixin): + + """A buffer for a writeable sequential RawIO object. + + The constructor creates a BufferedWriter for the given writeable raw + stream. If the buffer_size is not given, it defaults to + DEFAULT_BUFFER_SIZE. + """ + + _warning_stack_offset = 2 + + def __init__(self, raw, + buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=None): + if not raw.writable(): + raise IOError('"raw" argument must be writable.') + + _BufferedIOMixin.__init__(self, raw) + if buffer_size <= 0: + raise ValueError("invalid buffer size") + if max_buffer_size is not None: + warnings.warn("max_buffer_size is deprecated", DeprecationWarning, + self._warning_stack_offset) + self.buffer_size = buffer_size + self._write_buf = bytearray() + self._write_lock = Lock() + + def write(self, b): + if self.closed: + raise ValueError("write to closed file") + if isinstance(b, unicode): + raise TypeError("can't write unicode to binary stream") + with self._write_lock: + # XXX we can implement some more tricks to try and avoid + # partial writes + if len(self._write_buf) > self.buffer_size: + # We're full, so let's pre-flush the buffer. (This may + # raise BlockingIOError with characters_written == 0.) + self._flush_unlocked() + before = len(self._write_buf) + self._write_buf.extend(b) + written = len(self._write_buf) - before + if len(self._write_buf) > self.buffer_size: + try: + self._flush_unlocked() + except BlockingIOError as e: + if len(self._write_buf) > self.buffer_size: + # We've hit the buffer_size. We have to accept a partial + # write and cut back our buffer. + overage = len(self._write_buf) - self.buffer_size + written -= overage + self._write_buf = self._write_buf[:self.buffer_size] + raise BlockingIOError(e.errno, e.strerror, written) + return written + + def truncate(self, pos=None): + with self._write_lock: + self._flush_unlocked() + if pos is None: + pos = self.raw.tell() + return self.raw.truncate(pos) + + def flush(self): + with self._write_lock: + self._flush_unlocked() + + def _flush_unlocked(self): + if self.closed: + raise ValueError("flush of closed file") + while self._write_buf: + try: + n = self.raw.write(self._write_buf) + except BlockingIOError: + raise RuntimeError("self.raw should implement RawIOBase: it " + "should not raise BlockingIOError") + except IOError as e: + if e.errno != EINTR: + raise + continue + if n is None: + raise BlockingIOError( + errno.EAGAIN, + "write could not complete without blocking", 0) + if n > len(self._write_buf) or n < 0: + raise IOError("write() returned incorrect number of bytes") + del self._write_buf[:n] + + def tell(self): + return _BufferedIOMixin.tell(self) + len(self._write_buf) + + def seek(self, pos, whence=0): + if not (0 <= whence <= 2): + raise ValueError("invalid whence") + with self._write_lock: + self._flush_unlocked() + return _BufferedIOMixin.seek(self, pos, whence) + + +class BufferedRWPair(BufferedIOBase): + + """A buffered reader and writer object together. + + A buffered reader object and buffered writer object put together to + form a sequential IO object that can read and write. This is typically + used with a socket or two-way pipe. + + reader and writer are RawIOBase objects that are readable and + writeable respectively. If the buffer_size is omitted it defaults to + DEFAULT_BUFFER_SIZE. + """ + + # XXX The usefulness of this (compared to having two separate IO + # objects) is questionable. + + def __init__(self, reader, writer, + buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=None): + """Constructor. + + The arguments are two RawIO instances. + """ + if max_buffer_size is not None: + warnings.warn("max_buffer_size is deprecated", DeprecationWarning, 2) + + if not reader.readable(): + raise IOError('"reader" argument must be readable.') + + if not writer.writable(): + raise IOError('"writer" argument must be writable.') + + self.reader = BufferedReader(reader, buffer_size) + self.writer = BufferedWriter(writer, buffer_size) + + def read(self, n=None): + if n is None: + n = -1 + return self.reader.read(n) + + def readinto(self, b): + return self.reader.readinto(b) + + def write(self, b): + return self.writer.write(b) + + def peek(self, n=0): + return self.reader.peek(n) + + def read1(self, n): + return self.reader.read1(n) + + def readable(self): + return self.reader.readable() + + def writable(self): + return self.writer.writable() + + def flush(self): + return self.writer.flush() + + def close(self): + self.writer.close() + self.reader.close() + + def isatty(self): + return self.reader.isatty() or self.writer.isatty() + + @property + def closed(self): + return self.writer.closed + + +class BufferedRandom(BufferedWriter, BufferedReader): + + """A buffered interface to random access streams. + + The constructor creates a reader and writer for a seekable stream, + raw, given in the first argument. If the buffer_size is omitted it + defaults to DEFAULT_BUFFER_SIZE. + """ + + _warning_stack_offset = 3 + + def __init__(self, raw, + buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=None): + raw._checkSeekable() + BufferedReader.__init__(self, raw, buffer_size) + BufferedWriter.__init__(self, raw, buffer_size, max_buffer_size) + + def seek(self, pos, whence=0): + if not (0 <= whence <= 2): + raise ValueError("invalid whence") + self.flush() + if self._read_buf: + # Undo read ahead. + with self._read_lock: + self.raw.seek(self._read_pos - len(self._read_buf), 1) + # First do the raw seek, then empty the read buffer, so that + # if the raw seek fails, we don't lose buffered data forever. + pos = self.raw.seek(pos, whence) + with self._read_lock: + self._reset_read_buf() + if pos < 0: + raise IOError("seek() returned invalid position") + return pos + + def tell(self): + if self._write_buf: + return BufferedWriter.tell(self) + else: + return BufferedReader.tell(self) + + def truncate(self, pos=None): + if pos is None: + pos = self.tell() + # Use seek to flush the read buffer. + return BufferedWriter.truncate(self, pos) + + def read(self, n=None): + if n is None: + n = -1 + self.flush() + return BufferedReader.read(self, n) + + def readinto(self, b): + self.flush() + return BufferedReader.readinto(self, b) + + def peek(self, n=0): + self.flush() + return BufferedReader.peek(self, n) + + def read1(self, n): + self.flush() + return BufferedReader.read1(self, n) + + def write(self, b): + if self._read_buf: + # Undo readahead + with self._read_lock: + self.raw.seek(self._read_pos - len(self._read_buf), 1) + self._reset_read_buf() + return BufferedWriter.write(self, b) + + +class TextIOBase(IOBase): + + """Base class for text I/O. + + This class provides a character and line based interface to stream + I/O. There is no readinto method because Python's character strings + are immutable. There is no public constructor. + """ + + def read(self, n=-1): + """Read at most n characters from stream. + + Read from underlying buffer until we have n characters or we hit EOF. + If n is negative or omitted, read until EOF. + """ + self._unsupported("read") + + def write(self, s): + """Write string s to stream.""" + self._unsupported("write") + + def truncate(self, pos=None): + """Truncate size to pos.""" + self._unsupported("truncate") + + def readline(self): + """Read until newline or EOF. + + Returns an empty string if EOF is hit immediately. + """ + self._unsupported("readline") + + def detach(self): + """ + Separate the underlying buffer from the TextIOBase and return it. + + After the underlying buffer has been detached, the TextIO is in an + unusable state. + """ + self._unsupported("detach") + + @property + def encoding(self): + """Subclasses should override.""" + return None + + @property + def newlines(self): + """Line endings translated so far. + + Only line endings translated during reading are considered. + + Subclasses should override. + """ + return None + + @property + def errors(self): + """Error setting of the decoder or encoder. + + Subclasses should override.""" + return None + +io.TextIOBase.register(TextIOBase) + + +class IncrementalNewlineDecoder(codecs.IncrementalDecoder): + r"""Codec used when reading a file in universal newlines mode. It wraps + another incremental decoder, translating \r\n and \r into \n. It also + records the types of newlines encountered. When used with + translate=False, it ensures that the newline sequence is returned in + one piece. + """ + def __init__(self, decoder, translate, errors='strict'): + codecs.IncrementalDecoder.__init__(self, errors=errors) + self.translate = translate + self.decoder = decoder + self.seennl = 0 + self.pendingcr = False + + def decode(self, input, final=False): + # decode input (with the eventual \r from a previous pass) + if self.decoder is None: + output = input + else: + output = self.decoder.decode(input, final=final) + if self.pendingcr and (output or final): + output = "\r" + output + self.pendingcr = False + + # retain last \r even when not translating data: + # then readline() is sure to get \r\n in one pass + if output.endswith("\r") and not final: + output = output[:-1] + self.pendingcr = True + + # Record which newlines are read + crlf = output.count('\r\n') + cr = output.count('\r') - crlf + lf = output.count('\n') - crlf + self.seennl |= (lf and self._LF) | (cr and self._CR) \ + | (crlf and self._CRLF) + + if self.translate: + if crlf: + output = output.replace("\r\n", "\n") + if cr: + output = output.replace("\r", "\n") + + return output + + def getstate(self): + if self.decoder is None: + buf = b"" + flag = 0 + else: + buf, flag = self.decoder.getstate() + flag <<= 1 + if self.pendingcr: + flag |= 1 + return buf, flag + + def setstate(self, state): + buf, flag = state + self.pendingcr = bool(flag & 1) + if self.decoder is not None: + self.decoder.setstate((buf, flag >> 1)) + + def reset(self): + self.seennl = 0 + self.pendingcr = False + if self.decoder is not None: + self.decoder.reset() + + _LF = 1 + _CR = 2 + _CRLF = 4 + + @property + def newlines(self): + return (None, + "\n", + "\r", + ("\r", "\n"), + "\r\n", + ("\n", "\r\n"), + ("\r", "\r\n"), + ("\r", "\n", "\r\n") + )[self.seennl] + + +class TextIOWrapper(TextIOBase): + + r"""Character and line based layer over a BufferedIOBase object, buffer. + + encoding gives the name of the encoding that the stream will be + decoded or encoded with. It defaults to locale.getpreferredencoding. + + errors determines the strictness of encoding and decoding (see the + codecs.register) and defaults to "strict". + + newline can be None, '', '\n', '\r', or '\r\n'. It controls the + handling of line endings. If it is None, universal newlines is + enabled. With this enabled, on input, the lines endings '\n', '\r', + or '\r\n' are translated to '\n' before being returned to the + caller. Conversely, on output, '\n' is translated to the system + default line separator, os.linesep. If newline is any other of its + legal values, that newline becomes the newline when the file is read + and it is returned untranslated. On output, '\n' is converted to the + newline. + + If line_buffering is True, a call to flush is implied when a call to + write contains a newline character. + """ + + _CHUNK_SIZE = 2048 + + def __init__(self, buffer, encoding=None, errors=None, newline=None, + line_buffering=False): + if newline is not None and not isinstance(newline, basestring): + raise TypeError("illegal newline type: %r" % (type(newline),)) + if newline not in (None, "", "\n", "\r", "\r\n"): + raise ValueError("illegal newline value: %r" % (newline,)) + if encoding is None: + try: + import locale + except ImportError: + # Importing locale may fail if Python is being built + encoding = "ascii" + else: + encoding = locale.getpreferredencoding() + + if not isinstance(encoding, basestring): + raise ValueError("invalid encoding: %r" % encoding) + + if errors is None: + errors = "strict" + else: + if not isinstance(errors, basestring): + raise ValueError("invalid errors: %r" % errors) + + self._buffer = buffer + self._line_buffering = line_buffering + self._encoding = encoding + self._errors = errors + self._readuniversal = not newline + self._readtranslate = newline is None + self._readnl = newline + self._writetranslate = newline != '' + self._writenl = newline or os.linesep + self._encoder = None + self._decoder = None + self._decoded_chars = '' # buffer for text returned from decoder + self._decoded_chars_used = 0 # offset into _decoded_chars for read() + self._snapshot = None # info for reconstructing decoder state + self._seekable = self._telling = self.buffer.seekable() + + if self._seekable and self.writable(): + position = self.buffer.tell() + if position != 0: + try: + self._get_encoder().setstate(0) + except LookupError: + # Sometimes the encoder doesn't exist + pass + + # self._snapshot is either None, or a tuple (dec_flags, next_input) + # where dec_flags is the second (integer) item of the decoder state + # and next_input is the chunk of input bytes that comes next after the + # snapshot point. We use this to reconstruct decoder states in tell(). + + # Naming convention: + # - "bytes_..." for integer variables that count input bytes + # - "chars_..." for integer variables that count decoded characters + + def __repr__(self): + try: + name = self.name + except AttributeError: + return "<_pyio.TextIOWrapper encoding='{0}'>".format(self.encoding) + else: + return "<_pyio.TextIOWrapper name={0!r} encoding='{1}'>".format( + name, self.encoding) + + @property + def encoding(self): + return self._encoding + + @property + def errors(self): + return self._errors + + @property + def line_buffering(self): + return self._line_buffering + + @property + def buffer(self): + return self._buffer + + def seekable(self): + if self.closed: + raise ValueError("I/O operation on closed file.") + return self._seekable + + def readable(self): + return self.buffer.readable() + + def writable(self): + return self.buffer.writable() + + def flush(self): + self.buffer.flush() + self._telling = self._seekable + + def close(self): + if self.buffer is not None and not self.closed: + try: + self.flush() + finally: + self.buffer.close() + + @property + def closed(self): + return self.buffer.closed + + @property + def name(self): + return self.buffer.name + + def fileno(self): + return self.buffer.fileno() + + def isatty(self): + return self.buffer.isatty() + + def write(self, s): + if self.closed: + raise ValueError("write to closed file") + if not isinstance(s, unicode): + raise TypeError("can't write %s to text stream" % + s.__class__.__name__) + length = len(s) + haslf = (self._writetranslate or self._line_buffering) and "\n" in s + if haslf and self._writetranslate and self._writenl != "\n": + s = s.replace("\n", self._writenl) + encoder = self._encoder or self._get_encoder() + # XXX What if we were just reading? + b = encoder.encode(s) + self.buffer.write(b) + if self._line_buffering and (haslf or "\r" in s): + self.flush() + self._snapshot = None + if self._decoder: + self._decoder.reset() + return length + + def _get_encoder(self): + make_encoder = codecs.getincrementalencoder(self._encoding) + self._encoder = make_encoder(self._errors) + return self._encoder + + def _get_decoder(self): + make_decoder = codecs.getincrementaldecoder(self._encoding) + decoder = make_decoder(self._errors) + if self._readuniversal: + decoder = IncrementalNewlineDecoder(decoder, self._readtranslate) + self._decoder = decoder + return decoder + + # The following three methods implement an ADT for _decoded_chars. + # Text returned from the decoder is buffered here until the client + # requests it by calling our read() or readline() method. + def _set_decoded_chars(self, chars): + """Set the _decoded_chars buffer.""" + self._decoded_chars = chars + self._decoded_chars_used = 0 + + def _get_decoded_chars(self, n=None): + """Advance into the _decoded_chars buffer.""" + offset = self._decoded_chars_used + if n is None: + chars = self._decoded_chars[offset:] + else: + chars = self._decoded_chars[offset:offset + n] + self._decoded_chars_used += len(chars) + return chars + + def _rewind_decoded_chars(self, n): + """Rewind the _decoded_chars buffer.""" + if self._decoded_chars_used < n: + raise AssertionError("rewind decoded_chars out of bounds") + self._decoded_chars_used -= n + + def _read_chunk(self): + """ + Read and decode the next chunk of data from the BufferedReader. + """ + + # The return value is True unless EOF was reached. The decoded + # string is placed in self._decoded_chars (replacing its previous + # value). The entire input chunk is sent to the decoder, though + # some of it may remain buffered in the decoder, yet to be + # converted. + + if self._decoder is None: + raise ValueError("no decoder") + + if self._telling: + # To prepare for tell(), we need to snapshot a point in the + # file where the decoder's input buffer is empty. + + dec_buffer, dec_flags = self._decoder.getstate() + # Given this, we know there was a valid snapshot point + # len(dec_buffer) bytes ago with decoder state (b'', dec_flags). + + # Read a chunk, decode it, and put the result in self._decoded_chars. + input_chunk = self.buffer.read1(self._CHUNK_SIZE) + eof = not input_chunk + self._set_decoded_chars(self._decoder.decode(input_chunk, eof)) + + if self._telling: + # At the snapshot point, len(dec_buffer) bytes before the read, + # the next input to be decoded is dec_buffer + input_chunk. + self._snapshot = (dec_flags, dec_buffer + input_chunk) + + return not eof + + def _pack_cookie(self, position, dec_flags=0, + bytes_to_feed=0, need_eof=0, chars_to_skip=0): + # The meaning of a tell() cookie is: seek to position, set the + # decoder flags to dec_flags, read bytes_to_feed bytes, feed them + # into the decoder with need_eof as the EOF flag, then skip + # chars_to_skip characters of the decoded result. For most simple + # decoders, tell() will often just give a byte offset in the file. + return (position | (dec_flags<<64) | (bytes_to_feed<<128) | + (chars_to_skip<<192) | bool(need_eof)<<256) + + def _unpack_cookie(self, bigint): + rest, position = divmod(bigint, 1<<64) + rest, dec_flags = divmod(rest, 1<<64) + rest, bytes_to_feed = divmod(rest, 1<<64) + need_eof, chars_to_skip = divmod(rest, 1<<64) + return position, dec_flags, bytes_to_feed, need_eof, chars_to_skip + + def tell(self): + if not self._seekable: + raise IOError("underlying stream is not seekable") + if not self._telling: + raise IOError("telling position disabled by next() call") + self.flush() + position = self.buffer.tell() + decoder = self._decoder + if decoder is None or self._snapshot is None: + if self._decoded_chars: + # This should never happen. + raise AssertionError("pending decoded text") + return position + + # Skip backward to the snapshot point (see _read_chunk). + dec_flags, next_input = self._snapshot + position -= len(next_input) + + # How many decoded characters have been used up since the snapshot? + chars_to_skip = self._decoded_chars_used + if chars_to_skip == 0: + # We haven't moved from the snapshot point. + return self._pack_cookie(position, dec_flags) + + # Starting from the snapshot position, we will walk the decoder + # forward until it gives us enough decoded characters. + saved_state = decoder.getstate() + try: + # Note our initial start point. + decoder.setstate((b'', dec_flags)) + start_pos = position + start_flags, bytes_fed, chars_decoded = dec_flags, 0, 0 + need_eof = 0 + + # Feed the decoder one byte at a time. As we go, note the + # nearest "safe start point" before the current location + # (a point where the decoder has nothing buffered, so seek() + # can safely start from there and advance to this location). + for next_byte in next_input: + bytes_fed += 1 + chars_decoded += len(decoder.decode(next_byte)) + dec_buffer, dec_flags = decoder.getstate() + if not dec_buffer and chars_decoded <= chars_to_skip: + # Decoder buffer is empty, so this is a safe start point. + start_pos += bytes_fed + chars_to_skip -= chars_decoded + start_flags, bytes_fed, chars_decoded = dec_flags, 0, 0 + if chars_decoded >= chars_to_skip: + break + else: + # We didn't get enough decoded data; signal EOF to get more. + chars_decoded += len(decoder.decode(b'', final=True)) + need_eof = 1 + if chars_decoded < chars_to_skip: + raise IOError("can't reconstruct logical file position") + + # The returned cookie corresponds to the last safe start point. + return self._pack_cookie( + start_pos, start_flags, bytes_fed, need_eof, chars_to_skip) + finally: + decoder.setstate(saved_state) + + def truncate(self, pos=None): + self.flush() + if pos is None: + pos = self.tell() + return self.buffer.truncate(pos) + + def detach(self): + if self.buffer is None: + raise ValueError("buffer is already detached") + self.flush() + buffer = self._buffer + self._buffer = None + return buffer + + def seek(self, cookie, whence=0): + if self.closed: + raise ValueError("tell on closed file") + if not self._seekable: + raise IOError("underlying stream is not seekable") + if whence == 1: # seek relative to current position + if cookie != 0: + raise IOError("can't do nonzero cur-relative seeks") + # Seeking to the current position should attempt to + # sync the underlying buffer with the current position. + whence = 0 + cookie = self.tell() + if whence == 2: # seek relative to end of file + if cookie != 0: + raise IOError("can't do nonzero end-relative seeks") + self.flush() + position = self.buffer.seek(0, 2) + self._set_decoded_chars('') + self._snapshot = None + if self._decoder: + self._decoder.reset() + return position + if whence != 0: + raise ValueError("invalid whence (%r, should be 0, 1 or 2)" % + (whence,)) + if cookie < 0: + raise ValueError("negative seek position %r" % (cookie,)) + self.flush() + + # The strategy of seek() is to go back to the safe start point + # and replay the effect of read(chars_to_skip) from there. + start_pos, dec_flags, bytes_to_feed, need_eof, chars_to_skip = \ + self._unpack_cookie(cookie) + + # Seek back to the safe start point. + self.buffer.seek(start_pos) + self._set_decoded_chars('') + self._snapshot = None + + # Restore the decoder to its state from the safe start point. + if cookie == 0 and self._decoder: + self._decoder.reset() + elif self._decoder or dec_flags or chars_to_skip: + self._decoder = self._decoder or self._get_decoder() + self._decoder.setstate((b'', dec_flags)) + self._snapshot = (dec_flags, b'') + + if chars_to_skip: + # Just like _read_chunk, feed the decoder and save a snapshot. + input_chunk = self.buffer.read(bytes_to_feed) + self._set_decoded_chars( + self._decoder.decode(input_chunk, need_eof)) + self._snapshot = (dec_flags, input_chunk) + + # Skip chars_to_skip of the decoded characters. + if len(self._decoded_chars) < chars_to_skip: + raise IOError("can't restore logical file position") + self._decoded_chars_used = chars_to_skip + + # Finally, reset the encoder (merely useful for proper BOM handling) + try: + encoder = self._encoder or self._get_encoder() + except LookupError: + # Sometimes the encoder doesn't exist + pass + else: + if cookie != 0: + encoder.setstate(0) + else: + encoder.reset() + return cookie + + def read(self, n=None): + self._checkReadable() + if n is None: + n = -1 + decoder = self._decoder or self._get_decoder() + try: + n.__index__ + except AttributeError: + raise TypeError("an integer is required") + if n < 0: + # Read everything. + result = (self._get_decoded_chars() + + decoder.decode(self.buffer.read(), final=True)) + self._set_decoded_chars('') + self._snapshot = None + return result + else: + # Keep reading chunks until we have n characters to return. + eof = False + result = self._get_decoded_chars(n) + while len(result) < n and not eof: + eof = not self._read_chunk() + result += self._get_decoded_chars(n - len(result)) + return result + + def next(self): + self._telling = False + line = self.readline() + if not line: + self._snapshot = None + self._telling = self._seekable + raise StopIteration + return line + + def readline(self, limit=None): + if self.closed: + raise ValueError("read from closed file") + if limit is None: + limit = -1 + elif not isinstance(limit, (int, long)): + raise TypeError("limit must be an integer") + + # Grab all the decoded text (we will rewind any extra bits later). + line = self._get_decoded_chars() + + start = 0 + # Make the decoder if it doesn't already exist. + if not self._decoder: + self._get_decoder() + + pos = endpos = None + while True: + if self._readtranslate: + # Newlines are already translated, only search for \n + pos = line.find('\n', start) + if pos >= 0: + endpos = pos + 1 + break + else: + start = len(line) + + elif self._readuniversal: + # Universal newline search. Find any of \r, \r\n, \n + # The decoder ensures that \r\n are not split in two pieces + + # In C we'd look for these in parallel of course. + nlpos = line.find("\n", start) + crpos = line.find("\r", start) + if crpos == -1: + if nlpos == -1: + # Nothing found + start = len(line) + else: + # Found \n + endpos = nlpos + 1 + break + elif nlpos == -1: + # Found lone \r + endpos = crpos + 1 + break + elif nlpos < crpos: + # Found \n + endpos = nlpos + 1 + break + elif nlpos == crpos + 1: + # Found \r\n + endpos = crpos + 2 + break + else: + # Found \r + endpos = crpos + 1 + break + else: + # non-universal + pos = line.find(self._readnl) + if pos >= 0: + endpos = pos + len(self._readnl) + break + + if limit >= 0 and len(line) >= limit: + endpos = limit # reached length limit + break + + # No line ending seen yet - get more data' + while self._read_chunk(): + if self._decoded_chars: + break + if self._decoded_chars: + line += self._get_decoded_chars() + else: + # end of file + self._set_decoded_chars('') + self._snapshot = None + return line + + if limit >= 0 and endpos > limit: + endpos = limit # don't exceed limit + + # Rewind _decoded_chars to just after the line ending we found. + self._rewind_decoded_chars(len(line) - endpos) + return line[:endpos] + + @property + def newlines(self): + return self._decoder.newlines if self._decoder else None + + +class StringIO(TextIOWrapper): + """Text I/O implementation using an in-memory buffer. + + The initial_value argument sets the value of object. The newline + argument is like the one of TextIOWrapper's constructor. + """ + + def __init__(self, initial_value="", newline="\n"): + super(StringIO, self).__init__(BytesIO(), + encoding="utf-8", + errors="strict", + newline=newline) + # Issue #5645: make universal newlines semantics the same as in the + # C version, even under Windows. + if newline is None: + self._writetranslate = False + if initial_value: + if not isinstance(initial_value, unicode): + initial_value = unicode(initial_value) + self.write(initial_value) + self.seek(0) + + def getvalue(self): + self.flush() + return self.buffer.getvalue().decode(self._encoding, self._errors) + + def __repr__(self): + # TextIOWrapper tells the encoding in its repr. In StringIO, + # that's a implementation detail. + return object.__repr__(self) + + @property + def errors(self): + return None + + @property + def encoding(self): + return None + + def detach(self): + # This doesn't make sense on StringIO. + self._unsupported("detach") diff --git a/src/main/resources/PythonLibs/_rawffi.py b/src/main/resources/PythonLibs/_rawffi.py new file mode 100644 index 0000000000000000000000000000000000000000..fc255e2d8a13bffb4a199e8a675294e2d551d6f3 --- /dev/null +++ b/src/main/resources/PythonLibs/_rawffi.py @@ -0,0 +1,54 @@ +import com.sun.jna as jna + +def get_libc(): + return CDLL("c") + +typecode_map = {'h': 2, 'H': 2} + +class Array(object): + def __init__(self, typecode): + self.typecode = typecode + self.itemsize = typecode_map[typecode] + + def __call__(self, size, autofree=False): + if not autofree: + raise Exception + return ArrayInstance(self, size) + +class ArrayInstance(object): + def __init__(self, shape, size): + self.shape = shape + self.alloc = jna.Memory(shape.itemsize * size) + + def __setitem__(self, index, value): + self.alloc.setShort(index, value) + + def __getitem__(self, index): + return self.alloc.getShort(index) + +class FuncPtr(object): + def __init__(self, fn, name, argtypes, restype): + self.fn = fn + self.name = name + self.argtypes = argtypes + self.restype = restype + + def __call__(self, *args): + container = Array('H')(1, autofree=True) + container[0] = self.fn.invokeInt([i[0] for i in args]) + return container + +class CDLL(object): + def __init__(self, libname): + self.lib = jna.NativeLibrary.getInstance(libname) + self.cache = dict() + + def ptr(self, name, argtypes, restype): + key = (name, tuple(argtypes), restype) + try: + return self.cache[key] + except KeyError: + fn = self.lib.getFunction(name) + fnp = FuncPtr(fn, name, argtypes, restype) + self.cache[key] = fnp + return fnp diff --git a/src/main/resources/PythonLibs/_strptime.py b/src/main/resources/PythonLibs/_strptime.py new file mode 100644 index 0000000000000000000000000000000000000000..2df30a22ea5e8aaa35c742e0c5c76f80e91b6dc5 --- /dev/null +++ b/src/main/resources/PythonLibs/_strptime.py @@ -0,0 +1,467 @@ +"""Strptime-related classes and functions. + +CLASSES: + LocaleTime -- Discovers and stores locale-specific time information + TimeRE -- Creates regexes for pattern matching a string of text containing + time information + +FUNCTIONS: + _getlang -- Figure out what language is being used for the locale + strptime -- Calculates the time struct represented by the passed-in string + +""" +import time +import locale +import calendar +from re import compile as re_compile +from re import IGNORECASE +from re import escape as re_escape +from datetime import date as datetime_date +try: + from thread import allocate_lock as _thread_allocate_lock +except: + from dummy_thread import allocate_lock as _thread_allocate_lock + +__all__ = [] + +def _getlang(): + # Figure out what the current language is set to. + return locale.getlocale(locale.LC_TIME) + +class LocaleTime(object): + """Stores and handles locale-specific information related to time. + + ATTRIBUTES: + f_weekday -- full weekday names (7-item list) + a_weekday -- abbreviated weekday names (7-item list) + f_month -- full month names (13-item list; dummy value in [0], which + is added by code) + a_month -- abbreviated month names (13-item list, dummy value in + [0], which is added by code) + am_pm -- AM/PM representation (2-item list) + LC_date_time -- format string for date/time representation (string) + LC_date -- format string for date representation (string) + LC_time -- format string for time representation (string) + timezone -- daylight- and non-daylight-savings timezone representation + (2-item list of sets) + lang -- Language used by instance (2-item tuple) + """ + + def __init__(self): + """Set all attributes. + + Order of methods called matters for dependency reasons. + + The locale language is set at the offset and then checked again before + exiting. This is to make sure that the attributes were not set with a + mix of information from more than one locale. This would most likely + happen when using threads where one thread calls a locale-dependent + function while another thread changes the locale while the function in + the other thread is still running. Proper coding would call for + locks to prevent changing the locale while locale-dependent code is + running. The check here is done in case someone does not think about + doing this. + + Only other possible issue is if someone changed the timezone and did + not call tz.tzset . That is an issue for the programmer, though, + since changing the timezone is worthless without that call. + + """ + self.lang = _getlang() + self.__calc_weekday() + self.__calc_month() + self.__calc_am_pm() + self.__calc_timezone() + self.__calc_date_time() + if _getlang() != self.lang: + raise ValueError("locale changed during initialization") + + def __pad(self, seq, front): + # Add '' to seq to either the front (is True), else the back. + seq = list(seq) + if front: + seq.insert(0, '') + else: + seq.append('') + return seq + + def __calc_weekday(self): + # Set self.a_weekday and self.f_weekday using the calendar + # module. + a_weekday = [calendar.day_abbr[i].lower() for i in range(7)] + f_weekday = [calendar.day_name[i].lower() for i in range(7)] + self.a_weekday = a_weekday + self.f_weekday = f_weekday + + def __calc_month(self): + # Set self.f_month and self.a_month using the calendar module. + a_month = [calendar.month_abbr[i].lower() for i in range(13)] + f_month = [calendar.month_name[i].lower() for i in range(13)] + self.a_month = a_month + self.f_month = f_month + + def __calc_am_pm(self): + # Set self.am_pm by using time.strftime(). + + # The magic date (1999,3,17,hour,44,55,2,76,0) is not really that + # magical; just happened to have used it everywhere else where a + # static date was needed. + am_pm = [] + for hour in (01,22): + time_tuple = time.struct_time((1999,3,17,hour,44,55,2,76,0)) + am_pm.append(time.strftime("%p", time_tuple).lower()) + self.am_pm = am_pm + + def __calc_date_time(self): + # Set self.date_time, self.date, & self.time by using + # time.strftime(). + + # Use (1999,3,17,22,44,55,2,76,0) for magic date because the amount of + # overloaded numbers is minimized. The order in which searches for + # values within the format string is very important; it eliminates + # possible ambiguity for what something represents. + time_tuple = time.struct_time((1999,3,17,22,44,55,2,76,0)) + date_time = [None, None, None] + date_time[0] = time.strftime("%c", time_tuple).lower() + date_time[1] = time.strftime("%x", time_tuple).lower() + date_time[2] = time.strftime("%X", time_tuple).lower() + replacement_pairs = [('%', '%%'), (self.f_weekday[2], '%A'), + (self.f_month[3], '%B'), (self.a_weekday[2], '%a'), + (self.a_month[3], '%b'), (self.am_pm[1], '%p'), + ('1999', '%Y'), ('99', '%y'), ('22', '%H'), + ('44', '%M'), ('55', '%S'), ('76', '%j'), + ('17', '%d'), ('03', '%m'), ('3', '%m'), + # '3' needed for when no leading zero. + ('2', '%w'), ('10', '%I')] + replacement_pairs.extend([(tz, "%Z") for tz_values in self.timezone + for tz in tz_values]) + for offset,directive in ((0,'%c'), (1,'%x'), (2,'%X')): + current_format = date_time[offset] + for old, new in replacement_pairs: + # Must deal with possible lack of locale info + # manifesting itself as the empty string (e.g., Swedish's + # lack of AM/PM info) or a platform returning a tuple of empty + # strings (e.g., MacOS 9 having timezone as ('','')). + if old: + current_format = current_format.replace(old, new) + # If %W is used, then Sunday, 2005-01-03 will fall on week 0 since + # 2005-01-03 occurs before the first Monday of the year. Otherwise + # %U is used. + time_tuple = time.struct_time((1999,1,3,1,1,1,6,3,0)) + if '00' in time.strftime(directive, time_tuple): + U_W = '%W' + else: + U_W = '%U' + date_time[offset] = current_format.replace('11', U_W) + self.LC_date_time = date_time[0] + self.LC_date = date_time[1] + self.LC_time = date_time[2] + + def __calc_timezone(self): + # Set self.timezone by using time.tzname. + # Do not worry about possibility of time.tzname[0] == timetzname[1] + # and time.daylight; handle that in strptime . + try: + time.tzset() + except AttributeError: + pass + no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()]) + if time.daylight: + has_saving = frozenset([time.tzname[1].lower()]) + else: + has_saving = frozenset() + self.timezone = (no_saving, has_saving) + + +class TimeRE(dict): + """Handle conversion from format directives to regexes.""" + + def __init__(self, locale_time=None): + """Create keys/values. + + Order of execution is important for dependency reasons. + + """ + if locale_time: + self.locale_time = locale_time + else: + self.locale_time = LocaleTime() + base = super(TimeRE, self) + base.__init__({ + # The " \d" part of the regex is to make %c from ANSI C work + 'd': r"(?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])", + 'f': r"(?P<f>[0-9]{1,6})", + 'H': r"(?P<H>2[0-3]|[0-1]\d|\d)", + 'I': r"(?P<I>1[0-2]|0[1-9]|[1-9])", + 'j': r"(?P<j>36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])", + 'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])", + 'M': r"(?P<M>[0-5]\d|\d)", + 'S': r"(?P<S>6[0-1]|[0-5]\d|\d)", + 'U': r"(?P<U>5[0-3]|[0-4]\d|\d)", + 'w': r"(?P<w>[0-6])", + # W is set below by using 'U' + 'y': r"(?P<y>\d\d)", + #XXX: Does 'Y' need to worry about having less or more than + # 4 digits? + 'Y': r"(?P<Y>\d\d\d\d)", + 'A': self.__seqToRE(self.locale_time.f_weekday, 'A'), + 'a': self.__seqToRE(self.locale_time.a_weekday, 'a'), + 'B': self.__seqToRE(self.locale_time.f_month[1:], 'B'), + 'b': self.__seqToRE(self.locale_time.a_month[1:], 'b'), + 'p': self.__seqToRE(self.locale_time.am_pm, 'p'), + 'Z': self.__seqToRE((tz for tz_names in self.locale_time.timezone + for tz in tz_names), + 'Z'), + '%': '%'}) + base.__setitem__('W', base.__getitem__('U').replace('U', 'W')) + base.__setitem__('c', self.pattern(self.locale_time.LC_date_time)) + base.__setitem__('x', self.pattern(self.locale_time.LC_date)) + base.__setitem__('X', self.pattern(self.locale_time.LC_time)) + + def __seqToRE(self, to_convert, directive): + """Convert a list to a regex string for matching a directive. + + Want possible matching values to be from longest to shortest. This + prevents the possibility of a match occuring for a value that also + a substring of a larger value that should have matched (e.g., 'abc' + matching when 'abcdef' should have been the match). + + """ + to_convert = sorted(to_convert, key=len, reverse=True) + for value in to_convert: + if value != '': + break + else: + return '' + regex = '|'.join(re_escape(stuff) for stuff in to_convert) + regex = '(?P<%s>%s' % (directive, regex) + return '%s)' % regex + + def pattern(self, format): + """Return regex pattern for the format string. + + Need to make sure that any characters that might be interpreted as + regex syntax are escaped. + + """ + processed_format = '' + # The sub() call escapes all characters that might be misconstrued + # as regex syntax. Cannot use re.escape since we have to deal with + # format directives (%m, etc.). + regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])") + format = regex_chars.sub(r"\\\1", format) + whitespace_replacement = re_compile('\s+') + format = whitespace_replacement.sub('\s+', format) + while '%' in format: + directive_index = format.index('%')+1 + processed_format = "%s%s%s" % (processed_format, + format[:directive_index-1], + self[format[directive_index]]) + format = format[directive_index+1:] + return "%s%s" % (processed_format, format) + + def compile(self, format): + """Return a compiled re object for the format string.""" + return re_compile(self.pattern(format), IGNORECASE) + +_cache_lock = _thread_allocate_lock() +# DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock +# first! +_TimeRE_cache = TimeRE() +_CACHE_MAX_SIZE = 5 # Max number of regexes stored in _regex_cache +_regex_cache = {} + +def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon): + """Calculate the Julian day based on the year, week of the year, and day of + the week, with week_start_day representing whether the week of the year + assumes the week starts on Sunday or Monday (6 or 0).""" + first_weekday = datetime_date(year, 1, 1).weekday() + # If we are dealing with the %U directive (week starts on Sunday), it's + # easier to just shift the view to Sunday being the first day of the + # week. + if not week_starts_Mon: + first_weekday = (first_weekday + 1) % 7 + day_of_week = (day_of_week + 1) % 7 + # Need to watch out for a week 0 (when the first day of the year is not + # the same as that specified by %U or %W). + week_0_length = (7 - first_weekday) % 7 + if week_of_year == 0: + return 1 + day_of_week - first_weekday + else: + days_to_week = week_0_length + (7 * (week_of_year - 1)) + return 1 + days_to_week + day_of_week + + +def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): + """Return a time struct based on the input string and the format string.""" + global _TimeRE_cache, _regex_cache + with _cache_lock: + if _getlang() != _TimeRE_cache.locale_time.lang: + _TimeRE_cache = TimeRE() + _regex_cache.clear() + if len(_regex_cache) > _CACHE_MAX_SIZE: + _regex_cache.clear() + locale_time = _TimeRE_cache.locale_time + format_regex = _regex_cache.get(format) + if not format_regex: + try: + format_regex = _TimeRE_cache.compile(format) + # KeyError raised when a bad format is found; can be specified as + # \\, in which case it was a stray % but with a space after it + except KeyError, err: + bad_directive = err.args[0] + if bad_directive == "\\": + bad_directive = "%" + del err + raise ValueError("'%s' is a bad directive in format '%s'" % + (bad_directive, format)) + # IndexError only occurs when the format string is "%" + except IndexError: + raise ValueError("stray %% in format '%s'" % format) + _regex_cache[format] = format_regex + found = format_regex.match(data_string) + if not found: + raise ValueError("time data %r does not match format %r" % + (data_string, format)) + if len(data_string) != found.end(): + raise ValueError("unconverted data remains: %s" % + data_string[found.end():]) + + year = None + month = day = 1 + hour = minute = second = fraction = 0 + tz = -1 + # Default to -1 to signify that values not known; not critical to have, + # though + week_of_year = -1 + week_of_year_start = -1 + # weekday and julian defaulted to -1 so as to signal need to calculate + # values + weekday = julian = -1 + found_dict = found.groupdict() + for group_key in found_dict.iterkeys(): + # Directives not explicitly handled below: + # c, x, X + # handled by making out of other directives + # U, W + # worthless without day of the week + if group_key == 'y': + year = int(found_dict['y']) + # Open Group specification for strptime() states that a %y + #value in the range of [00, 68] is in the century 2000, while + #[69,99] is in the century 1900 + if year <= 68: + year += 2000 + else: + year += 1900 + elif group_key == 'Y': + year = int(found_dict['Y']) + elif group_key == 'm': + month = int(found_dict['m']) + elif group_key == 'B': + month = locale_time.f_month.index(found_dict['B'].lower()) + elif group_key == 'b': + month = locale_time.a_month.index(found_dict['b'].lower()) + elif group_key == 'd': + day = int(found_dict['d']) + elif group_key == 'H': + hour = int(found_dict['H']) + elif group_key == 'I': + hour = int(found_dict['I']) + ampm = found_dict.get('p', '').lower() + # If there was no AM/PM indicator, we'll treat this like AM + if ampm in ('', locale_time.am_pm[0]): + # We're in AM so the hour is correct unless we're + # looking at 12 midnight. + # 12 midnight == 12 AM == hour 0 + if hour == 12: + hour = 0 + elif ampm == locale_time.am_pm[1]: + # We're in PM so we need to add 12 to the hour unless + # we're looking at 12 noon. + # 12 noon == 12 PM == hour 12 + if hour != 12: + hour += 12 + elif group_key == 'M': + minute = int(found_dict['M']) + elif group_key == 'S': + second = int(found_dict['S']) + elif group_key == 'f': + s = found_dict['f'] + # Pad to always return microseconds. + s += "0" * (6 - len(s)) + fraction = int(s) + elif group_key == 'A': + weekday = locale_time.f_weekday.index(found_dict['A'].lower()) + elif group_key == 'a': + weekday = locale_time.a_weekday.index(found_dict['a'].lower()) + elif group_key == 'w': + weekday = int(found_dict['w']) + if weekday == 0: + weekday = 6 + else: + weekday -= 1 + elif group_key == 'j': + julian = int(found_dict['j']) + elif group_key in ('U', 'W'): + week_of_year = int(found_dict[group_key]) + if group_key == 'U': + # U starts week on Sunday. + week_of_year_start = 6 + else: + # W starts week on Monday. + week_of_year_start = 0 + elif group_key == 'Z': + # Since -1 is default value only need to worry about setting tz if + # it can be something other than -1. + found_zone = found_dict['Z'].lower() + for value, tz_values in enumerate(locale_time.timezone): + if found_zone in tz_values: + # Deal with bad locale setup where timezone names are the + # same and yet time.daylight is true; too ambiguous to + # be able to tell what timezone has daylight savings + if (time.tzname[0] == time.tzname[1] and + time.daylight and found_zone not in ("utc", "gmt")): + break + else: + tz = value + break + leap_year_fix = False + if year is None and month == 2 and day == 29: + year = 1904 # 1904 is first leap year of 20th century + leap_year_fix = True + elif year is None: + year = 1900 + # If we know the week of the year and what day of that week, we can figure + # out the Julian day of the year. + if julian == -1 and week_of_year != -1 and weekday != -1: + week_starts_Mon = True if week_of_year_start == 0 else False + julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, + week_starts_Mon) + # Cannot pre-calculate datetime_date() since can change in Julian + # calculation and thus could have different value for the day of the week + # calculation. + if julian == -1: + # Need to add 1 to result since first day of the year is 1, not 0. + julian = datetime_date(year, month, day).toordinal() - \ + datetime_date(year, 1, 1).toordinal() + 1 + else: # Assume that if they bothered to include Julian day it will + # be accurate. + datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal()) + year = datetime_result.year + month = datetime_result.month + day = datetime_result.day + if weekday == -1: + weekday = datetime_date(year, month, day).weekday() + if leap_year_fix: + # the caller didn't supply a year but asked for Feb 29th. We couldn't + # use the default of 1900 for computations. We set it back to ensure + # that February 29th is smaller than March 1st. + year = 1900 + + return (time.struct_time((year, month, day, + hour, minute, second, + weekday, julian, tz)), fraction) + +def _strptime_time(data_string, format="%a %b %d %H:%M:%S %Y"): + return _strptime(data_string, format)[0] diff --git a/src/main/resources/PythonLibs/_threading_local.py b/src/main/resources/PythonLibs/_threading_local.py new file mode 100644 index 0000000000000000000000000000000000000000..09a3515bdb92b40b1e43caa0cca25f0da5981aae --- /dev/null +++ b/src/main/resources/PythonLibs/_threading_local.py @@ -0,0 +1,251 @@ +"""Thread-local objects. + +(Note that this module provides a Python version of the threading.local + class. Depending on the version of Python you're using, there may be a + faster one available. You should always import the `local` class from + `threading`.) + +Thread-local objects support the management of thread-local data. +If you have data that you want to be local to a thread, simply create +a thread-local object and use its attributes: + + >>> mydata = local() + >>> mydata.number = 42 + >>> mydata.number + 42 + +You can also access the local-object's dictionary: + + >>> mydata.__dict__ + {'number': 42} + >>> mydata.__dict__.setdefault('widgets', []) + [] + >>> mydata.widgets + [] + +What's important about thread-local objects is that their data are +local to a thread. If we access the data in a different thread: + + >>> log = [] + >>> def f(): + ... items = mydata.__dict__.items() + ... items.sort() + ... log.append(items) + ... mydata.number = 11 + ... log.append(mydata.number) + + >>> import threading + >>> thread = threading.Thread(target=f) + >>> thread.start() + >>> thread.join() + >>> log + [[], 11] + +we get different data. Furthermore, changes made in the other thread +don't affect data seen in this thread: + + >>> mydata.number + 42 + +Of course, values you get from a local object, including a __dict__ +attribute, are for whatever thread was current at the time the +attribute was read. For that reason, you generally don't want to save +these values across threads, as they apply only to the thread they +came from. + +You can create custom local objects by subclassing the local class: + + >>> class MyLocal(local): + ... number = 2 + ... initialized = False + ... def __init__(self, **kw): + ... if self.initialized: + ... raise SystemError('__init__ called too many times') + ... self.initialized = True + ... self.__dict__.update(kw) + ... def squared(self): + ... return self.number ** 2 + +This can be useful to support default values, methods and +initialization. Note that if you define an __init__ method, it will be +called each time the local object is used in a separate thread. This +is necessary to initialize each thread's dictionary. + +Now if we create a local object: + + >>> mydata = MyLocal(color='red') + +Now we have a default number: + + >>> mydata.number + 2 + +an initial color: + + >>> mydata.color + 'red' + >>> del mydata.color + +And a method that operates on the data: + + >>> mydata.squared() + 4 + +As before, we can access the data in a separate thread: + + >>> log = [] + >>> thread = threading.Thread(target=f) + >>> thread.start() + >>> thread.join() + >>> log + [[('color', 'red'), ('initialized', True)], 11] + +without affecting this thread's data: + + >>> mydata.number + 2 + >>> mydata.color + Traceback (most recent call last): + ... + AttributeError: 'MyLocal' object has no attribute 'color' + +Note that subclasses can define slots, but they are not thread +local. They are shared across threads: + + >>> class MyLocal(local): + ... __slots__ = 'number' + + >>> mydata = MyLocal() + >>> mydata.number = 42 + >>> mydata.color = 'red' + +So, the separate thread: + + >>> thread = threading.Thread(target=f) + >>> thread.start() + >>> thread.join() + +affects what we see: + + >>> mydata.number + 11 + +>>> del mydata +""" + +__all__ = ["local"] + +# We need to use objects from the threading module, but the threading +# module may also want to use our `local` class, if support for locals +# isn't compiled in to the `thread` module. This creates potential problems +# with circular imports. For that reason, we don't import `threading` +# until the bottom of this file (a hack sufficient to worm around the +# potential problems). Note that almost all platforms do have support for +# locals in the `thread` module, and there is no circular import problem +# then, so problems introduced by fiddling the order of imports here won't +# manifest on most boxes. + +class _localbase(object): + __slots__ = '_local__key', '_local__args', '_local__lock' + + def __new__(cls, *args, **kw): + self = object.__new__(cls) + key = '_local__key', 'thread.local.' + str(id(self)) + object.__setattr__(self, '_local__key', key) + object.__setattr__(self, '_local__args', (args, kw)) + object.__setattr__(self, '_local__lock', RLock()) + + if (args or kw) and (cls.__init__ is object.__init__): + raise TypeError("Initialization arguments are not supported") + + # We need to create the thread dict in anticipation of + # __init__ being called, to make sure we don't call it + # again ourselves. + dict = object.__getattribute__(self, '__dict__') + current_thread().__dict__[key] = dict + + return self + +def _patch(self): + key = object.__getattribute__(self, '_local__key') + d = current_thread().__dict__.get(key) + if d is None: + d = {} + current_thread().__dict__[key] = d + object.__setattr__(self, '__dict__', d) + + # we have a new instance dict, so call out __init__ if we have + # one + cls = type(self) + if cls.__init__ is not object.__init__: + args, kw = object.__getattribute__(self, '_local__args') + cls.__init__(self, *args, **kw) + else: + object.__setattr__(self, '__dict__', d) + +class local(_localbase): + + def __getattribute__(self, name): + lock = object.__getattribute__(self, '_local__lock') + lock.acquire() + try: + _patch(self) + return object.__getattribute__(self, name) + finally: + lock.release() + + def __setattr__(self, name, value): + if name == '__dict__': + raise AttributeError( + "%r object attribute '__dict__' is read-only" + % self.__class__.__name__) + lock = object.__getattribute__(self, '_local__lock') + lock.acquire() + try: + _patch(self) + return object.__setattr__(self, name, value) + finally: + lock.release() + + def __delattr__(self, name): + if name == '__dict__': + raise AttributeError( + "%r object attribute '__dict__' is read-only" + % self.__class__.__name__) + lock = object.__getattribute__(self, '_local__lock') + lock.acquire() + try: + _patch(self) + return object.__delattr__(self, name) + finally: + lock.release() + + def __del__(self): + import threading + + key = object.__getattribute__(self, '_local__key') + + try: + # We use the non-locking API since we might already hold the lock + # (__del__ can be called at any point by the cyclic GC). + threads = threading._enumerate() + except: + # If enumerating the current threads fails, as it seems to do + # during shutdown, we'll skip cleanup under the assumption + # that there is nothing to clean up. + return + + for thread in threads: + try: + __dict__ = thread.__dict__ + except AttributeError: + # Thread is dying, rest in peace. + continue + + if key in __dict__: + try: + del __dict__[key] + except KeyError: + pass # didn't have anything in this thread + +from threading import current_thread, RLock diff --git a/src/main/resources/PythonLibs/_weakrefset.py b/src/main/resources/PythonLibs/_weakrefset.py new file mode 100644 index 0000000000000000000000000000000000000000..90e07d4768b8c0b6a6f41e983294a6109ac1bc8f --- /dev/null +++ b/src/main/resources/PythonLibs/_weakrefset.py @@ -0,0 +1,212 @@ +# Access WeakSet through the weakref module. +# This code is separated-out because it is needed +# by abc.py to load everything else at startup. + +from _weakref import ref + +__all__ = ['WeakSet'] + + +class _IterationGuard(object): + # This context manager registers itself in the current iterators of the + # weak container, such as to delay all removals until the context manager + # exits. + # This technique should be relatively thread-safe (since sets are). + + def __init__(self, weakcontainer): + # Don't create cycles + self.weakcontainer = ref(weakcontainer) + + def __enter__(self): + w = self.weakcontainer() + if w is not None: + w._iterating.add(self) + return self + + def __exit__(self, e, t, b): + w = self.weakcontainer() + if w is not None: + s = w._iterating + s.remove(self) + if not s: + w._commit_removals() + + +class WeakSet(object): + def __init__(self, data=None): + self.data = set() + def _remove(item, selfref=ref(self)): + self = selfref() + if self is not None: + if self._iterating: + self._pending_removals.append(item) + else: + self.data.discard(item) + self._remove = _remove + # A list of keys to be removed + self._pending_removals = [] + self._iterating = set() + if data is not None: + self.update(data) + + def _commit_removals(self): + l = self._pending_removals + discard = self.data.discard + while l: + discard(l.pop()) + + def __iter__(self): + with _IterationGuard(self): + for itemref in self.data: + item = itemref() + if item is not None: + yield item + + def __len__(self): + return sum(x() is not None for x in self.data) + + def __contains__(self, item): + return ref(item) in self.data + + def __reduce__(self): + return (self.__class__, (list(self),), + getattr(self, '__dict__', None)) + + __hash__ = None + + def add(self, item): + if self._pending_removals: + self._commit_removals() + self.data.add(ref(item, self._remove)) + + def clear(self): + if self._pending_removals: + self._commit_removals() + self.data.clear() + + def copy(self): + return self.__class__(self) + + def pop(self): + if self._pending_removals: + self._commit_removals() + while True: + try: + itemref = self.data.pop() + except KeyError: + raise KeyError('pop from empty WeakSet') + item = itemref() + if item is not None: + return item + + def remove(self, item): + if self._pending_removals: + self._commit_removals() + self.data.remove(ref(item)) + + def discard(self, item): + if self._pending_removals: + self._commit_removals() + self.data.discard(ref(item)) + + def update(self, other): + if self._pending_removals: + self._commit_removals() + if isinstance(other, self.__class__): + self.data.update(other.data) + else: + for element in other: + self.add(element) + + def __ior__(self, other): + self.update(other) + return self + + # Helper functions for simple delegating methods. + def _apply(self, other, method): + if not isinstance(other, self.__class__): + other = self.__class__(other) + newdata = method(other.data) + newset = self.__class__() + newset.data = newdata + return newset + + def difference(self, other): + return self._apply(other, self.data.difference) + __sub__ = difference + + def difference_update(self, other): + if self._pending_removals: + self._commit_removals() + if self is other: + self.data.clear() + else: + self.data.difference_update(ref(item) for item in other) + def __isub__(self, other): + if self._pending_removals: + self._commit_removals() + if self is other: + self.data.clear() + else: + self.data.difference_update(ref(item) for item in other) + return self + + def intersection(self, other): + return self._apply(other, self.data.intersection) + __and__ = intersection + + def intersection_update(self, other): + if self._pending_removals: + self._commit_removals() + self.data.intersection_update(ref(item) for item in other) + def __iand__(self, other): + if self._pending_removals: + self._commit_removals() + self.data.intersection_update(ref(item) for item in other) + return self + + def issubset(self, other): + return self.data.issubset(ref(item) for item in other) + __lt__ = issubset + + def __le__(self, other): + return self.data <= set(ref(item) for item in other) + + def issuperset(self, other): + return self.data.issuperset(ref(item) for item in other) + __gt__ = issuperset + + def __ge__(self, other): + return self.data >= set(ref(item) for item in other) + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.data == set(ref(item) for item in other) + + def symmetric_difference(self, other): + return self._apply(other, self.data.symmetric_difference) + __xor__ = symmetric_difference + + def symmetric_difference_update(self, other): + if self._pending_removals: + self._commit_removals() + if self is other: + self.data.clear() + else: + self.data.symmetric_difference_update(ref(item) for item in other) + def __ixor__(self, other): + if self._pending_removals: + self._commit_removals() + if self is other: + self.data.clear() + else: + self.data.symmetric_difference_update(ref(item) for item in other) + return self + + def union(self, other): + return self._apply(other, self.data.union) + __or__ = union + + def isdisjoint(self, other): + return len(self.intersection(other)) == 0 diff --git a/src/main/resources/PythonLibs/abc.py b/src/main/resources/PythonLibs/abc.py new file mode 100644 index 0000000000000000000000000000000000000000..02e48a1bb32f9bb0353180e4b0546e6985b0725d --- /dev/null +++ b/src/main/resources/PythonLibs/abc.py @@ -0,0 +1,185 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Abstract Base Classes (ABCs) according to PEP 3119.""" + +import types + +from _weakrefset import WeakSet + +# Instance of old-style class +class _C: pass +_InstanceType = type(_C()) + + +def abstractmethod(funcobj): + """A decorator indicating abstract methods. + + Requires that the metaclass is ABCMeta or derived from it. A + class that has a metaclass derived from ABCMeta cannot be + instantiated unless all of its abstract methods are overridden. + The abstract methods can be called using any of the normal + 'super' call mechanisms. + + Usage: + + class C: + __metaclass__ = ABCMeta + @abstractmethod + def my_abstract_method(self, ...): + ... + """ + funcobj.__isabstractmethod__ = True + return funcobj + + +class abstractproperty(property): + """A decorator indicating abstract properties. + + Requires that the metaclass is ABCMeta or derived from it. A + class that has a metaclass derived from ABCMeta cannot be + instantiated unless all of its abstract properties are overridden. + The abstract properties can be called using any of the normal + 'super' call mechanisms. + + Usage: + + class C: + __metaclass__ = ABCMeta + @abstractproperty + def my_abstract_property(self): + ... + + This defines a read-only property; you can also define a read-write + abstract property using the 'long' form of property declaration: + + class C: + __metaclass__ = ABCMeta + def getx(self): ... + def setx(self, value): ... + x = abstractproperty(getx, setx) + """ + __isabstractmethod__ = True + + +class ABCMeta(type): + + """Metaclass for defining Abstract Base Classes (ABCs). + + Use this metaclass to create an ABC. An ABC can be subclassed + directly, and then acts as a mix-in class. You can also register + unrelated concrete classes (even built-in classes) and unrelated + ABCs as 'virtual subclasses' -- these and their descendants will + be considered subclasses of the registering ABC by the built-in + issubclass() function, but the registering ABC won't show up in + their MRO (Method Resolution Order) nor will method + implementations defined by the registering ABC be callable (not + even via super()). + + """ + + # A global counter that is incremented each time a class is + # registered as a virtual subclass of anything. It forces the + # negative cache to be cleared before its next use. + _abc_invalidation_counter = 0 + + def __new__(mcls, name, bases, namespace): + cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace) + # Compute set of abstract method names + abstracts = set(name + for name, value in namespace.items() + if getattr(value, "__isabstractmethod__", False)) + for base in bases: + for name in getattr(base, "__abstractmethods__", set()): + value = getattr(cls, name, None) + if getattr(value, "__isabstractmethod__", False): + abstracts.add(name) + cls.__abstractmethods__ = frozenset(abstracts) + # Set up inheritance registry + cls._abc_registry = WeakSet() + cls._abc_cache = WeakSet() + cls._abc_negative_cache = WeakSet() + cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter + return cls + + def register(cls, subclass): + """Register a virtual subclass of an ABC.""" + if not isinstance(subclass, (type, types.ClassType)): + raise TypeError("Can only register classes") + if issubclass(subclass, cls): + return # Already a subclass + # Subtle: test for cycles *after* testing for "already a subclass"; + # this means we allow X.register(X) and interpret it as a no-op. + if issubclass(cls, subclass): + # This would create a cycle, which is bad for the algorithm below + raise RuntimeError("Refusing to create an inheritance cycle") + cls._abc_registry.add(subclass) + ABCMeta._abc_invalidation_counter += 1 # Invalidate negative cache + + def _dump_registry(cls, file=None): + """Debug helper to print the ABC registry.""" + print >> file, "Class: %s.%s" % (cls.__module__, cls.__name__) + print >> file, "Inv.counter: %s" % ABCMeta._abc_invalidation_counter + for name in sorted(cls.__dict__.keys()): + if name.startswith("_abc_"): + value = getattr(cls, name) + print >> file, "%s: %r" % (name, value) + + def __instancecheck__(cls, instance): + """Override for isinstance(instance, cls).""" + # Inline the cache checking when it's simple. + subclass = getattr(instance, '__class__', None) + if subclass is not None and subclass in cls._abc_cache: + return True + subtype = type(instance) + # Old-style instances + if subtype is _InstanceType: + subtype = subclass + if subtype is subclass or subclass is None: + if (cls._abc_negative_cache_version == + ABCMeta._abc_invalidation_counter and + subtype in cls._abc_negative_cache): + return False + # Fall back to the subclass check. + return cls.__subclasscheck__(subtype) + return (cls.__subclasscheck__(subclass) or + cls.__subclasscheck__(subtype)) + + def __subclasscheck__(cls, subclass): + """Override for issubclass(subclass, cls).""" + # Check cache + if subclass in cls._abc_cache: + return True + # Check negative cache; may have to invalidate + if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter: + # Invalidate the negative cache + cls._abc_negative_cache = WeakSet() + cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter + elif subclass in cls._abc_negative_cache: + return False + # Check the subclass hook + ok = cls.__subclasshook__(subclass) + if ok is not NotImplemented: + assert isinstance(ok, bool) + if ok: + cls._abc_cache.add(subclass) + else: + cls._abc_negative_cache.add(subclass) + return ok + # Check if it's a direct subclass + if cls in getattr(subclass, '__mro__', ()): + cls._abc_cache.add(subclass) + return True + # Check if it's a subclass of a registered class (recursive) + for rcls in cls._abc_registry: + if issubclass(subclass, rcls): + cls._abc_cache.add(subclass) + return True + # Check if it's a subclass of a subclass (recursive) + for scls in cls.__subclasses__(): + if issubclass(subclass, scls): + cls._abc_cache.add(subclass) + return True + # No dice; update negative cache + cls._abc_negative_cache.add(subclass) + return False diff --git a/src/main/resources/PythonLibs/aifc.py b/src/main/resources/PythonLibs/aifc.py new file mode 100644 index 0000000000000000000000000000000000000000..a0cfe5fc57e1ee76d440b0f4181bdd8c41b04312 --- /dev/null +++ b/src/main/resources/PythonLibs/aifc.py @@ -0,0 +1,975 @@ +"""Stuff to parse AIFF-C and AIFF files. + +Unless explicitly stated otherwise, the description below is true +both for AIFF-C files and AIFF files. + +An AIFF-C file has the following structure. + + +-----------------+ + | FORM | + +-----------------+ + | <size> | + +----+------------+ + | | AIFC | + | +------------+ + | | <chunks> | + | | . | + | | . | + | | . | + +----+------------+ + +An AIFF file has the string "AIFF" instead of "AIFC". + +A chunk consists of an identifier (4 bytes) followed by a size (4 bytes, +big endian order), followed by the data. The size field does not include +the size of the 8 byte header. + +The following chunk types are recognized. + + FVER + <version number of AIFF-C defining document> (AIFF-C only). + MARK + <# of markers> (2 bytes) + list of markers: + <marker ID> (2 bytes, must be > 0) + <position> (4 bytes) + <marker name> ("pstring") + COMM + <# of channels> (2 bytes) + <# of sound frames> (4 bytes) + <size of the samples> (2 bytes) + <sampling frequency> (10 bytes, IEEE 80-bit extended + floating point) + in AIFF-C files only: + <compression type> (4 bytes) + <human-readable version of compression type> ("pstring") + SSND + <offset> (4 bytes, not used by this program) + <blocksize> (4 bytes, not used by this program) + <sound data> + +A pstring consists of 1 byte length, a string of characters, and 0 or 1 +byte pad to make the total length even. + +Usage. + +Reading AIFF files: + f = aifc.open(file, 'r') +where file is either the name of a file or an open file pointer. +The open file pointer must have methods read(), seek(), and close(). +In some types of audio files, if the setpos() method is not used, +the seek() method is not necessary. + +This returns an instance of a class with the following public methods: + getnchannels() -- returns number of audio channels (1 for + mono, 2 for stereo) + getsampwidth() -- returns sample width in bytes + getframerate() -- returns sampling frequency + getnframes() -- returns number of audio frames + getcomptype() -- returns compression type ('NONE' for AIFF files) + getcompname() -- returns human-readable version of + compression type ('not compressed' for AIFF files) + getparams() -- returns a tuple consisting of all of the + above in the above order + getmarkers() -- get the list of marks in the audio file or None + if there are no marks + getmark(id) -- get mark with the specified id (raises an error + if the mark does not exist) + readframes(n) -- returns at most n frames of audio + rewind() -- rewind to the beginning of the audio stream + setpos(pos) -- seek to the specified position + tell() -- return the current position + close() -- close the instance (make it unusable) +The position returned by tell(), the position given to setpos() and +the position of marks are all compatible and have nothing to do with +the actual position in the file. +The close() method is called automatically when the class instance +is destroyed. + +Writing AIFF files: + f = aifc.open(file, 'w') +where file is either the name of a file or an open file pointer. +The open file pointer must have methods write(), tell(), seek(), and +close(). + +This returns an instance of a class with the following public methods: + aiff() -- create an AIFF file (AIFF-C default) + aifc() -- create an AIFF-C file + setnchannels(n) -- set the number of channels + setsampwidth(n) -- set the sample width + setframerate(n) -- set the frame rate + setnframes(n) -- set the number of frames + setcomptype(type, name) + -- set the compression type and the + human-readable compression type + setparams(tuple) + -- set all parameters at once + setmark(id, pos, name) + -- add specified mark to the list of marks + tell() -- return current position in output file (useful + in combination with setmark()) + writeframesraw(data) + -- write audio frames without pathing up the + file header + writeframes(data) + -- write audio frames and patch up the file header + close() -- patch up the file header and close the + output file +You should set the parameters before the first writeframesraw or +writeframes. The total number of frames does not need to be set, +but when it is set to the correct value, the header does not have to +be patched up. +It is best to first set all parameters, perhaps possibly the +compression type, and then write audio frames using writeframesraw. +When all frames have been written, either call writeframes('') or +close() to patch up the sizes in the header. +Marks can be added anytime. If there are any marks, ypu must call +close() after all frames have been written. +The close() method is called automatically when the class instance +is destroyed. + +When a file is opened with the extension '.aiff', an AIFF file is +written, otherwise an AIFF-C file is written. This default can be +changed by calling aiff() or aifc() before the first writeframes or +writeframesraw. +""" + +import struct +import __builtin__ + +__all__ = ["Error","open","openfp"] + +class Error(Exception): + pass + +_AIFC_version = 0xA2805140L # Version 1 of AIFF-C + +def _read_long(file): + try: + return struct.unpack('>l', file.read(4))[0] + except struct.error: + raise EOFError + +def _read_ulong(file): + try: + return struct.unpack('>L', file.read(4))[0] + except struct.error: + raise EOFError + +def _read_short(file): + try: + return struct.unpack('>h', file.read(2))[0] + except struct.error: + raise EOFError + +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + +def _read_string(file): + length = ord(file.read(1)) + if length == 0: + data = '' + else: + data = file.read(length) + if length & 1 == 0: + dummy = file.read(1) + return data + +_HUGE_VAL = 1.79769313486231e+308 # See <limits.h> + +def _read_float(f): # 10 bytes + expon = _read_short(f) # 2 bytes + sign = 1 + if expon < 0: + sign = -1 + expon = expon + 0x8000 + himant = _read_ulong(f) # 4 bytes + lomant = _read_ulong(f) # 4 bytes + if expon == himant == lomant == 0: + f = 0.0 + elif expon == 0x7FFF: + f = _HUGE_VAL + else: + expon = expon - 16383 + f = (himant * 0x100000000L + lomant) * pow(2.0, expon - 63) + return sign * f + +def _write_short(f, x): + f.write(struct.pack('>h', x)) + +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + +def _write_long(f, x): + f.write(struct.pack('>l', x)) + +def _write_ulong(f, x): + f.write(struct.pack('>L', x)) + +def _write_string(f, s): + if len(s) > 255: + raise ValueError("string exceeds maximum pstring length") + f.write(struct.pack('B', len(s))) + f.write(s) + if len(s) & 1 == 0: + f.write(chr(0)) + +def _write_float(f, x): + import math + if x < 0: + sign = 0x8000 + x = x * -1 + else: + sign = 0 + if x == 0: + expon = 0 + himant = 0 + lomant = 0 + else: + fmant, expon = math.frexp(x) + if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN + expon = sign|0x7FFF + himant = 0 + lomant = 0 + else: # Finite + expon = expon + 16382 + if expon < 0: # denormalized + fmant = math.ldexp(fmant, expon) + expon = 0 + expon = expon | sign + fmant = math.ldexp(fmant, 32) + fsmant = math.floor(fmant) + himant = long(fsmant) + fmant = math.ldexp(fmant - fsmant, 32) + fsmant = math.floor(fmant) + lomant = long(fsmant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) + +from chunk import Chunk + +class Aifc_read: + # Variables used in this class: + # + # These variables are available to the user though appropriate + # methods of this class: + # _file -- the open file with methods read(), close(), and seek() + # set through the __init__() method + # _nchannels -- the number of audio channels + # available through the getnchannels() method + # _nframes -- the number of audio frames + # available through the getnframes() method + # _sampwidth -- the number of bytes per audio sample + # available through the getsampwidth() method + # _framerate -- the sampling frequency + # available through the getframerate() method + # _comptype -- the AIFF-C compression type ('NONE' if AIFF) + # available through the getcomptype() method + # _compname -- the human-readable AIFF-C compression type + # available through the getcomptype() method + # _markers -- the marks in the audio file + # available through the getmarkers() and getmark() + # methods + # _soundpos -- the position in the audio stream + # available through the tell() method, set through the + # setpos() method + # + # These variables are used internally only: + # _version -- the AIFF-C version number + # _decomp -- the decompressor from builtin module cl + # _comm_chunk_read -- 1 iff the COMM chunk has been read + # _aifc -- 1 iff reading an AIFF-C file + # _ssnd_seek_needed -- 1 iff positioned correctly in audio + # file for readframes() + # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk + # _framesize -- size of one frame in the file + + def initfp(self, file): + self._version = 0 + self._decomp = None + self._convert = None + self._markers = [] + self._soundpos = 0 + self._file = file + chunk = Chunk(file) + if chunk.getname() != 'FORM': + raise Error, 'file does not start with FORM id' + formdata = chunk.read(4) + if formdata == 'AIFF': + self._aifc = 0 + elif formdata == 'AIFC': + self._aifc = 1 + else: + raise Error, 'not an AIFF or AIFF-C file' + self._comm_chunk_read = 0 + while 1: + self._ssnd_seek_needed = 1 + try: + chunk = Chunk(self._file) + except EOFError: + break + chunkname = chunk.getname() + if chunkname == 'COMM': + self._read_comm_chunk(chunk) + self._comm_chunk_read = 1 + elif chunkname == 'SSND': + self._ssnd_chunk = chunk + dummy = chunk.read(8) + self._ssnd_seek_needed = 0 + elif chunkname == 'FVER': + self._version = _read_ulong(chunk) + elif chunkname == 'MARK': + self._readmark(chunk) + chunk.skip() + if not self._comm_chunk_read or not self._ssnd_chunk: + raise Error, 'COMM chunk and/or SSND chunk missing' + if self._aifc and self._decomp: + import cl + params = [cl.ORIGINAL_FORMAT, 0, + cl.BITS_PER_COMPONENT, self._sampwidth * 8, + cl.FRAME_RATE, self._framerate] + if self._nchannels == 1: + params[1] = cl.MONO + elif self._nchannels == 2: + params[1] = cl.STEREO_INTERLEAVED + else: + raise Error, 'cannot compress more than 2 channels' + self._decomp.SetParams(params) + + def __init__(self, f): + if type(f) == type(''): + f = __builtin__.open(f, 'rb') + # else, assume it is an open file object already + self.initfp(f) + + # + # User visible methods. + # + def getfp(self): + return self._file + + def rewind(self): + self._ssnd_seek_needed = 1 + self._soundpos = 0 + + def close(self): + if self._decomp: + self._decomp.CloseDecompressor() + self._decomp = None + self._file.close() + + def tell(self): + return self._soundpos + + def getnchannels(self): + return self._nchannels + + def getnframes(self): + return self._nframes + + def getsampwidth(self): + return self._sampwidth + + def getframerate(self): + return self._framerate + + def getcomptype(self): + return self._comptype + + def getcompname(self): + return self._compname + +## def getversion(self): +## return self._version + + def getparams(self): + return self.getnchannels(), self.getsampwidth(), \ + self.getframerate(), self.getnframes(), \ + self.getcomptype(), self.getcompname() + + def getmarkers(self): + if len(self._markers) == 0: + return None + return self._markers + + def getmark(self, id): + for marker in self._markers: + if id == marker[0]: + return marker + raise Error, 'marker %r does not exist' % (id,) + + def setpos(self, pos): + if pos < 0 or pos > self._nframes: + raise Error, 'position not in range' + self._soundpos = pos + self._ssnd_seek_needed = 1 + + def readframes(self, nframes): + if self._ssnd_seek_needed: + self._ssnd_chunk.seek(0) + dummy = self._ssnd_chunk.read(8) + pos = self._soundpos * self._framesize + if pos: + self._ssnd_chunk.seek(pos + 8) + self._ssnd_seek_needed = 0 + if nframes == 0: + return '' + data = self._ssnd_chunk.read(nframes * self._framesize) + if self._convert and data: + data = self._convert(data) + self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth) + return data + + # + # Internal methods. + # + + def _decomp_data(self, data): + import cl + dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE, + len(data) * 2) + return self._decomp.Decompress(len(data) // self._nchannels, + data) + + def _ulaw2lin(self, data): + import audioop + return audioop.ulaw2lin(data, 2) + + def _adpcm2lin(self, data): + import audioop + if not hasattr(self, '_adpcmstate'): + # first time + self._adpcmstate = None + data, self._adpcmstate = audioop.adpcm2lin(data, 2, + self._adpcmstate) + return data + + def _read_comm_chunk(self, chunk): + self._nchannels = _read_short(chunk) + self._nframes = _read_long(chunk) + self._sampwidth = (_read_short(chunk) + 7) // 8 + self._framerate = int(_read_float(chunk)) + self._framesize = self._nchannels * self._sampwidth + if self._aifc: + #DEBUG: SGI's soundeditor produces a bad size :-( + kludge = 0 + if chunk.chunksize == 18: + kludge = 1 + print 'Warning: bad COMM chunk size' + chunk.chunksize = 23 + #DEBUG end + self._comptype = chunk.read(4) + #DEBUG start + if kludge: + length = ord(chunk.file.read(1)) + if length & 1 == 0: + length = length + 1 + chunk.chunksize = chunk.chunksize + length + chunk.file.seek(-1, 1) + #DEBUG end + self._compname = _read_string(chunk) + if self._comptype != 'NONE': + if self._comptype == 'G722': + try: + import audioop + except ImportError: + pass + else: + self._convert = self._adpcm2lin + self._framesize = self._framesize // 4 + return + # for ULAW and ALAW try Compression Library + try: + import cl + except ImportError: + if self._comptype == 'ULAW': + try: + import audioop + self._convert = self._ulaw2lin + self._framesize = self._framesize // 2 + return + except ImportError: + pass + raise Error, 'cannot read compressed AIFF-C files' + if self._comptype == 'ULAW': + scheme = cl.G711_ULAW + self._framesize = self._framesize // 2 + elif self._comptype == 'ALAW': + scheme = cl.G711_ALAW + self._framesize = self._framesize // 2 + else: + raise Error, 'unsupported compression type' + self._decomp = cl.OpenDecompressor(scheme) + self._convert = self._decomp_data + else: + self._comptype = 'NONE' + self._compname = 'not compressed' + + def _readmark(self, chunk): + nmarkers = _read_short(chunk) + # Some files appear to contain invalid counts. + # Cope with this by testing for EOF. + try: + for i in range(nmarkers): + id = _read_short(chunk) + pos = _read_long(chunk) + name = _read_string(chunk) + if pos or name: + # some files appear to have + # dummy markers consisting of + # a position 0 and name '' + self._markers.append((id, pos, name)) + except EOFError: + print 'Warning: MARK chunk contains only', + print len(self._markers), + if len(self._markers) == 1: print 'marker', + else: print 'markers', + print 'instead of', nmarkers + +class Aifc_write: + # Variables used in this class: + # + # These variables are user settable through appropriate methods + # of this class: + # _file -- the open file with methods write(), close(), tell(), seek() + # set through the __init__() method + # _comptype -- the AIFF-C compression type ('NONE' in AIFF) + # set through the setcomptype() or setparams() method + # _compname -- the human-readable AIFF-C compression type + # set through the setcomptype() or setparams() method + # _nchannels -- the number of audio channels + # set through the setnchannels() or setparams() method + # _sampwidth -- the number of bytes per audio sample + # set through the setsampwidth() or setparams() method + # _framerate -- the sampling frequency + # set through the setframerate() or setparams() method + # _nframes -- the number of audio frames written to the header + # set through the setnframes() or setparams() method + # _aifc -- whether we're writing an AIFF-C file or an AIFF file + # set through the aifc() method, reset through the + # aiff() method + # + # These variables are used internally only: + # _version -- the AIFF-C version number + # _comp -- the compressor from builtin module cl + # _nframeswritten -- the number of audio frames actually written + # _datalength -- the size of the audio samples written to the header + # _datawritten -- the size of the audio samples actually written + + def __init__(self, f): + if type(f) == type(''): + filename = f + f = __builtin__.open(f, 'wb') + else: + # else, assume it is an open file object already + filename = '???' + self.initfp(f) + if filename[-5:] == '.aiff': + self._aifc = 0 + else: + self._aifc = 1 + + def initfp(self, file): + self._file = file + self._version = _AIFC_version + self._comptype = 'NONE' + self._compname = 'not compressed' + self._comp = None + self._convert = None + self._nchannels = 0 + self._sampwidth = 0 + self._framerate = 0 + self._nframes = 0 + self._nframeswritten = 0 + self._datawritten = 0 + self._datalength = 0 + self._markers = [] + self._marklength = 0 + self._aifc = 1 # AIFF-C is default + + def __del__(self): + if self._file: + self.close() + + # + # User visible methods. + # + def aiff(self): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._aifc = 0 + + def aifc(self): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._aifc = 1 + + def setnchannels(self, nchannels): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if nchannels < 1: + raise Error, 'bad # of channels' + self._nchannels = nchannels + + def getnchannels(self): + if not self._nchannels: + raise Error, 'number of channels not set' + return self._nchannels + + def setsampwidth(self, sampwidth): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if sampwidth < 1 or sampwidth > 4: + raise Error, 'bad sample width' + self._sampwidth = sampwidth + + def getsampwidth(self): + if not self._sampwidth: + raise Error, 'sample width not set' + return self._sampwidth + + def setframerate(self, framerate): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if framerate <= 0: + raise Error, 'bad frame rate' + self._framerate = framerate + + def getframerate(self): + if not self._framerate: + raise Error, 'frame rate not set' + return self._framerate + + def setnframes(self, nframes): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._nframes = nframes + + def getnframes(self): + return self._nframeswritten + + def setcomptype(self, comptype, compname): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'): + raise Error, 'unsupported compression type' + self._comptype = comptype + self._compname = compname + + def getcomptype(self): + return self._comptype + + def getcompname(self): + return self._compname + +## def setversion(self, version): +## if self._nframeswritten: +## raise Error, 'cannot change parameters after starting to write' +## self._version = version + + def setparams(self, info): + nchannels, sampwidth, framerate, nframes, comptype, compname = info + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'): + raise Error, 'unsupported compression type' + self.setnchannels(nchannels) + self.setsampwidth(sampwidth) + self.setframerate(framerate) + self.setnframes(nframes) + self.setcomptype(comptype, compname) + + def getparams(self): + if not self._nchannels or not self._sampwidth or not self._framerate: + raise Error, 'not all parameters set' + return self._nchannels, self._sampwidth, self._framerate, \ + self._nframes, self._comptype, self._compname + + def setmark(self, id, pos, name): + if id <= 0: + raise Error, 'marker ID must be > 0' + if pos < 0: + raise Error, 'marker position must be >= 0' + if type(name) != type(''): + raise Error, 'marker name must be a string' + for i in range(len(self._markers)): + if id == self._markers[i][0]: + self._markers[i] = id, pos, name + return + self._markers.append((id, pos, name)) + + def getmark(self, id): + for marker in self._markers: + if id == marker[0]: + return marker + raise Error, 'marker %r does not exist' % (id,) + + def getmarkers(self): + if len(self._markers) == 0: + return None + return self._markers + + def tell(self): + return self._nframeswritten + + def writeframesraw(self, data): + self._ensure_header_written(len(data)) + nframes = len(data) // (self._sampwidth * self._nchannels) + if self._convert: + data = self._convert(data) + self._file.write(data) + self._nframeswritten = self._nframeswritten + nframes + self._datawritten = self._datawritten + len(data) + + def writeframes(self, data): + self.writeframesraw(data) + if self._nframeswritten != self._nframes or \ + self._datalength != self._datawritten: + self._patchheader() + + def close(self): + if self._file is None: + return + try: + self._ensure_header_written(0) + if self._datawritten & 1: + # quick pad to even size + self._file.write(chr(0)) + self._datawritten = self._datawritten + 1 + self._writemarkers() + if self._nframeswritten != self._nframes or \ + self._datalength != self._datawritten or \ + self._marklength: + self._patchheader() + if self._comp: + self._comp.CloseCompressor() + self._comp = None + finally: + # Prevent ref cycles + self._convert = None + f = self._file + self._file = None + f.close() + + # + # Internal methods. + # + + def _comp_data(self, data): + import cl + dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data)) + dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data)) + return self._comp.Compress(self._nframes, data) + + def _lin2ulaw(self, data): + import audioop + return audioop.lin2ulaw(data, 2) + + def _lin2adpcm(self, data): + import audioop + if not hasattr(self, '_adpcmstate'): + self._adpcmstate = None + data, self._adpcmstate = audioop.lin2adpcm(data, 2, + self._adpcmstate) + return data + + def _ensure_header_written(self, datasize): + if not self._nframeswritten: + if self._comptype in ('ULAW', 'ALAW'): + if not self._sampwidth: + self._sampwidth = 2 + if self._sampwidth != 2: + raise Error, 'sample width must be 2 when compressing with ULAW or ALAW' + if self._comptype == 'G722': + if not self._sampwidth: + self._sampwidth = 2 + if self._sampwidth != 2: + raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)' + if not self._nchannels: + raise Error, '# channels not specified' + if not self._sampwidth: + raise Error, 'sample width not specified' + if not self._framerate: + raise Error, 'sampling rate not specified' + self._write_header(datasize) + + def _init_compression(self): + if self._comptype == 'G722': + self._convert = self._lin2adpcm + return + try: + import cl + except ImportError: + if self._comptype == 'ULAW': + try: + import audioop + self._convert = self._lin2ulaw + return + except ImportError: + pass + raise Error, 'cannot write compressed AIFF-C files' + if self._comptype == 'ULAW': + scheme = cl.G711_ULAW + elif self._comptype == 'ALAW': + scheme = cl.G711_ALAW + else: + raise Error, 'unsupported compression type' + self._comp = cl.OpenCompressor(scheme) + params = [cl.ORIGINAL_FORMAT, 0, + cl.BITS_PER_COMPONENT, self._sampwidth * 8, + cl.FRAME_RATE, self._framerate, + cl.FRAME_BUFFER_SIZE, 100, + cl.COMPRESSED_BUFFER_SIZE, 100] + if self._nchannels == 1: + params[1] = cl.MONO + elif self._nchannels == 2: + params[1] = cl.STEREO_INTERLEAVED + else: + raise Error, 'cannot compress more than 2 channels' + self._comp.SetParams(params) + # the compressor produces a header which we ignore + dummy = self._comp.Compress(0, '') + self._convert = self._comp_data + + def _write_header(self, initlength): + if self._aifc and self._comptype != 'NONE': + self._init_compression() + self._file.write('FORM') + if not self._nframes: + self._nframes = initlength // (self._nchannels * self._sampwidth) + self._datalength = self._nframes * self._nchannels * self._sampwidth + if self._datalength & 1: + self._datalength = self._datalength + 1 + if self._aifc: + if self._comptype in ('ULAW', 'ALAW'): + self._datalength = self._datalength // 2 + if self._datalength & 1: + self._datalength = self._datalength + 1 + elif self._comptype == 'G722': + self._datalength = (self._datalength + 3) // 4 + if self._datalength & 1: + self._datalength = self._datalength + 1 + self._form_length_pos = self._file.tell() + commlength = self._write_form_length(self._datalength) + if self._aifc: + self._file.write('AIFC') + self._file.write('FVER') + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) + else: + self._file.write('AIFF') + self._file.write('COMM') + _write_ulong(self._file, commlength) + _write_short(self._file, self._nchannels) + self._nframes_pos = self._file.tell() + _write_ulong(self._file, self._nframes) + _write_short(self._file, self._sampwidth * 8) + _write_float(self._file, self._framerate) + if self._aifc: + self._file.write(self._comptype) + _write_string(self._file, self._compname) + self._file.write('SSND') + self._ssnd_length_pos = self._file.tell() + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) + + def _write_form_length(self, datalength): + if self._aifc: + commlength = 18 + 5 + len(self._compname) + if commlength & 1: + commlength = commlength + 1 + verslength = 12 + else: + commlength = 18 + verslength = 0 + _write_ulong(self._file, 4 + verslength + self._marklength + \ + 8 + commlength + 16 + datalength) + return commlength + + def _patchheader(self): + curpos = self._file.tell() + if self._datawritten & 1: + datalength = self._datawritten + 1 + self._file.write(chr(0)) + else: + datalength = self._datawritten + if datalength == self._datalength and \ + self._nframes == self._nframeswritten and \ + self._marklength == 0: + self._file.seek(curpos, 0) + return + self._file.seek(self._form_length_pos, 0) + dummy = self._write_form_length(datalength) + self._file.seek(self._nframes_pos, 0) + _write_ulong(self._file, self._nframeswritten) + self._file.seek(self._ssnd_length_pos, 0) + _write_ulong(self._file, datalength + 8) + self._file.seek(curpos, 0) + self._nframes = self._nframeswritten + self._datalength = datalength + + def _writemarkers(self): + if len(self._markers) == 0: + return + self._file.write('MARK') + length = 2 + for marker in self._markers: + id, pos, name = marker + length = length + len(name) + 1 + 6 + if len(name) & 1 == 0: + length = length + 1 + _write_ulong(self._file, length) + self._marklength = length + 8 + _write_short(self._file, len(self._markers)) + for marker in self._markers: + id, pos, name = marker + _write_short(self._file, id) + _write_ulong(self._file, pos) + _write_string(self._file, name) + +def open(f, mode=None): + if mode is None: + if hasattr(f, 'mode'): + mode = f.mode + else: + mode = 'rb' + if mode in ('r', 'rb'): + return Aifc_read(f) + elif mode in ('w', 'wb'): + return Aifc_write(f) + else: + raise Error, "mode must be 'r', 'rb', 'w', or 'wb'" + +openfp = open # B/W compatibility + +if __name__ == '__main__': + import sys + if not sys.argv[1:]: + sys.argv.append('/usr/demos/data/audio/bach.aiff') + fn = sys.argv[1] + f = open(fn, 'r') + print "Reading", fn + print "nchannels =", f.getnchannels() + print "nframes =", f.getnframes() + print "sampwidth =", f.getsampwidth() + print "framerate =", f.getframerate() + print "comptype =", f.getcomptype() + print "compname =", f.getcompname() + if sys.argv[2:]: + gn = sys.argv[2] + print "Writing", gn + g = open(gn, 'w') + g.setparams(f.getparams()) + while 1: + data = f.readframes(1024) + if not data: + break + g.writeframes(data) + g.close() + f.close() + print "Done." diff --git a/src/main/resources/PythonLibs/anydbm.py b/src/main/resources/PythonLibs/anydbm.py new file mode 100644 index 0000000000000000000000000000000000000000..ba7e90510a0a523a53c81a0c9b168caf4a2da251 --- /dev/null +++ b/src/main/resources/PythonLibs/anydbm.py @@ -0,0 +1,85 @@ +"""Generic interface to all dbm clones. + +Instead of + + import dbm + d = dbm.open(file, 'w', 0666) + +use + + import anydbm + d = anydbm.open(file, 'w') + +The returned object is a dbhash, gdbm, dbm or dumbdbm object, +dependent on the type of database being opened (determined by whichdb +module) in the case of an existing dbm. If the dbm does not exist and +the create or new flag ('c' or 'n') was specified, the dbm type will +be determined by the availability of the modules (tested in the above +order). + +It has the following interface (key and data are strings): + + d[key] = data # store data at key (may override data at + # existing key) + data = d[key] # retrieve data at key (raise KeyError if no + # such key) + del d[key] # delete data stored at key (raises KeyError + # if no such key) + flag = key in d # true if the key exists + list = d.keys() # return a list of all existing keys (slow!) + +Future versions may change the order in which implementations are +tested for existence, and add interfaces to other dbm-like +implementations. +""" + +class error(Exception): + pass + +_names = ['dbhash', 'gdbm', 'dbm', 'dumbdbm'] +_errors = [error] +_defaultmod = None + +for _name in _names: + try: + _mod = __import__(_name) + except ImportError: + continue + if not _defaultmod: + _defaultmod = _mod + _errors.append(_mod.error) + +if not _defaultmod: + raise ImportError, "no dbm clone found; tried %s" % _names + +error = tuple(_errors) + +def open(file, flag='r', mode=0666): + """Open or create database at path given by *file*. + + Optional argument *flag* can be 'r' (default) for read-only access, 'w' + for read-write access of an existing database, 'c' for read-write access + to a new or existing database, and 'n' for read-write access to a new + database. + + Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it + only if it doesn't exist; and 'n' always creates a new database. + """ + + # guess the type of an existing database + from whichdb import whichdb + result=whichdb(file) + if result is None: + # db doesn't exist + if 'c' in flag or 'n' in flag: + # file doesn't exist and the new + # flag was used so use default type + mod = _defaultmod + else: + raise error, "need 'c' or 'n' flag to open new db" + elif result == "": + # db type cannot be determined + raise error, "db type could not be determined" + else: + mod = __import__(result) + return mod.open(file, flag, mode) diff --git a/src/main/resources/PythonLibs/argparse.py b/src/main/resources/PythonLibs/argparse.py new file mode 100644 index 0000000000000000000000000000000000000000..30bae57896c316501940247fa76512756ea08932 --- /dev/null +++ b/src/main/resources/PythonLibs/argparse.py @@ -0,0 +1,2361 @@ +# Author: Steven J. Bethard <steven.bethard@gmail.com>. + +"""Command-line parsing library + +This module is an optparse-inspired command-line parsing library that: + + - handles both optional and positional arguments + - produces highly informative usage messages + - supports parsers that dispatch to sub-parsers + +The following is a simple usage example that sums integers from the +command-line and writes the result to a file:: + + parser = argparse.ArgumentParser( + description='sum the integers at the command line') + parser.add_argument( + 'integers', metavar='int', nargs='+', type=int, + help='an integer to be summed') + parser.add_argument( + '--log', default=sys.stdout, type=argparse.FileType('w'), + help='the file where the sum should be written') + args = parser.parse_args() + args.log.write('%s' % sum(args.integers)) + args.log.close() + +The module contains the following public classes: + + - ArgumentParser -- The main entry point for command-line parsing. As the + example above shows, the add_argument() method is used to populate + the parser with actions for optional and positional arguments. Then + the parse_args() method is invoked to convert the args at the + command-line into an object with attributes. + + - ArgumentError -- The exception raised by ArgumentParser objects when + there are errors with the parser's actions. Errors raised while + parsing the command-line are caught by ArgumentParser and emitted + as command-line messages. + + - FileType -- A factory for defining types of files to be created. As the + example above shows, instances of FileType are typically passed as + the type= argument of add_argument() calls. + + - Action -- The base class for parser actions. Typically actions are + selected by passing strings like 'store_true' or 'append_const' to + the action= argument of add_argument(). However, for greater + customization of ArgumentParser actions, subclasses of Action may + be defined and passed as the action= argument. + + - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter, + ArgumentDefaultsHelpFormatter -- Formatter classes which + may be passed as the formatter_class= argument to the + ArgumentParser constructor. HelpFormatter is the default, + RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser + not to change the formatting for help text, and + ArgumentDefaultsHelpFormatter adds information about argument defaults + to the help. + +All other classes in this module are considered implementation details. +(Also note that HelpFormatter and RawDescriptionHelpFormatter are only +considered public as object names -- the API of the formatter objects is +still considered an implementation detail.) +""" + +__version__ = '1.1' +__all__ = [ + 'ArgumentParser', + 'ArgumentError', + 'ArgumentTypeError', + 'FileType', + 'HelpFormatter', + 'ArgumentDefaultsHelpFormatter', + 'RawDescriptionHelpFormatter', + 'RawTextHelpFormatter', + 'Namespace', + 'Action', + 'ONE_OR_MORE', + 'OPTIONAL', + 'PARSER', + 'REMAINDER', + 'SUPPRESS', + 'ZERO_OR_MORE', +] + + +import collections as _collections +import copy as _copy +import os as _os +import re as _re +import sys as _sys +import textwrap as _textwrap + +from gettext import gettext as _ + + +def _callable(obj): + return hasattr(obj, '__call__') or hasattr(obj, '__bases__') + + +SUPPRESS = '==SUPPRESS==' + +OPTIONAL = '?' +ZERO_OR_MORE = '*' +ONE_OR_MORE = '+' +PARSER = 'A...' +REMAINDER = '...' +_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args' + +# ============================= +# Utility functions and classes +# ============================= + +class _AttributeHolder(object): + """Abstract base class that provides __repr__. + + The __repr__ method returns a string in the format:: + ClassName(attr=name, attr=name, ...) + The attributes are determined either by a class-level attribute, + '_kwarg_names', or by inspecting the instance __dict__. + """ + + def __repr__(self): + type_name = type(self).__name__ + arg_strings = [] + for arg in self._get_args(): + arg_strings.append(repr(arg)) + for name, value in self._get_kwargs(): + arg_strings.append('%s=%r' % (name, value)) + return '%s(%s)' % (type_name, ', '.join(arg_strings)) + + def _get_kwargs(self): + return sorted(self.__dict__.items()) + + def _get_args(self): + return [] + + +def _ensure_value(namespace, name, value): + if getattr(namespace, name, None) is None: + setattr(namespace, name, value) + return getattr(namespace, name) + + +# =============== +# Formatting Help +# =============== + +class HelpFormatter(object): + """Formatter for generating usage messages and argument help strings. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def __init__(self, + prog, + indent_increment=2, + max_help_position=24, + width=None): + + # default setting for width + if width is None: + try: + width = int(_os.environ['COLUMNS']) + except (KeyError, ValueError): + width = 80 + width -= 2 + + self._prog = prog + self._indent_increment = indent_increment + self._max_help_position = max_help_position + self._width = width + + self._current_indent = 0 + self._level = 0 + self._action_max_length = 0 + + self._root_section = self._Section(self, None) + self._current_section = self._root_section + + self._whitespace_matcher = _re.compile(r'\s+') + self._long_break_matcher = _re.compile(r'\n\n\n+') + + # =============================== + # Section and indentation methods + # =============================== + def _indent(self): + self._current_indent += self._indent_increment + self._level += 1 + + def _dedent(self): + self._current_indent -= self._indent_increment + assert self._current_indent >= 0, 'Indent decreased below 0.' + self._level -= 1 + + class _Section(object): + + def __init__(self, formatter, parent, heading=None): + self.formatter = formatter + self.parent = parent + self.heading = heading + self.items = [] + + def format_help(self): + # format the indented section + if self.parent is not None: + self.formatter._indent() + join = self.formatter._join_parts + for func, args in self.items: + func(*args) + item_help = join([func(*args) for func, args in self.items]) + if self.parent is not None: + self.formatter._dedent() + + # return nothing if the section was empty + if not item_help: + return '' + + # add the heading if the section was non-empty + if self.heading is not SUPPRESS and self.heading is not None: + current_indent = self.formatter._current_indent + heading = '%*s%s:\n' % (current_indent, '', self.heading) + else: + heading = '' + + # join the section-initial newline, the heading and the help + return join(['\n', heading, item_help, '\n']) + + def _add_item(self, func, args): + self._current_section.items.append((func, args)) + + # ======================== + # Message building methods + # ======================== + def start_section(self, heading): + self._indent() + section = self._Section(self, self._current_section, heading) + self._add_item(section.format_help, []) + self._current_section = section + + def end_section(self): + self._current_section = self._current_section.parent + self._dedent() + + def add_text(self, text): + if text is not SUPPRESS and text is not None: + self._add_item(self._format_text, [text]) + + def add_usage(self, usage, actions, groups, prefix=None): + if usage is not SUPPRESS: + args = usage, actions, groups, prefix + self._add_item(self._format_usage, args) + + def add_argument(self, action): + if action.help is not SUPPRESS: + + # find all invocations + get_invocation = self._format_action_invocation + invocations = [get_invocation(action)] + for subaction in self._iter_indented_subactions(action): + invocations.append(get_invocation(subaction)) + + # update the maximum item length + invocation_length = max([len(s) for s in invocations]) + action_length = invocation_length + self._current_indent + self._action_max_length = max(self._action_max_length, + action_length) + + # add the item to the list + self._add_item(self._format_action, [action]) + + def add_arguments(self, actions): + for action in actions: + self.add_argument(action) + + # ======================= + # Help-formatting methods + # ======================= + def format_help(self): + help = self._root_section.format_help() + if help: + help = self._long_break_matcher.sub('\n\n', help) + help = help.strip('\n') + '\n' + return help + + def _join_parts(self, part_strings): + return ''.join([part + for part in part_strings + if part and part is not SUPPRESS]) + + def _format_usage(self, usage, actions, groups, prefix): + if prefix is None: + prefix = _('usage: ') + + # if usage is specified, use that + if usage is not None: + usage = usage % dict(prog=self._prog) + + # if no optionals or positionals are available, usage is just prog + elif usage is None and not actions: + usage = '%(prog)s' % dict(prog=self._prog) + + # if optionals and positionals are available, calculate usage + elif usage is None: + prog = '%(prog)s' % dict(prog=self._prog) + + # split optionals from positionals + optionals = [] + positionals = [] + for action in actions: + if action.option_strings: + optionals.append(action) + else: + positionals.append(action) + + # build full usage string + format = self._format_actions_usage + action_usage = format(optionals + positionals, groups) + usage = ' '.join([s for s in [prog, action_usage] if s]) + + # wrap the usage parts if it's too long + text_width = self._width - self._current_indent + if len(prefix) + len(usage) > text_width: + + # break usage into wrappable parts + part_regexp = r'\(.*?\)+|\[.*?\]+|\S+' + opt_usage = format(optionals, groups) + pos_usage = format(positionals, groups) + opt_parts = _re.findall(part_regexp, opt_usage) + pos_parts = _re.findall(part_regexp, pos_usage) + assert ' '.join(opt_parts) == opt_usage + assert ' '.join(pos_parts) == pos_usage + + # helper for wrapping lines + def get_lines(parts, indent, prefix=None): + lines = [] + line = [] + if prefix is not None: + line_len = len(prefix) - 1 + else: + line_len = len(indent) - 1 + for part in parts: + if line_len + 1 + len(part) > text_width: + lines.append(indent + ' '.join(line)) + line = [] + line_len = len(indent) - 1 + line.append(part) + line_len += len(part) + 1 + if line: + lines.append(indent + ' '.join(line)) + if prefix is not None: + lines[0] = lines[0][len(indent):] + return lines + + # if prog is short, follow it with optionals or positionals + if len(prefix) + len(prog) <= 0.75 * text_width: + indent = ' ' * (len(prefix) + len(prog) + 1) + if opt_parts: + lines = get_lines([prog] + opt_parts, indent, prefix) + lines.extend(get_lines(pos_parts, indent)) + elif pos_parts: + lines = get_lines([prog] + pos_parts, indent, prefix) + else: + lines = [prog] + + # if prog is long, put it on its own line + else: + indent = ' ' * len(prefix) + parts = opt_parts + pos_parts + lines = get_lines(parts, indent) + if len(lines) > 1: + lines = [] + lines.extend(get_lines(opt_parts, indent)) + lines.extend(get_lines(pos_parts, indent)) + lines = [prog] + lines + + # join lines into usage + usage = '\n'.join(lines) + + # prefix with 'usage:' + return '%s%s\n\n' % (prefix, usage) + + def _format_actions_usage(self, actions, groups): + # find group indices and identify actions in groups + group_actions = set() + inserts = {} + for group in groups: + try: + start = actions.index(group._group_actions[0]) + except ValueError: + continue + else: + end = start + len(group._group_actions) + if actions[start:end] == group._group_actions: + for action in group._group_actions: + group_actions.add(action) + if not group.required: + if start in inserts: + inserts[start] += ' [' + else: + inserts[start] = '[' + inserts[end] = ']' + else: + if start in inserts: + inserts[start] += ' (' + else: + inserts[start] = '(' + inserts[end] = ')' + for i in range(start + 1, end): + inserts[i] = '|' + + # collect all actions format strings + parts = [] + for i, action in enumerate(actions): + + # suppressed arguments are marked with None + # remove | separators for suppressed arguments + if action.help is SUPPRESS: + parts.append(None) + if inserts.get(i) == '|': + inserts.pop(i) + elif inserts.get(i + 1) == '|': + inserts.pop(i + 1) + + # produce all arg strings + elif not action.option_strings: + part = self._format_args(action, action.dest) + + # if it's in a group, strip the outer [] + if action in group_actions: + if part[0] == '[' and part[-1] == ']': + part = part[1:-1] + + # add the action string to the list + parts.append(part) + + # produce the first way to invoke the option in brackets + else: + option_string = action.option_strings[0] + + # if the Optional doesn't take a value, format is: + # -s or --long + if action.nargs == 0: + part = '%s' % option_string + + # if the Optional takes a value, format is: + # -s ARGS or --long ARGS + else: + default = action.dest.upper() + args_string = self._format_args(action, default) + part = '%s %s' % (option_string, args_string) + + # make it look optional if it's not required or in a group + if not action.required and action not in group_actions: + part = '[%s]' % part + + # add the action string to the list + parts.append(part) + + # insert things at the necessary indices + for i in sorted(inserts, reverse=True): + parts[i:i] = [inserts[i]] + + # join all the action items with spaces + text = ' '.join([item for item in parts if item is not None]) + + # clean up separators for mutually exclusive groups + open = r'[\[(]' + close = r'[\])]' + text = _re.sub(r'(%s) ' % open, r'\1', text) + text = _re.sub(r' (%s)' % close, r'\1', text) + text = _re.sub(r'%s *%s' % (open, close), r'', text) + text = _re.sub(r'\(([^|]*)\)', r'\1', text) + text = text.strip() + + # return the text + return text + + def _format_text(self, text): + if '%(prog)' in text: + text = text % dict(prog=self._prog) + text_width = self._width - self._current_indent + indent = ' ' * self._current_indent + return self._fill_text(text, text_width, indent) + '\n\n' + + def _format_action(self, action): + # determine the required width and the entry label + help_position = min(self._action_max_length + 2, + self._max_help_position) + help_width = self._width - help_position + action_width = help_position - self._current_indent - 2 + action_header = self._format_action_invocation(action) + + # ho nelp; start on same line and add a final newline + if not action.help: + tup = self._current_indent, '', action_header + action_header = '%*s%s\n' % tup + + # short action name; start on the same line and pad two spaces + elif len(action_header) <= action_width: + tup = self._current_indent, '', action_width, action_header + action_header = '%*s%-*s ' % tup + indent_first = 0 + + # long action name; start on the next line + else: + tup = self._current_indent, '', action_header + action_header = '%*s%s\n' % tup + indent_first = help_position + + # collect the pieces of the action help + parts = [action_header] + + # if there was help for the action, add lines of help text + if action.help: + help_text = self._expand_help(action) + help_lines = self._split_lines(help_text, help_width) + parts.append('%*s%s\n' % (indent_first, '', help_lines[0])) + for line in help_lines[1:]: + parts.append('%*s%s\n' % (help_position, '', line)) + + # or add a newline if the description doesn't end with one + elif not action_header.endswith('\n'): + parts.append('\n') + + # if there are any sub-actions, add their help as well + for subaction in self._iter_indented_subactions(action): + parts.append(self._format_action(subaction)) + + # return a single string + return self._join_parts(parts) + + def _format_action_invocation(self, action): + if not action.option_strings: + metavar, = self._metavar_formatter(action, action.dest)(1) + return metavar + + else: + parts = [] + + # if the Optional doesn't take a value, format is: + # -s, --long + if action.nargs == 0: + parts.extend(action.option_strings) + + # if the Optional takes a value, format is: + # -s ARGS, --long ARGS + else: + default = action.dest.upper() + args_string = self._format_args(action, default) + for option_string in action.option_strings: + parts.append('%s %s' % (option_string, args_string)) + + return ', '.join(parts) + + def _metavar_formatter(self, action, default_metavar): + if action.metavar is not None: + result = action.metavar + elif action.choices is not None: + choice_strs = [str(choice) for choice in action.choices] + result = '{%s}' % ','.join(choice_strs) + else: + result = default_metavar + + def format(tuple_size): + if isinstance(result, tuple): + return result + else: + return (result, ) * tuple_size + return format + + def _format_args(self, action, default_metavar): + get_metavar = self._metavar_formatter(action, default_metavar) + if action.nargs is None: + result = '%s' % get_metavar(1) + elif action.nargs == OPTIONAL: + result = '[%s]' % get_metavar(1) + elif action.nargs == ZERO_OR_MORE: + result = '[%s [%s ...]]' % get_metavar(2) + elif action.nargs == ONE_OR_MORE: + result = '%s [%s ...]' % get_metavar(2) + elif action.nargs == REMAINDER: + result = '...' + elif action.nargs == PARSER: + result = '%s ...' % get_metavar(1) + else: + formats = ['%s' for _ in range(action.nargs)] + result = ' '.join(formats) % get_metavar(action.nargs) + return result + + def _expand_help(self, action): + params = dict(vars(action), prog=self._prog) + for name in list(params): + if params[name] is SUPPRESS: + del params[name] + for name in list(params): + if hasattr(params[name], '__name__'): + params[name] = params[name].__name__ + if params.get('choices') is not None: + choices_str = ', '.join([str(c) for c in params['choices']]) + params['choices'] = choices_str + return self._get_help_string(action) % params + + def _iter_indented_subactions(self, action): + try: + get_subactions = action._get_subactions + except AttributeError: + pass + else: + self._indent() + for subaction in get_subactions(): + yield subaction + self._dedent() + + def _split_lines(self, text, width): + text = self._whitespace_matcher.sub(' ', text).strip() + return _textwrap.wrap(text, width) + + def _fill_text(self, text, width, indent): + text = self._whitespace_matcher.sub(' ', text).strip() + return _textwrap.fill(text, width, initial_indent=indent, + subsequent_indent=indent) + + def _get_help_string(self, action): + return action.help + + +class RawDescriptionHelpFormatter(HelpFormatter): + """Help message formatter which retains any formatting in descriptions. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def _fill_text(self, text, width, indent): + return ''.join([indent + line for line in text.splitlines(True)]) + + +class RawTextHelpFormatter(RawDescriptionHelpFormatter): + """Help message formatter which retains formatting of all help text. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def _split_lines(self, text, width): + return text.splitlines() + + +class ArgumentDefaultsHelpFormatter(HelpFormatter): + """Help message formatter which adds default values to argument help. + + Only the name of this class is considered a public API. All the methods + provided by the class are considered an implementation detail. + """ + + def _get_help_string(self, action): + help = action.help + if '%(default)' not in action.help: + if action.default is not SUPPRESS: + defaulting_nargs = [OPTIONAL, ZERO_OR_MORE] + if action.option_strings or action.nargs in defaulting_nargs: + help += ' (default: %(default)s)' + return help + + +# ===================== +# Options and Arguments +# ===================== + +def _get_action_name(argument): + if argument is None: + return None + elif argument.option_strings: + return '/'.join(argument.option_strings) + elif argument.metavar not in (None, SUPPRESS): + return argument.metavar + elif argument.dest not in (None, SUPPRESS): + return argument.dest + else: + return None + + +class ArgumentError(Exception): + """An error from creating or using an argument (optional or positional). + + The string value of this exception is the message, augmented with + information about the argument that caused it. + """ + + def __init__(self, argument, message): + self.argument_name = _get_action_name(argument) + self.message = message + + def __str__(self): + if self.argument_name is None: + format = '%(message)s' + else: + format = 'argument %(argument_name)s: %(message)s' + return format % dict(message=self.message, + argument_name=self.argument_name) + + +class ArgumentTypeError(Exception): + """An error from trying to convert a command line string to a type.""" + pass + + +# ============== +# Action classes +# ============== + +class Action(_AttributeHolder): + """Information about how to convert command line strings to Python objects. + + Action objects are used by an ArgumentParser to represent the information + needed to parse a single argument from one or more strings from the + command line. The keyword arguments to the Action constructor are also + all attributes of Action instances. + + Keyword Arguments: + + - option_strings -- A list of command-line option strings which + should be associated with this action. + + - dest -- The name of the attribute to hold the created object(s) + + - nargs -- The number of command-line arguments that should be + consumed. By default, one argument will be consumed and a single + value will be produced. Other values include: + - N (an integer) consumes N arguments (and produces a list) + - '?' consumes zero or one arguments + - '*' consumes zero or more arguments (and produces a list) + - '+' consumes one or more arguments (and produces a list) + Note that the difference between the default and nargs=1 is that + with the default, a single value will be produced, while with + nargs=1, a list containing a single value will be produced. + + - const -- The value to be produced if the option is specified and the + option uses an action that takes no values. + + - default -- The value to be produced if the option is not specified. + + - type -- A callable that accepts a single string argument, and + returns the converted value. The standard Python types str, int, + float, and complex are useful examples of such callables. If None, + str is used. + + - choices -- A container of values that should be allowed. If not None, + after a command-line argument has been converted to the appropriate + type, an exception will be raised if it is not a member of this + collection. + + - required -- True if the action must always be specified at the + command line. This is only meaningful for optional command-line + arguments. + + - help -- The help string describing the argument. + + - metavar -- The name to be used for the option's argument with the + help string. If None, the 'dest' value will be used as the name. + """ + + def __init__(self, + option_strings, + dest, + nargs=None, + const=None, + default=None, + type=None, + choices=None, + required=False, + help=None, + metavar=None): + self.option_strings = option_strings + self.dest = dest + self.nargs = nargs + self.const = const + self.default = default + self.type = type + self.choices = choices + self.required = required + self.help = help + self.metavar = metavar + + def _get_kwargs(self): + names = [ + 'option_strings', + 'dest', + 'nargs', + 'const', + 'default', + 'type', + 'choices', + 'help', + 'metavar', + ] + return [(name, getattr(self, name)) for name in names] + + def __call__(self, parser, namespace, values, option_string=None): + raise NotImplementedError(_('.__call__() not defined')) + + +class _StoreAction(Action): + + def __init__(self, + option_strings, + dest, + nargs=None, + const=None, + default=None, + type=None, + choices=None, + required=False, + help=None, + metavar=None): + if nargs == 0: + raise ValueError('nargs for store actions must be > 0; if you ' + 'have nothing to store, actions such as store ' + 'true or store const may be more appropriate') + if const is not None and nargs != OPTIONAL: + raise ValueError('nargs must be %r to supply const' % OPTIONAL) + super(_StoreAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=nargs, + const=const, + default=default, + type=type, + choices=choices, + required=required, + help=help, + metavar=metavar) + + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, values) + + +class _StoreConstAction(Action): + + def __init__(self, + option_strings, + dest, + const, + default=None, + required=False, + help=None, + metavar=None): + super(_StoreConstAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + const=const, + default=default, + required=required, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, self.const) + + +class _StoreTrueAction(_StoreConstAction): + + def __init__(self, + option_strings, + dest, + default=False, + required=False, + help=None): + super(_StoreTrueAction, self).__init__( + option_strings=option_strings, + dest=dest, + const=True, + default=default, + required=required, + help=help) + + +class _StoreFalseAction(_StoreConstAction): + + def __init__(self, + option_strings, + dest, + default=True, + required=False, + help=None): + super(_StoreFalseAction, self).__init__( + option_strings=option_strings, + dest=dest, + const=False, + default=default, + required=required, + help=help) + + +class _AppendAction(Action): + + def __init__(self, + option_strings, + dest, + nargs=None, + const=None, + default=None, + type=None, + choices=None, + required=False, + help=None, + metavar=None): + if nargs == 0: + raise ValueError('nargs for append actions must be > 0; if arg ' + 'strings are not supplying the value to append, ' + 'the append const action may be more appropriate') + if const is not None and nargs != OPTIONAL: + raise ValueError('nargs must be %r to supply const' % OPTIONAL) + super(_AppendAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=nargs, + const=const, + default=default, + type=type, + choices=choices, + required=required, + help=help, + metavar=metavar) + + def __call__(self, parser, namespace, values, option_string=None): + items = _copy.copy(_ensure_value(namespace, self.dest, [])) + items.append(values) + setattr(namespace, self.dest, items) + + +class _AppendConstAction(Action): + + def __init__(self, + option_strings, + dest, + const, + default=None, + required=False, + help=None, + metavar=None): + super(_AppendConstAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + const=const, + default=default, + required=required, + help=help, + metavar=metavar) + + def __call__(self, parser, namespace, values, option_string=None): + items = _copy.copy(_ensure_value(namespace, self.dest, [])) + items.append(self.const) + setattr(namespace, self.dest, items) + + +class _CountAction(Action): + + def __init__(self, + option_strings, + dest, + default=None, + required=False, + help=None): + super(_CountAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=0, + default=default, + required=required, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + new_count = _ensure_value(namespace, self.dest, 0) + 1 + setattr(namespace, self.dest, new_count) + + +class _HelpAction(Action): + + def __init__(self, + option_strings, + dest=SUPPRESS, + default=SUPPRESS, + help=None): + super(_HelpAction, self).__init__( + option_strings=option_strings, + dest=dest, + default=default, + nargs=0, + help=help) + + def __call__(self, parser, namespace, values, option_string=None): + parser.print_help() + parser.exit() + + +class _VersionAction(Action): + + def __init__(self, + option_strings, + version=None, + dest=SUPPRESS, + default=SUPPRESS, + help="show program's version number and exit"): + super(_VersionAction, self).__init__( + option_strings=option_strings, + dest=dest, + default=default, + nargs=0, + help=help) + self.version = version + + def __call__(self, parser, namespace, values, option_string=None): + version = self.version + if version is None: + version = parser.version + formatter = parser._get_formatter() + formatter.add_text(version) + parser.exit(message=formatter.format_help()) + + +class _SubParsersAction(Action): + + class _ChoicesPseudoAction(Action): + + def __init__(self, name, help): + sup = super(_SubParsersAction._ChoicesPseudoAction, self) + sup.__init__(option_strings=[], dest=name, help=help) + + def __init__(self, + option_strings, + prog, + parser_class, + dest=SUPPRESS, + help=None, + metavar=None): + + self._prog_prefix = prog + self._parser_class = parser_class + self._name_parser_map = _collections.OrderedDict() + self._choices_actions = [] + + super(_SubParsersAction, self).__init__( + option_strings=option_strings, + dest=dest, + nargs=PARSER, + choices=self._name_parser_map, + help=help, + metavar=metavar) + + def add_parser(self, name, **kwargs): + # set prog from the existing prefix + if kwargs.get('prog') is None: + kwargs['prog'] = '%s %s' % (self._prog_prefix, name) + + # create a pseudo-action to hold the choice help + if 'help' in kwargs: + help = kwargs.pop('help') + choice_action = self._ChoicesPseudoAction(name, help) + self._choices_actions.append(choice_action) + + # create the parser and add it to the map + parser = self._parser_class(**kwargs) + self._name_parser_map[name] = parser + return parser + + def _get_subactions(self): + return self._choices_actions + + def __call__(self, parser, namespace, values, option_string=None): + parser_name = values[0] + arg_strings = values[1:] + + # set the parser name if requested + if self.dest is not SUPPRESS: + setattr(namespace, self.dest, parser_name) + + # select the parser + try: + parser = self._name_parser_map[parser_name] + except KeyError: + tup = parser_name, ', '.join(self._name_parser_map) + msg = _('unknown parser %r (choices: %s)') % tup + raise ArgumentError(self, msg) + + # parse all the remaining options into the namespace + # store any unrecognized options on the object, so that the top + # level parser can decide what to do with them + namespace, arg_strings = parser.parse_known_args(arg_strings, namespace) + if arg_strings: + vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) + getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) + + +# ============== +# Type classes +# ============== + +class FileType(object): + """Factory for creating file object types + + Instances of FileType are typically passed as type= arguments to the + ArgumentParser add_argument() method. + + Keyword Arguments: + - mode -- A string indicating how the file is to be opened. Accepts the + same values as the builtin open() function. + - bufsize -- The file's desired buffer size. Accepts the same values as + the builtin open() function. + """ + + def __init__(self, mode='r', bufsize=-1): + self._mode = mode + self._bufsize = bufsize + + def __call__(self, string): + # the special argument "-" means sys.std{in,out} + if string == '-': + if 'r' in self._mode: + return _sys.stdin + elif 'w' in self._mode: + return _sys.stdout + else: + msg = _('argument "-" with mode %r') % self._mode + raise ValueError(msg) + + # all other arguments are used as file names + try: + return open(string, self._mode, self._bufsize) + except IOError as e: + message = _("can't open '%s': %s") + raise ArgumentTypeError(message % (string, e)) + + def __repr__(self): + args = self._mode, self._bufsize + args_str = ', '.join(repr(arg) for arg in args if arg != -1) + return '%s(%s)' % (type(self).__name__, args_str) + +# =========================== +# Optional and Positional Parsing +# =========================== + +class Namespace(_AttributeHolder): + """Simple object for storing attributes. + + Implements equality by attribute names and values, and provides a simple + string representation. + """ + + def __init__(self, **kwargs): + for name in kwargs: + setattr(self, name, kwargs[name]) + + __hash__ = None + + def __eq__(self, other): + return vars(self) == vars(other) + + def __ne__(self, other): + return not (self == other) + + def __contains__(self, key): + return key in self.__dict__ + + +class _ActionsContainer(object): + + def __init__(self, + description, + prefix_chars, + argument_default, + conflict_handler): + super(_ActionsContainer, self).__init__() + + self.description = description + self.argument_default = argument_default + self.prefix_chars = prefix_chars + self.conflict_handler = conflict_handler + + # set up registries + self._registries = {} + + # register actions + self.register('action', None, _StoreAction) + self.register('action', 'store', _StoreAction) + self.register('action', 'store_const', _StoreConstAction) + self.register('action', 'store_true', _StoreTrueAction) + self.register('action', 'store_false', _StoreFalseAction) + self.register('action', 'append', _AppendAction) + self.register('action', 'append_const', _AppendConstAction) + self.register('action', 'count', _CountAction) + self.register('action', 'help', _HelpAction) + self.register('action', 'version', _VersionAction) + self.register('action', 'parsers', _SubParsersAction) + + # raise an exception if the conflict handler is invalid + self._get_handler() + + # action storage + self._actions = [] + self._option_string_actions = {} + + # groups + self._action_groups = [] + self._mutually_exclusive_groups = [] + + # defaults storage + self._defaults = {} + + # determines whether an "option" looks like a negative number + self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$') + + # whether or not there are any optionals that look like negative + # numbers -- uses a list so it can be shared and edited + self._has_negative_number_optionals = [] + + # ==================== + # Registration methods + # ==================== + def register(self, registry_name, value, object): + registry = self._registries.setdefault(registry_name, {}) + registry[value] = object + + def _registry_get(self, registry_name, value, default=None): + return self._registries[registry_name].get(value, default) + + # ================================== + # Namespace default accessor methods + # ================================== + def set_defaults(self, **kwargs): + self._defaults.update(kwargs) + + # if these defaults match any existing arguments, replace + # the previous default on the object with the new one + for action in self._actions: + if action.dest in kwargs: + action.default = kwargs[action.dest] + + def get_default(self, dest): + for action in self._actions: + if action.dest == dest and action.default is not None: + return action.default + return self._defaults.get(dest, None) + + + # ======================= + # Adding argument actions + # ======================= + def add_argument(self, *args, **kwargs): + """ + add_argument(dest, ..., name=value, ...) + add_argument(option_string, option_string, ..., name=value, ...) + """ + + # if no positional args are supplied or only one is supplied and + # it doesn't look like an option string, parse a positional + # argument + chars = self.prefix_chars + if not args or len(args) == 1 and args[0][0] not in chars: + if args and 'dest' in kwargs: + raise ValueError('dest supplied twice for positional argument') + kwargs = self._get_positional_kwargs(*args, **kwargs) + + # otherwise, we're adding an optional argument + else: + kwargs = self._get_optional_kwargs(*args, **kwargs) + + # if no default was supplied, use the parser-level default + if 'default' not in kwargs: + dest = kwargs['dest'] + if dest in self._defaults: + kwargs['default'] = self._defaults[dest] + elif self.argument_default is not None: + kwargs['default'] = self.argument_default + + # create the action object, and add it to the parser + action_class = self._pop_action_class(kwargs) + if not _callable(action_class): + raise ValueError('unknown action "%s"' % (action_class,)) + action = action_class(**kwargs) + + # raise an error if the action type is not callable + type_func = self._registry_get('type', action.type, action.type) + if not _callable(type_func): + raise ValueError('%r is not callable' % (type_func,)) + + # raise an error if the metavar does not match the type + if hasattr(self, "_get_formatter"): + try: + self._get_formatter()._format_args(action, None) + except TypeError: + raise ValueError("length of metavar tuple does not match nargs") + + return self._add_action(action) + + def add_argument_group(self, *args, **kwargs): + group = _ArgumentGroup(self, *args, **kwargs) + self._action_groups.append(group) + return group + + def add_mutually_exclusive_group(self, **kwargs): + group = _MutuallyExclusiveGroup(self, **kwargs) + self._mutually_exclusive_groups.append(group) + return group + + def _add_action(self, action): + # resolve any conflicts + self._check_conflict(action) + + # add to actions list + self._actions.append(action) + action.container = self + + # index the action by any option strings it has + for option_string in action.option_strings: + self._option_string_actions[option_string] = action + + # set the flag if any option strings look like negative numbers + for option_string in action.option_strings: + if self._negative_number_matcher.match(option_string): + if not self._has_negative_number_optionals: + self._has_negative_number_optionals.append(True) + + # return the created action + return action + + def _remove_action(self, action): + self._actions.remove(action) + + def _add_container_actions(self, container): + # collect groups by titles + title_group_map = {} + for group in self._action_groups: + if group.title in title_group_map: + msg = _('cannot merge actions - two groups are named %r') + raise ValueError(msg % (group.title)) + title_group_map[group.title] = group + + # map each action to its group + group_map = {} + for group in container._action_groups: + + # if a group with the title exists, use that, otherwise + # create a new group matching the container's group + if group.title not in title_group_map: + title_group_map[group.title] = self.add_argument_group( + title=group.title, + description=group.description, + conflict_handler=group.conflict_handler) + + # map the actions to their new group + for action in group._group_actions: + group_map[action] = title_group_map[group.title] + + # add container's mutually exclusive groups + # NOTE: if add_mutually_exclusive_group ever gains title= and + # description= then this code will need to be expanded as above + for group in container._mutually_exclusive_groups: + mutex_group = self.add_mutually_exclusive_group( + required=group.required) + + # map the actions to their new mutex group + for action in group._group_actions: + group_map[action] = mutex_group + + # add all actions to this container or their group + for action in container._actions: + group_map.get(action, self)._add_action(action) + + def _get_positional_kwargs(self, dest, **kwargs): + # make sure required is not specified + if 'required' in kwargs: + msg = _("'required' is an invalid argument for positionals") + raise TypeError(msg) + + # mark positional arguments as required if at least one is + # always required + if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]: + kwargs['required'] = True + if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs: + kwargs['required'] = True + + # return the keyword arguments with no option strings + return dict(kwargs, dest=dest, option_strings=[]) + + def _get_optional_kwargs(self, *args, **kwargs): + # determine short and long option strings + option_strings = [] + long_option_strings = [] + for option_string in args: + # error on strings that don't start with an appropriate prefix + if not option_string[0] in self.prefix_chars: + msg = _('invalid option string %r: ' + 'must start with a character %r') + tup = option_string, self.prefix_chars + raise ValueError(msg % tup) + + # strings starting with two prefix characters are long options + option_strings.append(option_string) + if option_string[0] in self.prefix_chars: + if len(option_string) > 1: + if option_string[1] in self.prefix_chars: + long_option_strings.append(option_string) + + # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x' + dest = kwargs.pop('dest', None) + if dest is None: + if long_option_strings: + dest_option_string = long_option_strings[0] + else: + dest_option_string = option_strings[0] + dest = dest_option_string.lstrip(self.prefix_chars) + if not dest: + msg = _('dest= is required for options like %r') + raise ValueError(msg % option_string) + dest = dest.replace('-', '_') + + # return the updated keyword arguments + return dict(kwargs, dest=dest, option_strings=option_strings) + + def _pop_action_class(self, kwargs, default=None): + action = kwargs.pop('action', default) + return self._registry_get('action', action, action) + + def _get_handler(self): + # determine function from conflict handler string + handler_func_name = '_handle_conflict_%s' % self.conflict_handler + try: + return getattr(self, handler_func_name) + except AttributeError: + msg = _('invalid conflict_resolution value: %r') + raise ValueError(msg % self.conflict_handler) + + def _check_conflict(self, action): + + # find all options that conflict with this option + confl_optionals = [] + for option_string in action.option_strings: + if option_string in self._option_string_actions: + confl_optional = self._option_string_actions[option_string] + confl_optionals.append((option_string, confl_optional)) + + # resolve any conflicts + if confl_optionals: + conflict_handler = self._get_handler() + conflict_handler(action, confl_optionals) + + def _handle_conflict_error(self, action, conflicting_actions): + message = _('conflicting option string(s): %s') + conflict_string = ', '.join([option_string + for option_string, action + in conflicting_actions]) + raise ArgumentError(action, message % conflict_string) + + def _handle_conflict_resolve(self, action, conflicting_actions): + + # remove all conflicting options + for option_string, action in conflicting_actions: + + # remove the conflicting option + action.option_strings.remove(option_string) + self._option_string_actions.pop(option_string, None) + + # if the option now has no option string, remove it from the + # container holding it + if not action.option_strings: + action.container._remove_action(action) + + +class _ArgumentGroup(_ActionsContainer): + + def __init__(self, container, title=None, description=None, **kwargs): + # add any missing keyword arguments by checking the container + update = kwargs.setdefault + update('conflict_handler', container.conflict_handler) + update('prefix_chars', container.prefix_chars) + update('argument_default', container.argument_default) + super_init = super(_ArgumentGroup, self).__init__ + super_init(description=description, **kwargs) + + # group attributes + self.title = title + self._group_actions = [] + + # share most attributes with the container + self._registries = container._registries + self._actions = container._actions + self._option_string_actions = container._option_string_actions + self._defaults = container._defaults + self._has_negative_number_optionals = \ + container._has_negative_number_optionals + self._mutually_exclusive_groups = container._mutually_exclusive_groups + + def _add_action(self, action): + action = super(_ArgumentGroup, self)._add_action(action) + self._group_actions.append(action) + return action + + def _remove_action(self, action): + super(_ArgumentGroup, self)._remove_action(action) + self._group_actions.remove(action) + + +class _MutuallyExclusiveGroup(_ArgumentGroup): + + def __init__(self, container, required=False): + super(_MutuallyExclusiveGroup, self).__init__(container) + self.required = required + self._container = container + + def _add_action(self, action): + if action.required: + msg = _('mutually exclusive arguments must be optional') + raise ValueError(msg) + action = self._container._add_action(action) + self._group_actions.append(action) + return action + + def _remove_action(self, action): + self._container._remove_action(action) + self._group_actions.remove(action) + + +class ArgumentParser(_AttributeHolder, _ActionsContainer): + """Object for parsing command line strings into Python objects. + + Keyword Arguments: + - prog -- The name of the program (default: sys.argv[0]) + - usage -- A usage message (default: auto-generated from arguments) + - description -- A description of what the program does + - epilog -- Text following the argument descriptions + - parents -- Parsers whose arguments should be copied into this one + - formatter_class -- HelpFormatter class for printing help messages + - prefix_chars -- Characters that prefix optional arguments + - fromfile_prefix_chars -- Characters that prefix files containing + additional arguments + - argument_default -- The default value for all arguments + - conflict_handler -- String indicating how to handle conflicts + - add_help -- Add a -h/-help option + """ + + def __init__(self, + prog=None, + usage=None, + description=None, + epilog=None, + version=None, + parents=[], + formatter_class=HelpFormatter, + prefix_chars='-', + fromfile_prefix_chars=None, + argument_default=None, + conflict_handler='error', + add_help=True): + + if version is not None: + import warnings + warnings.warn( + """The "version" argument to ArgumentParser is deprecated. """ + """Please use """ + """"add_argument(..., action='version', version="N", ...)" """ + """instead""", DeprecationWarning) + + superinit = super(ArgumentParser, self).__init__ + superinit(description=description, + prefix_chars=prefix_chars, + argument_default=argument_default, + conflict_handler=conflict_handler) + + # default setting for prog + if prog is None: + prog = _os.path.basename(_sys.argv[0]) + + self.prog = prog + self.usage = usage + self.epilog = epilog + self.version = version + self.formatter_class = formatter_class + self.fromfile_prefix_chars = fromfile_prefix_chars + self.add_help = add_help + + add_group = self.add_argument_group + self._positionals = add_group(_('positional arguments')) + self._optionals = add_group(_('optional arguments')) + self._subparsers = None + + # register types + def identity(string): + return string + self.register('type', None, identity) + + # add help and version arguments if necessary + # (using explicit default to override global argument_default) + default_prefix = '-' if '-' in prefix_chars else prefix_chars[0] + if self.add_help: + self.add_argument( + default_prefix+'h', default_prefix*2+'help', + action='help', default=SUPPRESS, + help=_('show this help message and exit')) + if self.version: + self.add_argument( + default_prefix+'v', default_prefix*2+'version', + action='version', default=SUPPRESS, + version=self.version, + help=_("show program's version number and exit")) + + # add parent arguments and defaults + for parent in parents: + self._add_container_actions(parent) + try: + defaults = parent._defaults + except AttributeError: + pass + else: + self._defaults.update(defaults) + + # ======================= + # Pretty __repr__ methods + # ======================= + def _get_kwargs(self): + names = [ + 'prog', + 'usage', + 'description', + 'version', + 'formatter_class', + 'conflict_handler', + 'add_help', + ] + return [(name, getattr(self, name)) for name in names] + + # ================================== + # Optional/Positional adding methods + # ================================== + def add_subparsers(self, **kwargs): + if self._subparsers is not None: + self.error(_('cannot have multiple subparser arguments')) + + # add the parser class to the arguments if it's not present + kwargs.setdefault('parser_class', type(self)) + + if 'title' in kwargs or 'description' in kwargs: + title = _(kwargs.pop('title', 'subcommands')) + description = _(kwargs.pop('description', None)) + self._subparsers = self.add_argument_group(title, description) + else: + self._subparsers = self._positionals + + # prog defaults to the usage message of this parser, skipping + # optional arguments and with no "usage:" prefix + if kwargs.get('prog') is None: + formatter = self._get_formatter() + positionals = self._get_positional_actions() + groups = self._mutually_exclusive_groups + formatter.add_usage(self.usage, positionals, groups, '') + kwargs['prog'] = formatter.format_help().strip() + + # create the parsers action and add it to the positionals list + parsers_class = self._pop_action_class(kwargs, 'parsers') + action = parsers_class(option_strings=[], **kwargs) + self._subparsers._add_action(action) + + # return the created parsers action + return action + + def _add_action(self, action): + if action.option_strings: + self._optionals._add_action(action) + else: + self._positionals._add_action(action) + return action + + def _get_optional_actions(self): + return [action + for action in self._actions + if action.option_strings] + + def _get_positional_actions(self): + return [action + for action in self._actions + if not action.option_strings] + + # ===================================== + # Command line argument parsing methods + # ===================================== + def parse_args(self, args=None, namespace=None): + args, argv = self.parse_known_args(args, namespace) + if argv: + msg = _('unrecognized arguments: %s') + self.error(msg % ' '.join(argv)) + return args + + def parse_known_args(self, args=None, namespace=None): + if args is None: + # args default to the system args + args = _sys.argv[1:] + else: + # make sure that args are mutable + args = list(args) + + # default Namespace built from parser defaults + if namespace is None: + namespace = Namespace() + + # add any action defaults that aren't present + for action in self._actions: + if action.dest is not SUPPRESS: + if not hasattr(namespace, action.dest): + if action.default is not SUPPRESS: + setattr(namespace, action.dest, action.default) + + # add any parser defaults that aren't present + for dest in self._defaults: + if not hasattr(namespace, dest): + setattr(namespace, dest, self._defaults[dest]) + + # parse the arguments and exit if there are any errors + try: + namespace, args = self._parse_known_args(args, namespace) + if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR): + args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) + delattr(namespace, _UNRECOGNIZED_ARGS_ATTR) + return namespace, args + except ArgumentError: + err = _sys.exc_info()[1] + self.error(str(err)) + + def _parse_known_args(self, arg_strings, namespace): + # replace arg strings that are file references + if self.fromfile_prefix_chars is not None: + arg_strings = self._read_args_from_files(arg_strings) + + # map all mutually exclusive arguments to the other arguments + # they can't occur with + action_conflicts = {} + for mutex_group in self._mutually_exclusive_groups: + group_actions = mutex_group._group_actions + for i, mutex_action in enumerate(mutex_group._group_actions): + conflicts = action_conflicts.setdefault(mutex_action, []) + conflicts.extend(group_actions[:i]) + conflicts.extend(group_actions[i + 1:]) + + # find all option indices, and determine the arg_string_pattern + # which has an 'O' if there is an option at an index, + # an 'A' if there is an argument, or a '-' if there is a '--' + option_string_indices = {} + arg_string_pattern_parts = [] + arg_strings_iter = iter(arg_strings) + for i, arg_string in enumerate(arg_strings_iter): + + # all args after -- are non-options + if arg_string == '--': + arg_string_pattern_parts.append('-') + for arg_string in arg_strings_iter: + arg_string_pattern_parts.append('A') + + # otherwise, add the arg to the arg strings + # and note the index if it was an option + else: + option_tuple = self._parse_optional(arg_string) + if option_tuple is None: + pattern = 'A' + else: + option_string_indices[i] = option_tuple + pattern = 'O' + arg_string_pattern_parts.append(pattern) + + # join the pieces together to form the pattern + arg_strings_pattern = ''.join(arg_string_pattern_parts) + + # converts arg strings to the appropriate and then takes the action + seen_actions = set() + seen_non_default_actions = set() + + def take_action(action, argument_strings, option_string=None): + seen_actions.add(action) + argument_values = self._get_values(action, argument_strings) + + # error if this argument is not allowed with other previously + # seen arguments, assuming that actions that use the default + # value don't really count as "present" + if argument_values is not action.default: + seen_non_default_actions.add(action) + for conflict_action in action_conflicts.get(action, []): + if conflict_action in seen_non_default_actions: + msg = _('not allowed with argument %s') + action_name = _get_action_name(conflict_action) + raise ArgumentError(action, msg % action_name) + + # take the action if we didn't receive a SUPPRESS value + # (e.g. from a default) + if argument_values is not SUPPRESS: + action(self, namespace, argument_values, option_string) + + # function to convert arg_strings into an optional action + def consume_optional(start_index): + + # get the optional identified at this index + option_tuple = option_string_indices[start_index] + action, option_string, explicit_arg = option_tuple + + # identify additional optionals in the same arg string + # (e.g. -xyz is the same as -x -y -z if no args are required) + match_argument = self._match_argument + action_tuples = [] + while True: + + # if we found no optional action, skip it + if action is None: + extras.append(arg_strings[start_index]) + return start_index + 1 + + # if there is an explicit argument, try to match the + # optional's string arguments to only this + if explicit_arg is not None: + arg_count = match_argument(action, 'A') + + # if the action is a single-dash option and takes no + # arguments, try to parse more single-dash options out + # of the tail of the option string + chars = self.prefix_chars + if arg_count == 0 and option_string[1] not in chars: + action_tuples.append((action, [], option_string)) + char = option_string[0] + option_string = char + explicit_arg[0] + new_explicit_arg = explicit_arg[1:] or None + optionals_map = self._option_string_actions + if option_string in optionals_map: + action = optionals_map[option_string] + explicit_arg = new_explicit_arg + else: + msg = _('ignored explicit argument %r') + raise ArgumentError(action, msg % explicit_arg) + + # if the action expect exactly one argument, we've + # successfully matched the option; exit the loop + elif arg_count == 1: + stop = start_index + 1 + args = [explicit_arg] + action_tuples.append((action, args, option_string)) + break + + # error if a double-dash option did not use the + # explicit argument + else: + msg = _('ignored explicit argument %r') + raise ArgumentError(action, msg % explicit_arg) + + # if there is no explicit argument, try to match the + # optional's string arguments with the following strings + # if successful, exit the loop + else: + start = start_index + 1 + selected_patterns = arg_strings_pattern[start:] + arg_count = match_argument(action, selected_patterns) + stop = start + arg_count + args = arg_strings[start:stop] + action_tuples.append((action, args, option_string)) + break + + # add the Optional to the list and return the index at which + # the Optional's string args stopped + assert action_tuples + for action, args, option_string in action_tuples: + take_action(action, args, option_string) + return stop + + # the list of Positionals left to be parsed; this is modified + # by consume_positionals() + positionals = self._get_positional_actions() + + # function to convert arg_strings into positional actions + def consume_positionals(start_index): + # match as many Positionals as possible + match_partial = self._match_arguments_partial + selected_pattern = arg_strings_pattern[start_index:] + arg_counts = match_partial(positionals, selected_pattern) + + # slice off the appropriate arg strings for each Positional + # and add the Positional and its args to the list + for action, arg_count in zip(positionals, arg_counts): + args = arg_strings[start_index: start_index + arg_count] + start_index += arg_count + take_action(action, args) + + # slice off the Positionals that we just parsed and return the + # index at which the Positionals' string args stopped + positionals[:] = positionals[len(arg_counts):] + return start_index + + # consume Positionals and Optionals alternately, until we have + # passed the last option string + extras = [] + start_index = 0 + if option_string_indices: + max_option_string_index = max(option_string_indices) + else: + max_option_string_index = -1 + while start_index <= max_option_string_index: + + # consume any Positionals preceding the next option + next_option_string_index = min([ + index + for index in option_string_indices + if index >= start_index]) + if start_index != next_option_string_index: + positionals_end_index = consume_positionals(start_index) + + # only try to parse the next optional if we didn't consume + # the option string during the positionals parsing + if positionals_end_index > start_index: + start_index = positionals_end_index + continue + else: + start_index = positionals_end_index + + # if we consumed all the positionals we could and we're not + # at the index of an option string, there were extra arguments + if start_index not in option_string_indices: + strings = arg_strings[start_index:next_option_string_index] + extras.extend(strings) + start_index = next_option_string_index + + # consume the next optional and any arguments for it + start_index = consume_optional(start_index) + + # consume any positionals following the last Optional + stop_index = consume_positionals(start_index) + + # if we didn't consume all the argument strings, there were extras + extras.extend(arg_strings[stop_index:]) + + # if we didn't use all the Positional objects, there were too few + # arg strings supplied. + if positionals: + self.error(_('too few arguments')) + + # make sure all required actions were present, and convert defaults. + for action in self._actions: + if action not in seen_actions: + if action.required: + name = _get_action_name(action) + self.error(_('argument %s is required') % name) + else: + # Convert action default now instead of doing it before + # parsing arguments to avoid calling convert functions + # twice (which may fail) if the argument was given, but + # only if it was defined already in the namespace + if (action.default is not None and + isinstance(action.default, basestring) and + hasattr(namespace, action.dest) and + action.default is getattr(namespace, action.dest)): + setattr(namespace, action.dest, + self._get_value(action, action.default)) + + # make sure all required groups had one option present + for group in self._mutually_exclusive_groups: + if group.required: + for action in group._group_actions: + if action in seen_non_default_actions: + break + + # if no actions were used, report the error + else: + names = [_get_action_name(action) + for action in group._group_actions + if action.help is not SUPPRESS] + msg = _('one of the arguments %s is required') + self.error(msg % ' '.join(names)) + + # return the updated namespace and the extra arguments + return namespace, extras + + def _read_args_from_files(self, arg_strings): + # expand arguments referencing files + new_arg_strings = [] + for arg_string in arg_strings: + + # for regular arguments, just add them back into the list + if not arg_string or arg_string[0] not in self.fromfile_prefix_chars: + new_arg_strings.append(arg_string) + + # replace arguments referencing files with the file content + else: + try: + args_file = open(arg_string[1:]) + try: + arg_strings = [] + for arg_line in args_file.read().splitlines(): + for arg in self.convert_arg_line_to_args(arg_line): + arg_strings.append(arg) + arg_strings = self._read_args_from_files(arg_strings) + new_arg_strings.extend(arg_strings) + finally: + args_file.close() + except IOError: + err = _sys.exc_info()[1] + self.error(str(err)) + + # return the modified argument list + return new_arg_strings + + def convert_arg_line_to_args(self, arg_line): + return [arg_line] + + def _match_argument(self, action, arg_strings_pattern): + # match the pattern for this action to the arg strings + nargs_pattern = self._get_nargs_pattern(action) + match = _re.match(nargs_pattern, arg_strings_pattern) + + # raise an exception if we weren't able to find a match + if match is None: + nargs_errors = { + None: _('expected one argument'), + OPTIONAL: _('expected at most one argument'), + ONE_OR_MORE: _('expected at least one argument'), + } + default = _('expected %s argument(s)') % action.nargs + msg = nargs_errors.get(action.nargs, default) + raise ArgumentError(action, msg) + + # return the number of arguments matched + return len(match.group(1)) + + def _match_arguments_partial(self, actions, arg_strings_pattern): + # progressively shorten the actions list by slicing off the + # final actions until we find a match + result = [] + for i in range(len(actions), 0, -1): + actions_slice = actions[:i] + pattern = ''.join([self._get_nargs_pattern(action) + for action in actions_slice]) + match = _re.match(pattern, arg_strings_pattern) + if match is not None: + result.extend([len(string) for string in match.groups()]) + break + + # return the list of arg string counts + return result + + def _parse_optional(self, arg_string): + # if it's an empty string, it was meant to be a positional + if not arg_string: + return None + + # if it doesn't start with a prefix, it was meant to be positional + if not arg_string[0] in self.prefix_chars: + return None + + # if the option string is present in the parser, return the action + if arg_string in self._option_string_actions: + action = self._option_string_actions[arg_string] + return action, arg_string, None + + # if it's just a single character, it was meant to be positional + if len(arg_string) == 1: + return None + + # if the option string before the "=" is present, return the action + if '=' in arg_string: + option_string, explicit_arg = arg_string.split('=', 1) + if option_string in self._option_string_actions: + action = self._option_string_actions[option_string] + return action, option_string, explicit_arg + + # search through all possible prefixes of the option string + # and all actions in the parser for possible interpretations + option_tuples = self._get_option_tuples(arg_string) + + # if multiple actions match, the option string was ambiguous + if len(option_tuples) > 1: + options = ', '.join([option_string + for action, option_string, explicit_arg in option_tuples]) + tup = arg_string, options + self.error(_('ambiguous option: %s could match %s') % tup) + + # if exactly one action matched, this segmentation is good, + # so return the parsed action + elif len(option_tuples) == 1: + option_tuple, = option_tuples + return option_tuple + + # if it was not found as an option, but it looks like a negative + # number, it was meant to be positional + # unless there are negative-number-like options + if self._negative_number_matcher.match(arg_string): + if not self._has_negative_number_optionals: + return None + + # if it contains a space, it was meant to be a positional + if ' ' in arg_string: + return None + + # it was meant to be an optional but there is no such option + # in this parser (though it might be a valid option in a subparser) + return None, arg_string, None + + def _get_option_tuples(self, option_string): + result = [] + + # option strings starting with two prefix characters are only + # split at the '=' + chars = self.prefix_chars + if option_string[0] in chars and option_string[1] in chars: + if '=' in option_string: + option_prefix, explicit_arg = option_string.split('=', 1) + else: + option_prefix = option_string + explicit_arg = None + for option_string in self._option_string_actions: + if option_string.startswith(option_prefix): + action = self._option_string_actions[option_string] + tup = action, option_string, explicit_arg + result.append(tup) + + # single character options can be concatenated with their arguments + # but multiple character options always have to have their argument + # separate + elif option_string[0] in chars and option_string[1] not in chars: + option_prefix = option_string + explicit_arg = None + short_option_prefix = option_string[:2] + short_explicit_arg = option_string[2:] + + for option_string in self._option_string_actions: + if option_string == short_option_prefix: + action = self._option_string_actions[option_string] + tup = action, option_string, short_explicit_arg + result.append(tup) + elif option_string.startswith(option_prefix): + action = self._option_string_actions[option_string] + tup = action, option_string, explicit_arg + result.append(tup) + + # shouldn't ever get here + else: + self.error(_('unexpected option string: %s') % option_string) + + # return the collected option tuples + return result + + def _get_nargs_pattern(self, action): + # in all examples below, we have to allow for '--' args + # which are represented as '-' in the pattern + nargs = action.nargs + + # the default (None) is assumed to be a single argument + if nargs is None: + nargs_pattern = '(-*A-*)' + + # allow zero or one arguments + elif nargs == OPTIONAL: + nargs_pattern = '(-*A?-*)' + + # allow zero or more arguments + elif nargs == ZERO_OR_MORE: + nargs_pattern = '(-*[A-]*)' + + # allow one or more arguments + elif nargs == ONE_OR_MORE: + nargs_pattern = '(-*A[A-]*)' + + # allow any number of options or arguments + elif nargs == REMAINDER: + nargs_pattern = '([-AO]*)' + + # allow one argument followed by any number of options or arguments + elif nargs == PARSER: + nargs_pattern = '(-*A[-AO]*)' + + # all others should be integers + else: + nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs) + + # if this is an optional action, -- is not allowed + if action.option_strings: + nargs_pattern = nargs_pattern.replace('-*', '') + nargs_pattern = nargs_pattern.replace('-', '') + + # return the pattern + return nargs_pattern + + # ======================== + # Value conversion methods + # ======================== + def _get_values(self, action, arg_strings): + # for everything but PARSER, REMAINDER args, strip out first '--' + if action.nargs not in [PARSER, REMAINDER]: + try: + arg_strings.remove('--') + except ValueError: + pass + + # optional argument produces a default when not present + if not arg_strings and action.nargs == OPTIONAL: + if action.option_strings: + value = action.const + else: + value = action.default + if isinstance(value, basestring): + value = self._get_value(action, value) + self._check_value(action, value) + + # when nargs='*' on a positional, if there were no command-line + # args, use the default if it is anything other than None + elif (not arg_strings and action.nargs == ZERO_OR_MORE and + not action.option_strings): + if action.default is not None: + value = action.default + else: + value = arg_strings + self._check_value(action, value) + + # single argument or optional argument produces a single value + elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: + arg_string, = arg_strings + value = self._get_value(action, arg_string) + self._check_value(action, value) + + # REMAINDER arguments convert all values, checking none + elif action.nargs == REMAINDER: + value = [self._get_value(action, v) for v in arg_strings] + + # PARSER arguments convert all values, but check only the first + elif action.nargs == PARSER: + value = [self._get_value(action, v) for v in arg_strings] + self._check_value(action, value[0]) + + # all other types of nargs produce a list + else: + value = [self._get_value(action, v) for v in arg_strings] + for v in value: + self._check_value(action, v) + + # return the converted value + return value + + def _get_value(self, action, arg_string): + type_func = self._registry_get('type', action.type, action.type) + if not _callable(type_func): + msg = _('%r is not callable') + raise ArgumentError(action, msg % type_func) + + # convert the value to the appropriate type + try: + result = type_func(arg_string) + + # ArgumentTypeErrors indicate errors + except ArgumentTypeError: + name = getattr(action.type, '__name__', repr(action.type)) + msg = str(_sys.exc_info()[1]) + raise ArgumentError(action, msg) + + # TypeErrors or ValueErrors also indicate errors + except (TypeError, ValueError): + name = getattr(action.type, '__name__', repr(action.type)) + msg = _('invalid %s value: %r') + raise ArgumentError(action, msg % (name, arg_string)) + + # return the converted value + return result + + def _check_value(self, action, value): + # converted value must be one of the choices (if specified) + if action.choices is not None and value not in action.choices: + tup = value, ', '.join(map(repr, action.choices)) + msg = _('invalid choice: %r (choose from %s)') % tup + raise ArgumentError(action, msg) + + # ======================= + # Help-formatting methods + # ======================= + def format_usage(self): + formatter = self._get_formatter() + formatter.add_usage(self.usage, self._actions, + self._mutually_exclusive_groups) + return formatter.format_help() + + def format_help(self): + formatter = self._get_formatter() + + # usage + formatter.add_usage(self.usage, self._actions, + self._mutually_exclusive_groups) + + # description + formatter.add_text(self.description) + + # positionals, optionals and user-defined groups + for action_group in self._action_groups: + formatter.start_section(action_group.title) + formatter.add_text(action_group.description) + formatter.add_arguments(action_group._group_actions) + formatter.end_section() + + # epilog + formatter.add_text(self.epilog) + + # determine help from format above + return formatter.format_help() + + def format_version(self): + import warnings + warnings.warn( + 'The format_version method is deprecated -- the "version" ' + 'argument to ArgumentParser is no longer supported.', + DeprecationWarning) + formatter = self._get_formatter() + formatter.add_text(self.version) + return formatter.format_help() + + def _get_formatter(self): + return self.formatter_class(prog=self.prog) + + # ===================== + # Help-printing methods + # ===================== + def print_usage(self, file=None): + if file is None: + file = _sys.stdout + self._print_message(self.format_usage(), file) + + def print_help(self, file=None): + if file is None: + file = _sys.stdout + self._print_message(self.format_help(), file) + + def print_version(self, file=None): + import warnings + warnings.warn( + 'The print_version method is deprecated -- the "version" ' + 'argument to ArgumentParser is no longer supported.', + DeprecationWarning) + self._print_message(self.format_version(), file) + + def _print_message(self, message, file=None): + if message: + if file is None: + file = _sys.stderr + file.write(message) + + # =============== + # Exiting methods + # =============== + def exit(self, status=0, message=None): + if message: + self._print_message(message, _sys.stderr) + _sys.exit(status) + + def error(self, message): + """error(message: string) + + Prints a usage message incorporating the message to stderr and + exits. + + If you override this in a subclass, it should not return -- it + should either exit or raise an exception. + """ + self.print_usage(_sys.stderr) + self.exit(2, _('%s: error: %s\n') % (self.prog, message)) diff --git a/src/main/resources/PythonLibs/ast.py b/src/main/resources/PythonLibs/ast.py new file mode 100644 index 0000000000000000000000000000000000000000..fd5dfdba676d97d6b45ddab30fcf8e7169faea0c --- /dev/null +++ b/src/main/resources/PythonLibs/ast.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +""" + ast + ~~~ + + The `ast` module helps Python applications to process trees of the Python + abstract syntax grammar. The abstract syntax itself might change with + each Python release; this module helps to find out programmatically what + the current grammar looks like and allows modifications of it. + + An abstract syntax tree can be generated by passing `ast.PyCF_ONLY_AST` as + a flag to the `compile()` builtin function or by using the `parse()` + function from this module. The result will be a tree of objects whose + classes all inherit from `ast.AST`. + + A modified abstract syntax tree can be compiled into a Python code object + using the built-in `compile()` function. + + Additionally various helper functions are provided that make working with + the trees simpler. The main intention of the helper functions and this + module in general is to provide an easy to use interface for libraries + that work tightly with the python syntax (template engines for example). + + + :copyright: Copyright 2008 by Armin Ronacher. + :license: Python License. +""" +from _ast import * +from _ast import __version__ + + +def parse(source, filename='<unknown>', mode='exec'): + """ + Parse the source into an AST node. + Equivalent to compile(source, filename, mode, PyCF_ONLY_AST). + """ + return compile(source, filename, mode, PyCF_ONLY_AST) + + +def literal_eval(node_or_string): + """ + Safely evaluate an expression node or a string containing a Python + expression. The string or node provided may only consist of the following + Python literal structures: strings, numbers, tuples, lists, dicts, booleans, + and None. + """ + _safe_names = {'None': None, 'True': True, 'False': False} + if isinstance(node_or_string, basestring): + node_or_string = parse(node_or_string, mode='eval') + if isinstance(node_or_string, Expression): + node_or_string = node_or_string.body + def _convert(node): + if isinstance(node, Str): + return node.s + elif isinstance(node, Num): + return node.n + elif isinstance(node, Tuple): + return tuple(map(_convert, node.elts)) + elif isinstance(node, List): + return list(map(_convert, node.elts)) + elif isinstance(node, Dict): + return dict((_convert(k), _convert(v)) for k, v + in zip(node.keys, node.values)) + elif isinstance(node, Name): + if node.id in _safe_names: + return _safe_names[node.id] + elif isinstance(node, BinOp) and \ + isinstance(node.op, (Add, Sub)) and \ + isinstance(node.right, Num) and \ + isinstance(node.right.n, complex) and \ + isinstance(node.left, Num) and \ + isinstance(node.left.n, (int, long, float)): + left = node.left.n + right = node.right.n + if isinstance(node.op, Add): + return left + right + else: + return left - right + raise ValueError('malformed string') + return _convert(node_or_string) + + +def dump(node, annotate_fields=True, include_attributes=False): + """ + Return a formatted dump of the tree in *node*. This is mainly useful for + debugging purposes. The returned string will show the names and the values + for fields. This makes the code impossible to evaluate, so if evaluation is + wanted *annotate_fields* must be set to False. Attributes such as line + numbers and column offsets are not dumped by default. If this is wanted, + *include_attributes* can be set to True. + """ + def _format(node): + if isinstance(node, AST): + fields = [(a, _format(b)) for a, b in iter_fields(node)] + rv = '%s(%s' % (node.__class__.__name__, ', '.join( + ('%s=%s' % field for field in fields) + if annotate_fields else + (b for a, b in fields) + )) + if include_attributes and node._attributes: + rv += fields and ', ' or ' ' + rv += ', '.join('%s=%s' % (a, _format(getattr(node, a))) + for a in node._attributes) + return rv + ')' + elif isinstance(node, list): + return '[%s]' % ', '.join(_format(x) for x in node) + return repr(node) + if not isinstance(node, AST): + raise TypeError('expected AST, got %r' % node.__class__.__name__) + return _format(node) + + +def copy_location(new_node, old_node): + """ + Copy source location (`lineno` and `col_offset` attributes) from + *old_node* to *new_node* if possible, and return *new_node*. + """ + for attr in 'lineno', 'col_offset': + if attr in old_node._attributes and attr in new_node._attributes \ + and hasattr(old_node, attr): + setattr(new_node, attr, getattr(old_node, attr)) + return new_node + + +def fix_missing_locations(node): + """ + When you compile a node tree with compile(), the compiler expects lineno and + col_offset attributes for every node that supports them. This is rather + tedious to fill in for generated nodes, so this helper adds these attributes + recursively where not already set, by setting them to the values of the + parent node. It works recursively starting at *node*. + """ + def _fix(node, lineno, col_offset): + if 'lineno' in node._attributes: + if not hasattr(node, 'lineno'): + node.lineno = lineno + else: + lineno = node.lineno + if 'col_offset' in node._attributes: + if not hasattr(node, 'col_offset'): + node.col_offset = col_offset + else: + col_offset = node.col_offset + for child in iter_child_nodes(node): + _fix(child, lineno, col_offset) + _fix(node, 1, 0) + return node + + +def increment_lineno(node, n=1): + """ + Increment the line number of each node in the tree starting at *node* by *n*. + This is useful to "move code" to a different location in a file. + """ + for child in walk(node): + if 'lineno' in child._attributes: + child.lineno = getattr(child, 'lineno', 0) + n + return node + + +def iter_fields(node): + """ + Yield a tuple of ``(fieldname, value)`` for each field in ``node._fields`` + that is present on *node*. + """ + for field in node._fields: + try: + yield field, getattr(node, field) + except AttributeError: + pass + + +def iter_child_nodes(node): + """ + Yield all direct child nodes of *node*, that is, all fields that are nodes + and all items of fields that are lists of nodes. + """ + for name, field in iter_fields(node): + if isinstance(field, AST): + yield field + elif isinstance(field, list): + for item in field: + if isinstance(item, AST): + yield item + + +def get_docstring(node, clean=True): + """ + Return the docstring for the given node or None if no docstring can + be found. If the node provided does not have docstrings a TypeError + will be raised. + """ + if not isinstance(node, (FunctionDef, ClassDef, Module)): + raise TypeError("%r can't have docstrings" % node.__class__.__name__) + if node.body and isinstance(node.body[0], Expr) and \ + isinstance(node.body[0].value, Str): + if clean: + import inspect + return inspect.cleandoc(node.body[0].value.s) + return node.body[0].value.s + + +def walk(node): + """ + Recursively yield all descendant nodes in the tree starting at *node* + (including *node* itself), in no specified order. This is useful if you + only want to modify nodes in place and don't care about the context. + """ + from collections import deque + todo = deque([node]) + while todo: + node = todo.popleft() + todo.extend(iter_child_nodes(node)) + yield node + + +class NodeVisitor(object): + """ + A node visitor base class that walks the abstract syntax tree and calls a + visitor function for every node found. This function may return a value + which is forwarded by the `visit` method. + + This class is meant to be subclassed, with the subclass adding visitor + methods. + + Per default the visitor functions for the nodes are ``'visit_'`` + + class name of the node. So a `TryFinally` node visit function would + be `visit_TryFinally`. This behavior can be changed by overriding + the `visit` method. If no visitor function exists for a node + (return value `None`) the `generic_visit` visitor is used instead. + + Don't use the `NodeVisitor` if you want to apply changes to nodes during + traversing. For this a special visitor exists (`NodeTransformer`) that + allows modifications. + """ + + def visit(self, node): + """Visit a node.""" + method = 'visit_' + node.__class__.__name__ + visitor = getattr(self, method, self.generic_visit) + return visitor(node) + + def generic_visit(self, node): + """Called if no explicit visitor function exists for a node.""" + for field, value in iter_fields(node): + if isinstance(value, list): + for item in value: + if isinstance(item, AST): + self.visit(item) + elif isinstance(value, AST): + self.visit(value) + + +class NodeTransformer(NodeVisitor): + """ + A :class:`NodeVisitor` subclass that walks the abstract syntax tree and + allows modification of nodes. + + The `NodeTransformer` will walk the AST and use the return value of the + visitor methods to replace or remove the old node. If the return value of + the visitor method is ``None``, the node will be removed from its location, + otherwise it is replaced with the return value. The return value may be the + original node in which case no replacement takes place. + + Here is an example transformer that rewrites all occurrences of name lookups + (``foo``) to ``data['foo']``:: + + class RewriteName(NodeTransformer): + + def visit_Name(self, node): + return copy_location(Subscript( + value=Name(id='data', ctx=Load()), + slice=Index(value=Str(s=node.id)), + ctx=node.ctx + ), node) + + Keep in mind that if the node you're operating on has child nodes you must + either transform the child nodes yourself or call the :meth:`generic_visit` + method for the node first. + + For nodes that were part of a collection of statements (that applies to all + statement nodes), the visitor may also return a list of nodes rather than + just a single node. + + Usually you use the transformer like this:: + + node = YourTransformer().visit(node) + """ + + def generic_visit(self, node): + for field, old_value in iter_fields(node): + old_value = getattr(node, field, None) + if isinstance(old_value, list): + new_values = [] + for value in old_value: + if isinstance(value, AST): + value = self.visit(value) + if value is None: + continue + elif not isinstance(value, AST): + new_values.extend(value) + continue + new_values.append(value) + old_value[:] = new_values + elif isinstance(old_value, AST): + new_node = self.visit(old_value) + if new_node is None: + delattr(node, field) + else: + setattr(node, field, new_node) + return node diff --git a/src/main/resources/PythonLibs/asynchat.py b/src/main/resources/PythonLibs/asynchat.py new file mode 100644 index 0000000000000000000000000000000000000000..6f99ba1063c85e48dae1c7f9a15965edcec4db61 --- /dev/null +++ b/src/main/resources/PythonLibs/asynchat.py @@ -0,0 +1,295 @@ +# -*- Mode: Python; tab-width: 4 -*- +# Id: asynchat.py,v 2.26 2000/09/07 22:29:26 rushing Exp +# Author: Sam Rushing <rushing@nightmare.com> + +# ====================================================================== +# Copyright 1996 by Sam Rushing +# +# 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 Sam +# Rushing not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL SAM RUSHING 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. +# ====================================================================== + +r"""A class supporting chat-style (command/response) protocols. + +This class adds support for 'chat' style protocols - where one side +sends a 'command', and the other sends a response (examples would be +the common internet protocols - smtp, nntp, ftp, etc..). + +The handle_read() method looks at the input stream for the current +'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n' +for multi-line output), calling self.found_terminator() on its +receipt. + +for example: +Say you build an async nntp client using this class. At the start +of the connection, you'll have self.terminator set to '\r\n', in +order to process the single-line greeting. Just before issuing a +'LIST' command you'll set it to '\r\n.\r\n'. The output of the LIST +command will be accumulated (using your own 'collect_incoming_data' +method) up to the terminator, and then control will be returned to +you - by calling your self.found_terminator() method. +""" + +import socket +import asyncore +from collections import deque + +class async_chat (asyncore.dispatcher): + """This is an abstract class. You must derive from this class, and add + the two methods collect_incoming_data() and found_terminator()""" + + # these are overridable defaults + + ac_in_buffer_size = 4096 + ac_out_buffer_size = 4096 + + def __init__ (self, conn=None): + self.ac_in_buffer = '' + self.ac_out_buffer = '' + self.producer_fifo = fifo() + asyncore.dispatcher.__init__ (self, conn) + + def collect_incoming_data(self, data): + raise NotImplementedError, "must be implemented in subclass" + + def found_terminator(self): + raise NotImplementedError, "must be implemented in subclass" + + def set_terminator (self, term): + "Set the input delimiter. Can be a fixed string of any length, an integer, or None" + self.terminator = term + + def get_terminator (self): + return self.terminator + + # grab some more data from the socket, + # throw it to the collector method, + # check for the terminator, + # if found, transition to the next state. + + def handle_read (self): + + try: + data = self.recv (self.ac_in_buffer_size) + except socket.error, why: + self.handle_error() + return + + self.ac_in_buffer = self.ac_in_buffer + data + + # Continue to search for self.terminator in self.ac_in_buffer, + # while calling self.collect_incoming_data. The while loop + # is necessary because we might read several data+terminator + # combos with a single recv(1024). + + while self.ac_in_buffer: + lb = len(self.ac_in_buffer) + terminator = self.get_terminator() + if not terminator: + # no terminator, collect it all + self.collect_incoming_data (self.ac_in_buffer) + self.ac_in_buffer = '' + elif isinstance(terminator, int) or isinstance(terminator, long): + # numeric terminator + n = terminator + if lb < n: + self.collect_incoming_data (self.ac_in_buffer) + self.ac_in_buffer = '' + self.terminator = self.terminator - lb + else: + self.collect_incoming_data (self.ac_in_buffer[:n]) + self.ac_in_buffer = self.ac_in_buffer[n:] + self.terminator = 0 + self.found_terminator() + else: + # 3 cases: + # 1) end of buffer matches terminator exactly: + # collect data, transition + # 2) end of buffer matches some prefix: + # collect data to the prefix + # 3) end of buffer does not match any prefix: + # collect data + terminator_len = len(terminator) + index = self.ac_in_buffer.find(terminator) + if index != -1: + # we found the terminator + if index > 0: + # don't bother reporting the empty string (source of subtle bugs) + self.collect_incoming_data (self.ac_in_buffer[:index]) + self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] + # This does the Right Thing if the terminator is changed here. + self.found_terminator() + else: + # check for a prefix of the terminator + index = find_prefix_at_end (self.ac_in_buffer, terminator) + if index: + if index != lb: + # we found a prefix, collect up to the prefix + self.collect_incoming_data (self.ac_in_buffer[:-index]) + self.ac_in_buffer = self.ac_in_buffer[-index:] + break + else: + # no prefix, collect it all + self.collect_incoming_data (self.ac_in_buffer) + self.ac_in_buffer = '' + + def handle_write (self): + self.initiate_send () + + def handle_close (self): + self.close() + + def push (self, data): + self.producer_fifo.push (simple_producer (data)) + self.initiate_send() + + def push_with_producer (self, producer): + self.producer_fifo.push (producer) + self.initiate_send() + + def readable (self): + "predicate for inclusion in the readable for select()" + return (len(self.ac_in_buffer) <= self.ac_in_buffer_size) + + def writable (self): + "predicate for inclusion in the writable for select()" + # return len(self.ac_out_buffer) or len(self.producer_fifo) or (not self.connected) + # this is about twice as fast, though not as clear. + return not ( + (self.ac_out_buffer == '') and + self.producer_fifo.is_empty() and + self.connected + ) + + def close_when_done (self): + "automatically close this channel once the outgoing queue is empty" + self.producer_fifo.push (None) + + # refill the outgoing buffer by calling the more() method + # of the first producer in the queue + def refill_buffer (self): + while 1: + if len(self.producer_fifo): + p = self.producer_fifo.first() + # a 'None' in the producer fifo is a sentinel, + # telling us to close the channel. + if p is None: + if not self.ac_out_buffer: + self.producer_fifo.pop() + self.close() + return + elif isinstance(p, str): + self.producer_fifo.pop() + self.ac_out_buffer = self.ac_out_buffer + p + return + data = p.more() + if data: + self.ac_out_buffer = self.ac_out_buffer + data + return + else: + self.producer_fifo.pop() + else: + return + + def initiate_send (self): + obs = self.ac_out_buffer_size + # try to refill the buffer + if (len (self.ac_out_buffer) < obs): + self.refill_buffer() + + if self.ac_out_buffer and self.connected: + # try to send the buffer + try: + num_sent = self.send (self.ac_out_buffer[:obs]) + if num_sent: + self.ac_out_buffer = self.ac_out_buffer[num_sent:] + + except socket.error, why: + self.handle_error() + return + + def discard_buffers (self): + # Emergencies only! + self.ac_in_buffer = '' + self.ac_out_buffer = '' + while self.producer_fifo: + self.producer_fifo.pop() + + +class simple_producer: + + def __init__ (self, data, buffer_size=512): + self.data = data + self.buffer_size = buffer_size + + def more (self): + if len (self.data) > self.buffer_size: + result = self.data[:self.buffer_size] + self.data = self.data[self.buffer_size:] + return result + else: + result = self.data + self.data = '' + return result + +class fifo: + def __init__ (self, list=None): + if not list: + self.list = deque() + else: + self.list = deque(list) + + def __len__ (self): + return len(self.list) + + def is_empty (self): + return not self.list + + def first (self): + return self.list[0] + + def push (self, data): + self.list.append(data) + + def pop (self): + if self.list: + return (1, self.list.popleft()) + else: + return (0, None) + +# Given 'haystack', see if any prefix of 'needle' is at its end. This +# assumes an exact match has already been checked. Return the number of +# characters matched. +# for example: +# f_p_a_e ("qwerty\r", "\r\n") => 1 +# f_p_a_e ("qwertydkjf", "\r\n") => 0 +# f_p_a_e ("qwerty\r\n", "\r\n") => <undefined> + +# this could maybe be made faster with a computed regex? +# [answer: no; circa Python-2.0, Jan 2001] +# new python: 28961/s +# old python: 18307/s +# re: 12820/s +# regex: 14035/s + +def find_prefix_at_end (haystack, needle): + l = len(needle) - 1 + while l and not haystack.endswith(needle[:l]): + l -= 1 + return l diff --git a/src/main/resources/PythonLibs/asyncore.py b/src/main/resources/PythonLibs/asyncore.py new file mode 100644 index 0000000000000000000000000000000000000000..84ec6a8cdafbe77d13028eb69d9a661bbd3c9080 --- /dev/null +++ b/src/main/resources/PythonLibs/asyncore.py @@ -0,0 +1,705 @@ +# -*- Mode: Python -*- +# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp +# Author: Sam Rushing <rushing@nightmare.com> + +# ====================================================================== +# Copyright 1996 by Sam Rushing +# +# 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 Sam +# Rushing not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL SAM RUSHING 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. +# ====================================================================== + +"""Basic infrastructure for asynchronous socket service clients and servers. + +There are only two ways to have a program on a single processor do "more +than one thing at a time". Multi-threaded programming is the simplest and +most popular way to do it, but there is another very different technique, +that lets you have nearly all the advantages of multi-threading, without +actually using multiple threads. it's really only practical if your program +is largely I/O bound. If your program is CPU bound, then pre-emptive +scheduled threads are probably what you really need. Network servers are +rarely CPU-bound, however. + +If your operating system supports the select() system call in its I/O +library (and nearly all do), then you can use it to juggle multiple +communication channels at once; doing other work while your I/O is taking +place in the "background." Although this strategy can seem strange and +complex, especially at first, it is in many ways easier to understand and +control than multi-threaded programming. The module documented here solves +many of the difficult problems for you, making the task of building +sophisticated high-performance network servers and clients a snap. +""" + +import select +import socket +import sys +import time +import warnings + +import os +from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \ + ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \ + errorcode + +_DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, + EBADF)) + +try: + socket_map +except NameError: + socket_map = {} + +def _strerror(err): + try: + return os.strerror(err) + except (ValueError, OverflowError, NameError): + if err in errorcode: + return errorcode[err] + return "Unknown error %s" %err + +class ExitNow(Exception): + pass + +_reraised_exceptions = (ExitNow, KeyboardInterrupt, SystemExit) + +def read(obj): + try: + obj.handle_read_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def write(obj): + try: + obj.handle_write_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def _exception(obj): + try: + obj.handle_expt_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def readwrite(obj, flags): + try: + if flags & select.POLLIN: + obj.handle_read_event() + if flags & select.POLLOUT: + obj.handle_write_event() + if flags & select.POLLPRI: + obj.handle_expt_event() + if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): + obj.handle_close() + except socket.error, e: + if e.args[0] not in _DISCONNECTED: + obj.handle_error() + else: + obj.handle_close() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def poll(timeout=0.0, map=None): + if map is None: + map = socket_map + if map: + r = []; w = []; e = [] + for fd, obj in map.items(): + is_r = obj.readable() + is_w = obj.writable() + if is_r: + r.append(fd) + # accepting sockets should not be writable + if is_w and not obj.accepting: + w.append(fd) + if is_r or is_w: + e.append(fd) + if [] == r == w == e: + time.sleep(timeout) + return + + try: + r, w, e = select.select(r, w, e, timeout) + except select.error, err: + if err.args[0] != EINTR: + raise + else: + return + + for fd in r: + obj = map.get(fd) + if obj is None: + continue + read(obj) + + for fd in w: + obj = map.get(fd) + if obj is None: + continue + write(obj) + + for fd in e: + obj = map.get(fd) + if obj is None: + continue + _exception(obj) + +def poll2(timeout=0.0, map=None): + # Use the poll() support added to the select module in Python 2.0 + if map is None: + map = socket_map + if timeout is not None: + # timeout is in milliseconds + timeout = int(timeout*1000) + pollster = select.poll() + if map: + for fd, obj in map.items(): + flags = 0 + if obj.readable(): + flags |= select.POLLIN | select.POLLPRI + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: + flags |= select.POLLOUT + if flags: + # Only check for exceptions if object was either readable + # or writable. + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL + pollster.register(fd, flags) + try: + r = pollster.poll(timeout) + except select.error, err: + if err.args[0] != EINTR: + raise + r = [] + for fd, flags in r: + obj = map.get(fd) + if obj is None: + continue + readwrite(obj, flags) + +poll3 = poll2 # Alias for backward compatibility + +def jython_poll_fun(timeout=0.0, map=None): + # On jython, select.poll() is the mechanism to use, + # select.select is implemented on top of it. + # Also, we have to use a cache of such objects, because of problems with frequent + # creation and destruction of such objects on windows + # "select() crashes with IOException": http://bugs.jython.org/issue1291 + # So this function is basically the same function as poll2 above, except + # with the select.poll() functionality wrapped in a try..finally clause. + if map is None: + map = socket_map + if timeout is not None: + # timeout is in milliseconds + timeout = int(timeout*1000) + if map: + try: + pollster = select._poll_object_cache.get_poll_object() + for fd, obj in map.items(): + flags = 0 + if obj.readable(): + flags |= select.POLLIN | select.POLLPRI + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: + flags |= select.POLLOUT + if flags: + # Only check for exceptions if object was either readable + # or writable. + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL + pollster.register(obj, flags) + try: + r = pollster.poll(timeout) + except select.error, err: + if err.args[0] != EINTR: + raise + r = [] + for obj, flags in r: + # obj = map.get(fd) + if obj is None: + continue + readwrite(obj, flags) + finally: + select._poll_object_cache.release_poll_object(pollster) + +def loop(timeout=30.0, use_poll=False, map=None, count=None): + if map is None: + map = socket_map + + if use_poll and hasattr(select, 'poll'): + poll_fun = poll2 + else: + poll_fun = poll + if sys.platform.startswith('java'): + poll_fun = jython_poll_fun + + if count is None: + while map: + poll_fun(timeout, map) + + else: + while map and count > 0: + poll_fun(timeout, map) + count = count - 1 + +class dispatcher: + + debug = False + connected = False + accepting = False + connecting = False + closing = False + addr = None + ignore_log_types = frozenset(['warning']) + + def __init__(self, sock=None, map=None): + if map is None: + self._map = socket_map + else: + self._map = map + + self._fileno = None + + if sock: + # Set to nonblocking just to make sure for cases where we + # get a socket from a blocking source. + sock.setblocking(0) + self.set_socket(sock, map) + self.connected = True + # The constructor no longer requires that the socket + # passed be connected. + try: + self.addr = sock.getpeername() + except socket.error, err: + if err.args[0] in (ENOTCONN, EINVAL): + # To handle the case where we got an unconnected + # socket. + self.connected = False + else: + # The socket is broken in some unknown way, alert + # the user and remove it from the map (to prevent + # polling of broken sockets). + self.del_channel(map) + raise + else: + self.socket = None + + def __repr__(self): + status = [self.__class__.__module__+"."+self.__class__.__name__] + if self.accepting and self.addr: + status.append('listening') + elif self.connected: + status.append('connected') + if self.addr is not None: + try: + status.append('%s:%d' % self.addr) + except TypeError: + status.append(repr(self.addr)) + return '<%s at %#x>' % (' '.join(status), id(self)) + + __str__ = __repr__ + + def add_channel(self, map=None): + #self.log_info('adding channel %s' % self) + if map is None: + map = self._map + map[self._fileno] = self + + def del_channel(self, map=None): + fd = self._fileno + if map is None: + map = self._map + if fd in map: + #self.log_info('closing channel %d:%s' % (fd, self)) + del map[fd] + self._fileno = None + + def create_socket(self, family, type): + self.family_and_type = family, type + sock = socket.socket(family, type) + sock.setblocking(0) + self.set_socket(sock) + + def set_socket(self, sock, map=None): + self.socket = sock +## self.__dict__['socket'] = sock + # On jython, the socket object itself is what is watchable. + # http://mail.python.org/pipermail/python-dev/2007-May/073443.html + self._fileno = sock + self.add_channel(map) + + def set_reuse_addr(self): + # try to re-use a server port if possible + try: + self.socket.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR, + self.socket.getsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR) | 1 + ) + except socket.error: + pass + + # ================================================== + # predicates for select() + # these are used as filters for the lists of sockets + # to pass to select(). + # ================================================== + + def readable(self): + return True + + def writable(self): + return True + + # ================================================== + # socket object methods. + # ================================================== + + def listen(self, num): + self.accepting = True + if os.name == 'nt' and num > 5: + num = 5 + return self.socket.listen(num) + + def bind(self, addr): + self.addr = addr + return self.socket.bind(addr) + + def connect(self, address): + self.connected = False + self.connecting = True + err = self.socket.connect_ex(address) + if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \ + or err == EINVAL and os.name in ('nt', 'ce'): + self.addr = address + return + if err in (0, EISCONN): + self.addr = address + self.handle_connect_event() + else: + raise socket.error(err, errorcode[err]) + + def accept(self): + # XXX can return either an address pair or None + try: + conn, addr = self.socket.accept() + except TypeError: + return None + except socket.error as why: + if why.args[0] in (EWOULDBLOCK, ECONNABORTED, EAGAIN): + return None + else: + raise + else: + return conn, addr + + def send(self, data): + try: + result = self.socket.send(data) + return result + except socket.error, why: + if why.args[0] == EWOULDBLOCK: + return 0 + elif why.args[0] in _DISCONNECTED: + self.handle_close() + return 0 + else: + raise + + def recv(self, buffer_size): + try: + data = self.socket.recv(buffer_size) + if not data: + # a closed connection is indicated by signaling + # a read condition, and having recv() return 0. + self.handle_close() + return '' + else: + return data + except socket.error, why: + # winsock sometimes throws ENOTCONN + if why.args[0] in _DISCONNECTED: + self.handle_close() + return '' + else: + raise + + def close(self): + self.connected = False + self.accepting = False + self.connecting = False + self.del_channel() + try: + self.socket.close() + except socket.error, why: + if why.args[0] not in (ENOTCONN, EBADF): + raise + + # cheap inheritance, used to pass all other attribute + # references to the underlying socket object. + def __getattr__(self, attr): + try: + retattr = getattr(self.socket, attr) + except AttributeError: + raise AttributeError("%s instance has no attribute '%s'" + %(self.__class__.__name__, attr)) + else: + msg = "%(me)s.%(attr)s is deprecated. Use %(me)s.socket.%(attr)s " \ + "instead." % {'me': self.__class__.__name__, 'attr':attr} + warnings.warn(msg, DeprecationWarning, stacklevel=2) + return retattr + + # log and log_info may be overridden to provide more sophisticated + # logging and warning methods. In general, log is for 'hit' logging + # and 'log_info' is for informational, warning and error logging. + + def log(self, message): + sys.stderr.write('log: %s\n' % str(message)) + + def log_info(self, message, type='info'): + if type not in self.ignore_log_types: + print '%s: %s' % (type, message) + + def handle_read_event(self): + if self.accepting: + # accepting sockets are never connected, they "spawn" new + # sockets that are connected + self.handle_accept() + elif not self.connected: + if self.connecting: + self.handle_connect_event() + self.handle_read() + else: + self.handle_read() + + def handle_connect_event(self): + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + raise socket.error(err, _strerror(err)) + self.handle_connect() + self.connected = True + self.connecting = False + + def handle_write_event(self): + if self.accepting: + # Accepting sockets shouldn't get a write event. + # We will pretend it didn't happen. + return + + if not self.connected: + if self.connecting: + self.handle_connect_event() + self.handle_write() + + def handle_expt_event(self): + # handle_expt_event() is called if there might be an error on the + # socket, or if there is OOB data + # check for the error condition first + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # we can get here when select.select() says that there is an + # exceptional condition on the socket + # since there is an error, we'll go ahead and close the socket + # like we would in a subclassed handle_read() that received no + # data + self.handle_close() + else: + self.handle_expt() + + def handle_error(self): + nil, t, v, tbinfo = compact_traceback() + + # sometimes a user repr method will crash. + try: + self_repr = repr(self) + except: + self_repr = '<__repr__(self) failed for object at %0x>' % id(self) + + self.log_info( + 'uncaptured python exception, closing channel %s (%s:%s %s)' % ( + self_repr, + t, + v, + tbinfo + ), + 'error' + ) + self.handle_close() + + def handle_expt(self): + self.log_info('unhandled incoming priority event', 'warning') + + def handle_read(self): + self.log_info('unhandled read event', 'warning') + + def handle_write(self): + self.log_info('unhandled write event', 'warning') + + def handle_connect(self): + self.log_info('unhandled connect event', 'warning') + + def handle_accept(self): + self.log_info('unhandled accept event', 'warning') + + def handle_close(self): + self.log_info('unhandled close event', 'warning') + self.close() + +# --------------------------------------------------------------------------- +# adds simple buffered output capability, useful for simple clients. +# [for more sophisticated usage use asynchat.async_chat] +# --------------------------------------------------------------------------- + +class dispatcher_with_send(dispatcher): + + def __init__(self, sock=None, map=None): + dispatcher.__init__(self, sock, map) + self.out_buffer = '' + + def initiate_send(self): + num_sent = 0 + num_sent = dispatcher.send(self, self.out_buffer[:512]) + self.out_buffer = self.out_buffer[num_sent:] + + def handle_write(self): + self.initiate_send() + + def writable(self): + return (not self.connected) or len(self.out_buffer) + + def send(self, data): + if self.debug: + self.log_info('sending %s' % repr(data)) + self.out_buffer = self.out_buffer + data + self.initiate_send() + +# --------------------------------------------------------------------------- +# used for debugging. +# --------------------------------------------------------------------------- + +def compact_traceback(): + t, v, tb = sys.exc_info() + tbinfo = [] + if not tb: # Must have a traceback + raise AssertionError("traceback does not exist") + while tb: + tbinfo.append(( + tb.tb_frame.f_code.co_filename, + tb.tb_frame.f_code.co_name, + str(tb.tb_lineno) + )) + tb = tb.tb_next + + # just to be safe + del tb + + file, function, line = tbinfo[-1] + info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo]) + return (file, function, line), t, v, info + +def close_all(map=None, ignore_all=False): + if map is None: + map = socket_map + for x in map.values(): + try: + x.close() + except OSError, x: + if x.args[0] == EBADF: + pass + elif not ignore_all: + raise + except _reraised_exceptions: + raise + except: + if not ignore_all: + raise + map.clear() + +# Asynchronous File I/O: +# +# After a little research (reading man pages on various unixen, and +# digging through the linux kernel), I've determined that select() +# isn't meant for doing asynchronous file i/o. +# Heartening, though - reading linux/mm/filemap.c shows that linux +# supports asynchronous read-ahead. So _MOST_ of the time, the data +# will be sitting in memory for us already when we go to read it. +# +# What other OS's (besides NT) support async file i/o? [VMS?] +# +# Regardless, this is useful for pipes, and stdin/stdout... + +if os.name == 'posix': + import fcntl + + class file_wrapper: + # Here we override just enough to make a file + # look like a socket for the purposes of asyncore. + # The passed fd is automatically os.dup()'d + + def __init__(self, fd): + self.fd = os.dup(fd) + + def recv(self, *args): + return os.read(self.fd, *args) + + def send(self, *args): + return os.write(self.fd, *args) + + def getsockopt(self, level, optname, buflen=None): + if (level == socket.SOL_SOCKET and + optname == socket.SO_ERROR and + not buflen): + return 0 + raise NotImplementedError("Only asyncore specific behaviour " + "implemented.") + + read = recv + write = send + + def close(self): + os.close(self.fd) + + def fileno(self): + return self.fd + + class file_dispatcher(dispatcher): + + def __init__(self, fd, map=None): + dispatcher.__init__(self, None, map) + self.connected = True + try: + fd = fd.fileno() + except AttributeError: + pass + self.set_file(fd) + # set it to non-blocking mode + flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) + + def set_file(self, fd): + self.socket = file_wrapper(fd) + self._fileno = self.socket.fileno() + self.add_channel() diff --git a/src/main/resources/PythonLibs/atexit.py b/src/main/resources/PythonLibs/atexit.py new file mode 100644 index 0000000000000000000000000000000000000000..93fddf7f99a4473f971474745a74330059150010 --- /dev/null +++ b/src/main/resources/PythonLibs/atexit.py @@ -0,0 +1,65 @@ +""" +atexit.py - allow programmer to define multiple exit functions to be executed +upon normal program termination. + +One public function, register, is defined. +""" + +__all__ = ["register"] + +import sys + +_exithandlers = [] +def _run_exitfuncs(): + """run any registered exit functions + + _exithandlers is traversed in reverse order so functions are executed + last in, first out. + """ + + exc_info = None + while _exithandlers: + func, targs, kargs = _exithandlers.pop() + try: + func(*targs, **kargs) + except SystemExit: + exc_info = sys.exc_info() + except: + import traceback + print >> sys.stderr, "Error in atexit._run_exitfuncs:" + traceback.print_exc() + exc_info = sys.exc_info() + + if exc_info is not None: + raise exc_info[0], exc_info[1], exc_info[2] + + +def register(func, *targs, **kargs): + """register a function to be executed upon normal program termination + + func - function to be called at exit + targs - optional arguments to pass to func + kargs - optional keyword arguments to pass to func + + func is returned to facilitate usage as a decorator. + """ + _exithandlers.append((func, targs, kargs)) + return func + +if hasattr(sys, "exitfunc"): + # Assume it's another registered exit function - append it to our list + register(sys.exitfunc) +sys.exitfunc = _run_exitfuncs + +if __name__ == "__main__": + def x1(): + print "running x1" + def x2(n): + print "running x2(%r)" % (n,) + def x3(n, kwd=None): + print "running x3(%r, kwd=%r)" % (n, kwd) + + register(x1) + register(x2, 12) + register(x3, 5, "bar") + register(x3, "no kwd args") diff --git a/src/main/resources/PythonLibs/base64.py b/src/main/resources/PythonLibs/base64.py new file mode 100644 index 0000000000000000000000000000000000000000..85204dd022ab467e3b34d4cbdae1b6b0b05fea1b --- /dev/null +++ b/src/main/resources/PythonLibs/base64.py @@ -0,0 +1,360 @@ +#! /usr/bin/env python + +"""RFC 3548: Base16, Base32, Base64 Data Encodings""" + +# Modified 04-Oct-1995 by Jack Jansen to use binascii module +# Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support + +import re +import struct +import binascii + + +__all__ = [ + # Legacy interface exports traditional RFC 1521 Base64 encodings + 'encode', 'decode', 'encodestring', 'decodestring', + # Generalized interface for other encodings + 'b64encode', 'b64decode', 'b32encode', 'b32decode', + 'b16encode', 'b16decode', + # Standard Base64 encoding + 'standard_b64encode', 'standard_b64decode', + # Some common Base64 alternatives. As referenced by RFC 3458, see thread + # starting at: + # + # http://zgp.org/pipermail/p2p-hackers/2001-September/000316.html + 'urlsafe_b64encode', 'urlsafe_b64decode', + ] + +_translation = [chr(_x) for _x in range(256)] +EMPTYSTRING = '' + + +def _translate(s, altchars): + translation = _translation[:] + for k, v in altchars.items(): + translation[ord(k)] = v + return s.translate(''.join(translation)) + + + +# Base64 encoding/decoding uses binascii + +def b64encode(s, altchars=None): + """Encode a string using Base64. + + s is the string to encode. Optional altchars must be a string of at least + length 2 (additional characters are ignored) which specifies an + alternative alphabet for the '+' and '/' characters. This allows an + application to e.g. generate url or filesystem safe Base64 strings. + + The encoded string is returned. + """ + # Strip off the trailing newline + encoded = binascii.b2a_base64(s)[:-1] + if altchars is not None: + return _translate(encoded, {'+': altchars[0], '/': altchars[1]}) + return encoded + + +def b64decode(s, altchars=None): + """Decode a Base64 encoded string. + + s is the string to decode. Optional altchars must be a string of at least + length 2 (additional characters are ignored) which specifies the + alternative alphabet used instead of the '+' and '/' characters. + + The decoded string is returned. A TypeError is raised if s were + incorrectly padded or if there are non-alphabet characters present in the + string. + """ + if altchars is not None: + s = _translate(s, {altchars[0]: '+', altchars[1]: '/'}) + try: + return binascii.a2b_base64(s) + except binascii.Error, msg: + # Transform this exception for consistency + raise TypeError(msg) + + +def standard_b64encode(s): + """Encode a string using the standard Base64 alphabet. + + s is the string to encode. The encoded string is returned. + """ + return b64encode(s) + +def standard_b64decode(s): + """Decode a string encoded with the standard Base64 alphabet. + + s is the string to decode. The decoded string is returned. A TypeError + is raised if the string is incorrectly padded or if there are non-alphabet + characters present in the string. + """ + return b64decode(s) + +def urlsafe_b64encode(s): + """Encode a string using a url-safe Base64 alphabet. + + s is the string to encode. The encoded string is returned. The alphabet + uses '-' instead of '+' and '_' instead of '/'. + """ + return b64encode(s, '-_') + +def urlsafe_b64decode(s): + """Decode a string encoded with the standard Base64 alphabet. + + s is the string to decode. The decoded string is returned. A TypeError + is raised if the string is incorrectly padded or if there are non-alphabet + characters present in the string. + + The alphabet uses '-' instead of '+' and '_' instead of '/'. + """ + return b64decode(s, '-_') + + + +# Base32 encoding/decoding must be done in Python +_b32alphabet = { + 0: 'A', 9: 'J', 18: 'S', 27: '3', + 1: 'B', 10: 'K', 19: 'T', 28: '4', + 2: 'C', 11: 'L', 20: 'U', 29: '5', + 3: 'D', 12: 'M', 21: 'V', 30: '6', + 4: 'E', 13: 'N', 22: 'W', 31: '7', + 5: 'F', 14: 'O', 23: 'X', + 6: 'G', 15: 'P', 24: 'Y', + 7: 'H', 16: 'Q', 25: 'Z', + 8: 'I', 17: 'R', 26: '2', + } + +_b32tab = _b32alphabet.items() +_b32tab.sort() +_b32tab = [v for k, v in _b32tab] +_b32rev = dict([(v, long(k)) for k, v in _b32alphabet.items()]) + + +def b32encode(s): + """Encode a string using Base32. + + s is the string to encode. The encoded string is returned. + """ + parts = [] + quanta, leftover = divmod(len(s), 5) + # Pad the last quantum with zero bits if necessary + if leftover: + s += ('\0' * (5 - leftover)) + quanta += 1 + for i in range(quanta): + # c1 and c2 are 16 bits wide, c3 is 8 bits wide. The intent of this + # code is to process the 40 bits in units of 5 bits. So we take the 1 + # leftover bit of c1 and tack it onto c2. Then we take the 2 leftover + # bits of c2 and tack them onto c3. The shifts and masks are intended + # to give us values of exactly 5 bits in width. + c1, c2, c3 = struct.unpack('!HHB', s[i*5:(i+1)*5]) + c2 += (c1 & 1) << 16 # 17 bits wide + c3 += (c2 & 3) << 8 # 10 bits wide + parts.extend([_b32tab[c1 >> 11], # bits 1 - 5 + _b32tab[(c1 >> 6) & 0x1f], # bits 6 - 10 + _b32tab[(c1 >> 1) & 0x1f], # bits 11 - 15 + _b32tab[c2 >> 12], # bits 16 - 20 (1 - 5) + _b32tab[(c2 >> 7) & 0x1f], # bits 21 - 25 (6 - 10) + _b32tab[(c2 >> 2) & 0x1f], # bits 26 - 30 (11 - 15) + _b32tab[c3 >> 5], # bits 31 - 35 (1 - 5) + _b32tab[c3 & 0x1f], # bits 36 - 40 (1 - 5) + ]) + encoded = EMPTYSTRING.join(parts) + # Adjust for any leftover partial quanta + if leftover == 1: + return encoded[:-6] + '======' + elif leftover == 2: + return encoded[:-4] + '====' + elif leftover == 3: + return encoded[:-3] + '===' + elif leftover == 4: + return encoded[:-1] + '=' + return encoded + + +def b32decode(s, casefold=False, map01=None): + """Decode a Base32 encoded string. + + s is the string to decode. Optional casefold is a flag specifying whether + a lowercase alphabet is acceptable as input. For security purposes, the + default is False. + + RFC 3548 allows for optional mapping of the digit 0 (zero) to the letter O + (oh), and for optional mapping of the digit 1 (one) to either the letter I + (eye) or letter L (el). The optional argument map01 when not None, + specifies which letter the digit 1 should be mapped to (when map01 is not + None, the digit 0 is always mapped to the letter O). For security + purposes the default is None, so that 0 and 1 are not allowed in the + input. + + The decoded string is returned. A TypeError is raised if s were + incorrectly padded or if there are non-alphabet characters present in the + string. + """ + quanta, leftover = divmod(len(s), 8) + if leftover: + raise TypeError('Incorrect padding') + # Handle section 2.4 zero and one mapping. The flag map01 will be either + # False, or the character to map the digit 1 (one) to. It should be + # either L (el) or I (eye). + if map01: + s = _translate(s, {'0': 'O', '1': map01}) + if casefold: + s = s.upper() + # Strip off pad characters from the right. We need to count the pad + # characters because this will tell us how many null bytes to remove from + # the end of the decoded string. + padchars = 0 + mo = re.search('(?P<pad>[=]*)$', s) + if mo: + padchars = len(mo.group('pad')) + if padchars > 0: + s = s[:-padchars] + # Now decode the full quanta + parts = [] + acc = 0 + shift = 35 + for c in s: + val = _b32rev.get(c) + if val is None: + raise TypeError('Non-base32 digit found') + acc += _b32rev[c] << shift + shift -= 5 + if shift < 0: + parts.append(binascii.unhexlify('%010x' % acc)) + acc = 0 + shift = 35 + # Process the last, partial quanta + last = binascii.unhexlify('%010x' % acc) + if padchars == 0: + last = '' # No characters + elif padchars == 1: + last = last[:-1] + elif padchars == 3: + last = last[:-2] + elif padchars == 4: + last = last[:-3] + elif padchars == 6: + last = last[:-4] + else: + raise TypeError('Incorrect padding') + parts.append(last) + return EMPTYSTRING.join(parts) + + + +# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns +# lowercase. The RFC also recommends against accepting input case +# insensitively. +def b16encode(s): + """Encode a string using Base16. + + s is the string to encode. The encoded string is returned. + """ + return binascii.hexlify(s).upper() + + +def b16decode(s, casefold=False): + """Decode a Base16 encoded string. + + s is the string to decode. Optional casefold is a flag specifying whether + a lowercase alphabet is acceptable as input. For security purposes, the + default is False. + + The decoded string is returned. A TypeError is raised if s were + incorrectly padded or if there are non-alphabet characters present in the + string. + """ + if casefold: + s = s.upper() + if re.search('[^0-9A-F]', s): + raise TypeError('Non-base16 digit found') + return binascii.unhexlify(s) + + + +# Legacy interface. This code could be cleaned up since I don't believe +# binascii has any line length limitations. It just doesn't seem worth it +# though. + +MAXLINESIZE = 76 # Excluding the CRLF +MAXBINSIZE = (MAXLINESIZE//4)*3 + +def encode(input, output): + """Encode a file.""" + while True: + s = input.read(MAXBINSIZE) + if not s: + break + while len(s) < MAXBINSIZE: + ns = input.read(MAXBINSIZE-len(s)) + if not ns: + break + s += ns + line = binascii.b2a_base64(s) + output.write(line) + + +def decode(input, output): + """Decode a file.""" + while True: + line = input.readline() + if not line: + break + s = binascii.a2b_base64(line) + output.write(s) + + +def encodestring(s): + """Encode a string into multiple lines of base-64 data.""" + pieces = [] + for i in range(0, len(s), MAXBINSIZE): + chunk = s[i : i + MAXBINSIZE] + pieces.append(binascii.b2a_base64(chunk)) + return "".join(pieces) + + +def decodestring(s): + """Decode a string.""" + return binascii.a2b_base64(s) + + + +# Useable as a script... +def test(): + """Small test program""" + import sys, getopt + try: + opts, args = getopt.getopt(sys.argv[1:], 'deut') + except getopt.error, msg: + sys.stdout = sys.stderr + print msg + print """usage: %s [-d|-e|-u|-t] [file|-] + -d, -u: decode + -e: encode (default) + -t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0] + sys.exit(2) + func = encode + for o, a in opts: + if o == '-e': func = encode + if o == '-d': func = decode + if o == '-u': func = decode + if o == '-t': test1(); return + if args and args[0] != '-': + with open(args[0], 'rb') as f: + func(f, sys.stdout) + else: + func(sys.stdin, sys.stdout) + + +def test1(): + s0 = "Aladdin:open sesame" + s1 = encodestring(s0) + s2 = decodestring(s1) + print s0, repr(s1), s2 + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/bdb.py b/src/main/resources/PythonLibs/bdb.py new file mode 100644 index 0000000000000000000000000000000000000000..59440a99a0fab025d1dcf8dd1610f56e1729b149 --- /dev/null +++ b/src/main/resources/PythonLibs/bdb.py @@ -0,0 +1,645 @@ +"""Debugger basics""" + +import fnmatch +import sys +import os +import types + +__all__ = ["BdbQuit","Bdb","Breakpoint"] + +class BdbQuit(Exception): + """Exception to give up completely""" + + +class Bdb: + + """Generic Python debugger base class. + + This class takes care of details of the trace facility; + a derived class should implement user interaction. + The standard debugger class (pdb.Pdb) is an example. + """ + + def __init__(self, skip=None): + self.skip = set(skip) if skip else None + self.breaks = {} + self.fncache = {} + self.frame_returning = None + + def canonic(self, filename): + if filename == "<" + filename[1:-1] + ">": + return filename + canonic = self.fncache.get(filename) + if not canonic: + canonic = os.path.abspath(filename) + canonic = os.path.normcase(canonic) + self.fncache[filename] = canonic + return canonic + + def reset(self): + import linecache + linecache.checkcache() + self.botframe = None + self._set_stopinfo(None, None) + + def trace_dispatch(self, frame, event, arg): + if self.quitting: + return # None + if event == 'line': + return self.dispatch_line(frame) + if event == 'call': + return self.dispatch_call(frame, arg) + if event == 'return': + return self.dispatch_return(frame, arg) + if event == 'exception': + return self.dispatch_exception(frame, arg) + if event == 'c_call': + return self.trace_dispatch + if event == 'c_exception': + return self.trace_dispatch + if event == 'c_return': + return self.trace_dispatch + print 'bdb.Bdb.dispatch: unknown debugging event:', repr(event) + return self.trace_dispatch + + def dispatch_line(self, frame): + if self.stop_here(frame) or self.break_here(frame): + self.user_line(frame) + if self.quitting: raise BdbQuit + return self.trace_dispatch + + def dispatch_call(self, frame, arg): + # XXX 'arg' is no longer used + if self.botframe is None: + # First call of dispatch since reset() + self.botframe = frame.f_back # (CT) Note that this may also be None! + return self.trace_dispatch + if not (self.stop_here(frame) or self.break_anywhere(frame)): + # No need to trace this function + return # None + self.user_call(frame, arg) + if self.quitting: raise BdbQuit + return self.trace_dispatch + + def dispatch_return(self, frame, arg): + if self.stop_here(frame) or frame == self.returnframe: + try: + self.frame_returning = frame + self.user_return(frame, arg) + finally: + self.frame_returning = None + if self.quitting: raise BdbQuit + return self.trace_dispatch + + def dispatch_exception(self, frame, arg): + if self.stop_here(frame): + self.user_exception(frame, arg) + if self.quitting: raise BdbQuit + return self.trace_dispatch + + # Normally derived classes don't override the following + # methods, but they may if they want to redefine the + # definition of stopping and breakpoints. + + def is_skipped_module(self, module_name): + for pattern in self.skip: + if fnmatch.fnmatch(module_name, pattern): + return True + return False + + def stop_here(self, frame): + # (CT) stopframe may now also be None, see dispatch_call. + # (CT) the former test for None is therefore removed from here. + if self.skip and \ + self.is_skipped_module(frame.f_globals.get('__name__')): + return False + if frame is self.stopframe: + if self.stoplineno == -1: + return False + return frame.f_lineno >= self.stoplineno + while frame is not None and frame is not self.stopframe: + if frame is self.botframe: + return True + frame = frame.f_back + return False + + def break_here(self, frame): + filename = self.canonic(frame.f_code.co_filename) + if not filename in self.breaks: + return False + lineno = frame.f_lineno + if not lineno in self.breaks[filename]: + # The line itself has no breakpoint, but maybe the line is the + # first line of a function with breakpoint set by function name. + lineno = frame.f_code.co_firstlineno + if not lineno in self.breaks[filename]: + return False + + # flag says ok to delete temp. bp + (bp, flag) = effective(filename, lineno, frame) + if bp: + self.currentbp = bp.number + if (flag and bp.temporary): + self.do_clear(str(bp.number)) + return True + else: + return False + + def do_clear(self, arg): + raise NotImplementedError, "subclass of bdb must implement do_clear()" + + def break_anywhere(self, frame): + return self.canonic(frame.f_code.co_filename) in self.breaks + + # Derived classes should override the user_* methods + # to gain control. + + def user_call(self, frame, argument_list): + """This method is called when there is the remote possibility + that we ever need to stop in this function.""" + pass + + def user_line(self, frame): + """This method is called when we stop or break at this line.""" + pass + + def user_return(self, frame, return_value): + """This method is called when a return trap is set here.""" + pass + + def user_exception(self, frame, exc_info): + exc_type, exc_value, exc_traceback = exc_info + """This method is called if an exception occurs, + but only if we are to stop at or just below this level.""" + pass + + def _set_stopinfo(self, stopframe, returnframe, stoplineno=0): + self.stopframe = stopframe + self.returnframe = returnframe + self.quitting = 0 + # stoplineno >= 0 means: stop at line >= the stoplineno + # stoplineno -1 means: don't stop at all + self.stoplineno = stoplineno + + # Derived classes and clients can call the following methods + # to affect the stepping state. + + def set_until(self, frame): #the name "until" is borrowed from gdb + """Stop when the line with the line no greater than the current one is + reached or when returning from current frame""" + self._set_stopinfo(frame, frame, frame.f_lineno+1) + + def set_step(self): + """Stop after one line of code.""" + # Issue #13183: pdb skips frames after hitting a breakpoint and running + # step commands. + # Restore the trace function in the caller (that may not have been set + # for performance reasons) when returning from the current frame. + if self.frame_returning: + caller_frame = self.frame_returning.f_back + if caller_frame and not caller_frame.f_trace: + caller_frame.f_trace = self.trace_dispatch + self._set_stopinfo(None, None) + + def set_next(self, frame): + """Stop on the next line in or below the given frame.""" + self._set_stopinfo(frame, None) + + def set_return(self, frame): + """Stop when returning from the given frame.""" + self._set_stopinfo(frame.f_back, frame) + + def set_trace(self, frame=None): + """Start debugging from `frame`. + + If frame is not specified, debugging starts from caller's frame. + """ + if frame is None: + frame = sys._getframe().f_back + self.reset() + while frame: + frame.f_trace = self.trace_dispatch + self.botframe = frame + frame = frame.f_back + self.set_step() + sys.settrace(self.trace_dispatch) + + def set_continue(self): + # Don't stop except at breakpoints or when finished + self._set_stopinfo(self.botframe, None, -1) + if not self.breaks: + # no breakpoints; run without debugger overhead + sys.settrace(None) + frame = sys._getframe().f_back + while frame and frame is not self.botframe: + del frame.f_trace + frame = frame.f_back + + def set_quit(self): + self.stopframe = self.botframe + self.returnframe = None + self.quitting = 1 + sys.settrace(None) + + # Derived classes and clients can call the following methods + # to manipulate breakpoints. These methods return an + # error message is something went wrong, None if all is well. + # Set_break prints out the breakpoint line and file:lineno. + # Call self.get_*break*() to see the breakpoints or better + # for bp in Breakpoint.bpbynumber: if bp: bp.bpprint(). + + def set_break(self, filename, lineno, temporary=0, cond = None, + funcname=None): + filename = self.canonic(filename) + import linecache # Import as late as possible + line = linecache.getline(filename, lineno) + if not line: + return 'Line %s:%d does not exist' % (filename, + lineno) + if not filename in self.breaks: + self.breaks[filename] = [] + list = self.breaks[filename] + if not lineno in list: + list.append(lineno) + bp = Breakpoint(filename, lineno, temporary, cond, funcname) + + def _prune_breaks(self, filename, lineno): + if (filename, lineno) not in Breakpoint.bplist: + self.breaks[filename].remove(lineno) + if not self.breaks[filename]: + del self.breaks[filename] + + def clear_break(self, filename, lineno): + filename = self.canonic(filename) + if not filename in self.breaks: + return 'There are no breakpoints in %s' % filename + if lineno not in self.breaks[filename]: + return 'There is no breakpoint at %s:%d' % (filename, + lineno) + # If there's only one bp in the list for that file,line + # pair, then remove the breaks entry + for bp in Breakpoint.bplist[filename, lineno][:]: + bp.deleteMe() + self._prune_breaks(filename, lineno) + + def clear_bpbynumber(self, arg): + try: + number = int(arg) + except: + return 'Non-numeric breakpoint number (%s)' % arg + try: + bp = Breakpoint.bpbynumber[number] + except IndexError: + return 'Breakpoint number (%d) out of range' % number + if not bp: + return 'Breakpoint (%d) already deleted' % number + bp.deleteMe() + self._prune_breaks(bp.file, bp.line) + + def clear_all_file_breaks(self, filename): + filename = self.canonic(filename) + if not filename in self.breaks: + return 'There are no breakpoints in %s' % filename + for line in self.breaks[filename]: + blist = Breakpoint.bplist[filename, line] + for bp in blist: + bp.deleteMe() + del self.breaks[filename] + + def clear_all_breaks(self): + if not self.breaks: + return 'There are no breakpoints' + for bp in Breakpoint.bpbynumber: + if bp: + bp.deleteMe() + self.breaks = {} + + def get_break(self, filename, lineno): + filename = self.canonic(filename) + return filename in self.breaks and \ + lineno in self.breaks[filename] + + def get_breaks(self, filename, lineno): + filename = self.canonic(filename) + return filename in self.breaks and \ + lineno in self.breaks[filename] and \ + Breakpoint.bplist[filename, lineno] or [] + + def get_file_breaks(self, filename): + filename = self.canonic(filename) + if filename in self.breaks: + return self.breaks[filename] + else: + return [] + + def get_all_breaks(self): + return self.breaks + + # Derived classes and clients can call the following method + # to get a data structure representing a stack trace. + + def get_stack(self, f, t): + stack = [] + if t and t.tb_frame is f: + t = t.tb_next + while f is not None: + stack.append((f, f.f_lineno)) + if f is self.botframe: + break + f = f.f_back + stack.reverse() + i = max(0, len(stack) - 1) + while t is not None: + stack.append((t.tb_frame, t.tb_lineno)) + t = t.tb_next + if f is None: + i = max(0, len(stack) - 1) + return stack, i + + # + + def format_stack_entry(self, frame_lineno, lprefix=': '): + import linecache, repr + frame, lineno = frame_lineno + filename = self.canonic(frame.f_code.co_filename) + s = '%s(%r)' % (filename, lineno) + if frame.f_code.co_name: + s = s + frame.f_code.co_name + else: + s = s + "<lambda>" + if '__args__' in frame.f_locals: + args = frame.f_locals['__args__'] + else: + args = None + if args: + s = s + repr.repr(args) + else: + s = s + '()' + if '__return__' in frame.f_locals: + rv = frame.f_locals['__return__'] + s = s + '->' + s = s + repr.repr(rv) + line = linecache.getline(filename, lineno, frame.f_globals) + if line: s = s + lprefix + line.strip() + return s + + # The following two methods can be called by clients to use + # a debugger to debug a statement, given as a string. + + def run(self, cmd, globals=None, locals=None): + if globals is None: + import __main__ + globals = __main__.__dict__ + if locals is None: + locals = globals + self.reset() + sys.settrace(self.trace_dispatch) + if not isinstance(cmd, types.CodeType): + cmd = cmd+'\n' + try: + exec cmd in globals, locals + except BdbQuit: + pass + finally: + self.quitting = 1 + sys.settrace(None) + + def runeval(self, expr, globals=None, locals=None): + if globals is None: + import __main__ + globals = __main__.__dict__ + if locals is None: + locals = globals + self.reset() + sys.settrace(self.trace_dispatch) + if not isinstance(expr, types.CodeType): + expr = expr+'\n' + try: + return eval(expr, globals, locals) + except BdbQuit: + pass + finally: + self.quitting = 1 + sys.settrace(None) + + def runctx(self, cmd, globals, locals): + # B/W compatibility + self.run(cmd, globals, locals) + + # This method is more useful to debug a single function call. + + def runcall(self, func, *args, **kwds): + self.reset() + sys.settrace(self.trace_dispatch) + res = None + try: + res = func(*args, **kwds) + except BdbQuit: + pass + finally: + self.quitting = 1 + sys.settrace(None) + return res + + +def set_trace(): + Bdb().set_trace() + + +class Breakpoint: + + """Breakpoint class + + Implements temporary breakpoints, ignore counts, disabling and + (re)-enabling, and conditionals. + + Breakpoints are indexed by number through bpbynumber and by + the file,line tuple using bplist. The former points to a + single instance of class Breakpoint. The latter points to a + list of such instances since there may be more than one + breakpoint per line. + + """ + + # XXX Keeping state in the class is a mistake -- this means + # you cannot have more than one active Bdb instance. + + next = 1 # Next bp to be assigned + bplist = {} # indexed by (file, lineno) tuple + bpbynumber = [None] # Each entry is None or an instance of Bpt + # index 0 is unused, except for marking an + # effective break .... see effective() + + def __init__(self, file, line, temporary=0, cond=None, funcname=None): + self.funcname = funcname + # Needed if funcname is not None. + self.func_first_executable_line = None + self.file = file # This better be in canonical form! + self.line = line + self.temporary = temporary + self.cond = cond + self.enabled = 1 + self.ignore = 0 + self.hits = 0 + self.number = Breakpoint.next + Breakpoint.next = Breakpoint.next + 1 + # Build the two lists + self.bpbynumber.append(self) + if (file, line) in self.bplist: + self.bplist[file, line].append(self) + else: + self.bplist[file, line] = [self] + + + def deleteMe(self): + index = (self.file, self.line) + self.bpbynumber[self.number] = None # No longer in list + self.bplist[index].remove(self) + if not self.bplist[index]: + # No more bp for this f:l combo + del self.bplist[index] + + def enable(self): + self.enabled = 1 + + def disable(self): + self.enabled = 0 + + def bpprint(self, out=None): + if out is None: + out = sys.stdout + if self.temporary: + disp = 'del ' + else: + disp = 'keep ' + if self.enabled: + disp = disp + 'yes ' + else: + disp = disp + 'no ' + print >>out, '%-4dbreakpoint %s at %s:%d' % (self.number, disp, + self.file, self.line) + if self.cond: + print >>out, '\tstop only if %s' % (self.cond,) + if self.ignore: + print >>out, '\tignore next %d hits' % (self.ignore) + if (self.hits): + if (self.hits > 1): ss = 's' + else: ss = '' + print >>out, ('\tbreakpoint already hit %d time%s' % + (self.hits, ss)) + +# -----------end of Breakpoint class---------- + +def checkfuncname(b, frame): + """Check whether we should break here because of `b.funcname`.""" + if not b.funcname: + # Breakpoint was set via line number. + if b.line != frame.f_lineno: + # Breakpoint was set at a line with a def statement and the function + # defined is called: don't break. + return False + return True + + # Breakpoint set via function name. + + if frame.f_code.co_name != b.funcname: + # It's not a function call, but rather execution of def statement. + return False + + # We are in the right frame. + if not b.func_first_executable_line: + # The function is entered for the 1st time. + b.func_first_executable_line = frame.f_lineno + + if b.func_first_executable_line != frame.f_lineno: + # But we are not at the first line number: don't break. + return False + return True + +# Determines if there is an effective (active) breakpoint at this +# line of code. Returns breakpoint number or 0 if none +def effective(file, line, frame): + """Determine which breakpoint for this file:line is to be acted upon. + + Called only if we know there is a bpt at this + location. Returns breakpoint that was triggered and a flag + that indicates if it is ok to delete a temporary bp. + + """ + possibles = Breakpoint.bplist[file,line] + for i in range(0, len(possibles)): + b = possibles[i] + if b.enabled == 0: + continue + if not checkfuncname(b, frame): + continue + # Count every hit when bp is enabled + b.hits = b.hits + 1 + if not b.cond: + # If unconditional, and ignoring, + # go on to next, else break + if b.ignore > 0: + b.ignore = b.ignore -1 + continue + else: + # breakpoint and marker that's ok + # to delete if temporary + return (b,1) + else: + # Conditional bp. + # Ignore count applies only to those bpt hits where the + # condition evaluates to true. + try: + val = eval(b.cond, frame.f_globals, + frame.f_locals) + if val: + if b.ignore > 0: + b.ignore = b.ignore -1 + # continue + else: + return (b,1) + # else: + # continue + except: + # if eval fails, most conservative + # thing is to stop on breakpoint + # regardless of ignore count. + # Don't delete temporary, + # as another hint to user. + return (b,0) + return (None, None) + +# -------------------- testing -------------------- + +class Tdb(Bdb): + def user_call(self, frame, args): + name = frame.f_code.co_name + if not name: name = '???' + print '+++ call', name, args + def user_line(self, frame): + import linecache + name = frame.f_code.co_name + if not name: name = '???' + fn = self.canonic(frame.f_code.co_filename) + line = linecache.getline(fn, frame.f_lineno, frame.f_globals) + print '+++', fn, frame.f_lineno, name, ':', line.strip() + def user_return(self, frame, retval): + print '+++ return', retval + def user_exception(self, frame, exc_stuff): + print '+++ exception', exc_stuff + self.set_continue() + +def foo(n): + print 'foo(', n, ')' + x = bar(n*10) + print 'bar returned', x + +def bar(a): + print 'bar(', a, ')' + return a/2 + +def test(): + t = Tdb() + t.run('import bdb; bdb.foo(10)') + +# end diff --git a/src/main/resources/PythonLibs/binhex.py b/src/main/resources/PythonLibs/binhex.py new file mode 100644 index 0000000000000000000000000000000000000000..8abc9f3e14c17a2f7421e8a7472993bb686047f4 --- /dev/null +++ b/src/main/resources/PythonLibs/binhex.py @@ -0,0 +1,508 @@ +"""Macintosh binhex compression/decompression. + +easy interface: +binhex(inputfilename, outputfilename) +hexbin(inputfilename, outputfilename) +""" + +# +# Jack Jansen, CWI, August 1995. +# +# The module is supposed to be as compatible as possible. Especially the +# easy interface should work "as expected" on any platform. +# XXXX Note: currently, textfiles appear in mac-form on all platforms. +# We seem to lack a simple character-translate in python. +# (we should probably use ISO-Latin-1 on all but the mac platform). +# XXXX The simple routines are too simple: they expect to hold the complete +# files in-core. Should be fixed. +# XXXX It would be nice to handle AppleDouble format on unix +# (for servers serving macs). +# XXXX I don't understand what happens when you get 0x90 times the same byte on +# input. The resulting code (xx 90 90) would appear to be interpreted as an +# escaped *value* of 0x90. All coders I've seen appear to ignore this nicety... +# +import sys +import os +import struct +import binascii + +__all__ = ["binhex","hexbin","Error"] + +class Error(Exception): + pass + +# States (what have we written) +[_DID_HEADER, _DID_DATA, _DID_RSRC] = range(3) + +# Various constants +REASONABLY_LARGE=32768 # Minimal amount we pass the rle-coder +LINELEN=64 +RUNCHAR=chr(0x90) # run-length introducer + +# +# This code is no longer byte-order dependent + +# +# Workarounds for non-mac machines. +try: + from Carbon.File import FSSpec, FInfo + from MacOS import openrf + + def getfileinfo(name): + finfo = FSSpec(name).FSpGetFInfo() + dir, file = os.path.split(name) + # XXX Get resource/data sizes + fp = open(name, 'rb') + fp.seek(0, 2) + dlen = fp.tell() + fp = openrf(name, '*rb') + fp.seek(0, 2) + rlen = fp.tell() + return file, finfo, dlen, rlen + + def openrsrc(name, *mode): + if not mode: + mode = '*rb' + else: + mode = '*' + mode[0] + return openrf(name, mode) + +except ImportError: + # + # Glue code for non-macintosh usage + # + + class FInfo: + def __init__(self): + self.Type = '????' + self.Creator = '????' + self.Flags = 0 + + def getfileinfo(name): + finfo = FInfo() + # Quick check for textfile + fp = open(name) + data = open(name).read(256) + for c in data: + if not c.isspace() and (c<' ' or ord(c) > 0x7f): + break + else: + finfo.Type = 'TEXT' + fp.seek(0, 2) + dsize = fp.tell() + fp.close() + dir, file = os.path.split(name) + file = file.replace(':', '-', 1) + return file, finfo, dsize, 0 + + class openrsrc: + def __init__(self, *args): + pass + + def read(self, *args): + return '' + + def write(self, *args): + pass + + def close(self): + pass + +class _Hqxcoderengine: + """Write data to the coder in 3-byte chunks""" + + def __init__(self, ofp): + self.ofp = ofp + self.data = '' + self.hqxdata = '' + self.linelen = LINELEN-1 + + def write(self, data): + self.data = self.data + data + datalen = len(self.data) + todo = (datalen//3)*3 + data = self.data[:todo] + self.data = self.data[todo:] + if not data: + return + self.hqxdata = self.hqxdata + binascii.b2a_hqx(data) + self._flush(0) + + def _flush(self, force): + first = 0 + while first <= len(self.hqxdata)-self.linelen: + last = first + self.linelen + self.ofp.write(self.hqxdata[first:last]+'\n') + self.linelen = LINELEN + first = last + self.hqxdata = self.hqxdata[first:] + if force: + self.ofp.write(self.hqxdata + ':\n') + + def close(self): + if self.data: + self.hqxdata = \ + self.hqxdata + binascii.b2a_hqx(self.data) + self._flush(1) + self.ofp.close() + del self.ofp + +class _Rlecoderengine: + """Write data to the RLE-coder in suitably large chunks""" + + def __init__(self, ofp): + self.ofp = ofp + self.data = '' + + def write(self, data): + self.data = self.data + data + if len(self.data) < REASONABLY_LARGE: + return + rledata = binascii.rlecode_hqx(self.data) + self.ofp.write(rledata) + self.data = '' + + def close(self): + if self.data: + rledata = binascii.rlecode_hqx(self.data) + self.ofp.write(rledata) + self.ofp.close() + del self.ofp + +class BinHex: + def __init__(self, name_finfo_dlen_rlen, ofp): + name, finfo, dlen, rlen = name_finfo_dlen_rlen + if type(ofp) == type(''): + ofname = ofp + ofp = open(ofname, 'w') + ofp.write('(This file must be converted with BinHex 4.0)\n\n:') + hqxer = _Hqxcoderengine(ofp) + self.ofp = _Rlecoderengine(hqxer) + self.crc = 0 + if finfo is None: + finfo = FInfo() + self.dlen = dlen + self.rlen = rlen + self._writeinfo(name, finfo) + self.state = _DID_HEADER + + def _writeinfo(self, name, finfo): + nl = len(name) + if nl > 63: + raise Error, 'Filename too long' + d = chr(nl) + name + '\0' + d2 = finfo.Type + finfo.Creator + + # Force all structs to be packed with big-endian + d3 = struct.pack('>h', finfo.Flags) + d4 = struct.pack('>ii', self.dlen, self.rlen) + info = d + d2 + d3 + d4 + self._write(info) + self._writecrc() + + def _write(self, data): + self.crc = binascii.crc_hqx(data, self.crc) + self.ofp.write(data) + + def _writecrc(self): + # XXXX Should this be here?? + # self.crc = binascii.crc_hqx('\0\0', self.crc) + if self.crc < 0: + fmt = '>h' + else: + fmt = '>H' + self.ofp.write(struct.pack(fmt, self.crc)) + self.crc = 0 + + def write(self, data): + if self.state != _DID_HEADER: + raise Error, 'Writing data at the wrong time' + self.dlen = self.dlen - len(data) + self._write(data) + + def close_data(self): + if self.dlen != 0: + raise Error, 'Incorrect data size, diff=%r' % (self.rlen,) + self._writecrc() + self.state = _DID_DATA + + def write_rsrc(self, data): + if self.state < _DID_DATA: + self.close_data() + if self.state != _DID_DATA: + raise Error, 'Writing resource data at the wrong time' + self.rlen = self.rlen - len(data) + self._write(data) + + def close(self): + if self.state < _DID_DATA: + self.close_data() + if self.state != _DID_DATA: + raise Error, 'Close at the wrong time' + if self.rlen != 0: + raise Error, \ + "Incorrect resource-datasize, diff=%r" % (self.rlen,) + self._writecrc() + self.ofp.close() + self.state = None + del self.ofp + +def binhex(inp, out): + """(infilename, outfilename) - Create binhex-encoded copy of a file""" + finfo = getfileinfo(inp) + ofp = BinHex(finfo, out) + + ifp = open(inp, 'rb') + # XXXX Do textfile translation on non-mac systems + while 1: + d = ifp.read(128000) + if not d: break + ofp.write(d) + ofp.close_data() + ifp.close() + + ifp = openrsrc(inp, 'rb') + while 1: + d = ifp.read(128000) + if not d: break + ofp.write_rsrc(d) + ofp.close() + ifp.close() + +class _Hqxdecoderengine: + """Read data via the decoder in 4-byte chunks""" + + def __init__(self, ifp): + self.ifp = ifp + self.eof = 0 + + def read(self, totalwtd): + """Read at least wtd bytes (or until EOF)""" + decdata = '' + wtd = totalwtd + # + # The loop here is convoluted, since we don't really now how + # much to decode: there may be newlines in the incoming data. + while wtd > 0: + if self.eof: return decdata + wtd = ((wtd+2)//3)*4 + data = self.ifp.read(wtd) + # + # Next problem: there may not be a complete number of + # bytes in what we pass to a2b. Solve by yet another + # loop. + # + while 1: + try: + decdatacur, self.eof = \ + binascii.a2b_hqx(data) + break + except binascii.Incomplete: + pass + newdata = self.ifp.read(1) + if not newdata: + raise Error, \ + 'Premature EOF on binhex file' + data = data + newdata + decdata = decdata + decdatacur + wtd = totalwtd - len(decdata) + if not decdata and not self.eof: + raise Error, 'Premature EOF on binhex file' + return decdata + + def close(self): + self.ifp.close() + +class _Rledecoderengine: + """Read data via the RLE-coder""" + + def __init__(self, ifp): + self.ifp = ifp + self.pre_buffer = '' + self.post_buffer = '' + self.eof = 0 + + def read(self, wtd): + if wtd > len(self.post_buffer): + self._fill(wtd-len(self.post_buffer)) + rv = self.post_buffer[:wtd] + self.post_buffer = self.post_buffer[wtd:] + return rv + + def _fill(self, wtd): + self.pre_buffer = self.pre_buffer + self.ifp.read(wtd+4) + if self.ifp.eof: + self.post_buffer = self.post_buffer + \ + binascii.rledecode_hqx(self.pre_buffer) + self.pre_buffer = '' + return + + # + # Obfuscated code ahead. We have to take care that we don't + # end up with an orphaned RUNCHAR later on. So, we keep a couple + # of bytes in the buffer, depending on what the end of + # the buffer looks like: + # '\220\0\220' - Keep 3 bytes: repeated \220 (escaped as \220\0) + # '?\220' - Keep 2 bytes: repeated something-else + # '\220\0' - Escaped \220: Keep 2 bytes. + # '?\220?' - Complete repeat sequence: decode all + # otherwise: keep 1 byte. + # + mark = len(self.pre_buffer) + if self.pre_buffer[-3:] == RUNCHAR + '\0' + RUNCHAR: + mark = mark - 3 + elif self.pre_buffer[-1] == RUNCHAR: + mark = mark - 2 + elif self.pre_buffer[-2:] == RUNCHAR + '\0': + mark = mark - 2 + elif self.pre_buffer[-2] == RUNCHAR: + pass # Decode all + else: + mark = mark - 1 + + self.post_buffer = self.post_buffer + \ + binascii.rledecode_hqx(self.pre_buffer[:mark]) + self.pre_buffer = self.pre_buffer[mark:] + + def close(self): + self.ifp.close() + +class HexBin: + def __init__(self, ifp): + if type(ifp) == type(''): + ifp = open(ifp) + # + # Find initial colon. + # + while 1: + ch = ifp.read(1) + if not ch: + raise Error, "No binhex data found" + # Cater for \r\n terminated lines (which show up as \n\r, hence + # all lines start with \r) + if ch == '\r': + continue + if ch == ':': + break + if ch != '\n': + dummy = ifp.readline() + + hqxifp = _Hqxdecoderengine(ifp) + self.ifp = _Rledecoderengine(hqxifp) + self.crc = 0 + self._readheader() + + def _read(self, len): + data = self.ifp.read(len) + self.crc = binascii.crc_hqx(data, self.crc) + return data + + def _checkcrc(self): + filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff + #self.crc = binascii.crc_hqx('\0\0', self.crc) + # XXXX Is this needed?? + self.crc = self.crc & 0xffff + if filecrc != self.crc: + raise Error, 'CRC error, computed %x, read %x' \ + %(self.crc, filecrc) + self.crc = 0 + + def _readheader(self): + len = self._read(1) + fname = self._read(ord(len)) + rest = self._read(1+4+4+2+4+4) + self._checkcrc() + + type = rest[1:5] + creator = rest[5:9] + flags = struct.unpack('>h', rest[9:11])[0] + self.dlen = struct.unpack('>l', rest[11:15])[0] + self.rlen = struct.unpack('>l', rest[15:19])[0] + + self.FName = fname + self.FInfo = FInfo() + self.FInfo.Creator = creator + self.FInfo.Type = type + self.FInfo.Flags = flags + + self.state = _DID_HEADER + + def read(self, *n): + if self.state != _DID_HEADER: + raise Error, 'Read data at wrong time' + if n: + n = n[0] + n = min(n, self.dlen) + else: + n = self.dlen + rv = '' + while len(rv) < n: + rv = rv + self._read(n-len(rv)) + self.dlen = self.dlen - n + return rv + + def close_data(self): + if self.state != _DID_HEADER: + raise Error, 'close_data at wrong time' + if self.dlen: + dummy = self._read(self.dlen) + self._checkcrc() + self.state = _DID_DATA + + def read_rsrc(self, *n): + if self.state == _DID_HEADER: + self.close_data() + if self.state != _DID_DATA: + raise Error, 'Read resource data at wrong time' + if n: + n = n[0] + n = min(n, self.rlen) + else: + n = self.rlen + self.rlen = self.rlen - n + return self._read(n) + + def close(self): + if self.rlen: + dummy = self.read_rsrc(self.rlen) + self._checkcrc() + self.state = _DID_RSRC + self.ifp.close() + +def hexbin(inp, out): + """(infilename, outfilename) - Decode binhexed file""" + ifp = HexBin(inp) + finfo = ifp.FInfo + if not out: + out = ifp.FName + + ofp = open(out, 'wb') + # XXXX Do translation on non-mac systems + while 1: + d = ifp.read(128000) + if not d: break + ofp.write(d) + ofp.close() + ifp.close_data() + + d = ifp.read_rsrc(128000) + if d: + ofp = openrsrc(out, 'wb') + ofp.write(d) + while 1: + d = ifp.read_rsrc(128000) + if not d: break + ofp.write(d) + ofp.close() + + ifp.close() + +def _test(): + fname = sys.argv[1] + binhex(fname, fname+'.hqx') + hexbin(fname+'.hqx', fname+'.viahqx') + #hexbin(fname, fname+'.unpacked') + sys.exit(1) + +if __name__ == '__main__': + _test() diff --git a/src/main/resources/PythonLibs/bisect.py b/src/main/resources/PythonLibs/bisect.py new file mode 100644 index 0000000000000000000000000000000000000000..4a4d05255e5810d5f918cd2176f915046d25e672 --- /dev/null +++ b/src/main/resources/PythonLibs/bisect.py @@ -0,0 +1,92 @@ +"""Bisection algorithms.""" + +def insort_right(a, x, lo=0, hi=None): + """Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the right of the rightmost x. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if x < a[mid]: hi = mid + else: lo = mid+1 + a.insert(lo, x) + +insort = insort_right # backward compatibility + +def bisect_right(a, x, lo=0, hi=None): + """Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e <= x, and all e in + a[i:] have e > x. So if x already appears in the list, a.insert(x) will + insert just after the rightmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if x < a[mid]: hi = mid + else: lo = mid+1 + return lo + +bisect = bisect_right # backward compatibility + +def insort_left(a, x, lo=0, hi=None): + """Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the left of the leftmost x. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if a[mid] < x: lo = mid+1 + else: hi = mid + a.insert(lo, x) + + +def bisect_left(a, x, lo=0, hi=None): + """Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e < x, and all e in + a[i:] have e >= x. So if x already appears in the list, a.insert(x) will + insert just before the leftmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if a[mid] < x: lo = mid+1 + else: hi = mid + return lo + +# Overwrite above definitions with a fast C implementation +try: + from _bisect import * +except ImportError: + pass diff --git a/src/main/resources/PythonLibs/calendar.py b/src/main/resources/PythonLibs/calendar.py new file mode 100644 index 0000000000000000000000000000000000000000..441b2f576bc31097a03f10b4897b7f77c545ee32 --- /dev/null +++ b/src/main/resources/PythonLibs/calendar.py @@ -0,0 +1,713 @@ +"""Calendar printing functions + +Note when comparing these calendars to the ones printed by cal(1): By +default, these calendars have Monday as the first day of the week, and +Sunday as the last (the European convention). Use setfirstweekday() to +set the first day of the week (0=Monday, 6=Sunday).""" + +import sys +import datetime +import locale as _locale + +__all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", + "firstweekday", "isleap", "leapdays", "weekday", "monthrange", + "monthcalendar", "prmonth", "month", "prcal", "calendar", + "timegm", "month_name", "month_abbr", "day_name", "day_abbr"] + +# Exception raised for bad input (with string parameter for details) +error = ValueError + +# Exceptions raised for bad input +class IllegalMonthError(ValueError): + def __init__(self, month): + self.month = month + def __str__(self): + return "bad month number %r; must be 1-12" % self.month + + +class IllegalWeekdayError(ValueError): + def __init__(self, weekday): + self.weekday = weekday + def __str__(self): + return "bad weekday number %r; must be 0 (Monday) to 6 (Sunday)" % self.weekday + + +# Constants for months referenced later +January = 1 +February = 2 + +# Number of days per month (except for February in leap years) +mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +# This module used to have hard-coded lists of day and month names, as +# English strings. The classes following emulate a read-only version of +# that, but supply localized names. Note that the values are computed +# fresh on each call, in case the user changes locale between calls. + +class _localized_month: + + _months = [datetime.date(2001, i+1, 1).strftime for i in range(12)] + _months.insert(0, lambda x: "") + + def __init__(self, format): + self.format = format + + def __getitem__(self, i): + funcs = self._months[i] + if isinstance(i, slice): + return [f(self.format) for f in funcs] + else: + return funcs(self.format) + + def __len__(self): + return 13 + + +class _localized_day: + + # January 1, 2001, was a Monday. + _days = [datetime.date(2001, 1, i+1).strftime for i in range(7)] + + def __init__(self, format): + self.format = format + + def __getitem__(self, i): + funcs = self._days[i] + if isinstance(i, slice): + return [f(self.format) for f in funcs] + else: + return funcs(self.format) + + def __len__(self): + return 7 + + +# Full and abbreviated names of weekdays +day_name = _localized_day('%A') +day_abbr = _localized_day('%a') + +# Full and abbreviated names of months (1-based arrays!!!) +month_name = _localized_month('%B') +month_abbr = _localized_month('%b') + +# Constants for weekdays +(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) + + +def isleap(year): + """Return True for leap years, False for non-leap years.""" + return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) + + +def leapdays(y1, y2): + """Return number of leap years in range [y1, y2). + Assume y1 <= y2.""" + y1 -= 1 + y2 -= 1 + return (y2//4 - y1//4) - (y2//100 - y1//100) + (y2//400 - y1//400) + + +def weekday(year, month, day): + """Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12), + day (1-31).""" + return datetime.date(year, month, day).weekday() + + +def monthrange(year, month): + """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for + year, month.""" + if not 1 <= month <= 12: + raise IllegalMonthError(month) + day1 = weekday(year, month, 1) + ndays = mdays[month] + (month == February and isleap(year)) + return day1, ndays + + +class Calendar(object): + """ + Base calendar class. This class doesn't do any formatting. It simply + provides data to subclasses. + """ + + def __init__(self, firstweekday=0): + self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday + + def getfirstweekday(self): + return self._firstweekday % 7 + + def setfirstweekday(self, firstweekday): + self._firstweekday = firstweekday + + firstweekday = property(getfirstweekday, setfirstweekday) + + def iterweekdays(self): + """ + Return a iterator for one week of weekday numbers starting with the + configured first one. + """ + for i in range(self.firstweekday, self.firstweekday + 7): + yield i%7 + + def itermonthdates(self, year, month): + """ + Return an iterator for one month. The iterator will yield datetime.date + values and will always iterate through complete weeks, so it will yield + dates outside the specified month. + """ + date = datetime.date(year, month, 1) + # Go back to the beginning of the week + days = (date.weekday() - self.firstweekday) % 7 + date -= datetime.timedelta(days=days) + oneday = datetime.timedelta(days=1) + while True: + yield date + try: + date += oneday + except OverflowError: + # Adding one day could fail after datetime.MAXYEAR + break + if date.month != month and date.weekday() == self.firstweekday: + break + + def itermonthdays2(self, year, month): + """ + Like itermonthdates(), but will yield (day number, weekday number) + tuples. For days outside the specified month the day number is 0. + """ + for date in self.itermonthdates(year, month): + if date.month != month: + yield (0, date.weekday()) + else: + yield (date.day, date.weekday()) + + def itermonthdays(self, year, month): + """ + Like itermonthdates(), but will yield day numbers. For days outside + the specified month the day number is 0. + """ + for date in self.itermonthdates(year, month): + if date.month != month: + yield 0 + else: + yield date.day + + def monthdatescalendar(self, year, month): + """ + Return a matrix (list of lists) representing a month's calendar. + Each row represents a week; week entries are datetime.date values. + """ + dates = list(self.itermonthdates(year, month)) + return [ dates[i:i+7] for i in range(0, len(dates), 7) ] + + def monthdays2calendar(self, year, month): + """ + Return a matrix representing a month's calendar. + Each row represents a week; week entries are + (day number, weekday number) tuples. Day numbers outside this month + are zero. + """ + days = list(self.itermonthdays2(year, month)) + return [ days[i:i+7] for i in range(0, len(days), 7) ] + + def monthdayscalendar(self, year, month): + """ + Return a matrix representing a month's calendar. + Each row represents a week; days outside this month are zero. + """ + days = list(self.itermonthdays(year, month)) + return [ days[i:i+7] for i in range(0, len(days), 7) ] + + def yeardatescalendar(self, year, width=3): + """ + Return the data for the specified year ready for formatting. The return + value is a list of month rows. Each month row contains upto width months. + Each month contains between 4 and 6 weeks and each week contains 1-7 + days. Days are datetime.date objects. + """ + months = [ + self.monthdatescalendar(year, i) + for i in range(January, January+12) + ] + return [months[i:i+width] for i in range(0, len(months), width) ] + + def yeardays2calendar(self, year, width=3): + """ + Return the data for the specified year ready for formatting (similar to + yeardatescalendar()). Entries in the week lists are + (day number, weekday number) tuples. Day numbers outside this month are + zero. + """ + months = [ + self.monthdays2calendar(year, i) + for i in range(January, January+12) + ] + return [months[i:i+width] for i in range(0, len(months), width) ] + + def yeardayscalendar(self, year, width=3): + """ + Return the data for the specified year ready for formatting (similar to + yeardatescalendar()). Entries in the week lists are day numbers. + Day numbers outside this month are zero. + """ + months = [ + self.monthdayscalendar(year, i) + for i in range(January, January+12) + ] + return [months[i:i+width] for i in range(0, len(months), width) ] + + +class TextCalendar(Calendar): + """ + Subclass of Calendar that outputs a calendar as a simple plain text + similar to the UNIX program cal. + """ + + def prweek(self, theweek, width): + """ + Print a single week (no newline). + """ + print self.formatweek(theweek, width), + + def formatday(self, day, weekday, width): + """ + Returns a formatted day. + """ + if day == 0: + s = '' + else: + s = '%2i' % day # right-align single-digit days + return s.center(width) + + def formatweek(self, theweek, width): + """ + Returns a single week in a string (no newline). + """ + return ' '.join(self.formatday(d, wd, width) for (d, wd) in theweek) + + def formatweekday(self, day, width): + """ + Returns a formatted week day name. + """ + if width >= 9: + names = day_name + else: + names = day_abbr + return names[day][:width].center(width) + + def formatweekheader(self, width): + """ + Return a header for a week. + """ + return ' '.join(self.formatweekday(i, width) for i in self.iterweekdays()) + + def formatmonthname(self, theyear, themonth, width, withyear=True): + """ + Return a formatted month name. + """ + s = month_name[themonth] + if withyear: + s = "%s %r" % (s, theyear) + return s.center(width) + + def prmonth(self, theyear, themonth, w=0, l=0): + """ + Print a month's calendar. + """ + print self.formatmonth(theyear, themonth, w, l), + + def formatmonth(self, theyear, themonth, w=0, l=0): + """ + Return a month's calendar string (multi-line). + """ + w = max(2, w) + l = max(1, l) + s = self.formatmonthname(theyear, themonth, 7 * (w + 1) - 1) + s = s.rstrip() + s += '\n' * l + s += self.formatweekheader(w).rstrip() + s += '\n' * l + for week in self.monthdays2calendar(theyear, themonth): + s += self.formatweek(week, w).rstrip() + s += '\n' * l + return s + + def formatyear(self, theyear, w=2, l=1, c=6, m=3): + """ + Returns a year's calendar as a multi-line string. + """ + w = max(2, w) + l = max(1, l) + c = max(2, c) + colwidth = (w + 1) * 7 - 1 + v = [] + a = v.append + a(repr(theyear).center(colwidth*m+c*(m-1)).rstrip()) + a('\n'*l) + header = self.formatweekheader(w) + for (i, row) in enumerate(self.yeardays2calendar(theyear, m)): + # months in this row + months = range(m*i+1, min(m*(i+1)+1, 13)) + a('\n'*l) + names = (self.formatmonthname(theyear, k, colwidth, False) + for k in months) + a(formatstring(names, colwidth, c).rstrip()) + a('\n'*l) + headers = (header for k in months) + a(formatstring(headers, colwidth, c).rstrip()) + a('\n'*l) + # max number of weeks for this row + height = max(len(cal) for cal in row) + for j in range(height): + weeks = [] + for cal in row: + if j >= len(cal): + weeks.append('') + else: + weeks.append(self.formatweek(cal[j], w)) + a(formatstring(weeks, colwidth, c).rstrip()) + a('\n' * l) + return ''.join(v) + + def pryear(self, theyear, w=0, l=0, c=6, m=3): + """Print a year's calendar.""" + print self.formatyear(theyear, w, l, c, m) + + +class HTMLCalendar(Calendar): + """ + This calendar returns complete HTML pages. + """ + + # CSS classes for the day <td>s + cssclasses = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] + + def formatday(self, day, weekday): + """ + Return a day as a table cell. + """ + if day == 0: + return '<td class="noday"> </td>' # day outside month + else: + return '<td class="%s">%d</td>' % (self.cssclasses[weekday], day) + + def formatweek(self, theweek): + """ + Return a complete week as a table row. + """ + s = ''.join(self.formatday(d, wd) for (d, wd) in theweek) + return '<tr>%s</tr>' % s + + def formatweekday(self, day): + """ + Return a weekday name as a table header. + """ + return '<th class="%s">%s</th>' % (self.cssclasses[day], day_abbr[day]) + + def formatweekheader(self): + """ + Return a header for a week as a table row. + """ + s = ''.join(self.formatweekday(i) for i in self.iterweekdays()) + return '<tr>%s</tr>' % s + + def formatmonthname(self, theyear, themonth, withyear=True): + """ + Return a month name as a table row. + """ + if withyear: + s = '%s %s' % (month_name[themonth], theyear) + else: + s = '%s' % month_name[themonth] + return '<tr><th colspan="7" class="month">%s</th></tr>' % s + + def formatmonth(self, theyear, themonth, withyear=True): + """ + Return a formatted month as a table. + """ + v = [] + a = v.append + a('<table border="0" cellpadding="0" cellspacing="0" class="month">') + a('\n') + a(self.formatmonthname(theyear, themonth, withyear=withyear)) + a('\n') + a(self.formatweekheader()) + a('\n') + for week in self.monthdays2calendar(theyear, themonth): + a(self.formatweek(week)) + a('\n') + a('</table>') + a('\n') + return ''.join(v) + + def formatyear(self, theyear, width=3): + """ + Return a formatted year as a table of tables. + """ + v = [] + a = v.append + width = max(width, 1) + a('<table border="0" cellpadding="0" cellspacing="0" class="year">') + a('\n') + a('<tr><th colspan="%d" class="year">%s</th></tr>' % (width, theyear)) + for i in range(January, January+12, width): + # months in this row + months = range(i, min(i+width, 13)) + a('<tr>') + for m in months: + a('<td>') + a(self.formatmonth(theyear, m, withyear=False)) + a('</td>') + a('</tr>') + a('</table>') + return ''.join(v) + + def formatyearpage(self, theyear, width=3, css='calendar.css', encoding=None): + """ + Return a formatted year as a complete HTML page. + """ + if encoding is None: + encoding = sys.getdefaultencoding() + v = [] + a = v.append + a('<?xml version="1.0" encoding="%s"?>\n' % encoding) + a('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n') + a('<html>\n') + a('<head>\n') + a('<meta http-equiv="Content-Type" content="text/html; charset=%s" />\n' % encoding) + if css is not None: + a('<link rel="stylesheet" type="text/css" href="%s" />\n' % css) + a('<title>Calendar for %d</title>\n' % theyear) + a('</head>\n') + a('<body>\n') + a(self.formatyear(theyear, width)) + a('</body>\n') + a('</html>\n') + return ''.join(v).encode(encoding, "xmlcharrefreplace") + + +class TimeEncoding: + def __init__(self, locale): + self.locale = locale + + def __enter__(self): + self.oldlocale = _locale.getlocale(_locale.LC_TIME) + _locale.setlocale(_locale.LC_TIME, self.locale) + return _locale.getlocale(_locale.LC_TIME)[1] + + def __exit__(self, *args): + _locale.setlocale(_locale.LC_TIME, self.oldlocale) + + +class LocaleTextCalendar(TextCalendar): + """ + This class can be passed a locale name in the constructor and will return + month and weekday names in the specified locale. If this locale includes + an encoding all strings containing month and weekday names will be returned + as unicode. + """ + + def __init__(self, firstweekday=0, locale=None): + TextCalendar.__init__(self, firstweekday) + if locale is None: + locale = _locale.getdefaultlocale() + self.locale = locale + + def formatweekday(self, day, width): + with TimeEncoding(self.locale) as encoding: + if width >= 9: + names = day_name + else: + names = day_abbr + name = names[day] + if encoding is not None: + name = name.decode(encoding) + return name[:width].center(width) + + def formatmonthname(self, theyear, themonth, width, withyear=True): + with TimeEncoding(self.locale) as encoding: + s = month_name[themonth] + if encoding is not None: + s = s.decode(encoding) + if withyear: + s = "%s %r" % (s, theyear) + return s.center(width) + + +class LocaleHTMLCalendar(HTMLCalendar): + """ + This class can be passed a locale name in the constructor and will return + month and weekday names in the specified locale. If this locale includes + an encoding all strings containing month and weekday names will be returned + as unicode. + """ + def __init__(self, firstweekday=0, locale=None): + HTMLCalendar.__init__(self, firstweekday) + if locale is None: + locale = _locale.getdefaultlocale() + self.locale = locale + + def formatweekday(self, day): + with TimeEncoding(self.locale) as encoding: + s = day_abbr[day] + if encoding is not None: + s = s.decode(encoding) + return '<th class="%s">%s</th>' % (self.cssclasses[day], s) + + def formatmonthname(self, theyear, themonth, withyear=True): + with TimeEncoding(self.locale) as encoding: + s = month_name[themonth] + if encoding is not None: + s = s.decode(encoding) + if withyear: + s = '%s %s' % (s, theyear) + return '<tr><th colspan="7" class="month">%s</th></tr>' % s + + +# Support for old module level interface +c = TextCalendar() + +firstweekday = c.getfirstweekday + +def setfirstweekday(firstweekday): + try: + firstweekday.__index__ + except AttributeError: + raise IllegalWeekdayError(firstweekday) + if not MONDAY <= firstweekday <= SUNDAY: + raise IllegalWeekdayError(firstweekday) + c.firstweekday = firstweekday + +monthcalendar = c.monthdayscalendar +prweek = c.prweek +week = c.formatweek +weekheader = c.formatweekheader +prmonth = c.prmonth +month = c.formatmonth +calendar = c.formatyear +prcal = c.pryear + + +# Spacing of month columns for multi-column year calendar +_colwidth = 7*3 - 1 # Amount printed by prweek() +_spacing = 6 # Number of spaces between columns + + +def format(cols, colwidth=_colwidth, spacing=_spacing): + """Prints multi-column formatting for year calendars""" + print formatstring(cols, colwidth, spacing) + + +def formatstring(cols, colwidth=_colwidth, spacing=_spacing): + """Returns a string formatted from n strings, centered within n columns.""" + spacing *= ' ' + return spacing.join(c.center(colwidth) for c in cols) + + +EPOCH = 1970 +_EPOCH_ORD = datetime.date(EPOCH, 1, 1).toordinal() + + +def timegm(tuple): + """Unrelated but handy function to calculate Unix timestamp from GMT.""" + year, month, day, hour, minute, second = tuple[:6] + days = datetime.date(year, month, 1).toordinal() - _EPOCH_ORD + day - 1 + hours = days*24 + hour + minutes = hours*60 + minute + seconds = minutes*60 + second + return seconds + + +def main(args): + import optparse + parser = optparse.OptionParser(usage="usage: %prog [options] [year [month]]") + parser.add_option( + "-w", "--width", + dest="width", type="int", default=2, + help="width of date column (default 2, text only)" + ) + parser.add_option( + "-l", "--lines", + dest="lines", type="int", default=1, + help="number of lines for each week (default 1, text only)" + ) + parser.add_option( + "-s", "--spacing", + dest="spacing", type="int", default=6, + help="spacing between months (default 6, text only)" + ) + parser.add_option( + "-m", "--months", + dest="months", type="int", default=3, + help="months per row (default 3, text only)" + ) + parser.add_option( + "-c", "--css", + dest="css", default="calendar.css", + help="CSS to use for page (html only)" + ) + parser.add_option( + "-L", "--locale", + dest="locale", default=None, + help="locale to be used from month and weekday names" + ) + parser.add_option( + "-e", "--encoding", + dest="encoding", default=None, + help="Encoding to use for output" + ) + parser.add_option( + "-t", "--type", + dest="type", default="text", + choices=("text", "html"), + help="output type (text or html)" + ) + + (options, args) = parser.parse_args(args) + + if options.locale and not options.encoding: + parser.error("if --locale is specified --encoding is required") + sys.exit(1) + + locale = options.locale, options.encoding + + if options.type == "html": + if options.locale: + cal = LocaleHTMLCalendar(locale=locale) + else: + cal = HTMLCalendar() + encoding = options.encoding + if encoding is None: + encoding = sys.getdefaultencoding() + optdict = dict(encoding=encoding, css=options.css) + if len(args) == 1: + print cal.formatyearpage(datetime.date.today().year, **optdict) + elif len(args) == 2: + print cal.formatyearpage(int(args[1]), **optdict) + else: + parser.error("incorrect number of arguments") + sys.exit(1) + else: + if options.locale: + cal = LocaleTextCalendar(locale=locale) + else: + cal = TextCalendar() + optdict = dict(w=options.width, l=options.lines) + if len(args) != 3: + optdict["c"] = options.spacing + optdict["m"] = options.months + if len(args) == 1: + result = cal.formatyear(datetime.date.today().year, **optdict) + elif len(args) == 2: + result = cal.formatyear(int(args[1]), **optdict) + elif len(args) == 3: + result = cal.formatmonth(int(args[1]), int(args[2]), **optdict) + else: + parser.error("incorrect number of arguments") + sys.exit(1) + if options.encoding: + result = result.encode(options.encoding) + print result + + +if __name__ == "__main__": + main(sys.argv) diff --git a/src/main/resources/PythonLibs/cgi.py b/src/main/resources/PythonLibs/cgi.py new file mode 100644 index 0000000000000000000000000000000000000000..67079db0d81a7cdb9d130f1a0c316b6468d453a0 --- /dev/null +++ b/src/main/resources/PythonLibs/cgi.py @@ -0,0 +1,1050 @@ +#! /usr/local/bin/python + +# NOTE: the above "/usr/local/bin/python" is NOT a mistake. It is +# intentionally NOT "/usr/bin/env python". On many systems +# (e.g. Solaris), /usr/local/bin is not in $PATH as passed to CGI +# scripts, and /usr/local/bin is the default directory where Python is +# installed, so /usr/bin/env would be unable to find python. Granted, +# binary installations by Linux vendors often install Python in +# /usr/bin. So let those vendors patch cgi.py to match their choice +# of installation. + +"""Support module for CGI (Common Gateway Interface) scripts. + +This module defines a number of utilities for use by CGI scripts +written in Python. +""" + +# XXX Perhaps there should be a slimmed version that doesn't contain +# all those backwards compatible and debugging classes and functions? + +# History +# ------- +# +# Michael McLay started this module. Steve Majewski changed the +# interface to SvFormContentDict and FormContentDict. The multipart +# parsing was inspired by code submitted by Andreas Paepcke. Guido van +# Rossum rewrote, reformatted and documented the module and is currently +# responsible for its maintenance. +# + +__version__ = "2.6" + + +# Imports +# ======= + +from operator import attrgetter +import sys +import os +import UserDict +import urlparse + +from warnings import filterwarnings, catch_warnings, warn +with catch_warnings(): + if sys.py3kwarning: + filterwarnings("ignore", ".*mimetools has been removed", + DeprecationWarning) + filterwarnings("ignore", ".*rfc822 has been removed", + DeprecationWarning) + import mimetools + import rfc822 + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +__all__ = ["MiniFieldStorage", "FieldStorage", "FormContentDict", + "SvFormContentDict", "InterpFormContentDict", "FormContent", + "parse", "parse_qs", "parse_qsl", "parse_multipart", + "parse_header", "print_exception", "print_environ", + "print_form", "print_directory", "print_arguments", + "print_environ_usage", "escape"] + +# Logging support +# =============== + +logfile = "" # Filename to log to, if not empty +logfp = None # File object to log to, if not None + +def initlog(*allargs): + """Write a log message, if there is a log file. + + Even though this function is called initlog(), you should always + use log(); log is a variable that is set either to initlog + (initially), to dolog (once the log file has been opened), or to + nolog (when logging is disabled). + + The first argument is a format string; the remaining arguments (if + any) are arguments to the % operator, so e.g. + log("%s: %s", "a", "b") + will write "a: b" to the log file, followed by a newline. + + If the global logfp is not None, it should be a file object to + which log data is written. + + If the global logfp is None, the global logfile may be a string + giving a filename to open, in append mode. This file should be + world writable!!! If the file can't be opened, logging is + silently disabled (since there is no safe place where we could + send an error message). + + """ + global logfp, log + if logfile and not logfp: + try: + logfp = open(logfile, "a") + except IOError: + pass + if not logfp: + log = nolog + else: + log = dolog + log(*allargs) + +def dolog(fmt, *args): + """Write a log message to the log file. See initlog() for docs.""" + logfp.write(fmt%args + "\n") + +def nolog(*allargs): + """Dummy function, assigned to log when logging is disabled.""" + pass + +log = initlog # The current logging function + + +# Parsing functions +# ================= + +# Maximum input we will accept when REQUEST_METHOD is POST +# 0 ==> unlimited input +maxlen = 0 + +def parse(fp=None, environ=os.environ, keep_blank_values=0, strict_parsing=0): + """Parse a query in the environment or from a file (default stdin) + + Arguments, all optional: + + fp : file pointer; default: sys.stdin + + environ : environment dictionary; default: os.environ + + keep_blank_values: flag indicating whether blank values in + percent-encoded forms should be treated as blank strings. + A true value indicates that blanks should be retained as + blank strings. The default false value indicates that + blank values are to be ignored and treated as if they were + not included. + + strict_parsing: flag indicating what to do with parsing errors. + If false (the default), errors are silently ignored. + If true, errors raise a ValueError exception. + """ + if fp is None: + fp = sys.stdin + if not 'REQUEST_METHOD' in environ: + environ['REQUEST_METHOD'] = 'GET' # For testing stand-alone + if environ['REQUEST_METHOD'] == 'POST': + ctype, pdict = parse_header(environ['CONTENT_TYPE']) + if ctype == 'multipart/form-data': + return parse_multipart(fp, pdict) + elif ctype == 'application/x-www-form-urlencoded': + clength = int(environ['CONTENT_LENGTH']) + if maxlen and clength > maxlen: + raise ValueError, 'Maximum content length exceeded' + qs = fp.read(clength) + else: + qs = '' # Unknown content-type + if 'QUERY_STRING' in environ: + if qs: qs = qs + '&' + qs = qs + environ['QUERY_STRING'] + elif sys.argv[1:]: + if qs: qs = qs + '&' + qs = qs + sys.argv[1] + environ['QUERY_STRING'] = qs # XXX Shouldn't, really + elif 'QUERY_STRING' in environ: + qs = environ['QUERY_STRING'] + else: + if sys.argv[1:]: + qs = sys.argv[1] + else: + qs = "" + environ['QUERY_STRING'] = qs # XXX Shouldn't, really + return urlparse.parse_qs(qs, keep_blank_values, strict_parsing) + + +# parse query string function called from urlparse, +# this is done in order to maintain backward compatiblity. + +def parse_qs(qs, keep_blank_values=0, strict_parsing=0): + """Parse a query given as a string argument.""" + warn("cgi.parse_qs is deprecated, use urlparse.parse_qs instead", + PendingDeprecationWarning, 2) + return urlparse.parse_qs(qs, keep_blank_values, strict_parsing) + + +def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): + """Parse a query given as a string argument.""" + warn("cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead", + PendingDeprecationWarning, 2) + return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing) + +def parse_multipart(fp, pdict): + """Parse multipart input. + + Arguments: + fp : input file + pdict: dictionary containing other parameters of content-type header + + Returns a dictionary just like parse_qs(): keys are the field names, each + value is a list of values for that field. This is easy to use but not + much good if you are expecting megabytes to be uploaded -- in that case, + use the FieldStorage class instead which is much more flexible. Note + that content-type is the raw, unparsed contents of the content-type + header. + + XXX This does not parse nested multipart parts -- use FieldStorage for + that. + + XXX This should really be subsumed by FieldStorage altogether -- no + point in having two implementations of the same parsing algorithm. + Also, FieldStorage protects itself better against certain DoS attacks + by limiting the size of the data read in one chunk. The API here + does not support that kind of protection. This also affects parse() + since it can call parse_multipart(). + + """ + boundary = "" + if 'boundary' in pdict: + boundary = pdict['boundary'] + if not valid_boundary(boundary): + raise ValueError, ('Invalid boundary in multipart form: %r' + % (boundary,)) + + nextpart = "--" + boundary + lastpart = "--" + boundary + "--" + partdict = {} + terminator = "" + + while terminator != lastpart: + bytes = -1 + data = None + if terminator: + # At start of next part. Read headers first. + headers = mimetools.Message(fp) + clength = headers.getheader('content-length') + if clength: + try: + bytes = int(clength) + except ValueError: + pass + if bytes > 0: + if maxlen and bytes > maxlen: + raise ValueError, 'Maximum content length exceeded' + data = fp.read(bytes) + else: + data = "" + # Read lines until end of part. + lines = [] + while 1: + line = fp.readline() + if not line: + terminator = lastpart # End outer loop + break + if line[:2] == "--": + terminator = line.strip() + if terminator in (nextpart, lastpart): + break + lines.append(line) + # Done with part. + if data is None: + continue + if bytes < 0: + if lines: + # Strip final line terminator + line = lines[-1] + if line[-2:] == "\r\n": + line = line[:-2] + elif line[-1:] == "\n": + line = line[:-1] + lines[-1] = line + data = "".join(lines) + line = headers['content-disposition'] + if not line: + continue + key, params = parse_header(line) + if key != 'form-data': + continue + if 'name' in params: + name = params['name'] + else: + continue + if name in partdict: + partdict[name].append(data) + else: + partdict[name] = [data] + + return partdict + + +def _parseparam(s): + while s[:1] == ';': + s = s[1:] + end = s.find(';') + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: + end = s.find(';', end + 1) + if end < 0: + end = len(s) + f = s[:end] + yield f.strip() + s = s[end:] + +def parse_header(line): + """Parse a Content-type like header. + + Return the main content-type and a dictionary of options. + + """ + parts = _parseparam(';' + line) + key = parts.next() + pdict = {} + for p in parts: + i = p.find('=') + if i >= 0: + name = p[:i].strip().lower() + value = p[i+1:].strip() + if len(value) >= 2 and value[0] == value[-1] == '"': + value = value[1:-1] + value = value.replace('\\\\', '\\').replace('\\"', '"') + pdict[name] = value + return key, pdict + + +# Classes for field storage +# ========================= + +class MiniFieldStorage: + + """Like FieldStorage, for use when no file uploads are possible.""" + + # Dummy attributes + filename = None + list = None + type = None + file = None + type_options = {} + disposition = None + disposition_options = {} + headers = {} + + def __init__(self, name, value): + """Constructor from field name and value.""" + self.name = name + self.value = value + # self.file = StringIO(value) + + def __repr__(self): + """Return printable representation.""" + return "MiniFieldStorage(%r, %r)" % (self.name, self.value) + + +class FieldStorage: + + """Store a sequence of fields, reading multipart/form-data. + + This class provides naming, typing, files stored on disk, and + more. At the top level, it is accessible like a dictionary, whose + keys are the field names. (Note: None can occur as a field name.) + The items are either a Python list (if there's multiple values) or + another FieldStorage or MiniFieldStorage object. If it's a single + object, it has the following attributes: + + name: the field name, if specified; otherwise None + + filename: the filename, if specified; otherwise None; this is the + client side filename, *not* the file name on which it is + stored (that's a temporary file you don't deal with) + + value: the value as a *string*; for file uploads, this + transparently reads the file every time you request the value + + file: the file(-like) object from which you can read the data; + None if the data is stored a simple string + + type: the content-type, or None if not specified + + type_options: dictionary of options specified on the content-type + line + + disposition: content-disposition, or None if not specified + + disposition_options: dictionary of corresponding options + + headers: a dictionary(-like) object (sometimes rfc822.Message or a + subclass thereof) containing *all* headers + + The class is subclassable, mostly for the purpose of overriding + the make_file() method, which is called internally to come up with + a file open for reading and writing. This makes it possible to + override the default choice of storing all files in a temporary + directory and unlinking them as soon as they have been opened. + + """ + + def __init__(self, fp=None, headers=None, outerboundary="", + environ=os.environ, keep_blank_values=0, strict_parsing=0): + """Constructor. Read multipart/* until last part. + + Arguments, all optional: + + fp : file pointer; default: sys.stdin + (not used when the request method is GET) + + headers : header dictionary-like object; default: + taken from environ as per CGI spec + + outerboundary : terminating multipart boundary + (for internal use only) + + environ : environment dictionary; default: os.environ + + keep_blank_values: flag indicating whether blank values in + percent-encoded forms should be treated as blank strings. + A true value indicates that blanks should be retained as + blank strings. The default false value indicates that + blank values are to be ignored and treated as if they were + not included. + + strict_parsing: flag indicating what to do with parsing errors. + If false (the default), errors are silently ignored. + If true, errors raise a ValueError exception. + + """ + method = 'GET' + self.keep_blank_values = keep_blank_values + self.strict_parsing = strict_parsing + if 'REQUEST_METHOD' in environ: + method = environ['REQUEST_METHOD'].upper() + self.qs_on_post = None + if method == 'GET' or method == 'HEAD': + if 'QUERY_STRING' in environ: + qs = environ['QUERY_STRING'] + elif sys.argv[1:]: + qs = sys.argv[1] + else: + qs = "" + fp = StringIO(qs) + if headers is None: + headers = {'content-type': + "application/x-www-form-urlencoded"} + if headers is None: + headers = {} + if method == 'POST': + # Set default content-type for POST to what's traditional + headers['content-type'] = "application/x-www-form-urlencoded" + if 'CONTENT_TYPE' in environ: + headers['content-type'] = environ['CONTENT_TYPE'] + if 'QUERY_STRING' in environ: + self.qs_on_post = environ['QUERY_STRING'] + if 'CONTENT_LENGTH' in environ: + headers['content-length'] = environ['CONTENT_LENGTH'] + self.fp = fp or sys.stdin + self.headers = headers + self.outerboundary = outerboundary + + # Process content-disposition header + cdisp, pdict = "", {} + if 'content-disposition' in self.headers: + cdisp, pdict = parse_header(self.headers['content-disposition']) + self.disposition = cdisp + self.disposition_options = pdict + self.name = None + if 'name' in pdict: + self.name = pdict['name'] + self.filename = None + if 'filename' in pdict: + self.filename = pdict['filename'] + + # Process content-type header + # + # Honor any existing content-type header. But if there is no + # content-type header, use some sensible defaults. Assume + # outerboundary is "" at the outer level, but something non-false + # inside a multi-part. The default for an inner part is text/plain, + # but for an outer part it should be urlencoded. This should catch + # bogus clients which erroneously forget to include a content-type + # header. + # + # See below for what we do if there does exist a content-type header, + # but it happens to be something we don't understand. + if 'content-type' in self.headers: + ctype, pdict = parse_header(self.headers['content-type']) + elif self.outerboundary or method != 'POST': + ctype, pdict = "text/plain", {} + else: + ctype, pdict = 'application/x-www-form-urlencoded', {} + self.type = ctype + self.type_options = pdict + self.innerboundary = "" + if 'boundary' in pdict: + self.innerboundary = pdict['boundary'] + clen = -1 + if 'content-length' in self.headers: + try: + clen = int(self.headers['content-length']) + except ValueError: + pass + if maxlen and clen > maxlen: + raise ValueError, 'Maximum content length exceeded' + self.length = clen + + self.list = self.file = None + self.done = 0 + if ctype == 'application/x-www-form-urlencoded': + self.read_urlencoded() + elif ctype[:10] == 'multipart/': + self.read_multi(environ, keep_blank_values, strict_parsing) + else: + self.read_single() + + def __repr__(self): + """Return a printable representation.""" + return "FieldStorage(%r, %r, %r)" % ( + self.name, self.filename, self.value) + + def __iter__(self): + return iter(self.keys()) + + def __getattr__(self, name): + if name != 'value': + raise AttributeError, name + if self.file: + self.file.seek(0) + value = self.file.read() + self.file.seek(0) + elif self.list is not None: + value = self.list + else: + value = None + return value + + def __getitem__(self, key): + """Dictionary style indexing.""" + if self.list is None: + raise TypeError, "not indexable" + found = [] + for item in self.list: + if item.name == key: found.append(item) + if not found: + raise KeyError, key + if len(found) == 1: + return found[0] + else: + return found + + def getvalue(self, key, default=None): + """Dictionary style get() method, including 'value' lookup.""" + if key in self: + value = self[key] + if type(value) is type([]): + return map(attrgetter('value'), value) + else: + return value.value + else: + return default + + def getfirst(self, key, default=None): + """ Return the first value received.""" + if key in self: + value = self[key] + if type(value) is type([]): + return value[0].value + else: + return value.value + else: + return default + + def getlist(self, key): + """ Return list of received values.""" + if key in self: + value = self[key] + if type(value) is type([]): + return map(attrgetter('value'), value) + else: + return [value.value] + else: + return [] + + def keys(self): + """Dictionary style keys() method.""" + if self.list is None: + raise TypeError, "not indexable" + return list(set(item.name for item in self.list)) + + def has_key(self, key): + """Dictionary style has_key() method.""" + if self.list is None: + raise TypeError, "not indexable" + return any(item.name == key for item in self.list) + + def __contains__(self, key): + """Dictionary style __contains__ method.""" + if self.list is None: + raise TypeError, "not indexable" + return any(item.name == key for item in self.list) + + def __len__(self): + """Dictionary style len(x) support.""" + return len(self.keys()) + + def __nonzero__(self): + return bool(self.list) + + def read_urlencoded(self): + """Internal: read data in query string format.""" + qs = self.fp.read(self.length) + if self.qs_on_post: + qs += '&' + self.qs_on_post + self.list = list = [] + for key, value in urlparse.parse_qsl(qs, self.keep_blank_values, + self.strict_parsing): + list.append(MiniFieldStorage(key, value)) + self.skip_lines() + + FieldStorageClass = None + + def read_multi(self, environ, keep_blank_values, strict_parsing): + """Internal: read a part that is itself multipart.""" + ib = self.innerboundary + if not valid_boundary(ib): + raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,) + self.list = [] + if self.qs_on_post: + for key, value in urlparse.parse_qsl(self.qs_on_post, + self.keep_blank_values, self.strict_parsing): + self.list.append(MiniFieldStorage(key, value)) + FieldStorageClass = None + + klass = self.FieldStorageClass or self.__class__ + part = klass(self.fp, {}, ib, + environ, keep_blank_values, strict_parsing) + # Throw first part away + while not part.done: + headers = rfc822.Message(self.fp) + part = klass(self.fp, headers, ib, + environ, keep_blank_values, strict_parsing) + self.list.append(part) + self.skip_lines() + + def read_single(self): + """Internal: read an atomic part.""" + if self.length >= 0: + self.read_binary() + self.skip_lines() + else: + self.read_lines() + self.file.seek(0) + + bufsize = 8*1024 # I/O buffering size for copy to file + + def read_binary(self): + """Internal: read binary data.""" + self.file = self.make_file('b') + todo = self.length + if todo >= 0: + while todo > 0: + data = self.fp.read(min(todo, self.bufsize)) + if not data: + self.done = -1 + break + self.file.write(data) + todo = todo - len(data) + + def read_lines(self): + """Internal: read lines until EOF or outerboundary.""" + self.file = self.__file = StringIO() + if self.outerboundary: + self.read_lines_to_outerboundary() + else: + self.read_lines_to_eof() + + def __write(self, line): + if self.__file is not None: + if self.__file.tell() + len(line) > 1000: + self.file = self.make_file('') + self.file.write(self.__file.getvalue()) + self.__file = None + self.file.write(line) + + def read_lines_to_eof(self): + """Internal: read lines until EOF.""" + while 1: + line = self.fp.readline(1<<16) + if not line: + self.done = -1 + break + self.__write(line) + + def read_lines_to_outerboundary(self): + """Internal: read lines until outerboundary.""" + next = "--" + self.outerboundary + last = next + "--" + delim = "" + last_line_lfend = True + while 1: + line = self.fp.readline(1<<16) + if not line: + self.done = -1 + break + if line[:2] == "--" and last_line_lfend: + strippedline = line.strip() + if strippedline == next: + break + if strippedline == last: + self.done = 1 + break + odelim = delim + if line[-2:] == "\r\n": + delim = "\r\n" + line = line[:-2] + last_line_lfend = True + elif line[-1] == "\n": + delim = "\n" + line = line[:-1] + last_line_lfend = True + else: + delim = "" + last_line_lfend = False + self.__write(odelim + line) + + def skip_lines(self): + """Internal: skip lines until outer boundary if defined.""" + if not self.outerboundary or self.done: + return + next = "--" + self.outerboundary + last = next + "--" + last_line_lfend = True + while 1: + line = self.fp.readline(1<<16) + if not line: + self.done = -1 + break + if line[:2] == "--" and last_line_lfend: + strippedline = line.strip() + if strippedline == next: + break + if strippedline == last: + self.done = 1 + break + last_line_lfend = line.endswith('\n') + + def make_file(self, binary=None): + """Overridable: return a readable & writable file. + + The file will be used as follows: + - data is written to it + - seek(0) + - data is read from it + + The 'binary' argument is unused -- the file is always opened + in binary mode. + + This version opens a temporary file for reading and writing, + and immediately deletes (unlinks) it. The trick (on Unix!) is + that the file can still be used, but it can't be opened by + another process, and it will automatically be deleted when it + is closed or when the current process terminates. + + If you want a more permanent file, you derive a class which + overrides this method. If you want a visible temporary file + that is nevertheless automatically deleted when the script + terminates, try defining a __del__ method in a derived class + which unlinks the temporary files you have created. + + """ + import tempfile + return tempfile.TemporaryFile("w+b") + + + +# Backwards Compatibility Classes +# =============================== + +class FormContentDict(UserDict.UserDict): + """Form content as dictionary with a list of values per field. + + form = FormContentDict() + + form[key] -> [value, value, ...] + key in form -> Boolean + form.keys() -> [key, key, ...] + form.values() -> [[val, val, ...], [val, val, ...], ...] + form.items() -> [(key, [val, val, ...]), (key, [val, val, ...]), ...] + form.dict == {key: [val, val, ...], ...} + + """ + def __init__(self, environ=os.environ, keep_blank_values=0, strict_parsing=0): + self.dict = self.data = parse(environ=environ, + keep_blank_values=keep_blank_values, + strict_parsing=strict_parsing) + self.query_string = environ['QUERY_STRING'] + + +class SvFormContentDict(FormContentDict): + """Form content as dictionary expecting a single value per field. + + If you only expect a single value for each field, then form[key] + will return that single value. It will raise an IndexError if + that expectation is not true. If you expect a field to have + possible multiple values, than you can use form.getlist(key) to + get all of the values. values() and items() are a compromise: + they return single strings where there is a single value, and + lists of strings otherwise. + + """ + def __getitem__(self, key): + if len(self.dict[key]) > 1: + raise IndexError, 'expecting a single value' + return self.dict[key][0] + def getlist(self, key): + return self.dict[key] + def values(self): + result = [] + for value in self.dict.values(): + if len(value) == 1: + result.append(value[0]) + else: result.append(value) + return result + def items(self): + result = [] + for key, value in self.dict.items(): + if len(value) == 1: + result.append((key, value[0])) + else: result.append((key, value)) + return result + + +class InterpFormContentDict(SvFormContentDict): + """This class is present for backwards compatibility only.""" + def __getitem__(self, key): + v = SvFormContentDict.__getitem__(self, key) + if v[0] in '0123456789+-.': + try: return int(v) + except ValueError: + try: return float(v) + except ValueError: pass + return v.strip() + def values(self): + result = [] + for key in self.keys(): + try: + result.append(self[key]) + except IndexError: + result.append(self.dict[key]) + return result + def items(self): + result = [] + for key in self.keys(): + try: + result.append((key, self[key])) + except IndexError: + result.append((key, self.dict[key])) + return result + + +class FormContent(FormContentDict): + """This class is present for backwards compatibility only.""" + def values(self, key): + if key in self.dict :return self.dict[key] + else: return None + def indexed_value(self, key, location): + if key in self.dict: + if len(self.dict[key]) > location: + return self.dict[key][location] + else: return None + else: return None + def value(self, key): + if key in self.dict: return self.dict[key][0] + else: return None + def length(self, key): + return len(self.dict[key]) + def stripped(self, key): + if key in self.dict: return self.dict[key][0].strip() + else: return None + def pars(self): + return self.dict + + +# Test/debug code +# =============== + +def test(environ=os.environ): + """Robust test CGI script, usable as main program. + + Write minimal HTTP headers and dump all information provided to + the script in HTML form. + + """ + print "Content-type: text/html" + print + sys.stderr = sys.stdout + try: + form = FieldStorage() # Replace with other classes to test those + print_directory() + print_arguments() + print_form(form) + print_environ(environ) + print_environ_usage() + def f(): + exec "testing print_exception() -- <I>italics?</I>" + def g(f=f): + f() + print "<H3>What follows is a test, not an actual exception:</H3>" + g() + except: + print_exception() + + print "<H1>Second try with a small maxlen...</H1>" + + global maxlen + maxlen = 50 + try: + form = FieldStorage() # Replace with other classes to test those + print_directory() + print_arguments() + print_form(form) + print_environ(environ) + except: + print_exception() + +def print_exception(type=None, value=None, tb=None, limit=None): + if type is None: + type, value, tb = sys.exc_info() + import traceback + print + print "<H3>Traceback (most recent call last):</H3>" + list = traceback.format_tb(tb, limit) + \ + traceback.format_exception_only(type, value) + print "<PRE>%s<B>%s</B></PRE>" % ( + escape("".join(list[:-1])), + escape(list[-1]), + ) + del tb + +def print_environ(environ=os.environ): + """Dump the shell environment as HTML.""" + keys = environ.keys() + keys.sort() + print + print "<H3>Shell Environment:</H3>" + print "<DL>" + for key in keys: + print "<DT>", escape(key), "<DD>", escape(environ[key]) + print "</DL>" + print + +def print_form(form): + """Dump the contents of a form as HTML.""" + keys = form.keys() + keys.sort() + print + print "<H3>Form Contents:</H3>" + if not keys: + print "<P>No form fields." + print "<DL>" + for key in keys: + print "<DT>" + escape(key) + ":", + value = form[key] + print "<i>" + escape(repr(type(value))) + "</i>" + print "<DD>" + escape(repr(value)) + print "</DL>" + print + +def print_directory(): + """Dump the current directory as HTML.""" + print + print "<H3>Current Working Directory:</H3>" + try: + pwd = os.getcwd() + except os.error, msg: + print "os.error:", escape(str(msg)) + else: + print escape(pwd) + print + +def print_arguments(): + print + print "<H3>Command Line Arguments:</H3>" + print + print sys.argv + print + +def print_environ_usage(): + """Dump a list of environment variables used by CGI as HTML.""" + print """ +<H3>These environment variables could have been set:</H3> +<UL> +<LI>AUTH_TYPE +<LI>CONTENT_LENGTH +<LI>CONTENT_TYPE +<LI>DATE_GMT +<LI>DATE_LOCAL +<LI>DOCUMENT_NAME +<LI>DOCUMENT_ROOT +<LI>DOCUMENT_URI +<LI>GATEWAY_INTERFACE +<LI>LAST_MODIFIED +<LI>PATH +<LI>PATH_INFO +<LI>PATH_TRANSLATED +<LI>QUERY_STRING +<LI>REMOTE_ADDR +<LI>REMOTE_HOST +<LI>REMOTE_IDENT +<LI>REMOTE_USER +<LI>REQUEST_METHOD +<LI>SCRIPT_NAME +<LI>SERVER_NAME +<LI>SERVER_PORT +<LI>SERVER_PROTOCOL +<LI>SERVER_ROOT +<LI>SERVER_SOFTWARE +</UL> +In addition, HTTP headers sent by the server may be passed in the +environment as well. Here are some common variable names: +<UL> +<LI>HTTP_ACCEPT +<LI>HTTP_CONNECTION +<LI>HTTP_HOST +<LI>HTTP_PRAGMA +<LI>HTTP_REFERER +<LI>HTTP_USER_AGENT +</UL> +""" + + +# Utilities +# ========= + +def escape(s, quote=None): + '''Replace special characters "&", "<" and ">" to HTML-safe sequences. + If the optional flag quote is true, the quotation mark character (") + is also translated.''' + s = s.replace("&", "&") # Must be done first! + s = s.replace("<", "<") + s = s.replace(">", ">") + if quote: + s = s.replace('"', """) + return s + +def valid_boundary(s, _vb_pattern="^[ -~]{0,200}[!-~]$"): + import re + return re.match(_vb_pattern, s) + +# Invoke mainline +# =============== + +# Call test() when this file is run as a script (not imported as a module) +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/cgitb.py b/src/main/resources/PythonLibs/cgitb.py new file mode 100644 index 0000000000000000000000000000000000000000..8acc4b75fe3b384c144ed14c23626188948612e4 --- /dev/null +++ b/src/main/resources/PythonLibs/cgitb.py @@ -0,0 +1,323 @@ +"""More comprehensive traceback formatting for Python scripts. + +To enable this module, do: + + import cgitb; cgitb.enable() + +at the top of your script. The optional arguments to enable() are: + + display - if true, tracebacks are displayed in the web browser + logdir - if set, tracebacks are written to files in this directory + context - number of lines of source code to show for each stack frame + format - 'text' or 'html' controls the output format + +By default, tracebacks are displayed but not saved, the context is 5 lines +and the output format is 'html' (for backwards compatibility with the +original use of this module) + +Alternatively, if you have caught an exception and want cgitb to display it +for you, call cgitb.handler(). The optional argument to handler() is a +3-item tuple (etype, evalue, etb) just like the value of sys.exc_info(). +The default handler displays output as HTML. + +""" +import inspect +import keyword +import linecache +import os +import pydoc +import sys +import tempfile +import time +import tokenize +import traceback +import types + +def reset(): + """Return a string that resets the CGI and browser to a known state.""" + return '''<!--: spam +Content-Type: text/html + +<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> +<body bgcolor="#f0f0f8"><font color="#f0f0f8" size="-5"> --> --> +</font> </font> </font> </script> </object> </blockquote> </pre> +</table> </table> </table> </table> </table> </font> </font> </font>''' + +__UNDEF__ = [] # a special sentinel object +def small(text): + if text: + return '<small>' + text + '</small>' + else: + return '' + +def strong(text): + if text: + return '<strong>' + text + '</strong>' + else: + return '' + +def grey(text): + if text: + return '<font color="#909090">' + text + '</font>' + else: + return '' + +def lookup(name, frame, locals): + """Find the value for a given name in the given environment.""" + if name in locals: + return 'local', locals[name] + if name in frame.f_globals: + return 'global', frame.f_globals[name] + if '__builtins__' in frame.f_globals: + builtins = frame.f_globals['__builtins__'] + if type(builtins) is type({}): + if name in builtins: + return 'builtin', builtins[name] + else: + if hasattr(builtins, name): + return 'builtin', getattr(builtins, name) + return None, __UNDEF__ + +def scanvars(reader, frame, locals): + """Scan one logical line of Python and look up values of variables used.""" + vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__ + for ttype, token, start, end, line in tokenize.generate_tokens(reader): + if ttype == tokenize.NEWLINE: break + if ttype == tokenize.NAME and token not in keyword.kwlist: + if lasttoken == '.': + if parent is not __UNDEF__: + value = getattr(parent, token, __UNDEF__) + vars.append((prefix + token, prefix, value)) + else: + where, value = lookup(token, frame, locals) + vars.append((token, where, value)) + elif token == '.': + prefix += lasttoken + '.' + parent = value + else: + parent, prefix = None, '' + lasttoken = token + return vars + +def html(einfo, context=5): + """Return a nice HTML document describing a given traceback.""" + etype, evalue, etb = einfo + if type(etype) is types.ClassType: + etype = etype.__name__ + pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable + date = time.ctime(time.time()) + head = '<body bgcolor="#f0f0f8">' + pydoc.html.heading( + '<big><big>%s</big></big>' % + strong(pydoc.html.escape(str(etype))), + '#ffffff', '#6622aa', pyver + '<br>' + date) + ''' +<p>A problem occurred in a Python script. Here is the sequence of +function calls leading up to the error, in the order they occurred.</p>''' + + indent = '<tt>' + small(' ' * 5) + ' </tt>' + frames = [] + records = inspect.getinnerframes(etb, context) + for frame, file, lnum, func, lines, index in records: + if file: + file = os.path.abspath(file) + link = '<a href="file://%s">%s</a>' % (file, pydoc.html.escape(file)) + else: + file = link = '?' + args, varargs, varkw, locals = inspect.getargvalues(frame) + call = '' + if func != '?': + call = 'in ' + strong(func) + \ + inspect.formatargvalues(args, varargs, varkw, locals, + formatvalue=lambda value: '=' + pydoc.html.repr(value)) + + highlight = {} + def reader(lnum=[lnum]): + highlight[lnum[0]] = 1 + try: return linecache.getline(file, lnum[0]) + finally: lnum[0] += 1 + vars = scanvars(reader, frame, locals) + + rows = ['<tr><td bgcolor="#d8bbff">%s%s %s</td></tr>' % + ('<big> </big>', link, call)] + if index is not None: + i = lnum - index + for line in lines: + num = small(' ' * (5-len(str(i))) + str(i)) + ' ' + if i in highlight: + line = '<tt>=>%s%s</tt>' % (num, pydoc.html.preformat(line)) + rows.append('<tr><td bgcolor="#ffccee">%s</td></tr>' % line) + else: + line = '<tt> %s%s</tt>' % (num, pydoc.html.preformat(line)) + rows.append('<tr><td>%s</td></tr>' % grey(line)) + i += 1 + + done, dump = {}, [] + for name, where, value in vars: + if name in done: continue + done[name] = 1 + if value is not __UNDEF__: + if where in ('global', 'builtin'): + name = ('<em>%s</em> ' % where) + strong(name) + elif where == 'local': + name = strong(name) + else: + name = where + strong(name.split('.')[-1]) + dump.append('%s = %s' % (name, pydoc.html.repr(value))) + else: + dump.append(name + ' <em>undefined</em>') + + rows.append('<tr><td>%s</td></tr>' % small(grey(', '.join(dump)))) + frames.append(''' +<table width="100%%" cellspacing=0 cellpadding=0 border=0> +%s</table>''' % '\n'.join(rows)) + + exception = ['<p>%s: %s' % (strong(pydoc.html.escape(str(etype))), + pydoc.html.escape(str(evalue)))] + if isinstance(evalue, BaseException): + for name in dir(evalue): + if name[:1] == '_': continue + value = pydoc.html.repr(getattr(evalue, name)) + exception.append('\n<br>%s%s =\n%s' % (indent, name, value)) + + return head + ''.join(frames) + ''.join(exception) + ''' + + +<!-- The above is a description of an error in a Python program, formatted + for a Web browser because the 'cgitb' module was enabled. In case you + are not reading this in a Web browser, here is the original traceback: + +%s +--> +''' % pydoc.html.escape( + ''.join(traceback.format_exception(etype, evalue, etb))) + +def text(einfo, context=5): + """Return a plain text document describing a given traceback.""" + etype, evalue, etb = einfo + if type(etype) is types.ClassType: + etype = etype.__name__ + pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable + date = time.ctime(time.time()) + head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + ''' +A problem occurred in a Python script. Here is the sequence of +function calls leading up to the error, in the order they occurred. +''' + + frames = [] + records = inspect.getinnerframes(etb, context) + for frame, file, lnum, func, lines, index in records: + file = file and os.path.abspath(file) or '?' + args, varargs, varkw, locals = inspect.getargvalues(frame) + call = '' + if func != '?': + call = 'in ' + func + \ + inspect.formatargvalues(args, varargs, varkw, locals, + formatvalue=lambda value: '=' + pydoc.text.repr(value)) + + highlight = {} + def reader(lnum=[lnum]): + highlight[lnum[0]] = 1 + try: return linecache.getline(file, lnum[0]) + finally: lnum[0] += 1 + vars = scanvars(reader, frame, locals) + + rows = [' %s %s' % (file, call)] + if index is not None: + i = lnum - index + for line in lines: + num = '%5d ' % i + rows.append(num+line.rstrip()) + i += 1 + + done, dump = {}, [] + for name, where, value in vars: + if name in done: continue + done[name] = 1 + if value is not __UNDEF__: + if where == 'global': name = 'global ' + name + elif where != 'local': name = where + name.split('.')[-1] + dump.append('%s = %s' % (name, pydoc.text.repr(value))) + else: + dump.append(name + ' undefined') + + rows.append('\n'.join(dump)) + frames.append('\n%s\n' % '\n'.join(rows)) + + exception = ['%s: %s' % (str(etype), str(evalue))] + if isinstance(evalue, BaseException): + for name in dir(evalue): + value = pydoc.text.repr(getattr(evalue, name)) + exception.append('\n%s%s = %s' % (" "*4, name, value)) + + return head + ''.join(frames) + ''.join(exception) + ''' + +The above is a description of an error in a Python program. Here is +the original traceback: + +%s +''' % ''.join(traceback.format_exception(etype, evalue, etb)) + +class Hook: + """A hook to replace sys.excepthook that shows tracebacks in HTML.""" + + def __init__(self, display=1, logdir=None, context=5, file=None, + format="html"): + self.display = display # send tracebacks to browser if true + self.logdir = logdir # log tracebacks to files if not None + self.context = context # number of source code lines per frame + self.file = file or sys.stdout # place to send the output + self.format = format + + def __call__(self, etype, evalue, etb): + self.handle((etype, evalue, etb)) + + def handle(self, info=None): + info = info or sys.exc_info() + if self.format == "html": + self.file.write(reset()) + + formatter = (self.format=="html") and html or text + plain = False + try: + doc = formatter(info, self.context) + except: # just in case something goes wrong + doc = ''.join(traceback.format_exception(*info)) + plain = True + + if self.display: + if plain: + doc = doc.replace('&', '&').replace('<', '<') + self.file.write('<pre>' + doc + '</pre>\n') + else: + self.file.write(doc + '\n') + else: + self.file.write('<p>A problem occurred in a Python script.\n') + + if self.logdir is not None: + suffix = ['.txt', '.html'][self.format=="html"] + (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir) + + try: + file = os.fdopen(fd, 'w') + file.write(doc) + file.close() + msg = '%s contains the description of this error.' % path + except: + msg = 'Tried to save traceback to %s, but failed.' % path + + if self.format == 'html': + self.file.write('<p>%s</p>\n' % msg) + else: + self.file.write(msg + '\n') + try: + self.file.flush() + except: pass + +handler = Hook().handle +def enable(display=1, logdir=None, context=5, format="html"): + """Install an exception handler that formats tracebacks as HTML. + + The optional argument 'display' can be set to 0 to suppress sending the + traceback to the browser, and 'logdir' can be set to a directory to cause + tracebacks to be written to files there.""" + sys.excepthook = Hook(display=display, logdir=logdir, + context=context, format=format) diff --git a/src/main/resources/PythonLibs/chunk.py b/src/main/resources/PythonLibs/chunk.py new file mode 100644 index 0000000000000000000000000000000000000000..a8fbc1051f3e44794427408fa0c4dbc89b3c9103 --- /dev/null +++ b/src/main/resources/PythonLibs/chunk.py @@ -0,0 +1,167 @@ +"""Simple class to read IFF chunks. + +An IFF chunk (used in formats such as AIFF, TIFF, RMFF (RealMedia File +Format)) has the following structure: + ++----------------+ +| ID (4 bytes) | ++----------------+ +| size (4 bytes) | ++----------------+ +| data | +| ... | ++----------------+ + +The ID is a 4-byte string which identifies the type of chunk. + +The size field (a 32-bit value, encoded using big-endian byte order) +gives the size of the whole chunk, including the 8-byte header. + +Usually an IFF-type file consists of one or more chunks. The proposed +usage of the Chunk class defined here is to instantiate an instance at +the start of each chunk and read from the instance until it reaches +the end, after which a new instance can be instantiated. At the end +of the file, creating a new instance will fail with a EOFError +exception. + +Usage: +while True: + try: + chunk = Chunk(file) + except EOFError: + break + chunktype = chunk.getname() + while True: + data = chunk.read(nbytes) + if not data: + pass + # do something with data + +The interface is file-like. The implemented methods are: +read, close, seek, tell, isatty. +Extra methods are: skip() (called by close, skips to the end of the chunk), +getname() (returns the name (ID) of the chunk) + +The __init__ method has one required argument, a file-like object +(including a chunk instance), and one optional argument, a flag which +specifies whether or not chunks are aligned on 2-byte boundaries. The +default is 1, i.e. aligned. +""" + +class Chunk: + def __init__(self, file, align=True, bigendian=True, inclheader=False): + import struct + self.closed = False + self.align = align # whether to align to word (2-byte) boundaries + if bigendian: + strflag = '>' + else: + strflag = '<' + self.file = file + self.chunkname = file.read(4) + if len(self.chunkname) < 4: + raise EOFError + try: + self.chunksize = struct.unpack(strflag+'L', file.read(4))[0] + except struct.error: + raise EOFError + if inclheader: + self.chunksize = self.chunksize - 8 # subtract header + self.size_read = 0 + try: + self.offset = self.file.tell() + except (AttributeError, IOError): + self.seekable = False + else: + self.seekable = True + + def getname(self): + """Return the name (ID) of the current chunk.""" + return self.chunkname + + def getsize(self): + """Return the size of the current chunk.""" + return self.chunksize + + def close(self): + if not self.closed: + self.skip() + self.closed = True + + def isatty(self): + if self.closed: + raise ValueError, "I/O operation on closed file" + return False + + def seek(self, pos, whence=0): + """Seek to specified position into the chunk. + Default position is 0 (start of chunk). + If the file is not seekable, this will result in an error. + """ + + if self.closed: + raise ValueError, "I/O operation on closed file" + if not self.seekable: + raise IOError, "cannot seek" + if whence == 1: + pos = pos + self.size_read + elif whence == 2: + pos = pos + self.chunksize + if pos < 0 or pos > self.chunksize: + raise RuntimeError + self.file.seek(self.offset + pos, 0) + self.size_read = pos + + def tell(self): + if self.closed: + raise ValueError, "I/O operation on closed file" + return self.size_read + + def read(self, size=-1): + """Read at most size bytes from the chunk. + If size is omitted or negative, read until the end + of the chunk. + """ + + if self.closed: + raise ValueError, "I/O operation on closed file" + if self.size_read >= self.chunksize: + return '' + if size < 0: + size = self.chunksize - self.size_read + if size > self.chunksize - self.size_read: + size = self.chunksize - self.size_read + data = self.file.read(size) + self.size_read = self.size_read + len(data) + if self.size_read == self.chunksize and \ + self.align and \ + (self.chunksize & 1): + dummy = self.file.read(1) + self.size_read = self.size_read + len(dummy) + return data + + def skip(self): + """Skip the rest of the chunk. + If you are not interested in the contents of the chunk, + this method should be called so that the file points to + the start of the next chunk. + """ + + if self.closed: + raise ValueError, "I/O operation on closed file" + if self.seekable: + try: + n = self.chunksize - self.size_read + # maybe fix alignment + if self.align and (self.chunksize & 1): + n = n + 1 + self.file.seek(n, 1) + self.size_read = self.size_read + n + return + except IOError: + pass + while self.size_read < self.chunksize: + n = min(8192, self.chunksize - self.size_read) + dummy = self.read(n) + if not dummy: + raise EOFError diff --git a/src/main/resources/PythonLibs/cmd.py b/src/main/resources/PythonLibs/cmd.py new file mode 100644 index 0000000000000000000000000000000000000000..05ba7e3bc6b724b59dc5ddd45e0c8e1cb178deba --- /dev/null +++ b/src/main/resources/PythonLibs/cmd.py @@ -0,0 +1,404 @@ +"""A generic class to build line-oriented command interpreters. + +Interpreters constructed with this class obey the following conventions: + +1. End of file on input is processed as the command 'EOF'. +2. A command is parsed out of each line by collecting the prefix composed + of characters in the identchars member. +3. A command `foo' is dispatched to a method 'do_foo()'; the do_ method + is passed a single argument consisting of the remainder of the line. +4. Typing an empty line repeats the last command. (Actually, it calls the + method `emptyline', which may be overridden in a subclass.) +5. There is a predefined `help' method. Given an argument `topic', it + calls the command `help_topic'. With no arguments, it lists all topics + with defined help_ functions, broken into up to three topics; documented + commands, miscellaneous help topics, and undocumented commands. +6. The command '?' is a synonym for `help'. The command '!' is a synonym + for `shell', if a do_shell method exists. +7. If completion is enabled, completing commands will be done automatically, + and completing of commands args is done by calling complete_foo() with + arguments text, line, begidx, endidx. text is string we are matching + against, all returned matches must begin with it. line is the current + input line (lstripped), begidx and endidx are the beginning and end + indexes of the text being matched, which could be used to provide + different completion depending upon which position the argument is in. + +The `default' method may be overridden to intercept commands for which there +is no do_ method. + +The `completedefault' method may be overridden to intercept completions for +commands that have no complete_ method. + +The data member `self.ruler' sets the character used to draw separator lines +in the help messages. If empty, no ruler line is drawn. It defaults to "=". + +If the value of `self.intro' is nonempty when the cmdloop method is called, +it is printed out on interpreter startup. This value may be overridden +via an optional argument to the cmdloop() method. + +The data members `self.doc_header', `self.misc_header', and +`self.undoc_header' set the headers used for the help function's +listings of documented functions, miscellaneous topics, and undocumented +functions respectively. + +These interpreters use raw_input; thus, if the readline module is loaded, +they automatically support Emacs-like command history and editing features. +""" + +import string + +__all__ = ["Cmd"] + +PROMPT = '(Cmd) ' +IDENTCHARS = string.ascii_letters + string.digits + '_' + +class Cmd: + """A simple framework for writing line-oriented command interpreters. + + These are often useful for test harnesses, administrative tools, and + prototypes that will later be wrapped in a more sophisticated interface. + + A Cmd instance or subclass instance is a line-oriented interpreter + framework. There is no good reason to instantiate Cmd itself; rather, + it's useful as a superclass of an interpreter class you define yourself + in order to inherit Cmd's methods and encapsulate action methods. + + """ + prompt = PROMPT + identchars = IDENTCHARS + ruler = '=' + lastcmd = '' + intro = None + doc_leader = "" + doc_header = "Documented commands (type help <topic>):" + misc_header = "Miscellaneous help topics:" + undoc_header = "Undocumented commands:" + nohelp = "*** No help on %s" + use_rawinput = 1 + + def __init__(self, completekey='tab', stdin=None, stdout=None): + """Instantiate a line-oriented interpreter framework. + + The optional argument 'completekey' is the readline name of a + completion key; it defaults to the Tab key. If completekey is + not None and the readline module is available, command completion + is done automatically. The optional arguments stdin and stdout + specify alternate input and output file objects; if not specified, + sys.stdin and sys.stdout are used. + + """ + import sys + if stdin is not None: + self.stdin = stdin + else: + self.stdin = sys.stdin + if stdout is not None: + self.stdout = stdout + else: + self.stdout = sys.stdout + self.cmdqueue = [] + self.completekey = completekey + + def cmdloop(self, intro=None): + """Repeatedly issue a prompt, accept input, parse an initial prefix + off the received input, and dispatch to action methods, passing them + the remainder of the line as argument. + + """ + + self.preloop() + if self.use_rawinput and self.completekey: + try: + import readline + self.old_completer = readline.get_completer() + readline.set_completer(self.complete) + readline.parse_and_bind(self.completekey+": complete") + except ImportError: + pass + try: + if intro is not None: + self.intro = intro + if self.intro: + self.stdout.write(str(self.intro)+"\n") + stop = None + while not stop: + if self.cmdqueue: + line = self.cmdqueue.pop(0) + else: + if self.use_rawinput: + try: + line = raw_input(self.prompt) + except EOFError: + line = 'EOF' + else: + self.stdout.write(self.prompt) + self.stdout.flush() + line = self.stdin.readline() + if not len(line): + line = 'EOF' + else: + line = line.rstrip('\r\n') + line = self.precmd(line) + stop = self.onecmd(line) + stop = self.postcmd(stop, line) + self.postloop() + finally: + if self.use_rawinput and self.completekey: + try: + import readline + readline.set_completer(self.old_completer) + except ImportError: + pass + + + def precmd(self, line): + """Hook method executed just before the command line is + interpreted, but after the input prompt is generated and issued. + + """ + return line + + def postcmd(self, stop, line): + """Hook method executed just after a command dispatch is finished.""" + return stop + + def preloop(self): + """Hook method executed once when the cmdloop() method is called.""" + pass + + def postloop(self): + """Hook method executed once when the cmdloop() method is about to + return. + + """ + pass + + def parseline(self, line): + """Parse the line into a command name and a string containing + the arguments. Returns a tuple containing (command, args, line). + 'command' and 'args' may be None if the line couldn't be parsed. + """ + line = line.strip() + if not line: + return None, None, line + elif line[0] == '?': + line = 'help ' + line[1:] + elif line[0] == '!': + if hasattr(self, 'do_shell'): + line = 'shell ' + line[1:] + else: + return None, None, line + i, n = 0, len(line) + while i < n and line[i] in self.identchars: i = i+1 + cmd, arg = line[:i], line[i:].strip() + return cmd, arg, line + + def onecmd(self, line): + """Interpret the argument as though it had been typed in response + to the prompt. + + This may be overridden, but should not normally need to be; + see the precmd() and postcmd() methods for useful execution hooks. + The return value is a flag indicating whether interpretation of + commands by the interpreter should stop. + + """ + cmd, arg, line = self.parseline(line) + if not line: + return self.emptyline() + if cmd is None: + return self.default(line) + self.lastcmd = line + if line == 'EOF' : + self.lastcmd = '' + if cmd == '': + return self.default(line) + else: + try: + func = getattr(self, 'do_' + cmd) + except AttributeError: + return self.default(line) + return func(arg) + + def emptyline(self): + """Called when an empty line is entered in response to the prompt. + + If this method is not overridden, it repeats the last nonempty + command entered. + + """ + if self.lastcmd: + return self.onecmd(self.lastcmd) + + def default(self, line): + """Called on an input line when the command prefix is not recognized. + + If this method is not overridden, it prints an error message and + returns. + + """ + self.stdout.write('*** Unknown syntax: %s\n'%line) + + def completedefault(self, *ignored): + """Method called to complete an input line when no command-specific + complete_*() method is available. + + By default, it returns an empty list. + + """ + return [] + + def completenames(self, text, *ignored): + dotext = 'do_'+text + return [a[3:] for a in self.get_names() if a.startswith(dotext)] + + def complete(self, text, state): + """Return the next possible completion for 'text'. + + If a command has not been entered, then complete against command list. + Otherwise try to call complete_<command> to get list of completions. + """ + if state == 0: + import readline + origline = readline.get_line_buffer() + line = origline.lstrip() + stripped = len(origline) - len(line) + begidx = readline.get_begidx() - stripped + endidx = readline.get_endidx() - stripped + if begidx>0: + cmd, args, foo = self.parseline(line) + if cmd == '': + compfunc = self.completedefault + else: + try: + compfunc = getattr(self, 'complete_' + cmd) + except AttributeError: + compfunc = self.completedefault + else: + compfunc = self.completenames + self.completion_matches = compfunc(text, line, begidx, endidx) + try: + return self.completion_matches[state] + except IndexError: + return None + + def get_names(self): + # This method used to pull in base class attributes + # at a time dir() didn't do it yet. + return dir(self.__class__) + + def complete_help(self, *args): + commands = set(self.completenames(*args)) + topics = set(a[5:] for a in self.get_names() + if a.startswith('help_' + args[0])) + return list(commands | topics) + + def do_help(self, arg): + 'List available commands with "help" or detailed help with "help cmd".' + if arg: + # XXX check arg syntax + try: + func = getattr(self, 'help_' + arg) + except AttributeError: + try: + doc=getattr(self, 'do_' + arg).__doc__ + if doc: + self.stdout.write("%s\n"%str(doc)) + return + except AttributeError: + pass + self.stdout.write("%s\n"%str(self.nohelp % (arg,))) + return + func() + else: + names = self.get_names() + cmds_doc = [] + cmds_undoc = [] + help = {} + for name in names: + if name[:5] == 'help_': + help[name[5:]]=1 + names.sort() + # There can be duplicates if routines overridden + prevname = '' + for name in names: + if name[:3] == 'do_': + if name == prevname: + continue + prevname = name + cmd=name[3:] + if cmd in help: + cmds_doc.append(cmd) + del help[cmd] + elif getattr(self, name).__doc__: + cmds_doc.append(cmd) + else: + cmds_undoc.append(cmd) + self.stdout.write("%s\n"%str(self.doc_leader)) + self.print_topics(self.doc_header, cmds_doc, 15,80) + self.print_topics(self.misc_header, help.keys(),15,80) + self.print_topics(self.undoc_header, cmds_undoc, 15,80) + + def print_topics(self, header, cmds, cmdlen, maxcol): + if cmds: + self.stdout.write("%s\n"%str(header)) + if self.ruler: + self.stdout.write("%s\n"%str(self.ruler * len(header))) + self.columnize(cmds, maxcol-1) + self.stdout.write("\n") + + def columnize(self, list, displaywidth=80): + """Display a list of strings as a compact set of columns. + + Each column is only as wide as necessary. + Columns are separated by two spaces (one was not legible enough). + """ + if not list: + self.stdout.write("<empty>\n") + return + nonstrings = [i for i in range(len(list)) + if not isinstance(list[i], str)] + if nonstrings: + raise TypeError, ("list[i] not a string for i in %s" % + ", ".join(map(str, nonstrings))) + size = len(list) + if size == 1: + self.stdout.write('%s\n'%str(list[0])) + return + # Try every row count from 1 upwards + for nrows in range(1, len(list)): + ncols = (size+nrows-1) // nrows + colwidths = [] + totwidth = -2 + for col in range(ncols): + colwidth = 0 + for row in range(nrows): + i = row + nrows*col + if i >= size: + break + x = list[i] + colwidth = max(colwidth, len(x)) + colwidths.append(colwidth) + totwidth += colwidth + 2 + if totwidth > displaywidth: + break + if totwidth <= displaywidth: + break + else: + nrows = len(list) + ncols = 1 + colwidths = [0] + for row in range(nrows): + texts = [] + for col in range(ncols): + i = row + nrows*col + if i >= size: + x = "" + else: + x = list[i] + texts.append(x) + while texts and not texts[-1]: + del texts[-1] + for col in range(len(texts)): + texts[col] = texts[col].ljust(colwidths[col]) + self.stdout.write("%s\n"%str(" ".join(texts))) diff --git a/src/main/resources/PythonLibs/code.py b/src/main/resources/PythonLibs/code.py new file mode 100644 index 0000000000000000000000000000000000000000..3b39d1b346f9092f9459e37470f4af1de8df8678 --- /dev/null +++ b/src/main/resources/PythonLibs/code.py @@ -0,0 +1,310 @@ +"""Utilities needed to emulate Python's interactive interpreter. + +""" + +# Inspired by similar code by Jeff Epler and Fredrik Lundh. + + +import sys +import traceback +from codeop import CommandCompiler, compile_command + +__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", + "compile_command"] + +def softspace(file, newvalue): + oldvalue = 0 + try: + oldvalue = file.softspace + except AttributeError: + pass + try: + file.softspace = newvalue + except (AttributeError, TypeError): + # "attribute-less object" or "read-only attributes" + pass + return oldvalue + +class InteractiveInterpreter: + """Base class for InteractiveConsole. + + This class deals with parsing and interpreter state (the user's + namespace); it doesn't deal with input buffering or prompting or + input file naming (the filename is always passed in explicitly). + + """ + + def __init__(self, locals=None): + """Constructor. + + The optional 'locals' argument specifies the dictionary in + which code will be executed; it defaults to a newly created + dictionary with key "__name__" set to "__console__" and key + "__doc__" set to None. + + """ + if locals is None: + locals = {"__name__": "__console__", "__doc__": None} + self.locals = locals + self.compile = CommandCompiler() + + def runsource(self, source, filename="<input>", symbol="single"): + """Compile and run some source in the interpreter. + + Arguments are as for compile_command(). + + One several things can happen: + + 1) The input is incorrect; compile_command() raised an + exception (SyntaxError or OverflowError). A syntax traceback + will be printed by calling the showsyntaxerror() method. + + 2) The input is incomplete, and more input is required; + compile_command() returned None. Nothing happens. + + 3) The input is complete; compile_command() returned a code + object. The code is executed by calling self.runcode() (which + also handles run-time exceptions, except for SystemExit). + + The return value is True in case 2, False in the other cases (unless + an exception is raised). The return value can be used to + decide whether to use sys.ps1 or sys.ps2 to prompt the next + line. + + """ + try: + code = self.compile(source, filename, symbol) + except (OverflowError, SyntaxError, ValueError): + # Case 1 + self.showsyntaxerror(filename) + return False + + if code is None: + # Case 2 + return True + + # Case 3 + self.runcode(code) + return False + + def runcode(self, code): + """Execute a code object. + + When an exception occurs, self.showtraceback() is called to + display a traceback. All exceptions are caught except + SystemExit, which is reraised. + + A note about KeyboardInterrupt: this exception may occur + elsewhere in this code, and may not always be caught. The + caller should be prepared to deal with it. + + """ + try: + exec code in self.locals + except SystemExit: + raise + except: + self.showtraceback() + else: + if softspace(sys.stdout, 0): + print + + def showsyntaxerror(self, filename=None): + """Display the syntax error that just occurred. + + This doesn't display a stack trace because there isn't one. + + If a filename is given, it is stuffed in the exception instead + of what was there before (because Python's parser always uses + "<string>" when reading from a string). + + The output is written by self.write(), below. + + """ + type, value, sys.last_traceback = sys.exc_info() + sys.last_type = type + sys.last_value = value + if filename and type is SyntaxError: + # Work hard to stuff the correct filename in the exception + try: + msg, (dummy_filename, lineno, offset, line) = value + except: + # Not the format we expect; leave it alone + pass + else: + # Stuff in the right filename + value = SyntaxError(msg, (filename, lineno, offset, line)) + sys.last_value = value + list = traceback.format_exception_only(type, value) + map(self.write, list) + + def showtraceback(self): + """Display the exception that just occurred. + + We remove the first stack item because it is our own code. + + The output is written by self.write(), below. + + """ + try: + type, value, tb = sys.exc_info() + sys.last_type = type + sys.last_value = value + sys.last_traceback = tb + tblist = traceback.extract_tb(tb) + del tblist[:1] + list = traceback.format_list(tblist) + if list: + list.insert(0, "Traceback (most recent call last):\n") + list[len(list):] = traceback.format_exception_only(type, value) + finally: + tblist = tb = None + map(self.write, list) + + def write(self, data): + """Write a string. + + The base implementation writes to sys.stderr; a subclass may + replace this with a different implementation. + + """ + sys.stderr.write(data) + + +class InteractiveConsole(InteractiveInterpreter): + """Closely emulate the behavior of the interactive Python interpreter. + + This class builds on InteractiveInterpreter and adds prompting + using the familiar sys.ps1 and sys.ps2, and input buffering. + + """ + + def __init__(self, locals=None, filename="<console>"): + """Constructor. + + The optional locals argument will be passed to the + InteractiveInterpreter base class. + + The optional filename argument should specify the (file)name + of the input stream; it will show up in tracebacks. + + """ + InteractiveInterpreter.__init__(self, locals) + self.filename = filename + self.resetbuffer() + + def resetbuffer(self): + """Reset the input buffer.""" + self.buffer = [] + + def interact(self, banner=None): + """Closely emulate the interactive Python console. + + The optional banner argument specify the banner to print + before the first interaction; by default it prints a banner + similar to the one printed by the real Python interpreter, + followed by the current class name in parentheses (so as not + to confuse this with the real interpreter -- since it's so + close!). + + """ + try: + sys.ps1 + except AttributeError: + sys.ps1 = ">>> " + try: + sys.ps2 + except AttributeError: + sys.ps2 = "... " + cprt = 'Type "help", "copyright", "credits" or "license" for more information.' + if banner is None: + self.write("Python %s on %s\n%s\n(%s)\n" % + (sys.version, sys.platform, cprt, + self.__class__.__name__)) + else: + self.write("%s\n" % str(banner)) + more = 0 + while 1: + try: + if more: + prompt = sys.ps2 + else: + prompt = sys.ps1 + try: + line = self.raw_input(prompt) + # Can be None if sys.stdin was redefined + encoding = getattr(sys.stdin, "encoding", None) + if encoding and not isinstance(line, unicode): + line = line.decode(encoding) + except EOFError: + self.write("\n") + break + else: + more = self.push(line) + except KeyboardInterrupt: + self.write("\nKeyboardInterrupt\n") + self.resetbuffer() + more = 0 + + def push(self, line): + """Push a line to the interpreter. + + The line should not have a trailing newline; it may have + internal newlines. The line is appended to a buffer and the + interpreter's runsource() method is called with the + concatenated contents of the buffer as source. If this + indicates that the command was executed or invalid, the buffer + is reset; otherwise, the command is incomplete, and the buffer + is left as it was after the line was appended. The return + value is 1 if more input is required, 0 if the line was dealt + with in some way (this is the same as runsource()). + + """ + self.buffer.append(line) + source = "\n".join(self.buffer) + more = self.runsource(source, self.filename) + if not more: + self.resetbuffer() + return more + + def raw_input(self, prompt=""): + """Write a prompt and read a line. + + The returned line does not include the trailing newline. + When the user enters the EOF key sequence, EOFError is raised. + + The base implementation uses the built-in function + raw_input(); a subclass may replace this with a different + implementation. + + """ + return raw_input(prompt) + + +def interact(banner=None, readfunc=None, local=None): + """Closely emulate the interactive Python interpreter. + + This is a backwards compatible interface to the InteractiveConsole + class. When readfunc is not specified, it attempts to import the + readline module to enable GNU readline if it is available. + + Arguments (all optional, all default to None): + + banner -- passed to InteractiveConsole.interact() + readfunc -- if not None, replaces InteractiveConsole.raw_input() + local -- passed to InteractiveInterpreter.__init__() + + """ + console = InteractiveConsole(local) + if readfunc is not None: + console.raw_input = readfunc + else: + try: + import readline + except ImportError: + pass + console.interact(banner) + + +if __name__ == "__main__": + interact() diff --git a/src/main/resources/PythonLibs/codecs.py b/src/main/resources/PythonLibs/codecs.py new file mode 100644 index 0000000000000000000000000000000000000000..f4cd60a14f2fd846ae8942d411e73b10ae829084 --- /dev/null +++ b/src/main/resources/PythonLibs/codecs.py @@ -0,0 +1,1098 @@ +""" codecs -- Python Codec Registry, API and helpers. + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +"""#" + +import __builtin__, sys + +### Registry and builtin stateless codec functions + +try: + from _codecs import * +except ImportError, why: + raise SystemError('Failed to load the builtin codecs: %s' % why) + +__all__ = ["register", "lookup", "open", "EncodedFile", "BOM", "BOM_BE", + "BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", + "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_LE", "BOM_UTF16_BE", + "BOM_UTF32", "BOM_UTF32_LE", "BOM_UTF32_BE", + "strict_errors", "ignore_errors", "replace_errors", + "xmlcharrefreplace_errors", + "register_error", "lookup_error"] + +### Constants + +# +# Byte Order Mark (BOM = ZERO WIDTH NO-BREAK SPACE = U+FEFF) +# and its possible byte string values +# for UTF8/UTF16/UTF32 output and little/big endian machines +# + +# UTF-8 +BOM_UTF8 = '\xef\xbb\xbf' + +# UTF-16, little endian +BOM_LE = BOM_UTF16_LE = '\xff\xfe' + +# UTF-16, big endian +BOM_BE = BOM_UTF16_BE = '\xfe\xff' + +# UTF-32, little endian +BOM_UTF32_LE = '\xff\xfe\x00\x00' + +# UTF-32, big endian +BOM_UTF32_BE = '\x00\x00\xfe\xff' + +if sys.byteorder == 'little': + + # UTF-16, native endianness + BOM = BOM_UTF16 = BOM_UTF16_LE + + # UTF-32, native endianness + BOM_UTF32 = BOM_UTF32_LE + +else: + + # UTF-16, native endianness + BOM = BOM_UTF16 = BOM_UTF16_BE + + # UTF-32, native endianness + BOM_UTF32 = BOM_UTF32_BE + +# Old broken names (don't use in new code) +BOM32_LE = BOM_UTF16_LE +BOM32_BE = BOM_UTF16_BE +BOM64_LE = BOM_UTF32_LE +BOM64_BE = BOM_UTF32_BE + + +### Codec base classes (defining the API) + +class CodecInfo(tuple): + + def __new__(cls, encode, decode, streamreader=None, streamwriter=None, + incrementalencoder=None, incrementaldecoder=None, name=None): + self = tuple.__new__(cls, (encode, decode, streamreader, streamwriter)) + self.name = name + self.encode = encode + self.decode = decode + self.incrementalencoder = incrementalencoder + self.incrementaldecoder = incrementaldecoder + self.streamwriter = streamwriter + self.streamreader = streamreader + return self + + def __repr__(self): + return "<%s.%s object for encoding %s at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self.name, id(self)) + +class Codec: + + """ Defines the interface for stateless encoders/decoders. + + The .encode()/.decode() methods may use different error + handling schemes by providing the errors argument. These + string values are predefined: + + 'strict' - raise a ValueError error (or a subclass) + 'ignore' - ignore the character and continue with the next + 'replace' - replace with a suitable replacement character; + Python will use the official U+FFFD REPLACEMENT + CHARACTER for the builtin Unicode codecs on + decoding and '?' on encoding. + 'xmlcharrefreplace' - Replace with the appropriate XML + character reference (only for encoding). + 'backslashreplace' - Replace with backslashed escape sequences + (only for encoding). + + The set of allowed values can be extended via register_error. + + """ + def encode(self, input, errors='strict'): + + """ Encodes the object input and returns a tuple (output + object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling. + + The method may not store state in the Codec instance. Use + StreamCodec for codecs which have to keep state in order to + make encoding/decoding efficient. + + The encoder must be able to handle zero length input and + return an empty object of the output object type in this + situation. + + """ + raise NotImplementedError + + def decode(self, input, errors='strict'): + + """ Decodes the object input and returns a tuple (output + object, length consumed). + + input must be an object which provides the bf_getreadbuf + buffer slot. Python strings, buffer objects and memory + mapped files are examples of objects providing this slot. + + errors defines the error handling to apply. It defaults to + 'strict' handling. + + The method may not store state in the Codec instance. Use + StreamCodec for codecs which have to keep state in order to + make encoding/decoding efficient. + + The decoder must be able to handle zero length input and + return an empty object of the output object type in this + situation. + + """ + raise NotImplementedError + +class IncrementalEncoder(object): + """ + An IncrementalEncoder encodes an input in multiple steps. The input can be + passed piece by piece to the encode() method. The IncrementalEncoder remembers + the state of the Encoding process between calls to encode(). + """ + def __init__(self, errors='strict'): + """ + Creates an IncrementalEncoder instance. + + The IncrementalEncoder may use different error handling schemes by + providing the errors keyword argument. See the module docstring + for a list of possible values. + """ + self.errors = errors + self.buffer = "" + + def encode(self, input, final=False): + """ + Encodes input and returns the resulting object. + """ + raise NotImplementedError + + def reset(self): + """ + Resets the encoder to the initial state. + """ + + def getstate(self): + """ + Return the current state of the encoder. + """ + return 0 + + def setstate(self, state): + """ + Set the current state of the encoder. state must have been + returned by getstate(). + """ + +class BufferedIncrementalEncoder(IncrementalEncoder): + """ + This subclass of IncrementalEncoder can be used as the baseclass for an + incremental encoder if the encoder must keep some of the output in a + buffer between calls to encode(). + """ + def __init__(self, errors='strict'): + IncrementalEncoder.__init__(self, errors) + self.buffer = "" # unencoded input that is kept between calls to encode() + + def _buffer_encode(self, input, errors, final): + # Overwrite this method in subclasses: It must encode input + # and return an (output, length consumed) tuple + raise NotImplementedError + + def encode(self, input, final=False): + # encode input (taking the buffer into account) + data = self.buffer + input + (result, consumed) = self._buffer_encode(data, self.errors, final) + # keep unencoded input until the next call + self.buffer = data[consumed:] + return result + + def reset(self): + IncrementalEncoder.reset(self) + self.buffer = "" + + def getstate(self): + return self.buffer or 0 + + def setstate(self, state): + self.buffer = state or "" + +class IncrementalDecoder(object): + """ + An IncrementalDecoder decodes an input in multiple steps. The input can be + passed piece by piece to the decode() method. The IncrementalDecoder + remembers the state of the decoding process between calls to decode(). + """ + def __init__(self, errors='strict'): + """ + Creates a IncrementalDecoder instance. + + The IncrementalDecoder may use different error handling schemes by + providing the errors keyword argument. See the module docstring + for a list of possible values. + """ + self.errors = errors + + def decode(self, input, final=False): + """ + Decodes input and returns the resulting object. + """ + raise NotImplementedError + + def reset(self): + """ + Resets the decoder to the initial state. + """ + + def getstate(self): + """ + Return the current state of the decoder. + + This must be a (buffered_input, additional_state_info) tuple. + buffered_input must be a bytes object containing bytes that + were passed to decode() that have not yet been converted. + additional_state_info must be a non-negative integer + representing the state of the decoder WITHOUT yet having + processed the contents of buffered_input. In the initial state + and after reset(), getstate() must return (b"", 0). + """ + return (b"", 0) + + def setstate(self, state): + """ + Set the current state of the decoder. + + state must have been returned by getstate(). The effect of + setstate((b"", 0)) must be equivalent to reset(). + """ + +class BufferedIncrementalDecoder(IncrementalDecoder): + """ + This subclass of IncrementalDecoder can be used as the baseclass for an + incremental decoder if the decoder must be able to handle incomplete byte + sequences. + """ + def __init__(self, errors='strict'): + IncrementalDecoder.__init__(self, errors) + self.buffer = "" # undecoded input that is kept between calls to decode() + + def _buffer_decode(self, input, errors, final): + # Overwrite this method in subclasses: It must decode input + # and return an (output, length consumed) tuple + raise NotImplementedError + + def decode(self, input, final=False): + # decode input (taking the buffer into account) + data = self.buffer + input + (result, consumed) = self._buffer_decode(data, self.errors, final) + # keep undecoded input until the next call + self.buffer = data[consumed:] + return result + + def reset(self): + IncrementalDecoder.reset(self) + self.buffer = "" + + def getstate(self): + # additional state info is always 0 + return (self.buffer, 0) + + def setstate(self, state): + # ignore additional state info + self.buffer = state[0] + +# +# The StreamWriter and StreamReader class provide generic working +# interfaces which can be used to implement new encoding submodules +# very easily. See encodings/utf_8.py for an example on how this is +# done. +# + +class StreamWriter(Codec): + + def __init__(self, stream, errors='strict'): + + """ Creates a StreamWriter instance. + + stream must be a file-like object open for writing + (binary) data. + + The StreamWriter may use different error handling + schemes by providing the errors keyword argument. These + parameters are predefined: + + 'strict' - raise a ValueError (or a subclass) + 'ignore' - ignore the character and continue with the next + 'replace'- replace with a suitable replacement character + 'xmlcharrefreplace' - Replace with the appropriate XML + character reference. + 'backslashreplace' - Replace with backslashed escape + sequences (only for encoding). + + The set of allowed parameter values can be extended via + register_error. + """ + self.stream = stream + self.errors = errors + + def write(self, object): + + """ Writes the object's contents encoded to self.stream. + """ + data, consumed = self.encode(object, self.errors) + self.stream.write(data) + + def writelines(self, list): + + """ Writes the concatenated list of strings to the stream + using .write(). + """ + self.write(''.join(list)) + + def reset(self): + + """ Flushes and resets the codec buffers used for keeping state. + + Calling this method should ensure that the data on the + output is put into a clean state, that allows appending + of new fresh data without having to rescan the whole + stream to recover state. + + """ + pass + + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + if whence == 0 and offset == 0: + self.reset() + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### + +class StreamReader(Codec): + + def __init__(self, stream, errors='strict'): + + """ Creates a StreamReader instance. + + stream must be a file-like object open for reading + (binary) data. + + The StreamReader may use different error handling + schemes by providing the errors keyword argument. These + parameters are predefined: + + 'strict' - raise a ValueError (or a subclass) + 'ignore' - ignore the character and continue with the next + 'replace'- replace with a suitable replacement character; + + The set of allowed parameter values can be extended via + register_error. + """ + self.stream = stream + self.errors = errors + self.bytebuffer = "" + # For str->str decoding this will stay a str + # For str->unicode decoding the first read will promote it to unicode + self.charbuffer = "" + self.linebuffer = None + + def decode(self, input, errors='strict'): + raise NotImplementedError + + def read(self, size=-1, chars=-1, firstline=False): + + """ Decodes data from the stream self.stream and returns the + resulting object. + + chars indicates the number of characters to read from the + stream. read() will never return more than chars + characters, but it might return less, if there are not enough + characters available. + + size indicates the approximate maximum number of bytes to + read from the stream for decoding purposes. The decoder + can modify this setting as appropriate. The default value + -1 indicates to read and decode as much as possible. size + is intended to prevent having to decode huge files in one + step. + + If firstline is true, and a UnicodeDecodeError happens + after the first line terminator in the input only the first line + will be returned, the rest of the input will be kept until the + next call to read(). + + The method should use a greedy read strategy meaning that + it should read as much data as is allowed within the + definition of the encoding and the given size, e.g. if + optional encoding endings or state markers are available + on the stream, these should be read too. + """ + # If we have lines cached, first merge them back into characters + if self.linebuffer: + self.charbuffer = "".join(self.linebuffer) + self.linebuffer = None + + # read until we get the required number of characters (if available) + while True: + # can the request can be satisfied from the character buffer? + if chars < 0: + if size < 0: + if self.charbuffer: + break + elif len(self.charbuffer) >= size: + break + else: + if len(self.charbuffer) >= chars: + break + # we need more data + if size < 0: + newdata = self.stream.read() + else: + newdata = self.stream.read(size) + # decode bytes (those remaining from the last call included) + data = self.bytebuffer + newdata + try: + newchars, decodedbytes = self.decode(data, self.errors) + except UnicodeDecodeError, exc: + if firstline: + newchars, decodedbytes = self.decode(data[:exc.start], self.errors) + lines = newchars.splitlines(True) + if len(lines)<=1: + raise + else: + raise + # keep undecoded bytes until the next call + self.bytebuffer = data[decodedbytes:] + # put new characters in the character buffer + self.charbuffer += newchars + # there was no data available + if not newdata: + break + if chars < 0: + # Return everything we've got + result = self.charbuffer + self.charbuffer = "" + else: + # Return the first chars characters + result = self.charbuffer[:chars] + self.charbuffer = self.charbuffer[chars:] + return result + + def readline(self, size=None, keepends=True): + + """ Read one line from the input stream and return the + decoded data. + + size, if given, is passed as size argument to the + read() method. + + """ + # If we have lines cached from an earlier read, return + # them unconditionally + if self.linebuffer: + line = self.linebuffer[0] + del self.linebuffer[0] + if len(self.linebuffer) == 1: + # revert to charbuffer mode; we might need more data + # next time + self.charbuffer = self.linebuffer[0] + self.linebuffer = None + if not keepends: + line = line.splitlines(False)[0] + return line + + readsize = size or 72 + line = "" + # If size is given, we call read() only once + while True: + data = self.read(readsize, firstline=True) + if data: + # If we're at a "\r" read one extra character (which might + # be a "\n") to get a proper line ending. If the stream is + # temporarily exhausted we return the wrong line ending. + if data.endswith("\r"): + data += self.read(size=1, chars=1) + + line += data + lines = line.splitlines(True) + if lines: + if len(lines) > 1: + # More than one line result; the first line is a full line + # to return + line = lines[0] + del lines[0] + if len(lines) > 1: + # cache the remaining lines + lines[-1] += self.charbuffer + self.linebuffer = lines + self.charbuffer = None + else: + # only one remaining line, put it back into charbuffer + self.charbuffer = lines[0] + self.charbuffer + if not keepends: + line = line.splitlines(False)[0] + break + line0withend = lines[0] + line0withoutend = lines[0].splitlines(False)[0] + if line0withend != line0withoutend: # We really have a line end + # Put the rest back together and keep it until the next call + self.charbuffer = "".join(lines[1:]) + self.charbuffer + if keepends: + line = line0withend + else: + line = line0withoutend + break + # we didn't get anything or this was our only try + if not data or size is not None: + if line and not keepends: + line = line.splitlines(False)[0] + break + if readsize<8000: + readsize *= 2 + return line + + def readlines(self, sizehint=None, keepends=True): + + """ Read all lines available on the input stream + and return them as list of lines. + + Line breaks are implemented using the codec's decoder + method and are included in the list entries. + + sizehint, if given, is ignored since there is no efficient + way to finding the true end-of-line. + + """ + data = self.read() + return data.splitlines(keepends) + + def reset(self): + + """ Resets the codec buffers used for keeping state. + + Note that no stream repositioning should take place. + This method is primarily intended to be able to recover + from decoding errors. + + """ + self.bytebuffer = "" + self.charbuffer = u"" + self.linebuffer = None + + def seek(self, offset, whence=0): + """ Set the input stream's current position. + + Resets the codec buffers used for keeping state. + """ + self.stream.seek(offset, whence) + self.reset() + + def next(self): + + """ Return the next decoded line from the input stream.""" + line = self.readline() + if line: + return line + raise StopIteration + + def __iter__(self): + return self + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### + +class StreamReaderWriter: + + """ StreamReaderWriter instances allow wrapping streams which + work in both read and write modes. + + The design is such that one can use the factory functions + returned by the codec.lookup() function to construct the + instance. + + """ + # Optional attributes set by the file wrappers below + encoding = 'unknown' + + def __init__(self, stream, Reader, Writer, errors='strict'): + + """ Creates a StreamReaderWriter instance. + + stream must be a Stream-like object. + + Reader, Writer must be factory functions or classes + providing the StreamReader, StreamWriter interface resp. + + Error handling is done in the same way as defined for the + StreamWriter/Readers. + + """ + self.stream = stream + self.reader = Reader(stream, errors) + self.writer = Writer(stream, errors) + self.errors = errors + + def read(self, size=-1): + + return self.reader.read(size) + + def readline(self, size=None): + + return self.reader.readline(size) + + def readlines(self, sizehint=None): + + return self.reader.readlines(sizehint) + + def next(self): + + """ Return the next decoded line from the input stream.""" + return self.reader.next() + + def __iter__(self): + return self + + def write(self, data): + + return self.writer.write(data) + + def writelines(self, list): + + return self.writer.writelines(list) + + def reset(self): + + self.reader.reset() + self.writer.reset() + + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + self.reader.reset() + if whence == 0 and offset == 0: + self.writer.reset() + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + # these are needed to make "with codecs.open(...)" work properly + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### + +class StreamRecoder: + + """ StreamRecoder instances provide a frontend - backend + view of encoding data. + + They use the complete set of APIs returned by the + codecs.lookup() function to implement their task. + + Data written to the stream is first decoded into an + intermediate format (which is dependent on the given codec + combination) and then written to the stream using an instance + of the provided Writer class. + + In the other direction, data is read from the stream using a + Reader instance and then return encoded data to the caller. + + """ + # Optional attributes set by the file wrappers below + data_encoding = 'unknown' + file_encoding = 'unknown' + + def __init__(self, stream, encode, decode, Reader, Writer, + errors='strict'): + + """ Creates a StreamRecoder instance which implements a two-way + conversion: encode and decode work on the frontend (the + input to .read() and output of .write()) while + Reader and Writer work on the backend (reading and + writing to the stream). + + You can use these objects to do transparent direct + recodings from e.g. latin-1 to utf-8 and back. + + stream must be a file-like object. + + encode, decode must adhere to the Codec interface, Reader, + Writer must be factory functions or classes providing the + StreamReader, StreamWriter interface resp. + + encode and decode are needed for the frontend translation, + Reader and Writer for the backend translation. Unicode is + used as intermediate encoding. + + Error handling is done in the same way as defined for the + StreamWriter/Readers. + + """ + self.stream = stream + self.encode = encode + self.decode = decode + self.reader = Reader(stream, errors) + self.writer = Writer(stream, errors) + self.errors = errors + + def read(self, size=-1): + + data = self.reader.read(size) + data, bytesencoded = self.encode(data, self.errors) + return data + + def readline(self, size=None): + + if size is None: + data = self.reader.readline() + else: + data = self.reader.readline(size) + data, bytesencoded = self.encode(data, self.errors) + return data + + def readlines(self, sizehint=None): + + data = self.reader.read() + data, bytesencoded = self.encode(data, self.errors) + return data.splitlines(1) + + def next(self): + + """ Return the next decoded line from the input stream.""" + data = self.reader.next() + data, bytesencoded = self.encode(data, self.errors) + return data + + def __iter__(self): + return self + + def write(self, data): + + data, bytesdecoded = self.decode(data, self.errors) + return self.writer.write(data) + + def writelines(self, list): + + data = ''.join(list) + data, bytesdecoded = self.decode(data, self.errors) + return self.writer.write(data) + + def reset(self): + + self.reader.reset() + self.writer.reset() + + def __getattr__(self, name, + getattr=getattr): + + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + +### Shortcuts + +def open(filename, mode='rb', encoding=None, errors='strict', buffering=1): + + """ Open an encoded file using the given mode and return + a wrapped version providing transparent encoding/decoding. + + Note: The wrapped version will only accept the object format + defined by the codecs, i.e. Unicode objects for most builtin + codecs. Output is also codec dependent and will usually be + Unicode as well. + + Files are always opened in binary mode, even if no binary mode + was specified. This is done to avoid data loss due to encodings + using 8-bit values. The default file mode is 'rb' meaning to + open the file in binary read mode. + + encoding specifies the encoding which is to be used for the + file. + + errors may be given to define the error handling. It defaults + to 'strict' which causes ValueErrors to be raised in case an + encoding error occurs. + + buffering has the same meaning as for the builtin open() API. + It defaults to line buffered. + + The returned wrapped file object provides an extra attribute + .encoding which allows querying the used encoding. This + attribute is only available if an encoding was specified as + parameter. + + """ + if encoding is not None: + if 'U' in mode: + # No automatic conversion of '\n' is done on reading and writing + mode = mode.strip().replace('U', '') + if mode[:1] not in set('rwa'): + mode = 'r' + mode + if 'b' not in mode: + # Force opening of the file in binary mode + mode = mode + 'b' + file = __builtin__.open(filename, mode, buffering) + if encoding is None: + return file + info = lookup(encoding) + srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors) + # Add attributes to simplify introspection + srw.encoding = encoding + return srw + +def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'): + + """ Return a wrapped version of file which provides transparent + encoding translation. + + Strings written to the wrapped file are interpreted according + to the given data_encoding and then written to the original + file as string using file_encoding. The intermediate encoding + will usually be Unicode but depends on the specified codecs. + + Strings are read from the file using file_encoding and then + passed back to the caller as string using data_encoding. + + If file_encoding is not given, it defaults to data_encoding. + + errors may be given to define the error handling. It defaults + to 'strict' which causes ValueErrors to be raised in case an + encoding error occurs. + + The returned wrapped file object provides two extra attributes + .data_encoding and .file_encoding which reflect the given + parameters of the same name. The attributes can be used for + introspection by Python programs. + + """ + if file_encoding is None: + file_encoding = data_encoding + data_info = lookup(data_encoding) + file_info = lookup(file_encoding) + sr = StreamRecoder(file, data_info.encode, data_info.decode, + file_info.streamreader, file_info.streamwriter, errors) + # Add attributes to simplify introspection + sr.data_encoding = data_encoding + sr.file_encoding = file_encoding + return sr + +### Helpers for codec lookup + +def getencoder(encoding): + + """ Lookup up the codec for the given encoding and return + its encoder function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).encode + +def getdecoder(encoding): + + """ Lookup up the codec for the given encoding and return + its decoder function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).decode + +def getincrementalencoder(encoding): + + """ Lookup up the codec for the given encoding and return + its IncrementalEncoder class or factory function. + + Raises a LookupError in case the encoding cannot be found + or the codecs doesn't provide an incremental encoder. + + """ + encoder = lookup(encoding).incrementalencoder + if encoder is None: + raise LookupError(encoding) + return encoder + +def getincrementaldecoder(encoding): + + """ Lookup up the codec for the given encoding and return + its IncrementalDecoder class or factory function. + + Raises a LookupError in case the encoding cannot be found + or the codecs doesn't provide an incremental decoder. + + """ + decoder = lookup(encoding).incrementaldecoder + if decoder is None: + raise LookupError(encoding) + return decoder + +def getreader(encoding): + + """ Lookup up the codec for the given encoding and return + its StreamReader class or factory function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).streamreader + +def getwriter(encoding): + + """ Lookup up the codec for the given encoding and return + its StreamWriter class or factory function. + + Raises a LookupError in case the encoding cannot be found. + + """ + return lookup(encoding).streamwriter + +def iterencode(iterator, encoding, errors='strict', **kwargs): + """ + Encoding iterator. + + Encodes the input strings from the iterator using a IncrementalEncoder. + + errors and kwargs are passed through to the IncrementalEncoder + constructor. + """ + encoder = getincrementalencoder(encoding)(errors, **kwargs) + for input in iterator: + output = encoder.encode(input) + if output: + yield output + output = encoder.encode("", True) + if output: + yield output + +def iterdecode(iterator, encoding, errors='strict', **kwargs): + """ + Decoding iterator. + + Decodes the input strings from the iterator using a IncrementalDecoder. + + errors and kwargs are passed through to the IncrementalDecoder + constructor. + """ + decoder = getincrementaldecoder(encoding)(errors, **kwargs) + for input in iterator: + output = decoder.decode(input) + if output: + yield output + output = decoder.decode("", True) + if output: + yield output + +### Helpers for charmap-based codecs + +def make_identity_dict(rng): + + """ make_identity_dict(rng) -> dict + + Return a dictionary where elements of the rng sequence are + mapped to themselves. + + """ + res = {} + for i in rng: + res[i]=i + return res + +def make_encoding_map(decoding_map): + + """ Creates an encoding map from a decoding map. + + If a target mapping in the decoding map occurs multiple + times, then that target is mapped to None (undefined mapping), + causing an exception when encountered by the charmap codec + during translation. + + One example where this happens is cp875.py which decodes + multiple character to \u001a. + + """ + m = {} + for k,v in decoding_map.items(): + if not v in m: + m[v] = k + else: + m[v] = None + return m + +### error handlers + +try: + strict_errors = lookup_error("strict") + ignore_errors = lookup_error("ignore") + replace_errors = lookup_error("replace") + xmlcharrefreplace_errors = lookup_error("xmlcharrefreplace") + backslashreplace_errors = lookup_error("backslashreplace") +except LookupError: + # In --disable-unicode builds, these error handler are missing + strict_errors = None + ignore_errors = None + replace_errors = None + xmlcharrefreplace_errors = None + backslashreplace_errors = None + +# Tell modulefinder that using codecs probably needs the encodings +# package +_false = 0 +if _false: + import encodings + +### Tests + +if __name__ == '__main__': + + # Make stdout translate Latin-1 output into UTF-8 output + sys.stdout = EncodedFile(sys.stdout, 'latin-1', 'utf-8') + + # Have stdin translate Latin-1 input into UTF-8 input + sys.stdin = EncodedFile(sys.stdin, 'utf-8', 'latin-1') diff --git a/src/main/resources/PythonLibs/codeop.py b/src/main/resources/PythonLibs/codeop.py new file mode 100644 index 0000000000000000000000000000000000000000..5c9f5e0b14797da31ff3bc6b198d69db7d3adff8 --- /dev/null +++ b/src/main/resources/PythonLibs/codeop.py @@ -0,0 +1,134 @@ +r"""Utilities to compile possibly incomplete Python source code. + +This module provides two interfaces, broadly similar to the builtin +function compile(), that take progam text, a filename and a 'mode' +and: + +- Return a code object if the command is complete and valid +- Return None if the command is incomplete +- Raise SyntaxError, ValueError or OverflowError if the command is a + syntax error (OverflowError and ValueError can be produced by + malformed literals). + +Approach: + +First, check if the source consists entirely of blank lines and +comments; if so, replace it with 'pass', because the built-in +parser doesn't always do the right thing for these. + +Compile three times: as is, with \n, and with \n\n appended. If it +compiles as is, it's complete. If it compiles with one \n appended, +we expect more. If it doesn't compile either way, we compare the +error we get when compiling with \n or \n\n appended. If the errors +are the same, the code is broken. But if the errors are different, we +expect more. Not intuitive; not even guaranteed to hold in future +releases; but this matches the compiler's behavior from Python 1.4 +through 2.2, at least. + +Caveat: + +It is possible (but not likely) that the parser stops parsing with a +successful outcome before reaching the end of the source; in this +case, trailing symbols may be ignored instead of causing an error. +For example, a backslash followed by two newlines may be followed by +arbitrary garbage. This will be fixed once the API for the parser is +better. + +The two interfaces are: + +compile_command(source, filename, symbol): + + Compiles a single command in the manner described above. + +CommandCompiler(): + + Instances of this class have __call__ methods identical in + signature to compile_command; the difference is that if the + instance compiles program text containing a __future__ statement, + the instance 'remembers' and compiles all subsequent program texts + with the statement in force. + +The module also provides another class: + +Compile(): + + Instances of this class act like the built-in function compile, + but with 'memory' in the sense described above. +""" + +# import internals, not guaranteed interface +from org.python.core import Py,CompilerFlags,CompileMode +from org.python.core.CompilerFlags import PyCF_DONT_IMPLY_DEDENT + +# public interface + +__all__ = ["compile_command", "Compile", "CommandCompiler"] + +def compile_command(source, filename="<input>", symbol="single"): + r"""Compile a command and determine whether it is incomplete. + + Arguments: + + source -- the source string; may contain \n characters + filename -- optional filename from which source was read; default + "<input>" + symbol -- optional grammar start symbol; "single" (default) or "eval" + + Return value / exceptions raised: + + - Return a code object if the command is complete and valid + - Return None if the command is incomplete + - Raise SyntaxError, ValueError or OverflowError if the command is a + syntax error (OverflowError and ValueError can be produced by + malformed literals). + """ + if symbol not in ['single','eval']: + raise ValueError,"symbol arg must be either single or eval" + symbol = CompileMode.getMode(symbol) + return Py.compile_command_flags(source,filename,symbol,Py.getCompilerFlags(),0) + +class Compile: + """Instances of this class behave much like the built-in compile + function, but if one is used to compile text containing a future + statement, it "remembers" and compiles all subsequent program texts + with the statement in force.""" + def __init__(self): + self._cflags = CompilerFlags() + + def __call__(self, source, filename, symbol): + symbol = CompileMode.getMode(symbol) + return Py.compile_flags(source, filename, symbol, self._cflags) + +class CommandCompiler: + """Instances of this class have __call__ methods identical in + signature to compile_command; the difference is that if the + instance compiles program text containing a __future__ statement, + the instance 'remembers' and compiles all subsequent program texts + with the statement in force.""" + + def __init__(self,): + self._cflags = CompilerFlags() + + def __call__(self, source, filename="<input>", symbol="single"): + r"""Compile a command and determine whether it is incomplete. + + Arguments: + + source -- the source string; may contain \n characters + filename -- optional filename from which source was read; + default "<input>" + symbol -- optional grammar start symbol; "single" (default) or + "eval" + + Return value / exceptions raised: + + - Return a code object if the command is complete and valid + - Return None if the command is incomplete + - Raise SyntaxError, ValueError or OverflowError if the command is a + syntax error (OverflowError and ValueError can be produced by + malformed literals). + """ + if symbol not in ['single','eval']: + raise ValueError,"symbol arg must be either single or eval" + symbol = CompileMode.getMode(symbol) + return Py.compile_command_flags(source,filename,symbol,self._cflags,0) diff --git a/src/main/resources/PythonLibs/collections.py b/src/main/resources/PythonLibs/collections.py new file mode 100644 index 0000000000000000000000000000000000000000..a0922412d7fd553680588efbf911c529e5b3af73 --- /dev/null +++ b/src/main/resources/PythonLibs/collections.py @@ -0,0 +1,695 @@ +__all__ = ['Counter', 'deque', 'defaultdict', 'namedtuple', 'OrderedDict'] +# For bootstrapping reasons, the collection ABCs are defined in _abcoll.py. +# They should however be considered an integral part of collections.py. +from _abcoll import * +import _abcoll +__all__ += _abcoll.__all__ + +from _collections import deque, defaultdict +from operator import itemgetter as _itemgetter, eq as _eq +from keyword import iskeyword as _iskeyword +import sys as _sys +import heapq as _heapq +from itertools import repeat as _repeat, chain as _chain, starmap as _starmap +from itertools import imap as _imap + +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + + +################################################################################ +### OrderedDict +################################################################################ + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as regular dictionaries. + + # The internal self.__map dict maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. The signature is the same as + regular dictionaries, but keyword arguments are not recommended because + their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link at the end of the linked list, + # and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + return dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which gets + # removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next # update link_prev[NEXT] + link_next[0] = link_prev # update link_next[PREV] + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + # Traverse the linked list in order. + root = self.__root + curr = root[1] # start at the first node + while curr is not root: + yield curr[2] # yield the curr[KEY] + curr = curr[1] # move to next node + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + # Traverse the linked list in reverse order. + root = self.__root + curr = root[0] # start at the last node + while curr is not root: + yield curr[2] # yield the curr[KEY] + curr = curr[0] # move to previous node + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + dict.clear(self) + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) pairs in od' + for k in self: + yield (k, self[k]) + + update = MutableMapping.update + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding + value. If key is not found, d is returned if given, otherwise KeyError + is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + key = next(reversed(self) if last else iter(self)) + value = self.pop(key) + return key, value + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S. + If not specified, the value defaults to None. + + ''' + self = cls() + for key in iterable: + self[key] = value + return self + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return dict.__eq__(self, other) and all(_imap(_eq, self, other)) + return dict.__eq__(self, other) + + def __ne__(self, other): + 'od.__ne__(y) <==> od!=y' + return not self == other + + # -- the following methods support python 3.x style dictionary views -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + + +################################################################################ +### namedtuple +################################################################################ + +_class_template = '''\ +class {typename}(tuple): + '{typename}({arg_list})' + + __slots__ = () + + _fields = {field_names!r} + + def __new__(_cls, {arg_list}): + 'Create new instance of {typename}({arg_list})' + return _tuple.__new__(_cls, ({arg_list})) + + @classmethod + def _make(cls, iterable, new=tuple.__new__, len=len): + 'Make a new {typename} object from a sequence or iterable' + result = new(cls, iterable) + if len(result) != {num_fields:d}: + raise TypeError('Expected {num_fields:d} arguments, got %d' % len(result)) + return result + + def __repr__(self): + 'Return a nicely formatted representation string' + return '{typename}({repr_fmt})' % self + + def _asdict(self): + 'Return a new OrderedDict which maps field names to their values' + return OrderedDict(zip(self._fields, self)) + + __dict__ = property(_asdict) + + def _replace(_self, **kwds): + 'Return a new {typename} object replacing specified fields with new values' + result = _self._make(map(kwds.pop, {field_names!r}, _self)) + if kwds: + raise ValueError('Got unexpected field names: %r' % kwds.keys()) + return result + + def __getnewargs__(self): + 'Return self as a plain tuple. Used by copy and pickle.' + return tuple(self) + +{field_defs} +''' + +_repr_template = '{name}=%r' + +_field_template = '''\ + {name} = _property(_itemgetter({index:d}), doc='Alias for field number {index:d}') +''' + +def namedtuple(typename, field_names, verbose=False, rename=False): + """Returns a new subclass of tuple with named fields. + + >>> Point = namedtuple('Point', ['x', 'y']) + >>> Point.__doc__ # docstring for the new class + 'Point(x, y)' + >>> p = Point(11, y=22) # instantiate with positional args or keywords + >>> p[0] + p[1] # indexable like a plain tuple + 33 + >>> x, y = p # unpack like a regular tuple + >>> x, y + (11, 22) + >>> p.x + p.y # fields also accessable by name + 33 + >>> d = p._asdict() # convert to a dictionary + >>> d['x'] + 11 + >>> Point(**d) # convert from a dictionary + Point(x=11, y=22) + >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields + Point(x=100, y=22) + + """ + + # Validate the field names. At the user's option, either generate an error + # message or automatically replace the field name with a valid name. + if isinstance(field_names, basestring): + field_names = field_names.replace(',', ' ').split() + field_names = map(str, field_names) + if rename: + seen = set() + for index, name in enumerate(field_names): + if (not all(c.isalnum() or c=='_' for c in name) + or _iskeyword(name) + or not name + or name[0].isdigit() + or name.startswith('_') + or name in seen): + field_names[index] = '_%d' % index + seen.add(name) + for name in [typename] + field_names: + if not all(c.isalnum() or c=='_' for c in name): + raise ValueError('Type names and field names can only contain ' + 'alphanumeric characters and underscores: %r' % name) + if _iskeyword(name): + raise ValueError('Type names and field names cannot be a ' + 'keyword: %r' % name) + if name[0].isdigit(): + raise ValueError('Type names and field names cannot start with ' + 'a number: %r' % name) + seen = set() + for name in field_names: + if name.startswith('_') and not rename: + raise ValueError('Field names cannot start with an underscore: ' + '%r' % name) + if name in seen: + raise ValueError('Encountered duplicate field name: %r' % name) + seen.add(name) + + # Fill-in the class template + class_definition = _class_template.format( + typename = typename, + field_names = tuple(field_names), + num_fields = len(field_names), + arg_list = repr(tuple(field_names)).replace("'", "")[1:-1], + repr_fmt = ', '.join(_repr_template.format(name=name) + for name in field_names), + field_defs = '\n'.join(_field_template.format(index=index, name=name) + for index, name in enumerate(field_names)) + ) + if verbose: + print class_definition + + # Execute the template string in a temporary namespace and support + # tracing utilities by setting a value for frame.f_globals['__name__'] + namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, + OrderedDict=OrderedDict, _property=property, _tuple=tuple) + try: + exec class_definition in namespace + except SyntaxError as e: + raise SyntaxError(e.message + ':\n' + class_definition) + result = namespace[typename] + + # For pickling to work, the __module__ variable needs to be set to the frame + # where the named tuple is created. Bypass this step in enviroments where + # sys._getframe is not defined (Jython for example) or sys._getframe is not + # defined for arguments greater than 0 (IronPython). + try: + result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass + + return result + + +######################################################################## +### Counter +######################################################################## + +class Counter(dict): + '''Dict subclass for counting hashable items. Sometimes called a bag + or multiset. Elements are stored as dictionary keys and their counts + are stored as dictionary values. + + >>> c = Counter('abcdeabcdabcaba') # count elements from a string + + >>> c.most_common(3) # three most common elements + [('a', 5), ('b', 4), ('c', 3)] + >>> sorted(c) # list all unique elements + ['a', 'b', 'c', 'd', 'e'] + >>> ''.join(sorted(c.elements())) # list elements with repetitions + 'aaaaabbbbcccdde' + >>> sum(c.values()) # total of all counts + 15 + + >>> c['a'] # count of letter 'a' + 5 + >>> for elem in 'shazam': # update counts from an iterable + ... c[elem] += 1 # by adding 1 to each element's count + >>> c['a'] # now there are seven 'a' + 7 + >>> del c['b'] # remove all 'b' + >>> c['b'] # now there are zero 'b' + 0 + + >>> d = Counter('simsalabim') # make another counter + >>> c.update(d) # add in the second counter + >>> c['a'] # now there are nine 'a' + 9 + + >>> c.clear() # empty the counter + >>> c + Counter() + + Note: If a count is set to zero or reduced to zero, it will remain + in the counter until the entry is deleted or the counter is cleared: + + >>> c = Counter('aaabbc') + >>> c['b'] -= 2 # reduce the count of 'b' by two + >>> c.most_common() # 'b' is still in, but its count is zero + [('a', 3), ('c', 1), ('b', 0)] + + ''' + # References: + # http://en.wikipedia.org/wiki/Multiset + # http://www.gnu.org/software/smalltalk/manual-base/html_node/Bag.html + # http://www.demo2s.com/Tutorial/Cpp/0380__set-multiset/Catalog0380__set-multiset.htm + # http://code.activestate.com/recipes/259174/ + # Knuth, TAOCP Vol. II section 4.6.3 + + def __init__(self, iterable=None, **kwds): + '''Create a new, empty Counter object. And if given, count elements + from an input iterable. Or, initialize the count from another mapping + of elements to their counts. + + >>> c = Counter() # a new, empty counter + >>> c = Counter('gallahad') # a new counter from an iterable + >>> c = Counter({'a': 4, 'b': 2}) # a new counter from a mapping + >>> c = Counter(a=4, b=2) # a new counter from keyword args + + ''' + super(Counter, self).__init__() + self.update(iterable, **kwds) + + def __missing__(self, key): + 'The count of elements not in the Counter is zero.' + # Needed so that self[missing_item] does not raise KeyError + return 0 + + def most_common(self, n=None): + '''List the n most common elements and their counts from the most + common to the least. If n is None, then list all element counts. + + >>> Counter('abcdeabcdabcaba').most_common(3) + [('a', 5), ('b', 4), ('c', 3)] + + ''' + # Emulate Bag.sortedByCount from Smalltalk + if n is None: + return sorted(self.iteritems(), key=_itemgetter(1), reverse=True) + return _heapq.nlargest(n, self.iteritems(), key=_itemgetter(1)) + + def elements(self): + '''Iterator over elements repeating each as many times as its count. + + >>> c = Counter('ABCABC') + >>> sorted(c.elements()) + ['A', 'A', 'B', 'B', 'C', 'C'] + + # Knuth's example for prime factors of 1836: 2**2 * 3**3 * 17**1 + >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) + >>> product = 1 + >>> for factor in prime_factors.elements(): # loop over factors + ... product *= factor # and multiply them + >>> product + 1836 + + Note, if an element's count has been set to zero or is a negative + number, elements() will ignore it. + + ''' + # Emulate Bag.do from Smalltalk and Multiset.begin from C++. + return _chain.from_iterable(_starmap(_repeat, self.iteritems())) + + # Override dict methods where necessary + + @classmethod + def fromkeys(cls, iterable, v=None): + # There is no equivalent method for counters because setting v=1 + # means that no element can have a count greater than one. + raise NotImplementedError( + 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') + + def update(self, iterable=None, **kwds): + '''Like dict.update() but add counts instead of replacing them. + + Source can be an iterable, a dictionary, or another Counter instance. + + >>> c = Counter('which') + >>> c.update('witch') # add elements from another iterable + >>> d = Counter('watch') + >>> c.update(d) # add elements from another counter + >>> c['h'] # four 'h' in which, witch, and watch + 4 + + ''' + # The regular dict.update() operation makes no sense here because the + # replace behavior results in the some of original untouched counts + # being mixed-in with all of the other counts for a mismash that + # doesn't have a straight-forward interpretation in most counting + # contexts. Instead, we implement straight-addition. Both the inputs + # and outputs are allowed to contain zero and negative counts. + + if iterable is not None: + if isinstance(iterable, Mapping): + if self: + self_get = self.get + for elem, count in iterable.iteritems(): + self[elem] = self_get(elem, 0) + count + else: + super(Counter, self).update(iterable) # fast path when counter is empty + else: + self_get = self.get + for elem in iterable: + self[elem] = self_get(elem, 0) + 1 + if kwds: + self.update(kwds) + + def subtract(self, iterable=None, **kwds): + '''Like dict.update() but subtracts counts instead of replacing them. + Counts can be reduced below zero. Both the inputs and outputs are + allowed to contain zero and negative counts. + + Source can be an iterable, a dictionary, or another Counter instance. + + >>> c = Counter('which') + >>> c.subtract('witch') # subtract elements from another iterable + >>> c.subtract(Counter('watch')) # subtract elements from another counter + >>> c['h'] # 2 in which, minus 1 in witch, minus 1 in watch + 0 + >>> c['w'] # 1 in which, minus 1 in witch, minus 1 in watch + -1 + + ''' + if iterable is not None: + self_get = self.get + if isinstance(iterable, Mapping): + for elem, count in iterable.items(): + self[elem] = self_get(elem, 0) - count + else: + for elem in iterable: + self[elem] = self_get(elem, 0) - 1 + if kwds: + self.subtract(kwds) + + def copy(self): + 'Return a shallow copy.' + return self.__class__(self) + + def __reduce__(self): + return self.__class__, (dict(self),) + + def __delitem__(self, elem): + 'Like dict.__delitem__() but does not raise KeyError for missing values.' + if elem in self: + super(Counter, self).__delitem__(elem) + + def __repr__(self): + if not self: + return '%s()' % self.__class__.__name__ + items = ', '.join(map('%r: %r'.__mod__, self.most_common())) + return '%s({%s})' % (self.__class__.__name__, items) + + # Multiset-style mathematical operations discussed in: + # Knuth TAOCP Volume II section 4.6.3 exercise 19 + # and at http://en.wikipedia.org/wiki/Multiset + # + # Outputs guaranteed to only include positive counts. + # + # To strip negative and zero counts, add-in an empty counter: + # c += Counter() + + def __add__(self, other): + '''Add counts from two counters. + + >>> Counter('abbb') + Counter('bcc') + Counter({'b': 4, 'c': 2, 'a': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + newcount = count + other[elem] + if newcount > 0: + result[elem] = newcount + for elem, count in other.items(): + if elem not in self and count > 0: + result[elem] = count + return result + + def __sub__(self, other): + ''' Subtract count, but keep only results with positive counts. + + >>> Counter('abbbc') - Counter('bccd') + Counter({'b': 2, 'a': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + newcount = count - other[elem] + if newcount > 0: + result[elem] = newcount + for elem, count in other.items(): + if elem not in self and count < 0: + result[elem] = 0 - count + return result + + def __or__(self, other): + '''Union is the maximum of value in either of the input counters. + + >>> Counter('abbb') | Counter('bcc') + Counter({'b': 3, 'c': 2, 'a': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + other_count = other[elem] + newcount = other_count if count < other_count else count + if newcount > 0: + result[elem] = newcount + for elem, count in other.items(): + if elem not in self and count > 0: + result[elem] = count + return result + + def __and__(self, other): + ''' Intersection is the minimum of corresponding counts. + + >>> Counter('abbb') & Counter('bcc') + Counter({'b': 1}) + + ''' + if not isinstance(other, Counter): + return NotImplemented + result = Counter() + for elem, count in self.items(): + other_count = other[elem] + newcount = count if count < other_count else other_count + if newcount > 0: + result[elem] = newcount + return result + + +if __name__ == '__main__': + # verify that instances can be pickled + from cPickle import loads, dumps + Point = namedtuple('Point', 'x, y', True) + p = Point(x=10, y=20) + assert p == loads(dumps(p)) + + # test and demonstrate ability to override methods + class Point(namedtuple('Point', 'x y')): + __slots__ = () + @property + def hypot(self): + return (self.x ** 2 + self.y ** 2) ** 0.5 + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + + for p in Point(3, 4), Point(14, 5/7.): + print p + + class Point(namedtuple('Point', 'x y')): + 'Point class with optimized _make() and _replace() without error-checking' + __slots__ = () + _make = classmethod(tuple.__new__) + def _replace(self, _map=map, **kwds): + return self._make(_map(kwds.get, ('x', 'y'), self)) + + print Point(11, 22)._replace(x=100) + + Point3D = namedtuple('Point3D', Point._fields + ('z',)) + print Point3D.__doc__ + + import doctest + TestResults = namedtuple('TestResults', 'failed attempted') + print TestResults(*doctest.testmod()) diff --git a/src/main/resources/PythonLibs/colorsys.py b/src/main/resources/PythonLibs/colorsys.py new file mode 100644 index 0000000000000000000000000000000000000000..a6c0cf6a4639e73e3aee9d66a52619d74dfb0d45 --- /dev/null +++ b/src/main/resources/PythonLibs/colorsys.py @@ -0,0 +1,156 @@ +"""Conversion functions between RGB and other color systems. + +This modules provides two functions for each color system ABC: + + rgb_to_abc(r, g, b) --> a, b, c + abc_to_rgb(a, b, c) --> r, g, b + +All inputs and outputs are triples of floats in the range [0.0...1.0] +(with the exception of I and Q, which covers a slightly larger range). +Inputs outside the valid range may cause exceptions or invalid outputs. + +Supported color systems: +RGB: Red, Green, Blue components +YIQ: Luminance, Chrominance (used by composite video signals) +HLS: Hue, Luminance, Saturation +HSV: Hue, Saturation, Value +""" + +# References: +# http://en.wikipedia.org/wiki/YIQ +# http://en.wikipedia.org/wiki/HLS_color_space +# http://en.wikipedia.org/wiki/HSV_color_space + +__all__ = ["rgb_to_yiq","yiq_to_rgb","rgb_to_hls","hls_to_rgb", + "rgb_to_hsv","hsv_to_rgb"] + +# Some floating point constants + +ONE_THIRD = 1.0/3.0 +ONE_SIXTH = 1.0/6.0 +TWO_THIRD = 2.0/3.0 + +# YIQ: used by composite video signals (linear combinations of RGB) +# Y: perceived grey level (0.0 == black, 1.0 == white) +# I, Q: color components + +def rgb_to_yiq(r, g, b): + y = 0.30*r + 0.59*g + 0.11*b + i = 0.60*r - 0.28*g - 0.32*b + q = 0.21*r - 0.52*g + 0.31*b + return (y, i, q) + +def yiq_to_rgb(y, i, q): + r = y + 0.948262*i + 0.624013*q + g = y - 0.276066*i - 0.639810*q + b = y - 1.105450*i + 1.729860*q + if r < 0.0: + r = 0.0 + if g < 0.0: + g = 0.0 + if b < 0.0: + b = 0.0 + if r > 1.0: + r = 1.0 + if g > 1.0: + g = 1.0 + if b > 1.0: + b = 1.0 + return (r, g, b) + + +# HLS: Hue, Luminance, Saturation +# H: position in the spectrum +# L: color lightness +# S: color saturation + +def rgb_to_hls(r, g, b): + maxc = max(r, g, b) + minc = min(r, g, b) + # XXX Can optimize (maxc+minc) and (maxc-minc) + l = (minc+maxc)/2.0 + if minc == maxc: + return 0.0, l, 0.0 + if l <= 0.5: + s = (maxc-minc) / (maxc+minc) + else: + s = (maxc-minc) / (2.0-maxc-minc) + rc = (maxc-r) / (maxc-minc) + gc = (maxc-g) / (maxc-minc) + bc = (maxc-b) / (maxc-minc) + if r == maxc: + h = bc-gc + elif g == maxc: + h = 2.0+rc-bc + else: + h = 4.0+gc-rc + h = (h/6.0) % 1.0 + return h, l, s + +def hls_to_rgb(h, l, s): + if s == 0.0: + return l, l, l + if l <= 0.5: + m2 = l * (1.0+s) + else: + m2 = l+s-(l*s) + m1 = 2.0*l - m2 + return (_v(m1, m2, h+ONE_THIRD), _v(m1, m2, h), _v(m1, m2, h-ONE_THIRD)) + +def _v(m1, m2, hue): + hue = hue % 1.0 + if hue < ONE_SIXTH: + return m1 + (m2-m1)*hue*6.0 + if hue < 0.5: + return m2 + if hue < TWO_THIRD: + return m1 + (m2-m1)*(TWO_THIRD-hue)*6.0 + return m1 + + +# HSV: Hue, Saturation, Value +# H: position in the spectrum +# S: color saturation ("purity") +# V: color brightness + +def rgb_to_hsv(r, g, b): + maxc = max(r, g, b) + minc = min(r, g, b) + v = maxc + if minc == maxc: + return 0.0, 0.0, v + s = (maxc-minc) / maxc + rc = (maxc-r) / (maxc-minc) + gc = (maxc-g) / (maxc-minc) + bc = (maxc-b) / (maxc-minc) + if r == maxc: + h = bc-gc + elif g == maxc: + h = 2.0+rc-bc + else: + h = 4.0+gc-rc + h = (h/6.0) % 1.0 + return h, s, v + +def hsv_to_rgb(h, s, v): + if s == 0.0: + return v, v, v + i = int(h*6.0) # XXX assume int() truncates! + f = (h*6.0) - i + p = v*(1.0 - s) + q = v*(1.0 - s*f) + t = v*(1.0 - s*(1.0-f)) + i = i%6 + if i == 0: + return v, t, p + if i == 1: + return q, v, p + if i == 2: + return p, v, t + if i == 3: + return p, q, v + if i == 4: + return t, p, v + if i == 5: + return v, p, q + # Cannot get here diff --git a/src/main/resources/PythonLibs/commands.py b/src/main/resources/PythonLibs/commands.py new file mode 100644 index 0000000000000000000000000000000000000000..d0e8dd5fe930105085a283e7aa38dc00e1582a99 --- /dev/null +++ b/src/main/resources/PythonLibs/commands.py @@ -0,0 +1,90 @@ +"""Execute shell commands via os.popen() and return status, output. + +Interface summary: + + import commands + + outtext = commands.getoutput(cmd) + (exitstatus, outtext) = commands.getstatusoutput(cmd) + outtext = commands.getstatus(file) # returns output of "ls -ld file" + +A trailing newline is removed from the output string. + +Encapsulates the basic operation: + + pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') + text = pipe.read() + sts = pipe.close() + + [Note: it would be nice to add functions to interpret the exit status.] +""" +from warnings import warnpy3k +warnpy3k("the commands module has been removed in Python 3.0; " + "use the subprocess module instead", stacklevel=2) +del warnpy3k + +__all__ = ["getstatusoutput","getoutput","getstatus"] + +# Module 'commands' +# +# Various tools for executing commands and looking at their output and status. +# +# NB This only works (and is only relevant) for UNIX. + + +# Get 'ls -l' status for an object into a string +# +def getstatus(file): + """Return output of "ls -ld <file>" in a string.""" + import warnings + warnings.warn("commands.getstatus() is deprecated", DeprecationWarning, 2) + return getoutput('ls -ld' + mkarg(file)) + + +# Get the output from a shell command into a string. +# The exit status is ignored; a trailing newline is stripped. +# Assume the command will work with '{ ... ; } 2>&1' around it.. +# +def getoutput(cmd): + """Return output (stdout or stderr) of executing cmd in a shell.""" + return getstatusoutput(cmd)[1] + + +# Ditto but preserving the exit status. +# Returns a pair (sts, output) +# +def getstatusoutput(cmd): + """Return (status, output) of executing cmd in a shell.""" + import os + pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') + text = pipe.read() + sts = pipe.close() + if sts is None: sts = 0 + if text[-1:] == '\n': text = text[:-1] + return sts, text + + +# Make command argument from directory and pathname (prefix space, add quotes). +# +def mk2arg(head, x): + import os + return mkarg(os.path.join(head, x)) + + +# Make a shell command argument from a string. +# Return a string beginning with a space followed by a shell-quoted +# version of the argument. +# Two strategies: enclose in single quotes if it contains none; +# otherwise, enclose in double quotes and prefix quotable characters +# with backslash. +# +def mkarg(x): + if '\'' not in x: + return ' \'' + x + '\'' + s = ' "' + for c in x: + if c in '\\$"`': + s = s + '\\' + s = s + c + s = s + '"' + return s diff --git a/src/main/resources/PythonLibs/compileall.py b/src/main/resources/PythonLibs/compileall.py new file mode 100644 index 0000000000000000000000000000000000000000..5cfa8bed3f9fa509df5d60360cddf5d5cdd0b3f0 --- /dev/null +++ b/src/main/resources/PythonLibs/compileall.py @@ -0,0 +1,227 @@ +"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. + +When called as a script with arguments, this compiles the directories +given as arguments recursively; the -l option prevents it from +recursing into directories. + +Without arguments, if compiles all modules on sys.path, without +recursing into subdirectories. (Even though it should do so for +packages -- for now, you'll have to deal with packages separately.) + +See module py_compile for details of the actual byte-compilation. +""" +import os +import sys +import py_compile +import struct +import imp + +__all__ = ["compile_dir","compile_file","compile_path"] + +def compile_dir(dir, maxlevels=10, ddir=None, + force=0, rx=None, quiet=0): + """Byte-compile all modules in the given directory tree. + + Arguments (only dir is required): + + dir: the directory to byte-compile + maxlevels: maximum recursion level (default 10) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. + force: if 1, force compilation, even if timestamps are up-to-date + quiet: if 1, be quiet during compilation + """ + if not quiet: + print 'Listing', dir, '...' + try: + names = os.listdir(dir) + except os.error: + print "Can't list", dir + names = [] + names.sort() + success = 1 + for name in names: + fullname = os.path.join(dir, name) + if ddir is not None: + dfile = os.path.join(ddir, name) + else: + dfile = None + if not os.path.isdir(fullname): + if not compile_file(fullname, ddir, force, rx, quiet): + success = 0 + elif maxlevels > 0 and \ + name != os.curdir and name != os.pardir and \ + os.path.isdir(fullname) and \ + not os.path.islink(fullname): + if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, + quiet): + success = 0 + return success + +def compile_file(fullname, ddir=None, force=0, rx=None, quiet=0): + """Byte-compile one file. + + Arguments (only fullname is required): + + fullname: the file to byte-compile + ddir: if given, the directory name compiled in to the + byte-code file. + force: if 1, force compilation, even if timestamps are up-to-date + quiet: if 1, be quiet during compilation + """ + success = 1 + name = os.path.basename(fullname) + if ddir is not None: + dfile = os.path.join(ddir, name) + else: + dfile = None + if rx is not None: + mo = rx.search(fullname) + if mo: + return success + if os.path.isfile(fullname): + head, tail = name[:-3], name[-3:] + if tail == '.py': + if not force: + try: + mtime = int(os.stat(fullname).st_mtime) + expect = struct.pack('<4sl', imp.get_magic(), mtime) + cfile = fullname + (__debug__ and 'c' or 'o') + with open(cfile, 'rb') as chandle: + actual = chandle.read(8) + if expect == actual: + return success + except IOError: + pass + if not quiet: + print 'Compiling', fullname, '...' + try: + ok = py_compile.compile(fullname, None, dfile, True) + except py_compile.PyCompileError,err: + if quiet: + print 'Compiling', fullname, '...' + print err.msg + success = 0 + except IOError, e: + print "Sorry", e + success = 0 + else: + if ok == 0: + success = 0 + return success + +def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0): + """Byte-compile all module on sys.path. + + Arguments (all optional): + + skip_curdir: if true, skip current directory (default true) + maxlevels: max recursion level (default 0) + force: as for compile_dir() (default 0) + quiet: as for compile_dir() (default 0) + """ + success = 1 + for dir in sys.path: + if (not dir or dir == os.curdir) and skip_curdir: + print 'Skipping current directory' + else: + success = success and compile_dir(dir, maxlevels, None, + force, quiet=quiet) + return success + +def expand_args(args, flist): + """read names in flist and append to args""" + expanded = args[:] + if flist: + try: + if flist == '-': + fd = sys.stdin + else: + fd = open(flist) + while 1: + line = fd.readline() + if not line: + break + expanded.append(line[:-1]) + except IOError: + print "Error reading file list %s" % flist + raise + return expanded + +def main(): + """Script main program.""" + import getopt + try: + opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:i:') + except getopt.error, msg: + print msg + print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \ + "[-x regexp] [-i list] [directory|file ...]" + print + print "arguments: zero or more file and directory names to compile; " \ + "if no arguments given, " + print " defaults to the equivalent of -l sys.path" + print + print "options:" + print "-l: don't recurse into subdirectories" + print "-f: force rebuild even if timestamps are up-to-date" + print "-q: output only error messages" + print "-d destdir: directory to prepend to file paths for use in " \ + "compile-time tracebacks and in" + print " runtime tracebacks in cases where the source " \ + "file is unavailable" + print "-x regexp: skip files matching the regular expression regexp; " \ + "the regexp is searched for" + print " in the full path of each file considered for " \ + "compilation" + print "-i file: add all the files and directories listed in file to " \ + "the list considered for" + print ' compilation; if "-", names are read from stdin' + + sys.exit(2) + maxlevels = 10 + ddir = None + force = 0 + quiet = 0 + rx = None + flist = None + for o, a in opts: + if o == '-l': maxlevels = 0 + if o == '-d': ddir = a + if o == '-f': force = 1 + if o == '-q': quiet = 1 + if o == '-x': + import re + rx = re.compile(a) + if o == '-i': flist = a + if ddir: + if len(args) != 1 and not os.path.isdir(args[0]): + print "-d destdir require exactly one directory argument" + sys.exit(2) + success = 1 + try: + if args or flist: + try: + if flist: + args = expand_args(args, flist) + except IOError: + success = 0 + if success: + for arg in args: + if os.path.isdir(arg): + if not compile_dir(arg, maxlevels, ddir, + force, rx, quiet): + success = 0 + else: + if not compile_file(arg, ddir, force, rx, quiet): + success = 0 + else: + success = compile_path() + except KeyboardInterrupt: + print "\n[interrupted]" + success = 0 + return success + +if __name__ == '__main__': + exit_status = int(not main()) + sys.exit(exit_status) diff --git a/src/main/resources/PythonLibs/compiler/__init__.py b/src/main/resources/PythonLibs/compiler/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2a6f64fa5092dce6221c3f6bdeebdfefbc2d3249 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/__init__.py @@ -0,0 +1,31 @@ +"""Package for parsing and compiling Python source code + +There are several functions defined at the top level that are imported +from modules contained in the package. + +parse(buf, mode="exec") -> AST + Converts a string containing Python source code to an abstract + syntax tree (AST). The AST is defined in compiler.ast. + +parseFile(path) -> AST + The same as parse(open(path)) + +walk(ast, visitor, verbose=None) + Does a pre-order walk over the ast using the visitor instance. + See compiler.visitor for details. + +compile(source, filename, mode, flags=None, dont_inherit=None) + Returns a code object. A replacement for the builtin compile() function. + +compileFile(filename) + Generates a .pyc file by compiling filename. +""" + +import warnings + +warnings.warn("The compiler package is deprecated and removed in Python 3.x.", + DeprecationWarning, stacklevel=2) + +from compiler.transformer import parse, parseFile +from compiler.visitor import walk +from compiler.pycodegen import compile, compileFile diff --git a/src/main/resources/PythonLibs/compiler/ast.py b/src/main/resources/PythonLibs/compiler/ast.py new file mode 100644 index 0000000000000000000000000000000000000000..4c3fc161d39f9faabfa6a390f0b281669f321096 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/ast.py @@ -0,0 +1,1419 @@ +"""Python abstract syntax node definitions + +This file is automatically generated by Tools/compiler/astgen.py +""" +from compiler.consts import CO_VARARGS, CO_VARKEYWORDS + +def flatten(seq): + l = [] + for elt in seq: + t = type(elt) + if t is tuple or t is list: + for elt2 in flatten(elt): + l.append(elt2) + else: + l.append(elt) + return l + +def flatten_nodes(seq): + return [n for n in flatten(seq) if isinstance(n, Node)] + +nodes = {} + +class Node: + """Abstract base class for ast nodes.""" + def getChildren(self): + pass # implemented by subclasses + def __iter__(self): + for n in self.getChildren(): + yield n + def asList(self): # for backwards compatibility + return self.getChildren() + def getChildNodes(self): + pass # implemented by subclasses + +class EmptyNode(Node): + pass + +class Expression(Node): + # Expression is an artificial node class to support "eval" + nodes["expression"] = "Expression" + def __init__(self, node): + self.node = node + + def getChildren(self): + return self.node, + + def getChildNodes(self): + return self.node, + + def __repr__(self): + return "Expression(%s)" % (repr(self.node)) + +class Add(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Add((%s, %s))" % (repr(self.left), repr(self.right)) + +class And(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "And(%s)" % (repr(self.nodes),) + +class AssAttr(Node): + def __init__(self, expr, attrname, flags, lineno=None): + self.expr = expr + self.attrname = attrname + self.flags = flags + self.lineno = lineno + + def getChildren(self): + return self.expr, self.attrname, self.flags + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) + +class AssList(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "AssList(%s)" % (repr(self.nodes),) + +class AssName(Node): + def __init__(self, name, flags, lineno=None): + self.name = name + self.flags = flags + self.lineno = lineno + + def getChildren(self): + return self.name, self.flags + + def getChildNodes(self): + return () + + def __repr__(self): + return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) + +class AssTuple(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "AssTuple(%s)" % (repr(self.nodes),) + +class Assert(Node): + def __init__(self, test, fail, lineno=None): + self.test = test + self.fail = fail + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.test) + children.append(self.fail) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.test) + if self.fail is not None: + nodelist.append(self.fail) + return tuple(nodelist) + + def __repr__(self): + return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) + +class Assign(Node): + def __init__(self, nodes, expr, lineno=None): + self.nodes = nodes + self.expr = expr + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.nodes)) + children.append(self.expr) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + nodelist.append(self.expr) + return tuple(nodelist) + + def __repr__(self): + return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) + +class AugAssign(Node): + def __init__(self, node, op, expr, lineno=None): + self.node = node + self.op = op + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.node, self.op, self.expr + + def getChildNodes(self): + return self.node, self.expr + + def __repr__(self): + return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) + +class Backquote(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Backquote(%s)" % (repr(self.expr),) + +class Bitand(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Bitand(%s)" % (repr(self.nodes),) + +class Bitor(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Bitor(%s)" % (repr(self.nodes),) + +class Bitxor(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Bitxor(%s)" % (repr(self.nodes),) + +class Break(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Break()" + +class CallFunc(Node): + def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None): + self.node = node + self.args = args + self.star_args = star_args + self.dstar_args = dstar_args + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.node) + children.extend(flatten(self.args)) + children.append(self.star_args) + children.append(self.dstar_args) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.node) + nodelist.extend(flatten_nodes(self.args)) + if self.star_args is not None: + nodelist.append(self.star_args) + if self.dstar_args is not None: + nodelist.append(self.dstar_args) + return tuple(nodelist) + + def __repr__(self): + return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) + +class Class(Node): + def __init__(self, name, bases, doc, code, decorators = None, lineno=None): + self.name = name + self.bases = bases + self.doc = doc + self.code = code + self.decorators = decorators + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.name) + children.extend(flatten(self.bases)) + children.append(self.doc) + children.append(self.code) + children.append(self.decorators) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.bases)) + nodelist.append(self.code) + if self.decorators is not None: + nodelist.append(self.decorators) + return tuple(nodelist) + + def __repr__(self): + return "Class(%s, %s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code), repr(self.decorators)) + +class Compare(Node): + def __init__(self, expr, ops, lineno=None): + self.expr = expr + self.ops = ops + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.ops)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.ops)) + return tuple(nodelist) + + def __repr__(self): + return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) + +class Const(Node): + def __init__(self, value, lineno=None): + self.value = value + self.lineno = lineno + + def getChildren(self): + return self.value, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Const(%s)" % (repr(self.value),) + +class Continue(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Continue()" + +class Decorators(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Decorators(%s)" % (repr(self.nodes),) + +class Dict(Node): + def __init__(self, items, lineno=None): + self.items = items + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.items)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.items)) + return tuple(nodelist) + + def __repr__(self): + return "Dict(%s)" % (repr(self.items),) + +class Discard(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Discard(%s)" % (repr(self.expr),) + +class Div(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Div((%s, %s))" % (repr(self.left), repr(self.right)) + +class Ellipsis(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Ellipsis()" + +class Exec(Node): + def __init__(self, expr, locals, globals, lineno=None): + self.expr = expr + self.locals = locals + self.globals = globals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.locals) + children.append(self.globals) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + if self.locals is not None: + nodelist.append(self.locals) + if self.globals is not None: + nodelist.append(self.globals) + return tuple(nodelist) + + def __repr__(self): + return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) + +class FloorDiv(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) + +class For(Node): + def __init__(self, assign, list, body, else_, lineno=None): + self.assign = assign + self.list = list + self.body = body + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.assign) + children.append(self.list) + children.append(self.body) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.list) + nodelist.append(self.body) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) + +class From(Node): + def __init__(self, modname, names, level, lineno=None): + self.modname = modname + self.names = names + self.level = level + self.lineno = lineno + + def getChildren(self): + return self.modname, self.names, self.level + + def getChildNodes(self): + return () + + def __repr__(self): + return "From(%s, %s, %s)" % (repr(self.modname), repr(self.names), repr(self.level)) + +class Function(Node): + def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None): + self.decorators = decorators + self.name = name + self.argnames = argnames + self.defaults = defaults + self.flags = flags + self.doc = doc + self.code = code + self.lineno = lineno + self.varargs = self.kwargs = None + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 + + + def getChildren(self): + children = [] + children.append(self.decorators) + children.append(self.name) + children.append(self.argnames) + children.extend(flatten(self.defaults)) + children.append(self.flags) + children.append(self.doc) + children.append(self.code) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + if self.decorators is not None: + nodelist.append(self.decorators) + nodelist.extend(flatten_nodes(self.defaults)) + nodelist.append(self.code) + return tuple(nodelist) + + def __repr__(self): + return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) + +class GenExpr(Node): + def __init__(self, code, lineno=None): + self.code = code + self.lineno = lineno + self.argnames = ['.0'] + self.varargs = self.kwargs = None + + + def getChildren(self): + return self.code, + + def getChildNodes(self): + return self.code, + + def __repr__(self): + return "GenExpr(%s)" % (repr(self.code),) + +class GenExprFor(Node): + def __init__(self, assign, iter, ifs, lineno=None): + self.assign = assign + self.iter = iter + self.ifs = ifs + self.lineno = lineno + self.is_outmost = False + + def getChildren(self): + children = [] + children.append(self.assign) + children.append(self.iter) + children.extend(flatten(self.ifs)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.iter) + nodelist.extend(flatten_nodes(self.ifs)) + return tuple(nodelist) + + def __repr__(self): + return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) + +class GenExprIf(Node): + def __init__(self, test, lineno=None): + self.test = test + self.lineno = lineno + + def getChildren(self): + return self.test, + + def getChildNodes(self): + return self.test, + + def __repr__(self): + return "GenExprIf(%s)" % (repr(self.test),) + +class GenExprInner(Node): + def __init__(self, expr, quals, lineno=None): + self.expr = expr + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) + +class Getattr(Node): + def __init__(self, expr, attrname, lineno=None): + self.expr = expr + self.attrname = attrname + self.lineno = lineno + + def getChildren(self): + return self.expr, self.attrname + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) + +class Global(Node): + def __init__(self, names, lineno=None): + self.names = names + self.lineno = lineno + + def getChildren(self): + return self.names, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Global(%s)" % (repr(self.names),) + +class If(Node): + def __init__(self, tests, else_, lineno=None): + self.tests = tests + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.tests)) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.tests)) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) + +class IfExp(Node): + def __init__(self, test, then, else_, lineno=None): + self.test = test + self.then = then + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + return self.test, self.then, self.else_ + + def getChildNodes(self): + return self.test, self.then, self.else_ + + def __repr__(self): + return "IfExp(%s, %s, %s)" % (repr(self.test), repr(self.then), repr(self.else_)) + +class Import(Node): + def __init__(self, names, lineno=None): + self.names = names + self.lineno = lineno + + def getChildren(self): + return self.names, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Import(%s)" % (repr(self.names),) + +class Invert(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Invert(%s)" % (repr(self.expr),) + +class Keyword(Node): + def __init__(self, name, expr, lineno=None): + self.name = name + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.name, self.expr + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) + +class Lambda(Node): + def __init__(self, argnames, defaults, flags, code, lineno=None): + self.argnames = argnames + self.defaults = defaults + self.flags = flags + self.code = code + self.lineno = lineno + self.varargs = self.kwargs = None + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 + + + def getChildren(self): + children = [] + children.append(self.argnames) + children.extend(flatten(self.defaults)) + children.append(self.flags) + children.append(self.code) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.defaults)) + nodelist.append(self.code) + return tuple(nodelist) + + def __repr__(self): + return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) + +class LeftShift(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) + +class List(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "List(%s)" % (repr(self.nodes),) + +class ListComp(Node): + def __init__(self, expr, quals, lineno=None): + self.expr = expr + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) + +class ListCompFor(Node): + def __init__(self, assign, list, ifs, lineno=None): + self.assign = assign + self.list = list + self.ifs = ifs + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.assign) + children.append(self.list) + children.extend(flatten(self.ifs)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.list) + nodelist.extend(flatten_nodes(self.ifs)) + return tuple(nodelist) + + def __repr__(self): + return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) + +class ListCompIf(Node): + def __init__(self, test, lineno=None): + self.test = test + self.lineno = lineno + + def getChildren(self): + return self.test, + + def getChildNodes(self): + return self.test, + + def __repr__(self): + return "ListCompIf(%s)" % (repr(self.test),) + +class SetComp(Node): + def __init__(self, expr, quals, lineno=None): + self.expr = expr + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "SetComp(%s, %s)" % (repr(self.expr), repr(self.quals)) + +class DictComp(Node): + def __init__(self, key, value, quals, lineno=None): + self.key = key + self.value = value + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.key) + children.append(self.value) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.key) + nodelist.append(self.value) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "DictComp(%s, %s, %s)" % (repr(self.key), repr(self.value), repr(self.quals)) + +class Mod(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) + +class Module(Node): + def __init__(self, doc, node, lineno=None): + self.doc = doc + self.node = node + self.lineno = lineno + + def getChildren(self): + return self.doc, self.node + + def getChildNodes(self): + return self.node, + + def __repr__(self): + return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) + +class Mul(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) + +class Name(Node): + def __init__(self, name, lineno=None): + self.name = name + self.lineno = lineno + + def getChildren(self): + return self.name, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Name(%s)" % (repr(self.name),) + +class Not(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Not(%s)" % (repr(self.expr),) + +class Or(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Or(%s)" % (repr(self.nodes),) + +class Pass(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Pass()" + +class Power(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Power((%s, %s))" % (repr(self.left), repr(self.right)) + +class Print(Node): + def __init__(self, nodes, dest, lineno=None): + self.nodes = nodes + self.dest = dest + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.nodes)) + children.append(self.dest) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + if self.dest is not None: + nodelist.append(self.dest) + return tuple(nodelist) + + def __repr__(self): + return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) + +class Printnl(Node): + def __init__(self, nodes, dest, lineno=None): + self.nodes = nodes + self.dest = dest + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.nodes)) + children.append(self.dest) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + if self.dest is not None: + nodelist.append(self.dest) + return tuple(nodelist) + + def __repr__(self): + return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) + +class Raise(Node): + def __init__(self, expr1, expr2, expr3, lineno=None): + self.expr1 = expr1 + self.expr2 = expr2 + self.expr3 = expr3 + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr1) + children.append(self.expr2) + children.append(self.expr3) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + if self.expr1 is not None: + nodelist.append(self.expr1) + if self.expr2 is not None: + nodelist.append(self.expr2) + if self.expr3 is not None: + nodelist.append(self.expr3) + return tuple(nodelist) + + def __repr__(self): + return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) + +class Return(Node): + def __init__(self, value, lineno=None): + self.value = value + self.lineno = lineno + + def getChildren(self): + return self.value, + + def getChildNodes(self): + return self.value, + + def __repr__(self): + return "Return(%s)" % (repr(self.value),) + +class RightShift(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) + +class Set(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Set(%s)" % (repr(self.nodes),) + +class Slice(Node): + def __init__(self, expr, flags, lower, upper, lineno=None): + self.expr = expr + self.flags = flags + self.lower = lower + self.upper = upper + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.flags) + children.append(self.lower) + children.append(self.upper) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + if self.lower is not None: + nodelist.append(self.lower) + if self.upper is not None: + nodelist.append(self.upper) + return tuple(nodelist) + + def __repr__(self): + return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) + +class Sliceobj(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Sliceobj(%s)" % (repr(self.nodes),) + +class Stmt(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Stmt(%s)" % (repr(self.nodes),) + +class Sub(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Sub((%s, %s))" % (repr(self.left), repr(self.right)) + +class Subscript(Node): + def __init__(self, expr, flags, subs, lineno=None): + self.expr = expr + self.flags = flags + self.subs = subs + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.flags) + children.extend(flatten(self.subs)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.subs)) + return tuple(nodelist) + + def __repr__(self): + return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) + +class TryExcept(Node): + def __init__(self, body, handlers, else_, lineno=None): + self.body = body + self.handlers = handlers + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.body) + children.extend(flatten(self.handlers)) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.body) + nodelist.extend(flatten_nodes(self.handlers)) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) + +class TryFinally(Node): + def __init__(self, body, final, lineno=None): + self.body = body + self.final = final + self.lineno = lineno + + def getChildren(self): + return self.body, self.final + + def getChildNodes(self): + return self.body, self.final + + def __repr__(self): + return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) + +class Tuple(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Tuple(%s)" % (repr(self.nodes),) + +class UnaryAdd(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "UnaryAdd(%s)" % (repr(self.expr),) + +class UnarySub(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "UnarySub(%s)" % (repr(self.expr),) + +class While(Node): + def __init__(self, test, body, else_, lineno=None): + self.test = test + self.body = body + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.test) + children.append(self.body) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.test) + nodelist.append(self.body) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) + +class With(Node): + def __init__(self, expr, vars, body, lineno=None): + self.expr = expr + self.vars = vars + self.body = body + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.vars) + children.append(self.body) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + if self.vars is not None: + nodelist.append(self.vars) + nodelist.append(self.body) + return tuple(nodelist) + + def __repr__(self): + return "With(%s, %s, %s)" % (repr(self.expr), repr(self.vars), repr(self.body)) + +class Yield(Node): + def __init__(self, value, lineno=None): + self.value = value + self.lineno = lineno + + def getChildren(self): + return self.value, + + def getChildNodes(self): + return self.value, + + def __repr__(self): + return "Yield(%s)" % (repr(self.value),) + +for name, obj in globals().items(): + if isinstance(obj, type) and issubclass(obj, Node): + nodes[name.lower()] = obj diff --git a/src/main/resources/PythonLibs/compiler/consts.py b/src/main/resources/PythonLibs/compiler/consts.py new file mode 100644 index 0000000000000000000000000000000000000000..c60b1d0b4f6ffc5339459ae58e5e01f888a92eae --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/consts.py @@ -0,0 +1,23 @@ +# operation flags +OP_ASSIGN = 'OP_ASSIGN' +OP_DELETE = 'OP_DELETE' +OP_APPLY = 'OP_APPLY' + +SC_LOCAL = 1 +SC_GLOBAL_IMPLICIT = 2 +SC_GLOBAL_EXPLICIT = 3 +SC_FREE = 4 +SC_CELL = 5 +SC_UNKNOWN = 6 + +CO_OPTIMIZED = 0x0001 +CO_NEWLOCALS = 0x0002 +CO_VARARGS = 0x0004 +CO_VARKEYWORDS = 0x0008 +CO_NESTED = 0x0010 +CO_GENERATOR = 0x0020 +CO_GENERATOR_ALLOWED = 0 +CO_FUTURE_DIVISION = 0x2000 +CO_FUTURE_ABSIMPORT = 0x4000 +CO_FUTURE_WITH_STATEMENT = 0x8000 +CO_FUTURE_PRINT_FUNCTION = 0x10000 diff --git a/src/main/resources/PythonLibs/compiler/future.py b/src/main/resources/PythonLibs/compiler/future.py new file mode 100644 index 0000000000000000000000000000000000000000..fd5e5dfb37427b29f1841b86cd23874e12fff6f7 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/future.py @@ -0,0 +1,74 @@ +"""Parser for future statements + +""" + +from compiler import ast, walk + +def is_future(stmt): + """Return true if statement is a well-formed future statement""" + if not isinstance(stmt, ast.From): + return 0 + if stmt.modname == "__future__": + return 1 + else: + return 0 + +class FutureParser: + + features = ("nested_scopes", "generators", "division", + "absolute_import", "with_statement", "print_function", + "unicode_literals") + + def __init__(self): + self.found = {} # set + + def visitModule(self, node): + stmt = node.node + for s in stmt.nodes: + if not self.check_stmt(s): + break + + def check_stmt(self, stmt): + if is_future(stmt): + for name, asname in stmt.names: + if name in self.features: + self.found[name] = 1 + else: + raise SyntaxError, \ + "future feature %s is not defined" % name + stmt.valid_future = 1 + return 1 + return 0 + + def get_features(self): + """Return list of features enabled by future statements""" + return self.found.keys() + +class BadFutureParser: + """Check for invalid future statements""" + + def visitFrom(self, node): + if hasattr(node, 'valid_future'): + return + if node.modname != "__future__": + return + raise SyntaxError, "invalid future statement " + repr(node) + +def find_futures(node): + p1 = FutureParser() + p2 = BadFutureParser() + walk(node, p1) + walk(node, p2) + return p1.get_features() + +if __name__ == "__main__": + import sys + from compiler import parseFile, walk + + for file in sys.argv[1:]: + print file + tree = parseFile(file) + v = FutureParser() + walk(tree, v) + print v.found + print diff --git a/src/main/resources/PythonLibs/compiler/misc.py b/src/main/resources/PythonLibs/compiler/misc.py new file mode 100644 index 0000000000000000000000000000000000000000..588c7fbd5aed9ed0bce255c07c5ff8ac8436187b --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/misc.py @@ -0,0 +1,73 @@ + +def flatten(tup): + elts = [] + for elt in tup: + if isinstance(elt, tuple): + elts = elts + flatten(elt) + else: + elts.append(elt) + return elts + +class Set: + def __init__(self): + self.elts = {} + def __len__(self): + return len(self.elts) + def __contains__(self, elt): + return elt in self.elts + def add(self, elt): + self.elts[elt] = elt + def elements(self): + return self.elts.keys() + def has_elt(self, elt): + return elt in self.elts + def remove(self, elt): + del self.elts[elt] + def copy(self): + c = Set() + c.elts.update(self.elts) + return c + +class Stack: + def __init__(self): + self.stack = [] + self.pop = self.stack.pop + def __len__(self): + return len(self.stack) + def push(self, elt): + self.stack.append(elt) + def top(self): + return self.stack[-1] + def __getitem__(self, index): # needed by visitContinue() + return self.stack[index] + +MANGLE_LEN = 256 # magic constant from compile.c + +def mangle(name, klass): + if not name.startswith('__'): + return name + if len(name) + 2 >= MANGLE_LEN: + return name + if name.endswith('__'): + return name + try: + i = 0 + while klass[i] == '_': + i = i + 1 + except IndexError: + return name + klass = klass[i:] + + tlen = len(klass) + len(name) + if tlen > MANGLE_LEN: + klass = klass[:MANGLE_LEN-tlen] + + return "_%s%s" % (klass, name) + +def set_filename(filename, tree): + """Set the filename attribute to filename on every node in tree""" + worklist = [tree] + while worklist: + node = worklist.pop(0) + node.filename = filename + worklist.extend(node.getChildNodes()) diff --git a/src/main/resources/PythonLibs/compiler/pyassem.py b/src/main/resources/PythonLibs/compiler/pyassem.py new file mode 100644 index 0000000000000000000000000000000000000000..286be0c8c7d02616d804cafbeea17912e3ccd0d8 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/pyassem.py @@ -0,0 +1,763 @@ +"""A flow graph representation for Python bytecode""" + +import dis +import types +import sys + +from compiler import misc +from compiler.consts \ + import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS + +class FlowGraph: + def __init__(self): + self.current = self.entry = Block() + self.exit = Block("exit") + self.blocks = misc.Set() + self.blocks.add(self.entry) + self.blocks.add(self.exit) + + def startBlock(self, block): + if self._debug: + if self.current: + print "end", repr(self.current) + print " next", self.current.next + print " prev", self.current.prev + print " ", self.current.get_children() + print repr(block) + self.current = block + + def nextBlock(self, block=None): + # XXX think we need to specify when there is implicit transfer + # from one block to the next. might be better to represent this + # with explicit JUMP_ABSOLUTE instructions that are optimized + # out when they are unnecessary. + # + # I think this strategy works: each block has a child + # designated as "next" which is returned as the last of the + # children. because the nodes in a graph are emitted in + # reverse post order, the "next" block will always be emitted + # immediately after its parent. + # Worry: maintaining this invariant could be tricky + if block is None: + block = self.newBlock() + + # Note: If the current block ends with an unconditional control + # transfer, then it is techically incorrect to add an implicit + # transfer to the block graph. Doing so results in code generation + # for unreachable blocks. That doesn't appear to be very common + # with Python code and since the built-in compiler doesn't optimize + # it out we don't either. + self.current.addNext(block) + self.startBlock(block) + + def newBlock(self): + b = Block() + self.blocks.add(b) + return b + + def startExitBlock(self): + self.startBlock(self.exit) + + _debug = 0 + + def _enable_debug(self): + self._debug = 1 + + def _disable_debug(self): + self._debug = 0 + + def emit(self, *inst): + if self._debug: + print "\t", inst + if len(inst) == 2 and isinstance(inst[1], Block): + self.current.addOutEdge(inst[1]) + self.current.emit(inst) + + def getBlocksInOrder(self): + """Return the blocks in reverse postorder + + i.e. each node appears before all of its successors + """ + order = order_blocks(self.entry, self.exit) + return order + + def getBlocks(self): + return self.blocks.elements() + + def getRoot(self): + """Return nodes appropriate for use with dominator""" + return self.entry + + def getContainedGraphs(self): + l = [] + for b in self.getBlocks(): + l.extend(b.getContainedGraphs()) + return l + + +def order_blocks(start_block, exit_block): + """Order blocks so that they are emitted in the right order""" + # Rules: + # - when a block has a next block, the next block must be emitted just after + # - when a block has followers (relative jumps), it must be emitted before + # them + # - all reachable blocks must be emitted + order = [] + + # Find all the blocks to be emitted. + remaining = set() + todo = [start_block] + while todo: + b = todo.pop() + if b in remaining: + continue + remaining.add(b) + for c in b.get_children(): + if c not in remaining: + todo.append(c) + + # A block is dominated by another block if that block must be emitted + # before it. + dominators = {} + for b in remaining: + if __debug__ and b.next: + assert b is b.next[0].prev[0], (b, b.next) + # Make sure every block appears in dominators, even if no + # other block must precede it. + dominators.setdefault(b, set()) + # preceeding blocks dominate following blocks + for c in b.get_followers(): + while 1: + dominators.setdefault(c, set()).add(b) + # Any block that has a next pointer leading to c is also + # dominated because the whole chain will be emitted at once. + # Walk backwards and add them all. + if c.prev and c.prev[0] is not b: + c = c.prev[0] + else: + break + + def find_next(): + # Find a block that can be emitted next. + for b in remaining: + for c in dominators[b]: + if c in remaining: + break # can't emit yet, dominated by a remaining block + else: + return b + assert 0, 'circular dependency, cannot find next block' + + b = start_block + while 1: + order.append(b) + remaining.discard(b) + if b.next: + b = b.next[0] + continue + elif b is not exit_block and not b.has_unconditional_transfer(): + order.append(exit_block) + if not remaining: + break + b = find_next() + return order + + +class Block: + _count = 0 + + def __init__(self, label=''): + self.insts = [] + self.outEdges = set() + self.label = label + self.bid = Block._count + self.next = [] + self.prev = [] + Block._count = Block._count + 1 + + def __repr__(self): + if self.label: + return "<block %s id=%d>" % (self.label, self.bid) + else: + return "<block id=%d>" % (self.bid) + + def __str__(self): + insts = map(str, self.insts) + return "<block %s %d:\n%s>" % (self.label, self.bid, + '\n'.join(insts)) + + def emit(self, inst): + op = inst[0] + self.insts.append(inst) + + def getInstructions(self): + return self.insts + + def addOutEdge(self, block): + self.outEdges.add(block) + + def addNext(self, block): + self.next.append(block) + assert len(self.next) == 1, map(str, self.next) + block.prev.append(self) + assert len(block.prev) == 1, map(str, block.prev) + + _uncond_transfer = ('RETURN_VALUE', 'RAISE_VARARGS', + 'JUMP_ABSOLUTE', 'JUMP_FORWARD', 'CONTINUE_LOOP', + ) + + def has_unconditional_transfer(self): + """Returns True if there is an unconditional transfer to an other block + at the end of this block. This means there is no risk for the bytecode + executer to go past this block's bytecode.""" + try: + op, arg = self.insts[-1] + except (IndexError, ValueError): + return + return op in self._uncond_transfer + + def get_children(self): + return list(self.outEdges) + self.next + + def get_followers(self): + """Get the whole list of followers, including the next block.""" + followers = set(self.next) + # Blocks that must be emitted *after* this one, because of + # bytecode offsets (e.g. relative jumps) pointing to them. + for inst in self.insts: + if inst[0] in PyFlowGraph.hasjrel: + followers.add(inst[1]) + return followers + + def getContainedGraphs(self): + """Return all graphs contained within this block. + + For example, a MAKE_FUNCTION block will contain a reference to + the graph for the function body. + """ + contained = [] + for inst in self.insts: + if len(inst) == 1: + continue + op = inst[1] + if hasattr(op, 'graph'): + contained.append(op.graph) + return contained + +# flags for code objects + +# the FlowGraph is transformed in place; it exists in one of these states +RAW = "RAW" +FLAT = "FLAT" +CONV = "CONV" +DONE = "DONE" + +class PyFlowGraph(FlowGraph): + super_init = FlowGraph.__init__ + + def __init__(self, name, filename, args=(), optimized=0, klass=None): + self.super_init() + self.name = name + self.filename = filename + self.docstring = None + self.args = args # XXX + self.argcount = getArgCount(args) + self.klass = klass + if optimized: + self.flags = CO_OPTIMIZED | CO_NEWLOCALS + else: + self.flags = 0 + self.consts = [] + self.names = [] + # Free variables found by the symbol table scan, including + # variables used only in nested scopes, are included here. + self.freevars = [] + self.cellvars = [] + # The closure list is used to track the order of cell + # variables and free variables in the resulting code object. + # The offsets used by LOAD_CLOSURE/LOAD_DEREF refer to both + # kinds of variables. + self.closure = [] + self.varnames = list(args) or [] + for i in range(len(self.varnames)): + var = self.varnames[i] + if isinstance(var, TupleArg): + self.varnames[i] = var.getName() + self.stage = RAW + + def setDocstring(self, doc): + self.docstring = doc + + def setFlag(self, flag): + self.flags = self.flags | flag + if flag == CO_VARARGS: + self.argcount = self.argcount - 1 + + def checkFlag(self, flag): + if self.flags & flag: + return 1 + + def setFreeVars(self, names): + self.freevars = list(names) + + def setCellVars(self, names): + self.cellvars = names + + def getCode(self): + """Get a Python code object""" + assert self.stage == RAW + self.computeStackDepth() + self.flattenGraph() + assert self.stage == FLAT + self.convertArgs() + assert self.stage == CONV + self.makeByteCode() + assert self.stage == DONE + return self.newCodeObject() + + def dump(self, io=None): + if io: + save = sys.stdout + sys.stdout = io + pc = 0 + for t in self.insts: + opname = t[0] + if opname == "SET_LINENO": + print + if len(t) == 1: + print "\t", "%3d" % pc, opname + pc = pc + 1 + else: + print "\t", "%3d" % pc, opname, t[1] + pc = pc + 3 + if io: + sys.stdout = save + + def computeStackDepth(self): + """Compute the max stack depth. + + Approach is to compute the stack effect of each basic block. + Then find the path through the code with the largest total + effect. + """ + depth = {} + exit = None + for b in self.getBlocks(): + depth[b] = findDepth(b.getInstructions()) + + seen = {} + + def max_depth(b, d): + if b in seen: + return d + seen[b] = 1 + d = d + depth[b] + children = b.get_children() + if children: + return max([max_depth(c, d) for c in children]) + else: + if not b.label == "exit": + return max_depth(self.exit, d) + else: + return d + + self.stacksize = max_depth(self.entry, 0) + + def flattenGraph(self): + """Arrange the blocks in order and resolve jumps""" + assert self.stage == RAW + self.insts = insts = [] + pc = 0 + begin = {} + end = {} + for b in self.getBlocksInOrder(): + begin[b] = pc + for inst in b.getInstructions(): + insts.append(inst) + if len(inst) == 1: + pc = pc + 1 + elif inst[0] != "SET_LINENO": + # arg takes 2 bytes + pc = pc + 3 + end[b] = pc + pc = 0 + for i in range(len(insts)): + inst = insts[i] + if len(inst) == 1: + pc = pc + 1 + elif inst[0] != "SET_LINENO": + pc = pc + 3 + opname = inst[0] + if opname in self.hasjrel: + oparg = inst[1] + offset = begin[oparg] - pc + insts[i] = opname, offset + elif opname in self.hasjabs: + insts[i] = opname, begin[inst[1]] + self.stage = FLAT + + hasjrel = set() + for i in dis.hasjrel: + hasjrel.add(dis.opname[i]) + hasjabs = set() + for i in dis.hasjabs: + hasjabs.add(dis.opname[i]) + + def convertArgs(self): + """Convert arguments from symbolic to concrete form""" + assert self.stage == FLAT + self.consts.insert(0, self.docstring) + self.sort_cellvars() + for i in range(len(self.insts)): + t = self.insts[i] + if len(t) == 2: + opname, oparg = t + conv = self._converters.get(opname, None) + if conv: + self.insts[i] = opname, conv(self, oparg) + self.stage = CONV + + def sort_cellvars(self): + """Sort cellvars in the order of varnames and prune from freevars. + """ + cells = {} + for name in self.cellvars: + cells[name] = 1 + self.cellvars = [name for name in self.varnames + if name in cells] + for name in self.cellvars: + del cells[name] + self.cellvars = self.cellvars + cells.keys() + self.closure = self.cellvars + self.freevars + + def _lookupName(self, name, list): + """Return index of name in list, appending if necessary + + This routine uses a list instead of a dictionary, because a + dictionary can't store two different keys if the keys have the + same value but different types, e.g. 2 and 2L. The compiler + must treat these two separately, so it does an explicit type + comparison before comparing the values. + """ + t = type(name) + for i in range(len(list)): + if t == type(list[i]) and list[i] == name: + return i + end = len(list) + list.append(name) + return end + + _converters = {} + def _convert_LOAD_CONST(self, arg): + if hasattr(arg, 'getCode'): + arg = arg.getCode() + return self._lookupName(arg, self.consts) + + def _convert_LOAD_FAST(self, arg): + self._lookupName(arg, self.names) + return self._lookupName(arg, self.varnames) + _convert_STORE_FAST = _convert_LOAD_FAST + _convert_DELETE_FAST = _convert_LOAD_FAST + + def _convert_LOAD_NAME(self, arg): + if self.klass is None: + self._lookupName(arg, self.varnames) + return self._lookupName(arg, self.names) + + def _convert_NAME(self, arg): + if self.klass is None: + self._lookupName(arg, self.varnames) + return self._lookupName(arg, self.names) + _convert_STORE_NAME = _convert_NAME + _convert_DELETE_NAME = _convert_NAME + _convert_IMPORT_NAME = _convert_NAME + _convert_IMPORT_FROM = _convert_NAME + _convert_STORE_ATTR = _convert_NAME + _convert_LOAD_ATTR = _convert_NAME + _convert_DELETE_ATTR = _convert_NAME + _convert_LOAD_GLOBAL = _convert_NAME + _convert_STORE_GLOBAL = _convert_NAME + _convert_DELETE_GLOBAL = _convert_NAME + + def _convert_DEREF(self, arg): + self._lookupName(arg, self.names) + self._lookupName(arg, self.varnames) + return self._lookupName(arg, self.closure) + _convert_LOAD_DEREF = _convert_DEREF + _convert_STORE_DEREF = _convert_DEREF + + def _convert_LOAD_CLOSURE(self, arg): + self._lookupName(arg, self.varnames) + return self._lookupName(arg, self.closure) + + _cmp = list(dis.cmp_op) + def _convert_COMPARE_OP(self, arg): + return self._cmp.index(arg) + + # similarly for other opcodes... + + for name, obj in locals().items(): + if name[:9] == "_convert_": + opname = name[9:] + _converters[opname] = obj + del name, obj, opname + + def makeByteCode(self): + assert self.stage == CONV + self.lnotab = lnotab = LineAddrTable() + for t in self.insts: + opname = t[0] + if len(t) == 1: + lnotab.addCode(self.opnum[opname]) + else: + oparg = t[1] + if opname == "SET_LINENO": + lnotab.nextLine(oparg) + continue + hi, lo = twobyte(oparg) + try: + lnotab.addCode(self.opnum[opname], lo, hi) + except ValueError: + print opname, oparg + print self.opnum[opname], lo, hi + raise + self.stage = DONE + + opnum = {} + for num in range(len(dis.opname)): + opnum[dis.opname[num]] = num + del num + + def newCodeObject(self): + assert self.stage == DONE + if (self.flags & CO_NEWLOCALS) == 0: + nlocals = 0 + else: + nlocals = len(self.varnames) + argcount = self.argcount + if self.flags & CO_VARKEYWORDS: + argcount = argcount - 1 + return types.CodeType(argcount, nlocals, self.stacksize, self.flags, + self.lnotab.getCode(), self.getConsts(), + tuple(self.names), tuple(self.varnames), + self.filename, self.name, self.lnotab.firstline, + self.lnotab.getTable(), tuple(self.freevars), + tuple(self.cellvars)) + + def getConsts(self): + """Return a tuple for the const slot of the code object + + Must convert references to code (MAKE_FUNCTION) to code + objects recursively. + """ + l = [] + for elt in self.consts: + if isinstance(elt, PyFlowGraph): + elt = elt.getCode() + l.append(elt) + return tuple(l) + +def isJump(opname): + if opname[:4] == 'JUMP': + return 1 + +class TupleArg: + """Helper for marking func defs with nested tuples in arglist""" + def __init__(self, count, names): + self.count = count + self.names = names + def __repr__(self): + return "TupleArg(%s, %s)" % (self.count, self.names) + def getName(self): + return ".%d" % self.count + +def getArgCount(args): + argcount = len(args) + if args: + for arg in args: + if isinstance(arg, TupleArg): + numNames = len(misc.flatten(arg.names)) + argcount = argcount - numNames + return argcount + +def twobyte(val): + """Convert an int argument into high and low bytes""" + assert isinstance(val, int) + return divmod(val, 256) + +class LineAddrTable: + """lnotab + + This class builds the lnotab, which is documented in compile.c. + Here's a brief recap: + + For each SET_LINENO instruction after the first one, two bytes are + added to lnotab. (In some cases, multiple two-byte entries are + added.) The first byte is the distance in bytes between the + instruction for the last SET_LINENO and the current SET_LINENO. + The second byte is offset in line numbers. If either offset is + greater than 255, multiple two-byte entries are added -- see + compile.c for the delicate details. + """ + + def __init__(self): + self.code = [] + self.codeOffset = 0 + self.firstline = 0 + self.lastline = 0 + self.lastoff = 0 + self.lnotab = [] + + def addCode(self, *args): + for arg in args: + self.code.append(chr(arg)) + self.codeOffset = self.codeOffset + len(args) + + def nextLine(self, lineno): + if self.firstline == 0: + self.firstline = lineno + self.lastline = lineno + else: + # compute deltas + addr = self.codeOffset - self.lastoff + line = lineno - self.lastline + # Python assumes that lineno always increases with + # increasing bytecode address (lnotab is unsigned char). + # Depending on when SET_LINENO instructions are emitted + # this is not always true. Consider the code: + # a = (1, + # b) + # In the bytecode stream, the assignment to "a" occurs + # after the loading of "b". This works with the C Python + # compiler because it only generates a SET_LINENO instruction + # for the assignment. + if line >= 0: + push = self.lnotab.append + while addr > 255: + push(255); push(0) + addr -= 255 + while line > 255: + push(addr); push(255) + line -= 255 + addr = 0 + if addr > 0 or line > 0: + push(addr); push(line) + self.lastline = lineno + self.lastoff = self.codeOffset + + def getCode(self): + return ''.join(self.code) + + def getTable(self): + return ''.join(map(chr, self.lnotab)) + +class StackDepthTracker: + # XXX 1. need to keep track of stack depth on jumps + # XXX 2. at least partly as a result, this code is broken + + def findDepth(self, insts, debug=0): + depth = 0 + maxDepth = 0 + for i in insts: + opname = i[0] + if debug: + print i, + delta = self.effect.get(opname, None) + if delta is not None: + depth = depth + delta + else: + # now check patterns + for pat, pat_delta in self.patterns: + if opname[:len(pat)] == pat: + delta = pat_delta + depth = depth + delta + break + # if we still haven't found a match + if delta is None: + meth = getattr(self, opname, None) + if meth is not None: + depth = depth + meth(i[1]) + if depth > maxDepth: + maxDepth = depth + if debug: + print depth, maxDepth + return maxDepth + + effect = { + 'POP_TOP': -1, + 'DUP_TOP': 1, + 'LIST_APPEND': -1, + 'SET_ADD': -1, + 'MAP_ADD': -2, + 'SLICE+1': -1, + 'SLICE+2': -1, + 'SLICE+3': -2, + 'STORE_SLICE+0': -1, + 'STORE_SLICE+1': -2, + 'STORE_SLICE+2': -2, + 'STORE_SLICE+3': -3, + 'DELETE_SLICE+0': -1, + 'DELETE_SLICE+1': -2, + 'DELETE_SLICE+2': -2, + 'DELETE_SLICE+3': -3, + 'STORE_SUBSCR': -3, + 'DELETE_SUBSCR': -2, + # PRINT_EXPR? + 'PRINT_ITEM': -1, + 'RETURN_VALUE': -1, + 'YIELD_VALUE': -1, + 'EXEC_STMT': -3, + 'BUILD_CLASS': -2, + 'STORE_NAME': -1, + 'STORE_ATTR': -2, + 'DELETE_ATTR': -1, + 'STORE_GLOBAL': -1, + 'BUILD_MAP': 1, + 'COMPARE_OP': -1, + 'STORE_FAST': -1, + 'IMPORT_STAR': -1, + 'IMPORT_NAME': -1, + 'IMPORT_FROM': 1, + 'LOAD_ATTR': 0, # unlike other loads + # close enough... + 'SETUP_EXCEPT': 3, + 'SETUP_FINALLY': 3, + 'FOR_ITER': 1, + 'WITH_CLEANUP': -1, + } + # use pattern match + patterns = [ + ('BINARY_', -1), + ('LOAD_', 1), + ] + + def UNPACK_SEQUENCE(self, count): + return count-1 + def BUILD_TUPLE(self, count): + return -count+1 + def BUILD_LIST(self, count): + return -count+1 + def BUILD_SET(self, count): + return -count+1 + def CALL_FUNCTION(self, argc): + hi, lo = divmod(argc, 256) + return -(lo + hi * 2) + def CALL_FUNCTION_VAR(self, argc): + return self.CALL_FUNCTION(argc)-1 + def CALL_FUNCTION_KW(self, argc): + return self.CALL_FUNCTION(argc)-1 + def CALL_FUNCTION_VAR_KW(self, argc): + return self.CALL_FUNCTION(argc)-2 + def MAKE_FUNCTION(self, argc): + return -argc + def MAKE_CLOSURE(self, argc): + # XXX need to account for free variables too! + return -argc + def BUILD_SLICE(self, argc): + if argc == 2: + return -1 + elif argc == 3: + return -2 + def DUP_TOPX(self, argc): + return argc + +findDepth = StackDepthTracker().findDepth diff --git a/src/main/resources/PythonLibs/compiler/pycodegen.py b/src/main/resources/PythonLibs/compiler/pycodegen.py new file mode 100644 index 0000000000000000000000000000000000000000..4eebd286578a8f3a6326f60d8cb406286658a5b4 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/pycodegen.py @@ -0,0 +1,1546 @@ +import imp +import os +import marshal +import struct +import sys +from cStringIO import StringIO +is_jython = sys.platform.startswith('java') + +from compiler import ast, parse, walk, syntax +from compiler import misc, future, symbols +from compiler.consts import SC_LOCAL, SC_GLOBAL_IMPLICIT, SC_GLOBAL_EXPLICT, \ + SC_FREE, SC_CELL +from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS, + CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION, + CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_PRINT_FUNCTION) +if not is_jython: + from compiler.pyassem import TupleArg +else: + TupleArg = None + +# XXX The version-specific code can go, since this code only works with 2.x. +# Do we have Python 1.x or Python 2.x? +try: + VERSION = sys.version_info[0] +except AttributeError: + VERSION = 1 + +callfunc_opcode_info = { + # (Have *args, Have **args) : opcode + (0,0) : "CALL_FUNCTION", + (1,0) : "CALL_FUNCTION_VAR", + (0,1) : "CALL_FUNCTION_KW", + (1,1) : "CALL_FUNCTION_VAR_KW", +} + +LOOP = 1 +EXCEPT = 2 +TRY_FINALLY = 3 +END_FINALLY = 4 + +def compileFile(filename, display=0): + f = open(filename, 'U') + buf = f.read() + f.close() + mod = Module(buf, filename) + try: + mod.compile(display) + except SyntaxError: + raise + else: + f = open(filename + "c", "wb") + mod.dump(f) + f.close() + +if is_jython: + # use __builtin__ compile + compile = compile +else: + def compile(source, filename, mode, flags=None, dont_inherit=None): + """Replacement for builtin compile() function""" + if flags is not None or dont_inherit is not None: + raise RuntimeError, "not implemented yet" + + if mode == "single": + gen = Interactive(source, filename) + elif mode == "exec": + gen = Module(source, filename) + elif mode == "eval": + gen = Expression(source, filename) + else: + raise ValueError("compile() 3rd arg must be 'exec' or " + "'eval' or 'single'") + gen.compile() + return gen.code + +class AbstractCompileMode: + + mode = None # defined by subclass + + def __init__(self, source, filename): + self.source = source + self.filename = filename + self.code = None + + def _get_tree(self): + tree = parse(self.source, self.mode) + misc.set_filename(self.filename, tree) + syntax.check(tree) + return tree + + def compile(self): + pass # implemented by subclass + + def getCode(self): + return self.code + +class Expression(AbstractCompileMode): + + mode = "eval" + + def compile(self): + tree = self._get_tree() + gen = ExpressionCodeGenerator(tree) + self.code = gen.getCode() + +class Interactive(AbstractCompileMode): + + mode = "single" + + def compile(self): + tree = self._get_tree() + gen = InteractiveCodeGenerator(tree) + self.code = gen.getCode() + +class Module(AbstractCompileMode): + + mode = "exec" + + def compile(self, display=0): + tree = self._get_tree() + gen = ModuleCodeGenerator(tree) + if display: + import pprint + print pprint.pprint(tree) + self.code = gen.getCode() + + def dump(self, f): + f.write(self.getPycHeader()) + marshal.dump(self.code, f) + + MAGIC = None if is_jython else imp.get_magic() + + def getPycHeader(self): + # compile.c uses marshal to write a long directly, with + # calling the interface that would also generate a 1-byte code + # to indicate the type of the value. simplest way to get the + # same effect is to call marshal and then skip the code. + mtime = os.path.getmtime(self.filename) + mtime = struct.pack('<i', mtime) + return self.MAGIC + mtime + +class LocalNameFinder: + """Find local names in scope""" + def __init__(self, names=()): + self.names = misc.Set() + self.globals = misc.Set() + for name in names: + self.names.add(name) + + # XXX list comprehensions and for loops + + def getLocals(self): + for elt in self.globals.elements(): + if self.names.has_elt(elt): + self.names.remove(elt) + return self.names + + def visitDict(self, node): + pass + + def visitGlobal(self, node): + for name in node.names: + self.globals.add(name) + + def visitFunction(self, node): + self.names.add(node.name) + + def visitLambda(self, node): + pass + + def visitImport(self, node): + for name, alias in node.names: + self.names.add(alias or name) + + def visitFrom(self, node): + for name, alias in node.names: + self.names.add(alias or name) + + def visitClass(self, node): + self.names.add(node.name) + + def visitAssName(self, node): + self.names.add(node.name) + +def is_constant_false(node): + if isinstance(node, ast.Const): + if not node.value: + return 1 + return 0 + +class CodeGenerator: + """Defines basic code generator for Python bytecode + + This class is an abstract base class. Concrete subclasses must + define an __init__() that defines self.graph and then calls the + __init__() defined in this class. + + The concrete class must also define the class attributes + NameFinder, FunctionGen, and ClassGen. These attributes can be + defined in the initClass() method, which is a hook for + initializing these methods after all the classes have been + defined. + """ + + optimized = 0 # is namespace access optimized? + __initialized = None + class_name = None # provide default for instance variable + + def __init__(self): + if self.__initialized is None: + self.initClass() + self.__class__.__initialized = 1 + self.checkClass() + self.locals = misc.Stack() + self.setups = misc.Stack() + self.last_lineno = None + self._setupGraphDelegation() + self._div_op = "BINARY_DIVIDE" + + # XXX set flags based on future features + futures = self.get_module().futures + for feature in futures: + if feature == "division": + self.graph.setFlag(CO_FUTURE_DIVISION) + self._div_op = "BINARY_TRUE_DIVIDE" + elif feature == "absolute_import": + self.graph.setFlag(CO_FUTURE_ABSIMPORT) + elif feature == "with_statement": + self.graph.setFlag(CO_FUTURE_WITH_STATEMENT) + elif feature == "print_function": + self.graph.setFlag(CO_FUTURE_PRINT_FUNCTION) + + def initClass(self): + """This method is called once for each class""" + + def checkClass(self): + """Verify that class is constructed correctly""" + try: + assert hasattr(self, 'graph') + assert getattr(self, 'NameFinder') + assert getattr(self, 'FunctionGen') + assert getattr(self, 'ClassGen') + except AssertionError, msg: + intro = "Bad class construction for %s" % self.__class__.__name__ + raise AssertionError, intro + + def _setupGraphDelegation(self): + self.emit = self.graph.emit + self.newBlock = self.graph.newBlock + self.startBlock = self.graph.startBlock + self.nextBlock = self.graph.nextBlock + self.setDocstring = self.graph.setDocstring + + def getCode(self): + """Return a code object""" + return self.graph.getCode() + + def mangle(self, name): + if self.class_name is not None: + return misc.mangle(name, self.class_name) + else: + return name + + def parseSymbols(self, tree): + s = symbols.SymbolVisitor() + walk(tree, s) + return s.scopes + + def get_module(self): + raise RuntimeError, "should be implemented by subclasses" + + # Next five methods handle name access + + def isLocalName(self, name): + return self.locals.top().has_elt(name) + + def storeName(self, name): + self._nameOp('STORE', name) + + def loadName(self, name): + self._nameOp('LOAD', name) + + def delName(self, name): + self._nameOp('DELETE', name) + + def _nameOp(self, prefix, name): + name = self.mangle(name) + scope = self.scope.check_name(name) + if scope == SC_LOCAL: + if not self.optimized: + self.emit(prefix + '_NAME', name) + else: + self.emit(prefix + '_FAST', name) + elif scope == SC_GLOBAL_EXPLICT: + self.emit(prefix + '_GLOBAL', name) + elif scope == SC_GLOBAL_IMPLICIT: + if not self.optimized: + self.emit(prefix + '_NAME', name) + else: + self.emit(prefix + '_GLOBAL', name) + elif scope == SC_FREE or scope == SC_CELL: + self.emit(prefix + '_DEREF', name) + else: + raise RuntimeError, "unsupported scope for var %s: %d" % \ + (name, scope) + + def _implicitNameOp(self, prefix, name): + """Emit name ops for names generated implicitly by for loops + + The interpreter generates names that start with a period or + dollar sign. The symbol table ignores these names because + they aren't present in the program text. + """ + if self.optimized: + self.emit(prefix + '_FAST', name) + else: + self.emit(prefix + '_NAME', name) + + # The set_lineno() function and the explicit emit() calls for + # SET_LINENO below are only used to generate the line number table. + # As of Python 2.3, the interpreter does not have a SET_LINENO + # instruction. pyassem treats SET_LINENO opcodes as a special case. + + def set_lineno(self, node, force=False): + """Emit SET_LINENO if necessary. + + The instruction is considered necessary if the node has a + lineno attribute and it is different than the last lineno + emitted. + + Returns true if SET_LINENO was emitted. + + There are no rules for when an AST node should have a lineno + attribute. The transformer and AST code need to be reviewed + and a consistent policy implemented and documented. Until + then, this method works around missing line numbers. + """ + lineno = getattr(node, 'lineno', None) + if lineno is not None and (lineno != self.last_lineno + or force): + self.emit('SET_LINENO', lineno) + self.last_lineno = lineno + return True + return False + + # The first few visitor methods handle nodes that generator new + # code objects. They use class attributes to determine what + # specialized code generators to use. + + NameFinder = LocalNameFinder + FunctionGen = None + ClassGen = None + + def visitModule(self, node): + self.scopes = self.parseSymbols(node) + self.scope = self.scopes[node] + self.emit('SET_LINENO', 0) + if node.doc: + self.emit('LOAD_CONST', node.doc) + self.storeName('__doc__') + lnf = walk(node.node, self.NameFinder(), verbose=0) + self.locals.push(lnf.getLocals()) + self.visit(node.node) + self.emit('LOAD_CONST', None) + self.emit('RETURN_VALUE') + + def visitExpression(self, node): + self.set_lineno(node) + self.scopes = self.parseSymbols(node) + self.scope = self.scopes[node] + self.visit(node.node) + self.emit('RETURN_VALUE') + + def visitFunction(self, node): + self._visitFuncOrLambda(node, isLambda=0) + if node.doc: + self.setDocstring(node.doc) + self.storeName(node.name) + + def visitLambda(self, node): + self._visitFuncOrLambda(node, isLambda=1) + + def _visitFuncOrLambda(self, node, isLambda=0): + if not isLambda and node.decorators: + for decorator in node.decorators.nodes: + self.visit(decorator) + ndecorators = len(node.decorators.nodes) + else: + ndecorators = 0 + + gen = self.FunctionGen(node, self.scopes, isLambda, + self.class_name, self.get_module()) + walk(node.code, gen) + gen.finish() + self.set_lineno(node) + for default in node.defaults: + self.visit(default) + self._makeClosure(gen, len(node.defaults)) + for i in range(ndecorators): + self.emit('CALL_FUNCTION', 1) + + def visitClass(self, node): + gen = self.ClassGen(node, self.scopes, + self.get_module()) + walk(node.code, gen) + gen.finish() + self.set_lineno(node) + self.emit('LOAD_CONST', node.name) + for base in node.bases: + self.visit(base) + self.emit('BUILD_TUPLE', len(node.bases)) + self._makeClosure(gen, 0) + self.emit('CALL_FUNCTION', 0) + self.emit('BUILD_CLASS') + self.storeName(node.name) + + # The rest are standard visitor methods + + # The next few implement control-flow statements + + def visitIf(self, node): + end = self.newBlock() + numtests = len(node.tests) + for i in range(numtests): + test, suite = node.tests[i] + if is_constant_false(test): + # XXX will need to check generator stuff here + continue + self.set_lineno(test) + self.visit(test) + nextTest = self.newBlock() + self.emit('JUMP_IF_FALSE', nextTest) + self.nextBlock() + self.emit('POP_TOP') + self.visit(suite) + self.emit('JUMP_FORWARD', end) + self.startBlock(nextTest) + self.emit('POP_TOP') + if node.else_: + self.visit(node.else_) + self.nextBlock(end) + + def visitWhile(self, node): + self.set_lineno(node) + + loop = self.newBlock() + else_ = self.newBlock() + + after = self.newBlock() + self.emit('SETUP_LOOP', after) + + self.nextBlock(loop) + self.setups.push((LOOP, loop)) + + self.set_lineno(node, force=True) + self.visit(node.test) + self.emit('JUMP_IF_FALSE', else_ or after) + + self.nextBlock() + self.emit('POP_TOP') + self.visit(node.body) + self.emit('JUMP_ABSOLUTE', loop) + + self.startBlock(else_) # or just the POPs if not else clause + self.emit('POP_TOP') + self.emit('POP_BLOCK') + self.setups.pop() + if node.else_: + self.visit(node.else_) + self.nextBlock(after) + + def visitFor(self, node): + start = self.newBlock() + anchor = self.newBlock() + after = self.newBlock() + self.setups.push((LOOP, start)) + + self.set_lineno(node) + self.emit('SETUP_LOOP', after) + self.visit(node.list) + self.emit('GET_ITER') + + self.nextBlock(start) + self.set_lineno(node, force=1) + self.emit('FOR_ITER', anchor) + self.visit(node.assign) + self.visit(node.body) + self.emit('JUMP_ABSOLUTE', start) + self.nextBlock(anchor) + self.emit('POP_BLOCK') + self.setups.pop() + if node.else_: + self.visit(node.else_) + self.nextBlock(after) + + def visitBreak(self, node): + if not self.setups: + raise SyntaxError, "'break' outside loop (%s, %d)" % \ + (node.filename, node.lineno) + self.set_lineno(node) + self.emit('BREAK_LOOP') + + def visitContinue(self, node): + if not self.setups: + raise SyntaxError, "'continue' outside loop (%s, %d)" % \ + (node.filename, node.lineno) + kind, block = self.setups.top() + if kind == LOOP: + self.set_lineno(node) + self.emit('JUMP_ABSOLUTE', block) + self.nextBlock() + elif kind == EXCEPT or kind == TRY_FINALLY: + self.set_lineno(node) + # find the block that starts the loop + top = len(self.setups) + while top > 0: + top = top - 1 + kind, loop_block = self.setups[top] + if kind == LOOP: + break + if kind != LOOP: + raise SyntaxError, "'continue' outside loop (%s, %d)" % \ + (node.filename, node.lineno) + self.emit('CONTINUE_LOOP', loop_block) + self.nextBlock() + elif kind == END_FINALLY: + msg = "'continue' not allowed inside 'finally' clause (%s, %d)" + raise SyntaxError, msg % (node.filename, node.lineno) + + def visitTest(self, node, jump): + end = self.newBlock() + for child in node.nodes[:-1]: + self.visit(child) + self.emit(jump, end) + self.nextBlock() + self.emit('POP_TOP') + self.visit(node.nodes[-1]) + self.nextBlock(end) + + def visitAnd(self, node): + self.visitTest(node, 'JUMP_IF_FALSE') + + def visitOr(self, node): + self.visitTest(node, 'JUMP_IF_TRUE') + + def visitIfExp(self, node): + endblock = self.newBlock() + elseblock = self.newBlock() + self.visit(node.test) + self.emit('JUMP_IF_FALSE', elseblock) + self.emit('POP_TOP') + self.visit(node.then) + self.emit('JUMP_FORWARD', endblock) + self.nextBlock(elseblock) + self.emit('POP_TOP') + self.visit(node.else_) + self.nextBlock(endblock) + + def visitCompare(self, node): + self.visit(node.expr) + cleanup = self.newBlock() + for op, code in node.ops[:-1]: + self.visit(code) + self.emit('DUP_TOP') + self.emit('ROT_THREE') + self.emit('COMPARE_OP', op) + self.emit('JUMP_IF_FALSE', cleanup) + self.nextBlock() + self.emit('POP_TOP') + # now do the last comparison + if node.ops: + op, code = node.ops[-1] + self.visit(code) + self.emit('COMPARE_OP', op) + if len(node.ops) > 1: + end = self.newBlock() + self.emit('JUMP_FORWARD', end) + self.startBlock(cleanup) + self.emit('ROT_TWO') + self.emit('POP_TOP') + self.nextBlock(end) + + # list comprehensions + __list_count = 0 + + def visitListComp(self, node): + self.set_lineno(node) + # setup list + append = "$append%d" % self.__list_count + self.__list_count = self.__list_count + 1 + self.emit('BUILD_LIST', 0) + self.emit('DUP_TOP') + self.emit('LOAD_ATTR', 'append') + self._implicitNameOp('STORE', append) + + stack = [] + for i, for_ in zip(range(len(node.quals)), node.quals): + start, anchor = self.visit(for_) + cont = None + for if_ in for_.ifs: + if cont is None: + cont = self.newBlock() + self.visit(if_, cont) + stack.insert(0, (start, cont, anchor)) + + self._implicitNameOp('LOAD', append) + self.visit(node.expr) + self.emit('CALL_FUNCTION', 1) + self.emit('POP_TOP') + + for start, cont, anchor in stack: + if cont: + skip_one = self.newBlock() + self.emit('JUMP_FORWARD', skip_one) + self.startBlock(cont) + self.emit('POP_TOP') + self.nextBlock(skip_one) + self.emit('JUMP_ABSOLUTE', start) + self.startBlock(anchor) + self._implicitNameOp('DELETE', append) + + self.__list_count = self.__list_count - 1 + + def visitListCompFor(self, node): + start = self.newBlock() + anchor = self.newBlock() + + self.visit(node.list) + self.emit('GET_ITER') + self.nextBlock(start) + self.set_lineno(node, force=True) + self.emit('FOR_ITER', anchor) + self.nextBlock() + self.visit(node.assign) + return start, anchor + + def visitListCompIf(self, node, branch): + self.set_lineno(node, force=True) + self.visit(node.test) + self.emit('JUMP_IF_FALSE', branch) + self.newBlock() + self.emit('POP_TOP') + + def _makeClosure(self, gen, args): + frees = gen.scope.get_free_vars() + if frees: + for name in frees: + self.emit('LOAD_CLOSURE', name) + self.emit('BUILD_TUPLE', len(frees)) + self.emit('LOAD_CONST', gen) + self.emit('MAKE_CLOSURE', args) + else: + self.emit('LOAD_CONST', gen) + self.emit('MAKE_FUNCTION', args) + + def visitGenExpr(self, node): + gen = GenExprCodeGenerator(node, self.scopes, self.class_name, + self.get_module()) + walk(node.code, gen) + gen.finish() + self.set_lineno(node) + self._makeClosure(gen, 0) + # precomputation of outmost iterable + self.visit(node.code.quals[0].iter) + self.emit('GET_ITER') + self.emit('CALL_FUNCTION', 1) + + def visitGenExprInner(self, node): + self.set_lineno(node) + # setup list + + stack = [] + for i, for_ in zip(range(len(node.quals)), node.quals): + start, anchor, end = self.visit(for_) + cont = None + for if_ in for_.ifs: + if cont is None: + cont = self.newBlock() + self.visit(if_, cont) + stack.insert(0, (start, cont, anchor, end)) + + self.visit(node.expr) + self.emit('YIELD_VALUE') + self.emit('POP_TOP') + + for start, cont, anchor, end in stack: + if cont: + skip_one = self.newBlock() + self.emit('JUMP_FORWARD', skip_one) + self.startBlock(cont) + self.emit('POP_TOP') + self.nextBlock(skip_one) + self.emit('JUMP_ABSOLUTE', start) + self.startBlock(anchor) + self.emit('POP_BLOCK') + self.setups.pop() + self.startBlock(end) + + self.emit('LOAD_CONST', None) + + def visitGenExprFor(self, node): + start = self.newBlock() + anchor = self.newBlock() + end = self.newBlock() + + self.setups.push((LOOP, start)) + self.emit('SETUP_LOOP', end) + + if node.is_outmost: + self.loadName('.0') + else: + self.visit(node.iter) + self.emit('GET_ITER') + + self.nextBlock(start) + self.set_lineno(node, force=True) + self.emit('FOR_ITER', anchor) + self.nextBlock() + self.visit(node.assign) + return start, anchor, end + + def visitGenExprIf(self, node, branch): + self.set_lineno(node, force=True) + self.visit(node.test) + self.emit('JUMP_IF_FALSE', branch) + self.newBlock() + self.emit('POP_TOP') + + # exception related + + def visitAssert(self, node): + # XXX would be interesting to implement this via a + # transformation of the AST before this stage + if __debug__: + end = self.newBlock() + self.set_lineno(node) + # XXX AssertionError appears to be special case -- it is always + # loaded as a global even if there is a local name. I guess this + # is a sort of renaming op. + self.nextBlock() + self.visit(node.test) + self.emit('JUMP_IF_TRUE', end) + self.nextBlock() + self.emit('POP_TOP') + self.emit('LOAD_GLOBAL', 'AssertionError') + if node.fail: + self.visit(node.fail) + self.emit('RAISE_VARARGS', 2) + else: + self.emit('RAISE_VARARGS', 1) + self.nextBlock(end) + self.emit('POP_TOP') + + def visitRaise(self, node): + self.set_lineno(node) + n = 0 + if node.expr1: + self.visit(node.expr1) + n = n + 1 + if node.expr2: + self.visit(node.expr2) + n = n + 1 + if node.expr3: + self.visit(node.expr3) + n = n + 1 + self.emit('RAISE_VARARGS', n) + + def visitTryExcept(self, node): + body = self.newBlock() + handlers = self.newBlock() + end = self.newBlock() + if node.else_: + lElse = self.newBlock() + else: + lElse = end + self.set_lineno(node) + self.emit('SETUP_EXCEPT', handlers) + self.nextBlock(body) + self.setups.push((EXCEPT, body)) + self.visit(node.body) + self.emit('POP_BLOCK') + self.setups.pop() + self.emit('JUMP_FORWARD', lElse) + self.startBlock(handlers) + + last = len(node.handlers) - 1 + for i in range(len(node.handlers)): + expr, target, body = node.handlers[i] + self.set_lineno(expr) + if expr: + self.emit('DUP_TOP') + self.visit(expr) + self.emit('COMPARE_OP', 'exception match') + next = self.newBlock() + self.emit('JUMP_IF_FALSE', next) + self.nextBlock() + self.emit('POP_TOP') + self.emit('POP_TOP') + if target: + self.visit(target) + else: + self.emit('POP_TOP') + self.emit('POP_TOP') + self.visit(body) + self.emit('JUMP_FORWARD', end) + if expr: + self.nextBlock(next) + else: + self.nextBlock() + if expr: # XXX + self.emit('POP_TOP') + self.emit('END_FINALLY') + if node.else_: + self.nextBlock(lElse) + self.visit(node.else_) + self.nextBlock(end) + + def visitTryFinally(self, node): + body = self.newBlock() + final = self.newBlock() + self.set_lineno(node) + self.emit('SETUP_FINALLY', final) + self.nextBlock(body) + self.setups.push((TRY_FINALLY, body)) + self.visit(node.body) + self.emit('POP_BLOCK') + self.setups.pop() + self.emit('LOAD_CONST', None) + self.nextBlock(final) + self.setups.push((END_FINALLY, final)) + self.visit(node.final) + self.emit('END_FINALLY') + self.setups.pop() + + __with_count = 0 + + def visitWith(self, node): + body = self.newBlock() + final = self.newBlock() + exitvar = "$exit%d" % self.__with_count + valuevar = "$value%d" % self.__with_count + self.__with_count += 1 + self.set_lineno(node) + self.visit(node.expr) + self.emit('DUP_TOP') + self.emit('LOAD_ATTR', '__exit__') + self._implicitNameOp('STORE', exitvar) + self.emit('LOAD_ATTR', '__enter__') + self.emit('CALL_FUNCTION', 0) + if node.vars is None: + self.emit('POP_TOP') + else: + self._implicitNameOp('STORE', valuevar) + self.emit('SETUP_FINALLY', final) + self.nextBlock(body) + self.setups.push((TRY_FINALLY, body)) + if node.vars is not None: + self._implicitNameOp('LOAD', valuevar) + self._implicitNameOp('DELETE', valuevar) + self.visit(node.vars) + self.visit(node.body) + self.emit('POP_BLOCK') + self.setups.pop() + self.emit('LOAD_CONST', None) + self.nextBlock(final) + self.setups.push((END_FINALLY, final)) + self._implicitNameOp('LOAD', exitvar) + self._implicitNameOp('DELETE', exitvar) + self.emit('WITH_CLEANUP') + self.emit('END_FINALLY') + self.setups.pop() + self.__with_count -= 1 + + # misc + + def visitDiscard(self, node): + self.set_lineno(node) + self.visit(node.expr) + self.emit('POP_TOP') + + def visitConst(self, node): + self.emit('LOAD_CONST', node.value) + + def visitKeyword(self, node): + self.emit('LOAD_CONST', node.name) + self.visit(node.expr) + + def visitGlobal(self, node): + # no code to generate + pass + + def visitName(self, node): + self.set_lineno(node) + self.loadName(node.name) + + def visitPass(self, node): + self.set_lineno(node) + + def visitImport(self, node): + self.set_lineno(node) + level = 0 if self.graph.checkFlag(CO_FUTURE_ABSIMPORT) else -1 + for name, alias in node.names: + if VERSION > 1: + self.emit('LOAD_CONST', level) + self.emit('LOAD_CONST', None) + self.emit('IMPORT_NAME', name) + mod = name.split(".")[0] + if alias: + self._resolveDots(name) + self.storeName(alias) + else: + self.storeName(mod) + + def visitFrom(self, node): + self.set_lineno(node) + level = node.level + if level == 0 and not self.graph.checkFlag(CO_FUTURE_ABSIMPORT): + level = -1 + fromlist = map(lambda (name, alias): name, node.names) + if VERSION > 1: + self.emit('LOAD_CONST', level) + self.emit('LOAD_CONST', tuple(fromlist)) + self.emit('IMPORT_NAME', node.modname) + for name, alias in node.names: + if VERSION > 1: + if name == '*': + self.namespace = 0 + self.emit('IMPORT_STAR') + # There can only be one name w/ from ... import * + assert len(node.names) == 1 + return + else: + self.emit('IMPORT_FROM', name) + self._resolveDots(name) + self.storeName(alias or name) + else: + self.emit('IMPORT_FROM', name) + self.emit('POP_TOP') + + def _resolveDots(self, name): + elts = name.split(".") + if len(elts) == 1: + return + for elt in elts[1:]: + self.emit('LOAD_ATTR', elt) + + def visitGetattr(self, node): + self.visit(node.expr) + self.emit('LOAD_ATTR', self.mangle(node.attrname)) + + # next five implement assignments + + def visitAssign(self, node): + self.set_lineno(node) + self.visit(node.expr) + dups = len(node.nodes) - 1 + for i in range(len(node.nodes)): + elt = node.nodes[i] + if i < dups: + self.emit('DUP_TOP') + if isinstance(elt, ast.Node): + self.visit(elt) + + def visitAssName(self, node): + if node.flags == 'OP_ASSIGN': + self.storeName(node.name) + elif node.flags == 'OP_DELETE': + self.set_lineno(node) + self.delName(node.name) + else: + print "oops", node.flags + + def visitAssAttr(self, node): + self.visit(node.expr) + if node.flags == 'OP_ASSIGN': + self.emit('STORE_ATTR', self.mangle(node.attrname)) + elif node.flags == 'OP_DELETE': + self.emit('DELETE_ATTR', self.mangle(node.attrname)) + else: + print "warning: unexpected flags:", node.flags + print node + + def _visitAssSequence(self, node, op='UNPACK_SEQUENCE'): + if findOp(node) != 'OP_DELETE': + self.emit(op, len(node.nodes)) + for child in node.nodes: + self.visit(child) + + if VERSION > 1: + visitAssTuple = _visitAssSequence + visitAssList = _visitAssSequence + else: + def visitAssTuple(self, node): + self._visitAssSequence(node, 'UNPACK_TUPLE') + + def visitAssList(self, node): + self._visitAssSequence(node, 'UNPACK_LIST') + + # augmented assignment + + def visitAugAssign(self, node): + self.set_lineno(node) + aug_node = wrap_aug(node.node) + self.visit(aug_node, "load") + self.visit(node.expr) + self.emit(self._augmented_opcode[node.op]) + self.visit(aug_node, "store") + + _augmented_opcode = { + '+=' : 'INPLACE_ADD', + '-=' : 'INPLACE_SUBTRACT', + '*=' : 'INPLACE_MULTIPLY', + '/=' : 'INPLACE_DIVIDE', + '//=': 'INPLACE_FLOOR_DIVIDE', + '%=' : 'INPLACE_MODULO', + '**=': 'INPLACE_POWER', + '>>=': 'INPLACE_RSHIFT', + '<<=': 'INPLACE_LSHIFT', + '&=' : 'INPLACE_AND', + '^=' : 'INPLACE_XOR', + '|=' : 'INPLACE_OR', + } + + def visitAugName(self, node, mode): + if mode == "load": + self.loadName(node.name) + elif mode == "store": + self.storeName(node.name) + + def visitAugGetattr(self, node, mode): + if mode == "load": + self.visit(node.expr) + self.emit('DUP_TOP') + self.emit('LOAD_ATTR', self.mangle(node.attrname)) + elif mode == "store": + self.emit('ROT_TWO') + self.emit('STORE_ATTR', self.mangle(node.attrname)) + + def visitAugSlice(self, node, mode): + if mode == "load": + self.visitSlice(node, 1) + elif mode == "store": + slice = 0 + if node.lower: + slice = slice | 1 + if node.upper: + slice = slice | 2 + if slice == 0: + self.emit('ROT_TWO') + elif slice == 3: + self.emit('ROT_FOUR') + else: + self.emit('ROT_THREE') + self.emit('STORE_SLICE+%d' % slice) + + def visitAugSubscript(self, node, mode): + if mode == "load": + self.visitSubscript(node, 1) + elif mode == "store": + self.emit('ROT_THREE') + self.emit('STORE_SUBSCR') + + def visitExec(self, node): + self.visit(node.expr) + if node.locals is None: + self.emit('LOAD_CONST', None) + else: + self.visit(node.locals) + if node.globals is None: + self.emit('DUP_TOP') + else: + self.visit(node.globals) + self.emit('EXEC_STMT') + + def visitCallFunc(self, node): + pos = 0 + kw = 0 + self.set_lineno(node) + self.visit(node.node) + for arg in node.args: + self.visit(arg) + if isinstance(arg, ast.Keyword): + kw = kw + 1 + else: + pos = pos + 1 + if node.star_args is not None: + self.visit(node.star_args) + if node.dstar_args is not None: + self.visit(node.dstar_args) + have_star = node.star_args is not None + have_dstar = node.dstar_args is not None + opcode = callfunc_opcode_info[have_star, have_dstar] + self.emit(opcode, kw << 8 | pos) + + def visitPrint(self, node, newline=0): + self.set_lineno(node) + if node.dest: + self.visit(node.dest) + for child in node.nodes: + if node.dest: + self.emit('DUP_TOP') + self.visit(child) + if node.dest: + self.emit('ROT_TWO') + self.emit('PRINT_ITEM_TO') + else: + self.emit('PRINT_ITEM') + if node.dest and not newline: + self.emit('POP_TOP') + + def visitPrintnl(self, node): + self.visitPrint(node, newline=1) + if node.dest: + self.emit('PRINT_NEWLINE_TO') + else: + self.emit('PRINT_NEWLINE') + + def visitReturn(self, node): + self.set_lineno(node) + self.visit(node.value) + self.emit('RETURN_VALUE') + + def visitYield(self, node): + self.set_lineno(node) + self.visit(node.value) + self.emit('YIELD_VALUE') + + # slice and subscript stuff + + def visitSlice(self, node, aug_flag=None): + # aug_flag is used by visitAugSlice + self.visit(node.expr) + slice = 0 + if node.lower: + self.visit(node.lower) + slice = slice | 1 + if node.upper: + self.visit(node.upper) + slice = slice | 2 + if aug_flag: + if slice == 0: + self.emit('DUP_TOP') + elif slice == 3: + self.emit('DUP_TOPX', 3) + else: + self.emit('DUP_TOPX', 2) + if node.flags == 'OP_APPLY': + self.emit('SLICE+%d' % slice) + elif node.flags == 'OP_ASSIGN': + self.emit('STORE_SLICE+%d' % slice) + elif node.flags == 'OP_DELETE': + self.emit('DELETE_SLICE+%d' % slice) + else: + print "weird slice", node.flags + raise + + def visitSubscript(self, node, aug_flag=None): + self.visit(node.expr) + for sub in node.subs: + self.visit(sub) + if len(node.subs) > 1: + self.emit('BUILD_TUPLE', len(node.subs)) + if aug_flag: + self.emit('DUP_TOPX', 2) + if node.flags == 'OP_APPLY': + self.emit('BINARY_SUBSCR') + elif node.flags == 'OP_ASSIGN': + self.emit('STORE_SUBSCR') + elif node.flags == 'OP_DELETE': + self.emit('DELETE_SUBSCR') + + # binary ops + + def binaryOp(self, node, op): + self.visit(node.left) + self.visit(node.right) + self.emit(op) + + def visitAdd(self, node): + return self.binaryOp(node, 'BINARY_ADD') + + def visitSub(self, node): + return self.binaryOp(node, 'BINARY_SUBTRACT') + + def visitMul(self, node): + return self.binaryOp(node, 'BINARY_MULTIPLY') + + def visitDiv(self, node): + return self.binaryOp(node, self._div_op) + + def visitFloorDiv(self, node): + return self.binaryOp(node, 'BINARY_FLOOR_DIVIDE') + + def visitMod(self, node): + return self.binaryOp(node, 'BINARY_MODULO') + + def visitPower(self, node): + return self.binaryOp(node, 'BINARY_POWER') + + def visitLeftShift(self, node): + return self.binaryOp(node, 'BINARY_LSHIFT') + + def visitRightShift(self, node): + return self.binaryOp(node, 'BINARY_RSHIFT') + + # unary ops + + def unaryOp(self, node, op): + self.visit(node.expr) + self.emit(op) + + def visitInvert(self, node): + return self.unaryOp(node, 'UNARY_INVERT') + + def visitUnarySub(self, node): + return self.unaryOp(node, 'UNARY_NEGATIVE') + + def visitUnaryAdd(self, node): + return self.unaryOp(node, 'UNARY_POSITIVE') + + def visitUnaryInvert(self, node): + return self.unaryOp(node, 'UNARY_INVERT') + + def visitNot(self, node): + return self.unaryOp(node, 'UNARY_NOT') + + def visitBackquote(self, node): + return self.unaryOp(node, 'UNARY_CONVERT') + + # bit ops + + def bitOp(self, nodes, op): + self.visit(nodes[0]) + for node in nodes[1:]: + self.visit(node) + self.emit(op) + + def visitBitand(self, node): + return self.bitOp(node.nodes, 'BINARY_AND') + + def visitBitor(self, node): + return self.bitOp(node.nodes, 'BINARY_OR') + + def visitBitxor(self, node): + return self.bitOp(node.nodes, 'BINARY_XOR') + + # object constructors + + def visitEllipsis(self, node): + self.emit('LOAD_CONST', Ellipsis) + + def visitTuple(self, node): + self.set_lineno(node) + for elt in node.nodes: + self.visit(elt) + self.emit('BUILD_TUPLE', len(node.nodes)) + + def visitList(self, node): + self.set_lineno(node) + for elt in node.nodes: + self.visit(elt) + self.emit('BUILD_LIST', len(node.nodes)) + + def visitSliceobj(self, node): + for child in node.nodes: + self.visit(child) + self.emit('BUILD_SLICE', len(node.nodes)) + + def visitDict(self, node): + self.set_lineno(node) + self.emit('BUILD_MAP', 0) + for k, v in node.items: + self.emit('DUP_TOP') + self.visit(k) + self.visit(v) + self.emit('ROT_THREE') + self.emit('STORE_SUBSCR') + +class NestedScopeMixin: + """Defines initClass() for nested scoping (Python 2.2-compatible)""" + def initClass(self): + self.__class__.NameFinder = LocalNameFinder + self.__class__.FunctionGen = FunctionCodeGenerator + self.__class__.ClassGen = ClassCodeGenerator + +class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator): + __super_init = CodeGenerator.__init__ + + scopes = None + + def __init__(self, tree): + self.graph = pyassem.PyFlowGraph("<module>", tree.filename) + self.futures = future.find_futures(tree) + self.__super_init() + walk(tree, self) + + def get_module(self): + return self + +class ExpressionCodeGenerator(NestedScopeMixin, CodeGenerator): + __super_init = CodeGenerator.__init__ + + scopes = None + futures = () + + def __init__(self, tree): + self.graph = pyassem.PyFlowGraph("<expression>", tree.filename) + self.__super_init() + walk(tree, self) + + def get_module(self): + return self + +class InteractiveCodeGenerator(NestedScopeMixin, CodeGenerator): + + __super_init = CodeGenerator.__init__ + + scopes = None + futures = () + + def __init__(self, tree): + self.graph = pyassem.PyFlowGraph("<interactive>", tree.filename) + self.__super_init() + self.set_lineno(tree) + walk(tree, self) + self.emit('RETURN_VALUE') + + def get_module(self): + return self + + def visitDiscard(self, node): + # XXX Discard means it's an expression. Perhaps this is a bad + # name. + self.visit(node.expr) + self.emit('PRINT_EXPR') + +class AbstractFunctionCode: + optimized = 1 + lambdaCount = 0 + + def __init__(self, func, scopes, isLambda, class_name, mod): + self.class_name = class_name + self.module = mod + if isLambda: + klass = FunctionCodeGenerator + name = "<lambda.%d>" % klass.lambdaCount + klass.lambdaCount = klass.lambdaCount + 1 + else: + name = func.name + + args, hasTupleArg = generateArgList(func.argnames) + self.graph = pyassem.PyFlowGraph(name, func.filename, args, + optimized=1) + self.isLambda = isLambda + self.super_init() + + if not isLambda and func.doc: + self.setDocstring(func.doc) + + lnf = walk(func.code, self.NameFinder(args), verbose=0) + self.locals.push(lnf.getLocals()) + if func.varargs: + self.graph.setFlag(CO_VARARGS) + if func.kwargs: + self.graph.setFlag(CO_VARKEYWORDS) + self.set_lineno(func) + if hasTupleArg: + self.generateArgUnpack(func.argnames) + + def get_module(self): + return self.module + + def finish(self): + self.graph.startExitBlock() + if not self.isLambda: + self.emit('LOAD_CONST', None) + self.emit('RETURN_VALUE') + + def generateArgUnpack(self, args): + for i in range(len(args)): + arg = args[i] + if isinstance(arg, tuple): + self.emit('LOAD_FAST', '.%d' % (i * 2)) + self.unpackSequence(arg) + + def unpackSequence(self, tup): + if VERSION > 1: + self.emit('UNPACK_SEQUENCE', len(tup)) + else: + self.emit('UNPACK_TUPLE', len(tup)) + for elt in tup: + if isinstance(elt, tuple): + self.unpackSequence(elt) + else: + self._nameOp('STORE', elt) + + unpackTuple = unpackSequence + +class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode, + CodeGenerator): + super_init = CodeGenerator.__init__ # call be other init + scopes = None + + __super_init = AbstractFunctionCode.__init__ + + def __init__(self, func, scopes, isLambda, class_name, mod): + self.scopes = scopes + self.scope = scopes[func] + self.__super_init(func, scopes, isLambda, class_name, mod) + self.graph.setFreeVars(self.scope.get_free_vars()) + self.graph.setCellVars(self.scope.get_cell_vars()) + if self.scope.generator is not None: + self.graph.setFlag(CO_GENERATOR) + +class GenExprCodeGenerator(NestedScopeMixin, AbstractFunctionCode, + CodeGenerator): + super_init = CodeGenerator.__init__ # call be other init + scopes = None + + __super_init = AbstractFunctionCode.__init__ + + def __init__(self, gexp, scopes, class_name, mod): + self.scopes = scopes + self.scope = scopes[gexp] + self.__super_init(gexp, scopes, 1, class_name, mod) + self.graph.setFreeVars(self.scope.get_free_vars()) + self.graph.setCellVars(self.scope.get_cell_vars()) + self.graph.setFlag(CO_GENERATOR) + +class AbstractClassCode: + + def __init__(self, klass, scopes, module): + self.class_name = klass.name + self.module = module + self.graph = pyassem.PyFlowGraph(klass.name, klass.filename, + optimized=0, klass=1) + self.super_init() + lnf = walk(klass.code, self.NameFinder(), verbose=0) + self.locals.push(lnf.getLocals()) + self.graph.setFlag(CO_NEWLOCALS) + if klass.doc: + self.setDocstring(klass.doc) + + def get_module(self): + return self.module + + def finish(self): + self.graph.startExitBlock() + self.emit('LOAD_LOCALS') + self.emit('RETURN_VALUE') + +class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator): + super_init = CodeGenerator.__init__ + scopes = None + + __super_init = AbstractClassCode.__init__ + + def __init__(self, klass, scopes, module): + self.scopes = scopes + self.scope = scopes[klass] + self.__super_init(klass, scopes, module) + self.graph.setFreeVars(self.scope.get_free_vars()) + self.graph.setCellVars(self.scope.get_cell_vars()) + self.set_lineno(klass) + self.emit("LOAD_GLOBAL", "__name__") + self.storeName("__module__") + if klass.doc: + self.emit("LOAD_CONST", klass.doc) + self.storeName('__doc__') + +def generateArgList(arglist): + """Generate an arg list marking TupleArgs""" + args = [] + extra = [] + count = 0 + for i in range(len(arglist)): + elt = arglist[i] + if isinstance(elt, str): + args.append(elt) + elif isinstance(elt, tuple): + args.append(TupleArg(i * 2, elt)) + extra.extend(misc.flatten(elt)) + count = count + 1 + else: + raise ValueError, "unexpect argument type:", elt + return args + extra, count + +def findOp(node): + """Find the op (DELETE, LOAD, STORE) in an AssTuple tree""" + v = OpFinder() + walk(node, v, verbose=0) + return v.op + +class OpFinder: + def __init__(self): + self.op = None + def visitAssName(self, node): + if self.op is None: + self.op = node.flags + elif self.op != node.flags: + raise ValueError, "mixed ops in stmt" + visitAssAttr = visitAssName + visitSubscript = visitAssName + +class Delegator: + """Base class to support delegation for augmented assignment nodes + + To generator code for augmented assignments, we use the following + wrapper classes. In visitAugAssign, the left-hand expression node + is visited twice. The first time the visit uses the normal method + for that node . The second time the visit uses a different method + that generates the appropriate code to perform the assignment. + These delegator classes wrap the original AST nodes in order to + support the variant visit methods. + """ + def __init__(self, obj): + self.obj = obj + + def __getattr__(self, attr): + return getattr(self.obj, attr) + +class AugGetattr(Delegator): + pass + +class AugName(Delegator): + pass + +class AugSlice(Delegator): + pass + +class AugSubscript(Delegator): + pass + +wrapper = { + ast.Getattr: AugGetattr, + ast.Name: AugName, + ast.Slice: AugSlice, + ast.Subscript: AugSubscript, + } + +def wrap_aug(node): + return wrapper[node.__class__](node) + +if __name__ == "__main__": + for file in sys.argv[1:]: + compileFile(file) diff --git a/src/main/resources/PythonLibs/compiler/symbols.py b/src/main/resources/PythonLibs/compiler/symbols.py new file mode 100644 index 0000000000000000000000000000000000000000..afeec501538fd652f78b6fcb6ec24c34bad62aa8 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/symbols.py @@ -0,0 +1,462 @@ +"""Module symbol-table generator""" + +from compiler import ast +from compiler.consts import SC_LOCAL, SC_GLOBAL_IMPLICIT, SC_GLOBAL_EXPLICIT, \ + SC_FREE, SC_CELL, SC_UNKNOWN +from compiler.misc import mangle +import types + + +import sys + +MANGLE_LEN = 256 + +class Scope: + # XXX how much information do I need about each name? + def __init__(self, name, module, klass=None): + self.name = name + self.module = module + self.defs = {} + self.uses = {} + self.globals = {} + self.params = {} + self.frees = {} + self.cells = {} + self.children = [] + # nested is true if the class could contain free variables, + # i.e. if it is nested within another function. + self.nested = None + self.generator = None + self.klass = None + if klass is not None: + for i in range(len(klass)): + if klass[i] != '_': + self.klass = klass[i:] + break + + def __repr__(self): + return "<%s: %s>" % (self.__class__.__name__, self.name) + + def mangle(self, name): + if self.klass is None: + return name + return mangle(name, self.klass) + + def add_def(self, name): + self.defs[self.mangle(name)] = 1 + + def add_use(self, name): + self.uses[self.mangle(name)] = 1 + + def add_global(self, name): + name = self.mangle(name) + if name in self.uses or name in self.defs: + pass # XXX warn about global following def/use + if name in self.params: + raise SyntaxError, "%s in %s is global and parameter" % \ + (name, self.name) + self.globals[name] = 1 + self.module.add_def(name) + + def add_param(self, name): + name = self.mangle(name) + self.defs[name] = 1 + self.params[name] = 1 + + def get_names(self): + d = {} + d.update(self.defs) + d.update(self.uses) + d.update(self.globals) + return d.keys() + + def add_child(self, child): + self.children.append(child) + + def get_children(self): + return self.children + + def DEBUG(self): + print >> sys.stderr, self.name, self.nested and "nested" or "" + print >> sys.stderr, "\tglobals: ", self.globals + print >> sys.stderr, "\tcells: ", self.cells + print >> sys.stderr, "\tdefs: ", self.defs + print >> sys.stderr, "\tuses: ", self.uses + print >> sys.stderr, "\tfrees:", self.frees + + def check_name(self, name): + """Return scope of name. + + The scope of a name could be LOCAL, GLOBAL, FREE, or CELL. + """ + if name in self.globals: + return SC_GLOBAL_EXPLICIT + if name in self.cells: + return SC_CELL + if name in self.defs: + return SC_LOCAL + if self.nested and (name in self.frees or name in self.uses): + return SC_FREE + if self.nested: + return SC_UNKNOWN + else: + return SC_GLOBAL_IMPLICIT + + def get_free_vars(self): + if not self.nested: + return () + free = {} + free.update(self.frees) + for name in self.uses.keys(): + if name not in self.defs and name not in self.globals: + free[name] = 1 + return free.keys() + + def handle_children(self): + for child in self.children: + frees = child.get_free_vars() + globals = self.add_frees(frees) + for name in globals: + child.force_global(name) + + def force_global(self, name): + """Force name to be global in scope. + + Some child of the current node had a free reference to name. + When the child was processed, it was labelled a free + variable. Now that all its enclosing scope have been + processed, the name is known to be a global or builtin. So + walk back down the child chain and set the name to be global + rather than free. + + Be careful to stop if a child does not think the name is + free. + """ + self.globals[name] = 1 + if name in self.frees: + del self.frees[name] + for child in self.children: + if child.check_name(name) == SC_FREE: + child.force_global(name) + + def add_frees(self, names): + """Process list of free vars from nested scope. + + Returns a list of names that are either 1) declared global in the + parent or 2) undefined in a top-level parent. In either case, + the nested scope should treat them as globals. + """ + child_globals = [] + for name in names: + sc = self.check_name(name) + if self.nested: + if sc == SC_UNKNOWN or sc == SC_FREE \ + or isinstance(self, ClassScope): + self.frees[name] = 1 + elif sc == SC_GLOBAL_IMPLICIT: + child_globals.append(name) + elif isinstance(self, FunctionScope) and sc == SC_LOCAL: + self.cells[name] = 1 + elif sc != SC_CELL: + child_globals.append(name) + else: + if sc == SC_LOCAL: + self.cells[name] = 1 + elif sc != SC_CELL: + child_globals.append(name) + return child_globals + + def get_cell_vars(self): + return self.cells.keys() + +class ModuleScope(Scope): + __super_init = Scope.__init__ + + def __init__(self): + self.__super_init("global", self) + +class FunctionScope(Scope): + pass + +class GenExprScope(Scope): + __super_init = Scope.__init__ + + __counter = 1 + + def __init__(self, module, klass=None): + i = self.__counter + self.__counter += 1 + self.__super_init("generator expression<%d>"%i, module, klass) + self.add_param('.0') + + def get_names(self): + keys = Scope.get_names(self) + return keys + +class LambdaScope(FunctionScope): + __super_init = Scope.__init__ + + __counter = 1 + + def __init__(self, module, klass=None): + i = self.__counter + self.__counter += 1 + self.__super_init("lambda.%d" % i, module, klass) + +class ClassScope(Scope): + __super_init = Scope.__init__ + + def __init__(self, name, module): + self.__super_init(name, module, name) + +class SymbolVisitor: + def __init__(self): + self.scopes = {} + self.klass = None + + # node that define new scopes + + def visitModule(self, node): + scope = self.module = self.scopes[node] = ModuleScope() + self.visit(node.node, scope) + + visitExpression = visitModule + + def visitFunction(self, node, parent): + if node.decorators: + self.visit(node.decorators, parent) + parent.add_def(node.name) + for n in node.defaults: + self.visit(n, parent) + scope = FunctionScope(node.name, self.module, self.klass) + if parent.nested or isinstance(parent, FunctionScope): + scope.nested = 1 + self.scopes[node] = scope + self._do_args(scope, node.argnames) + self.visit(node.code, scope) + self.handle_free_vars(scope, parent) + + def visitGenExpr(self, node, parent): + scope = GenExprScope(self.module, self.klass); + if parent.nested or isinstance(parent, FunctionScope) \ + or isinstance(parent, GenExprScope): + scope.nested = 1 + + self.scopes[node] = scope + self.visit(node.code, scope) + + self.handle_free_vars(scope, parent) + + def visitGenExprInner(self, node, scope): + for genfor in node.quals: + self.visit(genfor, scope) + + self.visit(node.expr, scope) + + def visitGenExprFor(self, node, scope): + self.visit(node.assign, scope, 1) + self.visit(node.iter, scope) + for if_ in node.ifs: + self.visit(if_, scope) + + def visitGenExprIf(self, node, scope): + self.visit(node.test, scope) + + def visitLambda(self, node, parent, assign=0): + # Lambda is an expression, so it could appear in an expression + # context where assign is passed. The transformer should catch + # any code that has a lambda on the left-hand side. + assert not assign + + for n in node.defaults: + self.visit(n, parent) + scope = LambdaScope(self.module, self.klass) + if parent.nested or isinstance(parent, FunctionScope): + scope.nested = 1 + self.scopes[node] = scope + self._do_args(scope, node.argnames) + self.visit(node.code, scope) + self.handle_free_vars(scope, parent) + + def _do_args(self, scope, args): + for name in args: + if type(name) == types.TupleType: + self._do_args(scope, name) + else: + scope.add_param(name) + + def handle_free_vars(self, scope, parent): + parent.add_child(scope) + scope.handle_children() + + def visitClass(self, node, parent): + parent.add_def(node.name) + for n in node.bases: + self.visit(n, parent) + scope = ClassScope(node.name, self.module) + if parent.nested or isinstance(parent, FunctionScope): + scope.nested = 1 + if node.doc is not None: + scope.add_def('__doc__') + scope.add_def('__module__') + self.scopes[node] = scope + prev = self.klass + self.klass = node.name + self.visit(node.code, scope) + self.klass = prev + self.handle_free_vars(scope, parent) + + # name can be a def or a use + + # XXX a few calls and nodes expect a third "assign" arg that is + # true if the name is being used as an assignment. only + # expressions contained within statements may have the assign arg. + + def visitName(self, node, scope, assign=0): + if assign: + scope.add_def(node.name) + else: + scope.add_use(node.name) + + # operations that bind new names + + def visitFor(self, node, scope): + self.visit(node.assign, scope, 1) + self.visit(node.list, scope) + self.visit(node.body, scope) + if node.else_: + self.visit(node.else_, scope) + + def visitFrom(self, node, scope): + for name, asname in node.names: + if name == "*": + continue + scope.add_def(asname or name) + + def visitImport(self, node, scope): + for name, asname in node.names: + i = name.find(".") + if i > -1: + name = name[:i] + scope.add_def(asname or name) + + def visitGlobal(self, node, scope): + for name in node.names: + scope.add_global(name) + + def visitAssign(self, node, scope): + """Propagate assignment flag down to child nodes. + + The Assign node doesn't itself contains the variables being + assigned to. Instead, the children in node.nodes are visited + with the assign flag set to true. When the names occur in + those nodes, they are marked as defs. + + Some names that occur in an assignment target are not bound by + the assignment, e.g. a name occurring inside a slice. The + visitor handles these nodes specially; they do not propagate + the assign flag to their children. + """ + for n in node.nodes: + self.visit(n, scope, 1) + self.visit(node.expr, scope) + + def visitAssName(self, node, scope, assign=1): + scope.add_def(node.name) + + def visitAssAttr(self, node, scope, assign=0): + self.visit(node.expr, scope, 0) + + def visitSubscript(self, node, scope, assign=0): + self.visit(node.expr, scope, 0) + for n in node.subs: + self.visit(n, scope, 0) + + def visitSlice(self, node, scope, assign=0): + self.visit(node.expr, scope, 0) + if node.lower: + self.visit(node.lower, scope, 0) + if node.upper: + self.visit(node.upper, scope, 0) + + def visitAugAssign(self, node, scope): + # If the LHS is a name, then this counts as assignment. + # Otherwise, it's just use. + self.visit(node.node, scope) + if isinstance(node.node, ast.Name): + self.visit(node.node, scope, 1) # XXX worry about this + self.visit(node.expr, scope) + + # prune if statements if tests are false + + _const_types = types.StringType, types.IntType, types.FloatType + + def visitIf(self, node, scope): + for test, body in node.tests: + if isinstance(test, ast.Const): + if type(test.value) in self._const_types: + if not test.value: + continue + self.visit(test, scope) + self.visit(body, scope) + if node.else_: + self.visit(node.else_, scope) + + # a yield statement signals a generator + + def visitYield(self, node, scope): + scope.generator = 1 + self.visit(node.value, scope) + +def list_eq(l1, l2): + return sorted(l1) == sorted(l2) + +if __name__ == "__main__": + import sys + from compiler import parseFile, walk + import symtable + + def get_names(syms): + return [s for s in [s.get_name() for s in syms.get_symbols()] + if not (s.startswith('_[') or s.startswith('.'))] + + for file in sys.argv[1:]: + print file + f = open(file) + buf = f.read() + f.close() + syms = symtable.symtable(buf, file, "exec") + mod_names = get_names(syms) + tree = parseFile(file) + s = SymbolVisitor() + walk(tree, s) + + # compare module-level symbols + names2 = s.scopes[tree].get_names() + + if not list_eq(mod_names, names2): + print + print "oops", file + print sorted(mod_names) + print sorted(names2) + sys.exit(-1) + + d = {} + d.update(s.scopes) + del d[tree] + scopes = d.values() + del d + + for s in syms.get_symbols(): + if s.is_namespace(): + l = [sc for sc in scopes + if sc.name == s.get_name()] + if len(l) > 1: + print "skipping", s.get_name() + else: + if not list_eq(get_names(s.get_namespace()), + l[0].get_names()): + print s.get_name() + print sorted(get_names(s.get_namespace())) + print sorted(l[0].get_names()) + sys.exit(-1) diff --git a/src/main/resources/PythonLibs/compiler/syntax.py b/src/main/resources/PythonLibs/compiler/syntax.py new file mode 100644 index 0000000000000000000000000000000000000000..a45d9c2cf6f3f797f5ba3fbc883cfeecc1290fb1 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/syntax.py @@ -0,0 +1,46 @@ +"""Check for errs in the AST. + +The Python parser does not catch all syntax errors. Others, like +assignments with invalid targets, are caught in the code generation +phase. + +The compiler package catches some errors in the transformer module. +But it seems clearer to write checkers that use the AST to detect +errors. +""" + +from compiler import ast, walk + +def check(tree, multi=None): + v = SyntaxErrorChecker(multi) + walk(tree, v) + return v.errors + +class SyntaxErrorChecker: + """A visitor to find syntax errors in the AST.""" + + def __init__(self, multi=None): + """Create new visitor object. + + If optional argument multi is not None, then print messages + for each error rather than raising a SyntaxError for the + first. + """ + self.multi = multi + self.errors = 0 + + def error(self, node, msg): + self.errors = self.errors + 1 + if self.multi is not None: + print "%s:%s: %s" % (node.filename, node.lineno, msg) + else: + raise SyntaxError, "%s (%s:%s)" % (msg, node.filename, node.lineno) + + def visitAssign(self, node): + # the transformer module handles many of these + pass +## for target in node.nodes: +## if isinstance(target, ast.AssList): +## if target.lineno is None: +## target.lineno = node.lineno +## self.error(target, "can't assign to list comprehension") diff --git a/src/main/resources/PythonLibs/compiler/transformer.py b/src/main/resources/PythonLibs/compiler/transformer.py new file mode 100644 index 0000000000000000000000000000000000000000..fefa1a8f8b42e5cfcd4daade726378deffea990a --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/transformer.py @@ -0,0 +1,1491 @@ +"""Parse tree transformation module. + +Transforms Python source code into an abstract syntax tree (AST) +defined in the ast module. + +The simplest ways to invoke this module are via parse and parseFile. +parse(buf) -> AST +parseFile(path) -> AST +""" + +# Original version written by Greg Stein (gstein@lyra.org) +# and Bill Tutt (rassilon@lima.mudlib.org) +# February 1997. +# +# Modifications and improvements for Python 2.0 by Jeremy Hylton and +# Mark Hammond +# +# Some fixes to try to have correct line number on almost all nodes +# (except Module, Discard and Stmt) added by Sylvain Thenault +# +# Portions of this file are: +# Copyright (C) 1997-1998 Greg Stein. All Rights Reserved. +# +# This module is provided under a BSD-ish license. See +# http://www.opensource.org/licenses/bsd-license.html +# and replace OWNER, ORGANIZATION, and YEAR as appropriate. + +from compiler.ast import * +import symbol +import token +import sys +if not sys.platform.startswith('java'): + import parser + +class WalkerError(StandardError): + pass + +from compiler.consts import CO_VARARGS, CO_VARKEYWORDS +from compiler.consts import OP_ASSIGN, OP_DELETE, OP_APPLY + +def parseFile(path): + f = open(path, "U") + # XXX The parser API tolerates files without a trailing newline, + # but not strings without a trailing newline. Always add an extra + # newline to the file contents, since we're going through the string + # version of the API. + src = f.read() + "\n" + f.close() + return parse(src) + +def parse(buf, mode="exec"): + if mode == "exec" or mode == "single": + return Transformer().parsesuite(buf) + elif mode == "eval": + return Transformer().parseexpr(buf) + else: + raise ValueError("compile() arg 3 must be" + " 'exec' or 'eval' or 'single'") + +def asList(nodes): + l = [] + for item in nodes: + if hasattr(item, "asList"): + l.append(item.asList()) + else: + if type(item) is type( (None, None) ): + l.append(tuple(asList(item))) + elif type(item) is type( [] ): + l.append(asList(item)) + else: + l.append(item) + return l + +def extractLineNo(ast): + if not isinstance(ast[1], tuple): + # get a terminal node + return ast[2] + for child in ast[1:]: + if isinstance(child, tuple): + lineno = extractLineNo(child) + if lineno is not None: + return lineno + +def Node(*args): + kind = args[0] + if nodes.has_key(kind): + try: + return nodes[kind](*args[1:]) + except TypeError: + print nodes[kind], len(args), args + raise + else: + raise WalkerError, "Can't find appropriate Node type: %s" % str(args) + #return apply(ast.Node, args) + +class Transformer: + """Utility object for transforming Python parse trees. + + Exposes the following methods: + tree = transform(ast_tree) + tree = parsesuite(text) + tree = parseexpr(text) + tree = parsefile(fileob | filename) + """ + + def __init__(self): + self._dispatch = {} + for value, name in symbol.sym_name.items(): + if hasattr(self, name): + self._dispatch[value] = getattr(self, name) + self._dispatch[token.NEWLINE] = self.com_NEWLINE + self._atom_dispatch = {token.LPAR: self.atom_lpar, + token.LSQB: self.atom_lsqb, + token.LBRACE: self.atom_lbrace, + token.BACKQUOTE: self.atom_backquote, + token.NUMBER: self.atom_number, + token.STRING: self.atom_string, + token.NAME: self.atom_name, + } + self.encoding = None + + def transform(self, tree): + """Transform an AST into a modified parse tree.""" + if not (isinstance(tree, tuple) or isinstance(tree, list)): + tree = parser.ast2tuple(tree, line_info=1) + return self.compile_node(tree) + + def parsesuite(self, text): + """Return a modified parse tree for the given suite text.""" + return self.transform(parser.suite(text)) + + def parseexpr(self, text): + """Return a modified parse tree for the given expression text.""" + return self.transform(parser.expr(text)) + + def parsefile(self, file): + """Return a modified parse tree for the contents of the given file.""" + if type(file) == type(''): + file = open(file) + return self.parsesuite(file.read()) + + # -------------------------------------------------------------- + # + # PRIVATE METHODS + # + + def compile_node(self, node): + ### emit a line-number node? + n = node[0] + + if n == symbol.encoding_decl: + self.encoding = node[2] + node = node[1] + n = node[0] + + if n == symbol.single_input: + return self.single_input(node[1:]) + if n == symbol.file_input: + return self.file_input(node[1:]) + if n == symbol.eval_input: + return self.eval_input(node[1:]) + if n == symbol.lambdef: + return self.lambdef(node[1:]) + if n == symbol.funcdef: + return self.funcdef(node[1:]) + if n == symbol.classdef: + return self.classdef(node[1:]) + + raise WalkerError, ('unexpected node type', n) + + def single_input(self, node): + ### do we want to do anything about being "interactive" ? + + # NEWLINE | simple_stmt | compound_stmt NEWLINE + n = node[0][0] + if n != token.NEWLINE: + return self.com_stmt(node[0]) + + return Pass() + + def file_input(self, nodelist): + doc = self.get_docstring(nodelist, symbol.file_input) + if doc is not None: + i = 1 + else: + i = 0 + stmts = [] + for node in nodelist[i:]: + if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: + self.com_append_stmt(stmts, node) + return Module(doc, Stmt(stmts)) + + def eval_input(self, nodelist): + # from the built-in function input() + ### is this sufficient? + return Expression(self.com_node(nodelist[0])) + + def decorator_name(self, nodelist): + listlen = len(nodelist) + assert listlen >= 1 and listlen % 2 == 1 + + item = self.atom_name(nodelist) + i = 1 + while i < listlen: + assert nodelist[i][0] == token.DOT + assert nodelist[i + 1][0] == token.NAME + item = Getattr(item, nodelist[i + 1][1]) + i += 2 + + return item + + def decorator(self, nodelist): + # '@' dotted_name [ '(' [arglist] ')' ] + assert len(nodelist) in (3, 5, 6) + assert nodelist[0][0] == token.AT + assert nodelist[-1][0] == token.NEWLINE + + assert nodelist[1][0] == symbol.dotted_name + funcname = self.decorator_name(nodelist[1][1:]) + + if len(nodelist) > 3: + assert nodelist[2][0] == token.LPAR + expr = self.com_call_function(funcname, nodelist[3]) + else: + expr = funcname + + return expr + + def decorators(self, nodelist): + # decorators: decorator ([NEWLINE] decorator)* NEWLINE + items = [] + for dec_nodelist in nodelist: + assert dec_nodelist[0] == symbol.decorator + items.append(self.decorator(dec_nodelist[1:])) + return Decorators(items) + + def funcdef(self, nodelist): + # -6 -5 -4 -3 -2 -1 + # funcdef: [decorators] 'def' NAME parameters ':' suite + # parameters: '(' [varargslist] ')' + + if len(nodelist) == 6: + assert nodelist[0][0] == symbol.decorators + decorators = self.decorators(nodelist[0][1:]) + else: + assert len(nodelist) == 5 + decorators = None + + lineno = nodelist[-4][2] + name = nodelist[-4][1] + args = nodelist[-3][2] + + if args[0] == symbol.varargslist: + names, defaults, flags = self.com_arglist(args[1:]) + else: + names = defaults = () + flags = 0 + doc = self.get_docstring(nodelist[-1]) + + # code for function + code = self.com_node(nodelist[-1]) + + if doc is not None: + assert isinstance(code, Stmt) + assert isinstance(code.nodes[0], Discard) + del code.nodes[0] + return Function(decorators, name, names, defaults, flags, doc, code, + lineno=lineno) + + def lambdef(self, nodelist): + # lambdef: 'lambda' [varargslist] ':' test + if nodelist[2][0] == symbol.varargslist: + names, defaults, flags = self.com_arglist(nodelist[2][1:]) + else: + names = defaults = () + flags = 0 + + # code for lambda + code = self.com_node(nodelist[-1]) + + return Lambda(names, defaults, flags, code, lineno=nodelist[1][2]) + old_lambdef = lambdef + + def classdef(self, nodelist): + # classdef: 'class' NAME ['(' [testlist] ')'] ':' suite + + name = nodelist[1][1] + doc = self.get_docstring(nodelist[-1]) + if nodelist[2][0] == token.COLON: + bases = [] + elif nodelist[3][0] == token.RPAR: + bases = [] + else: + bases = self.com_bases(nodelist[3]) + + # code for class + code = self.com_node(nodelist[-1]) + + if doc is not None: + assert isinstance(code, Stmt) + assert isinstance(code.nodes[0], Discard) + del code.nodes[0] + + return Class(name, bases, doc, code, lineno=nodelist[1][2]) + + def stmt(self, nodelist): + return self.com_stmt(nodelist[0]) + + small_stmt = stmt + flow_stmt = stmt + compound_stmt = stmt + + def simple_stmt(self, nodelist): + # small_stmt (';' small_stmt)* [';'] NEWLINE + stmts = [] + for i in range(0, len(nodelist), 2): + self.com_append_stmt(stmts, nodelist[i]) + return Stmt(stmts) + + def parameters(self, nodelist): + raise WalkerError + + def varargslist(self, nodelist): + raise WalkerError + + def fpdef(self, nodelist): + raise WalkerError + + def fplist(self, nodelist): + raise WalkerError + + def dotted_name(self, nodelist): + raise WalkerError + + def comp_op(self, nodelist): + raise WalkerError + + def trailer(self, nodelist): + raise WalkerError + + def sliceop(self, nodelist): + raise WalkerError + + def argument(self, nodelist): + raise WalkerError + + # -------------------------------------------------------------- + # + # STATEMENT NODES (invoked by com_node()) + # + + def expr_stmt(self, nodelist): + # augassign testlist | testlist ('=' testlist)* + en = nodelist[-1] + exprNode = self.lookup_node(en)(en[1:]) + if len(nodelist) == 1: + return Discard(exprNode, lineno=exprNode.lineno) + if nodelist[1][0] == token.EQUAL: + nodesl = [] + for i in range(0, len(nodelist) - 2, 2): + nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN)) + return Assign(nodesl, exprNode, lineno=nodelist[1][2]) + else: + lval = self.com_augassign(nodelist[0]) + op = self.com_augassign_op(nodelist[1]) + return AugAssign(lval, op[1], exprNode, lineno=op[2]) + raise WalkerError, "can't get here" + + def print_stmt(self, nodelist): + # print ([ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ]) + items = [] + if len(nodelist) == 1: + start = 1 + dest = None + elif nodelist[1][0] == token.RIGHTSHIFT: + assert len(nodelist) == 3 \ + or nodelist[3][0] == token.COMMA + dest = self.com_node(nodelist[2]) + start = 4 + else: + dest = None + start = 1 + for i in range(start, len(nodelist), 2): + items.append(self.com_node(nodelist[i])) + if nodelist[-1][0] == token.COMMA: + return Print(items, dest, lineno=nodelist[0][2]) + return Printnl(items, dest, lineno=nodelist[0][2]) + + def del_stmt(self, nodelist): + return self.com_assign(nodelist[1], OP_DELETE) + + def pass_stmt(self, nodelist): + return Pass(lineno=nodelist[0][2]) + + def break_stmt(self, nodelist): + return Break(lineno=nodelist[0][2]) + + def continue_stmt(self, nodelist): + return Continue(lineno=nodelist[0][2]) + + def return_stmt(self, nodelist): + # return: [testlist] + if len(nodelist) < 2: + return Return(Const(None), lineno=nodelist[0][2]) + return Return(self.com_node(nodelist[1]), lineno=nodelist[0][2]) + + def yield_stmt(self, nodelist): + expr = self.com_node(nodelist[0]) + return Discard(expr, lineno=expr.lineno) + + def yield_expr(self, nodelist): + if len(nodelist) > 1: + value = self.com_node(nodelist[1]) + else: + value = Const(None) + return Yield(value, lineno=nodelist[0][2]) + + def raise_stmt(self, nodelist): + # raise: [test [',' test [',' test]]] + if len(nodelist) > 5: + expr3 = self.com_node(nodelist[5]) + else: + expr3 = None + if len(nodelist) > 3: + expr2 = self.com_node(nodelist[3]) + else: + expr2 = None + if len(nodelist) > 1: + expr1 = self.com_node(nodelist[1]) + else: + expr1 = None + return Raise(expr1, expr2, expr3, lineno=nodelist[0][2]) + + def import_stmt(self, nodelist): + # import_stmt: import_name | import_from + assert len(nodelist) == 1 + return self.com_node(nodelist[0]) + + def import_name(self, nodelist): + # import_name: 'import' dotted_as_names + return Import(self.com_dotted_as_names(nodelist[1]), + lineno=nodelist[0][2]) + + def import_from(self, nodelist): + # import_from: 'from' ('.'* dotted_name | '.') 'import' ('*' | + # '(' import_as_names ')' | import_as_names) + assert nodelist[0][1] == 'from' + idx = 1 + while nodelist[idx][1] == '.': + idx += 1 + level = idx - 1 + if nodelist[idx][0] == symbol.dotted_name: + fromname = self.com_dotted_name(nodelist[idx]) + idx += 1 + else: + fromname = "" + assert nodelist[idx][1] == 'import' + if nodelist[idx + 1][0] == token.STAR: + return From(fromname, [('*', None)], level, + lineno=nodelist[0][2]) + else: + node = nodelist[idx + 1 + (nodelist[idx + 1][0] == token.LPAR)] + return From(fromname, self.com_import_as_names(node), level, + lineno=nodelist[0][2]) + + def global_stmt(self, nodelist): + # global: NAME (',' NAME)* + names = [] + for i in range(1, len(nodelist), 2): + names.append(nodelist[i][1]) + return Global(names, lineno=nodelist[0][2]) + + def exec_stmt(self, nodelist): + # exec_stmt: 'exec' expr ['in' expr [',' expr]] + expr1 = self.com_node(nodelist[1]) + if len(nodelist) >= 4: + expr2 = self.com_node(nodelist[3]) + if len(nodelist) >= 6: + expr3 = self.com_node(nodelist[5]) + else: + expr3 = None + else: + expr2 = expr3 = None + + return Exec(expr1, expr2, expr3, lineno=nodelist[0][2]) + + def assert_stmt(self, nodelist): + # 'assert': test, [',' test] + expr1 = self.com_node(nodelist[1]) + if (len(nodelist) == 4): + expr2 = self.com_node(nodelist[3]) + else: + expr2 = None + return Assert(expr1, expr2, lineno=nodelist[0][2]) + + def if_stmt(self, nodelist): + # if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite] + tests = [] + for i in range(0, len(nodelist) - 3, 4): + testNode = self.com_node(nodelist[i + 1]) + suiteNode = self.com_node(nodelist[i + 3]) + tests.append((testNode, suiteNode)) + + if len(nodelist) % 4 == 3: + elseNode = self.com_node(nodelist[-1]) +## elseNode.lineno = nodelist[-1][1][2] + else: + elseNode = None + return If(tests, elseNode, lineno=nodelist[0][2]) + + def while_stmt(self, nodelist): + # 'while' test ':' suite ['else' ':' suite] + + testNode = self.com_node(nodelist[1]) + bodyNode = self.com_node(nodelist[3]) + + if len(nodelist) > 4: + elseNode = self.com_node(nodelist[6]) + else: + elseNode = None + + return While(testNode, bodyNode, elseNode, lineno=nodelist[0][2]) + + def for_stmt(self, nodelist): + # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] + + assignNode = self.com_assign(nodelist[1], OP_ASSIGN) + listNode = self.com_node(nodelist[3]) + bodyNode = self.com_node(nodelist[5]) + + if len(nodelist) > 8: + elseNode = self.com_node(nodelist[8]) + else: + elseNode = None + + return For(assignNode, listNode, bodyNode, elseNode, + lineno=nodelist[0][2]) + + def try_stmt(self, nodelist): + return self.com_try_except_finally(nodelist) + + def with_stmt(self, nodelist): + return self.com_with(nodelist) + + def with_var(self, nodelist): + return self.com_with_var(nodelist) + + def suite(self, nodelist): + # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT + if len(nodelist) == 1: + return self.com_stmt(nodelist[0]) + + stmts = [] + for node in nodelist: + if node[0] == symbol.stmt: + self.com_append_stmt(stmts, node) + return Stmt(stmts) + + # -------------------------------------------------------------- + # + # EXPRESSION NODES (invoked by com_node()) + # + + def testlist(self, nodelist): + # testlist: expr (',' expr)* [','] + # testlist_safe: test [(',' test)+ [',']] + # exprlist: expr (',' expr)* [','] + return self.com_binary(Tuple, nodelist) + + testlist_safe = testlist # XXX + testlist1 = testlist + exprlist = testlist + + def testlist_gexp(self, nodelist): + if len(nodelist) == 2 and nodelist[1][0] == symbol.gen_for: + test = self.com_node(nodelist[0]) + return self.com_generator_expression(test, nodelist[1]) + return self.testlist(nodelist) + + def test(self, nodelist): + # or_test ['if' or_test 'else' test] | lambdef + if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef: + return self.lambdef(nodelist[0]) + then = self.com_node(nodelist[0]) + if len(nodelist) > 1: + assert len(nodelist) == 5 + assert nodelist[1][1] == 'if' + assert nodelist[3][1] == 'else' + test = self.com_node(nodelist[2]) + else_ = self.com_node(nodelist[4]) + return IfExp(test, then, else_, lineno=nodelist[1][2]) + return then + + def or_test(self, nodelist): + # and_test ('or' and_test)* | lambdef + if len(nodelist) == 1 and nodelist[0][0] == symbol.lambdef: + return self.lambdef(nodelist[0]) + return self.com_binary(Or, nodelist) + old_test = or_test + + def and_test(self, nodelist): + # not_test ('and' not_test)* + return self.com_binary(And, nodelist) + + def not_test(self, nodelist): + # 'not' not_test | comparison + result = self.com_node(nodelist[-1]) + if len(nodelist) == 2: + return Not(result, lineno=nodelist[0][2]) + return result + + def comparison(self, nodelist): + # comparison: expr (comp_op expr)* + node = self.com_node(nodelist[0]) + if len(nodelist) == 1: + return node + + results = [] + for i in range(2, len(nodelist), 2): + nl = nodelist[i-1] + + # comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '==' + # | 'in' | 'not' 'in' | 'is' | 'is' 'not' + n = nl[1] + if n[0] == token.NAME: + type = n[1] + if len(nl) == 3: + if type == 'not': + type = 'not in' + else: + type = 'is not' + else: + type = _cmp_types[n[0]] + + lineno = nl[1][2] + results.append((type, self.com_node(nodelist[i]))) + + # we need a special "compare" node so that we can distinguish + # 3 < x < 5 from (3 < x) < 5 + # the two have very different semantics and results (note that the + # latter form is always true) + + return Compare(node, results, lineno=lineno) + + def expr(self, nodelist): + # xor_expr ('|' xor_expr)* + return self.com_binary(Bitor, nodelist) + + def xor_expr(self, nodelist): + # xor_expr ('^' xor_expr)* + return self.com_binary(Bitxor, nodelist) + + def and_expr(self, nodelist): + # xor_expr ('&' xor_expr)* + return self.com_binary(Bitand, nodelist) + + def shift_expr(self, nodelist): + # shift_expr ('<<'|'>>' shift_expr)* + node = self.com_node(nodelist[0]) + for i in range(2, len(nodelist), 2): + right = self.com_node(nodelist[i]) + if nodelist[i-1][0] == token.LEFTSHIFT: + node = LeftShift([node, right], lineno=nodelist[1][2]) + elif nodelist[i-1][0] == token.RIGHTSHIFT: + node = RightShift([node, right], lineno=nodelist[1][2]) + else: + raise ValueError, "unexpected token: %s" % nodelist[i-1][0] + return node + + def arith_expr(self, nodelist): + node = self.com_node(nodelist[0]) + for i in range(2, len(nodelist), 2): + right = self.com_node(nodelist[i]) + if nodelist[i-1][0] == token.PLUS: + node = Add([node, right], lineno=nodelist[1][2]) + elif nodelist[i-1][0] == token.MINUS: + node = Sub([node, right], lineno=nodelist[1][2]) + else: + raise ValueError, "unexpected token: %s" % nodelist[i-1][0] + return node + + def term(self, nodelist): + node = self.com_node(nodelist[0]) + for i in range(2, len(nodelist), 2): + right = self.com_node(nodelist[i]) + t = nodelist[i-1][0] + if t == token.STAR: + node = Mul([node, right]) + elif t == token.SLASH: + node = Div([node, right]) + elif t == token.PERCENT: + node = Mod([node, right]) + elif t == token.DOUBLESLASH: + node = FloorDiv([node, right]) + else: + raise ValueError, "unexpected token: %s" % t + node.lineno = nodelist[1][2] + return node + + def factor(self, nodelist): + elt = nodelist[0] + t = elt[0] + node = self.lookup_node(nodelist[-1])(nodelist[-1][1:]) + # need to handle (unary op)constant here... + if t == token.PLUS: + return UnaryAdd(node, lineno=elt[2]) + elif t == token.MINUS: + return UnarySub(node, lineno=elt[2]) + elif t == token.TILDE: + node = Invert(node, lineno=elt[2]) + return node + + def power(self, nodelist): + # power: atom trailer* ('**' factor)* + node = self.com_node(nodelist[0]) + for i in range(1, len(nodelist)): + elt = nodelist[i] + if elt[0] == token.DOUBLESTAR: + return Power([node, self.com_node(nodelist[i+1])], + lineno=elt[2]) + + node = self.com_apply_trailer(node, elt) + + return node + + def atom(self, nodelist): + return self._atom_dispatch[nodelist[0][0]](nodelist) + + def atom_lpar(self, nodelist): + if nodelist[1][0] == token.RPAR: + return Tuple((), lineno=nodelist[0][2]) + return self.com_node(nodelist[1]) + + def atom_lsqb(self, nodelist): + if nodelist[1][0] == token.RSQB: + return List((), lineno=nodelist[0][2]) + return self.com_list_constructor(nodelist[1]) + + def atom_lbrace(self, nodelist): + if nodelist[1][0] == token.RBRACE: + return Dict((), lineno=nodelist[0][2]) + return self.com_dictmaker(nodelist[1]) + + def atom_backquote(self, nodelist): + return Backquote(self.com_node(nodelist[1])) + + def atom_number(self, nodelist): + ### need to verify this matches compile.c + k = eval(nodelist[0][1]) + return Const(k, lineno=nodelist[0][2]) + + def decode_literal(self, lit): + if self.encoding: + # this is particularly fragile & a bit of a + # hack... changes in compile.c:parsestr and + # tokenizer.c must be reflected here. + if self.encoding not in ['utf-8', 'iso-8859-1']: + lit = unicode(lit, 'utf-8').encode(self.encoding) + return eval("# coding: %s\n%s" % (self.encoding, lit)) + else: + return eval(lit) + + def atom_string(self, nodelist): + k = '' + for node in nodelist: + k += self.decode_literal(node[1]) + return Const(k, lineno=nodelist[0][2]) + + def atom_name(self, nodelist): + return Name(nodelist[0][1], lineno=nodelist[0][2]) + + # -------------------------------------------------------------- + # + # INTERNAL PARSING UTILITIES + # + + # The use of com_node() introduces a lot of extra stack frames, + # enough to cause a stack overflow compiling test.test_parser with + # the standard interpreter recursionlimit. The com_node() is a + # convenience function that hides the dispatch details, but comes + # at a very high cost. It is more efficient to dispatch directly + # in the callers. In these cases, use lookup_node() and call the + # dispatched node directly. + + def lookup_node(self, node): + return self._dispatch[node[0]] + + def com_node(self, node): + # Note: compile.c has handling in com_node for del_stmt, pass_stmt, + # break_stmt, stmt, small_stmt, flow_stmt, simple_stmt, + # and compound_stmt. + # We'll just dispatch them. + return self._dispatch[node[0]](node[1:]) + + def com_NEWLINE(self, *args): + # A ';' at the end of a line can make a NEWLINE token appear + # here, Render it harmless. (genc discards ('discard', + # ('const', xxxx)) Nodes) + return Discard(Const(None)) + + def com_arglist(self, nodelist): + # varargslist: + # (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) + # | fpdef ['=' test] (',' fpdef ['=' test])* [','] + # fpdef: NAME | '(' fplist ')' + # fplist: fpdef (',' fpdef)* [','] + names = [] + defaults = [] + flags = 0 + + i = 0 + while i < len(nodelist): + node = nodelist[i] + if node[0] == token.STAR or node[0] == token.DOUBLESTAR: + if node[0] == token.STAR: + node = nodelist[i+1] + if node[0] == token.NAME: + names.append(node[1]) + flags = flags | CO_VARARGS + i = i + 3 + + if i < len(nodelist): + # should be DOUBLESTAR + t = nodelist[i][0] + if t == token.DOUBLESTAR: + node = nodelist[i+1] + else: + raise ValueError, "unexpected token: %s" % t + names.append(node[1]) + flags = flags | CO_VARKEYWORDS + + break + + # fpdef: NAME | '(' fplist ')' + names.append(self.com_fpdef(node)) + + i = i + 1 + if i < len(nodelist) and nodelist[i][0] == token.EQUAL: + defaults.append(self.com_node(nodelist[i + 1])) + i = i + 2 + elif len(defaults): + # we have already seen an argument with default, but here + # came one without + raise SyntaxError, "non-default argument follows default argument" + + # skip the comma + i = i + 1 + + return names, defaults, flags + + def com_fpdef(self, node): + # fpdef: NAME | '(' fplist ')' + if node[1][0] == token.LPAR: + return self.com_fplist(node[2]) + return node[1][1] + + def com_fplist(self, node): + # fplist: fpdef (',' fpdef)* [','] + if len(node) == 2: + return self.com_fpdef(node[1]) + list = [] + for i in range(1, len(node), 2): + list.append(self.com_fpdef(node[i])) + return tuple(list) + + def com_dotted_name(self, node): + # String together the dotted names and return the string + name = "" + for n in node: + if type(n) == type(()) and n[0] == 1: + name = name + n[1] + '.' + return name[:-1] + + def com_dotted_as_name(self, node): + assert node[0] == symbol.dotted_as_name + node = node[1:] + dot = self.com_dotted_name(node[0][1:]) + if len(node) == 1: + return dot, None + assert node[1][1] == 'as' + assert node[2][0] == token.NAME + return dot, node[2][1] + + def com_dotted_as_names(self, node): + assert node[0] == symbol.dotted_as_names + node = node[1:] + names = [self.com_dotted_as_name(node[0])] + for i in range(2, len(node), 2): + names.append(self.com_dotted_as_name(node[i])) + return names + + def com_import_as_name(self, node): + assert node[0] == symbol.import_as_name + node = node[1:] + assert node[0][0] == token.NAME + if len(node) == 1: + return node[0][1], None + assert node[1][1] == 'as', node + assert node[2][0] == token.NAME + return node[0][1], node[2][1] + + def com_import_as_names(self, node): + assert node[0] == symbol.import_as_names + node = node[1:] + names = [self.com_import_as_name(node[0])] + for i in range(2, len(node), 2): + names.append(self.com_import_as_name(node[i])) + return names + + def com_bases(self, node): + bases = [] + for i in range(1, len(node), 2): + bases.append(self.com_node(node[i])) + return bases + + def com_try_except_finally(self, nodelist): + # ('try' ':' suite + # ((except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] + # | 'finally' ':' suite)) + + if nodelist[3][0] == token.NAME: + # first clause is a finally clause: only try-finally + return TryFinally(self.com_node(nodelist[2]), + self.com_node(nodelist[5]), + lineno=nodelist[0][2]) + + #tryexcept: [TryNode, [except_clauses], elseNode)] + clauses = [] + elseNode = None + finallyNode = None + for i in range(3, len(nodelist), 3): + node = nodelist[i] + if node[0] == symbol.except_clause: + # except_clause: 'except' [expr [',' expr]] */ + if len(node) > 2: + expr1 = self.com_node(node[2]) + if len(node) > 4: + expr2 = self.com_assign(node[4], OP_ASSIGN) + else: + expr2 = None + else: + expr1 = expr2 = None + clauses.append((expr1, expr2, self.com_node(nodelist[i+2]))) + + if node[0] == token.NAME: + if node[1] == 'else': + elseNode = self.com_node(nodelist[i+2]) + elif node[1] == 'finally': + finallyNode = self.com_node(nodelist[i+2]) + try_except = TryExcept(self.com_node(nodelist[2]), clauses, elseNode, + lineno=nodelist[0][2]) + if finallyNode: + return TryFinally(try_except, finallyNode, lineno=nodelist[0][2]) + else: + return try_except + + def com_with(self, nodelist): + # with_stmt: 'with' expr [with_var] ':' suite + expr = self.com_node(nodelist[1]) + body = self.com_node(nodelist[-1]) + if nodelist[2][0] == token.COLON: + var = None + else: + var = self.com_assign(nodelist[2][2], OP_ASSIGN) + return With(expr, var, body, lineno=nodelist[0][2]) + + def com_with_var(self, nodelist): + # with_var: 'as' expr + return self.com_node(nodelist[1]) + + def com_augassign_op(self, node): + assert node[0] == symbol.augassign + return node[1] + + def com_augassign(self, node): + """Return node suitable for lvalue of augmented assignment + + Names, slices, and attributes are the only allowable nodes. + """ + l = self.com_node(node) + if l.__class__ in (Name, Slice, Subscript, Getattr): + return l + raise SyntaxError, "can't assign to %s" % l.__class__.__name__ + + def com_assign(self, node, assigning): + # return a node suitable for use as an "lvalue" + # loop to avoid trivial recursion + while 1: + t = node[0] + if t in (symbol.exprlist, symbol.testlist, symbol.testlist_safe, symbol.testlist_gexp): + if len(node) > 2: + return self.com_assign_tuple(node, assigning) + node = node[1] + elif t in _assign_types: + if len(node) > 2: + raise SyntaxError, "can't assign to operator" + node = node[1] + elif t == symbol.power: + if node[1][0] != symbol.atom: + raise SyntaxError, "can't assign to operator" + if len(node) > 2: + primary = self.com_node(node[1]) + for i in range(2, len(node)-1): + ch = node[i] + if ch[0] == token.DOUBLESTAR: + raise SyntaxError, "can't assign to operator" + primary = self.com_apply_trailer(primary, ch) + return self.com_assign_trailer(primary, node[-1], + assigning) + node = node[1] + elif t == symbol.atom: + t = node[1][0] + if t == token.LPAR: + node = node[2] + if node[0] == token.RPAR: + raise SyntaxError, "can't assign to ()" + elif t == token.LSQB: + node = node[2] + if node[0] == token.RSQB: + raise SyntaxError, "can't assign to []" + return self.com_assign_list(node, assigning) + elif t == token.NAME: + return self.com_assign_name(node[1], assigning) + else: + raise SyntaxError, "can't assign to literal" + else: + raise SyntaxError, "bad assignment (%s)" % t + + def com_assign_tuple(self, node, assigning): + assigns = [] + for i in range(1, len(node), 2): + assigns.append(self.com_assign(node[i], assigning)) + return AssTuple(assigns, lineno=extractLineNo(node)) + + def com_assign_list(self, node, assigning): + assigns = [] + for i in range(1, len(node), 2): + if i + 1 < len(node): + if node[i + 1][0] == symbol.list_for: + raise SyntaxError, "can't assign to list comprehension" + assert node[i + 1][0] == token.COMMA, node[i + 1] + assigns.append(self.com_assign(node[i], assigning)) + return AssList(assigns, lineno=extractLineNo(node)) + + def com_assign_name(self, node, assigning): + return AssName(node[1], assigning, lineno=node[2]) + + def com_assign_trailer(self, primary, node, assigning): + t = node[1][0] + if t == token.DOT: + return self.com_assign_attr(primary, node[2], assigning) + if t == token.LSQB: + return self.com_subscriptlist(primary, node[2], assigning) + if t == token.LPAR: + raise SyntaxError, "can't assign to function call" + raise SyntaxError, "unknown trailer type: %s" % t + + def com_assign_attr(self, primary, node, assigning): + return AssAttr(primary, node[1], assigning, lineno=node[-1]) + + def com_binary(self, constructor, nodelist): + "Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])." + l = len(nodelist) + if l == 1: + n = nodelist[0] + return self.lookup_node(n)(n[1:]) + items = [] + for i in range(0, l, 2): + n = nodelist[i] + items.append(self.lookup_node(n)(n[1:])) + return constructor(items, lineno=extractLineNo(nodelist)) + + def com_stmt(self, node): + result = self.lookup_node(node)(node[1:]) + assert result is not None + if isinstance(result, Stmt): + return result + return Stmt([result]) + + def com_append_stmt(self, stmts, node): + result = self.lookup_node(node)(node[1:]) + assert result is not None + if isinstance(result, Stmt): + stmts.extend(result.nodes) + else: + stmts.append(result) + + if hasattr(symbol, 'list_for'): + def com_list_constructor(self, nodelist): + # listmaker: test ( list_for | (',' test)* [','] ) + values = [] + for i in range(1, len(nodelist)): + if nodelist[i][0] == symbol.list_for: + assert len(nodelist[i:]) == 1 + return self.com_list_comprehension(values[0], + nodelist[i]) + elif nodelist[i][0] == token.COMMA: + continue + values.append(self.com_node(nodelist[i])) + return List(values, lineno=values[0].lineno) + + def com_list_comprehension(self, expr, node): + # list_iter: list_for | list_if + # list_for: 'for' exprlist 'in' testlist [list_iter] + # list_if: 'if' test [list_iter] + + # XXX should raise SyntaxError for assignment + + lineno = node[1][2] + fors = [] + while node: + t = node[1][1] + if t == 'for': + assignNode = self.com_assign(node[2], OP_ASSIGN) + listNode = self.com_node(node[4]) + newfor = ListCompFor(assignNode, listNode, []) + newfor.lineno = node[1][2] + fors.append(newfor) + if len(node) == 5: + node = None + else: + node = self.com_list_iter(node[5]) + elif t == 'if': + test = self.com_node(node[2]) + newif = ListCompIf(test, lineno=node[1][2]) + newfor.ifs.append(newif) + if len(node) == 3: + node = None + else: + node = self.com_list_iter(node[3]) + else: + raise SyntaxError, \ + ("unexpected list comprehension element: %s %d" + % (node, lineno)) + return ListComp(expr, fors, lineno=lineno) + + def com_list_iter(self, node): + assert node[0] == symbol.list_iter + return node[1] + else: + def com_list_constructor(self, nodelist): + values = [] + for i in range(1, len(nodelist), 2): + values.append(self.com_node(nodelist[i])) + return List(values, lineno=values[0].lineno) + + if hasattr(symbol, 'gen_for'): + def com_generator_expression(self, expr, node): + # gen_iter: gen_for | gen_if + # gen_for: 'for' exprlist 'in' test [gen_iter] + # gen_if: 'if' test [gen_iter] + + lineno = node[1][2] + fors = [] + while node: + t = node[1][1] + if t == 'for': + assignNode = self.com_assign(node[2], OP_ASSIGN) + genNode = self.com_node(node[4]) + newfor = GenExprFor(assignNode, genNode, [], + lineno=node[1][2]) + fors.append(newfor) + if (len(node)) == 5: + node = None + else: + node = self.com_gen_iter(node[5]) + elif t == 'if': + test = self.com_node(node[2]) + newif = GenExprIf(test, lineno=node[1][2]) + newfor.ifs.append(newif) + if len(node) == 3: + node = None + else: + node = self.com_gen_iter(node[3]) + else: + raise SyntaxError, \ + ("unexpected generator expression element: %s %d" + % (node, lineno)) + fors[0].is_outmost = True + return GenExpr(GenExprInner(expr, fors), lineno=lineno) + + def com_gen_iter(self, node): + assert node[0] == symbol.gen_iter + return node[1] + + def com_dictmaker(self, nodelist): + # dictmaker: test ':' test (',' test ':' value)* [','] + items = [] + for i in range(1, len(nodelist), 4): + items.append((self.com_node(nodelist[i]), + self.com_node(nodelist[i+2]))) + return Dict(items, lineno=items[0][0].lineno) + + def com_apply_trailer(self, primaryNode, nodelist): + t = nodelist[1][0] + if t == token.LPAR: + return self.com_call_function(primaryNode, nodelist[2]) + if t == token.DOT: + return self.com_select_member(primaryNode, nodelist[2]) + if t == token.LSQB: + return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY) + + raise SyntaxError, 'unknown node type: %s' % t + + def com_select_member(self, primaryNode, nodelist): + if nodelist[0] != token.NAME: + raise SyntaxError, "member must be a name" + return Getattr(primaryNode, nodelist[1], lineno=nodelist[2]) + + def com_call_function(self, primaryNode, nodelist): + if nodelist[0] == token.RPAR: + return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist)) + args = [] + kw = 0 + len_nodelist = len(nodelist) + for i in range(1, len_nodelist, 2): + node = nodelist[i] + if node[0] == token.STAR or node[0] == token.DOUBLESTAR: + break + kw, result = self.com_argument(node, kw) + + if len_nodelist != 2 and isinstance(result, GenExpr) \ + and len(node) == 3 and node[2][0] == symbol.gen_for: + # allow f(x for x in y), but reject f(x for x in y, 1) + # should use f((x for x in y), 1) instead of f(x for x in y, 1) + raise SyntaxError, 'generator expression needs parenthesis' + + args.append(result) + else: + # No broken by star arg, so skip the last one we processed. + i = i + 1 + if i < len_nodelist and nodelist[i][0] == token.COMMA: + # need to accept an application that looks like "f(a, b,)" + i = i + 1 + star_node = dstar_node = None + while i < len_nodelist: + tok = nodelist[i] + ch = nodelist[i+1] + i = i + 3 + if tok[0]==token.STAR: + if star_node is not None: + raise SyntaxError, 'already have the varargs indentifier' + star_node = self.com_node(ch) + elif tok[0]==token.DOUBLESTAR: + if dstar_node is not None: + raise SyntaxError, 'already have the kwargs indentifier' + dstar_node = self.com_node(ch) + else: + raise SyntaxError, 'unknown node type: %s' % tok + return CallFunc(primaryNode, args, star_node, dstar_node, + lineno=extractLineNo(nodelist)) + + def com_argument(self, nodelist, kw): + if len(nodelist) == 3 and nodelist[2][0] == symbol.gen_for: + test = self.com_node(nodelist[1]) + return 0, self.com_generator_expression(test, nodelist[2]) + if len(nodelist) == 2: + if kw: + raise SyntaxError, "non-keyword arg after keyword arg" + return 0, self.com_node(nodelist[1]) + result = self.com_node(nodelist[3]) + n = nodelist[1] + while len(n) == 2 and n[0] != token.NAME: + n = n[1] + if n[0] != token.NAME: + raise SyntaxError, "keyword can't be an expression (%s)"%n[0] + node = Keyword(n[1], result, lineno=n[2]) + return 1, node + + def com_subscriptlist(self, primary, nodelist, assigning): + # slicing: simple_slicing | extended_slicing + # simple_slicing: primary "[" short_slice "]" + # extended_slicing: primary "[" slice_list "]" + # slice_list: slice_item ("," slice_item)* [","] + + # backwards compat slice for '[i:j]' + if len(nodelist) == 2: + sub = nodelist[1] + if (sub[1][0] == token.COLON or \ + (len(sub) > 2 and sub[2][0] == token.COLON)) and \ + sub[-1][0] != symbol.sliceop: + return self.com_slice(primary, sub, assigning) + + subscripts = [] + for i in range(1, len(nodelist), 2): + subscripts.append(self.com_subscript(nodelist[i])) + return Subscript(primary, assigning, subscripts, + lineno=extractLineNo(nodelist)) + + def com_subscript(self, node): + # slice_item: expression | proper_slice | ellipsis + ch = node[1] + t = ch[0] + if t == token.DOT and node[2][0] == token.DOT: + return Ellipsis() + if t == token.COLON or len(node) > 2: + return self.com_sliceobj(node) + return self.com_node(ch) + + def com_sliceobj(self, node): + # proper_slice: short_slice | long_slice + # short_slice: [lower_bound] ":" [upper_bound] + # long_slice: short_slice ":" [stride] + # lower_bound: expression + # upper_bound: expression + # stride: expression + # + # Note: a stride may be further slicing... + + items = [] + + if node[1][0] == token.COLON: + items.append(Const(None)) + i = 2 + else: + items.append(self.com_node(node[1])) + # i == 2 is a COLON + i = 3 + + if i < len(node) and node[i][0] == symbol.test: + items.append(self.com_node(node[i])) + i = i + 1 + else: + items.append(Const(None)) + + # a short_slice has been built. look for long_slice now by looking + # for strides... + for j in range(i, len(node)): + ch = node[j] + if len(ch) == 2: + items.append(Const(None)) + else: + items.append(self.com_node(ch[2])) + return Sliceobj(items, lineno=extractLineNo(node)) + + def com_slice(self, primary, node, assigning): + # short_slice: [lower_bound] ":" [upper_bound] + lower = upper = None + if len(node) == 3: + if node[1][0] == token.COLON: + upper = self.com_node(node[2]) + else: + lower = self.com_node(node[1]) + elif len(node) == 4: + lower = self.com_node(node[1]) + upper = self.com_node(node[3]) + return Slice(primary, assigning, lower, upper, + lineno=extractLineNo(node)) + + def get_docstring(self, node, n=None): + if n is None: + n = node[0] + node = node[1:] + if n == symbol.suite: + if len(node) == 1: + return self.get_docstring(node[0]) + for sub in node: + if sub[0] == symbol.stmt: + return self.get_docstring(sub) + return None + if n == symbol.file_input: + for sub in node: + if sub[0] == symbol.stmt: + return self.get_docstring(sub) + return None + if n == symbol.atom: + if node[0][0] == token.STRING: + s = '' + for t in node: + s = s + eval(t[1]) + return s + return None + if n == symbol.stmt or n == symbol.simple_stmt \ + or n == symbol.small_stmt: + return self.get_docstring(node[0]) + if n in _doc_nodes and len(node) == 1: + return self.get_docstring(node[0]) + return None + + +_doc_nodes = [ + symbol.expr_stmt, + symbol.testlist, + symbol.testlist_safe, + symbol.test, + symbol.or_test, + symbol.and_test, + symbol.not_test, + symbol.comparison, + symbol.expr, + symbol.xor_expr, + symbol.and_expr, + symbol.shift_expr, + symbol.arith_expr, + symbol.term, + symbol.factor, + symbol.power, + ] + +# comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '==' +# | 'in' | 'not' 'in' | 'is' | 'is' 'not' +_cmp_types = { + token.LESS : '<', + token.GREATER : '>', + token.EQEQUAL : '==', + token.EQUAL : '==', + token.LESSEQUAL : '<=', + token.GREATEREQUAL : '>=', + token.NOTEQUAL : '!=', + } + +_legal_node_types = [ + symbol.funcdef, + symbol.classdef, + symbol.stmt, + symbol.small_stmt, + symbol.flow_stmt, + symbol.simple_stmt, + symbol.compound_stmt, + symbol.expr_stmt, + symbol.print_stmt, + symbol.del_stmt, + symbol.pass_stmt, + symbol.break_stmt, + symbol.continue_stmt, + symbol.return_stmt, + symbol.raise_stmt, + symbol.import_stmt, + symbol.global_stmt, + symbol.exec_stmt, + symbol.assert_stmt, + symbol.if_stmt, + symbol.while_stmt, + symbol.for_stmt, + symbol.try_stmt, + symbol.with_stmt, + symbol.suite, + symbol.testlist, + symbol.testlist_safe, + symbol.test, + symbol.and_test, + symbol.not_test, + symbol.comparison, + symbol.exprlist, + symbol.expr, + symbol.xor_expr, + symbol.and_expr, + symbol.shift_expr, + symbol.arith_expr, + symbol.term, + symbol.factor, + symbol.power, + symbol.atom, + ] + +if hasattr(symbol, 'yield_stmt'): + _legal_node_types.append(symbol.yield_stmt) +if hasattr(symbol, 'yield_expr'): + _legal_node_types.append(symbol.yield_expr) + +_assign_types = [ + symbol.test, + symbol.or_test, + symbol.and_test, + symbol.not_test, + symbol.comparison, + symbol.expr, + symbol.xor_expr, + symbol.and_expr, + symbol.shift_expr, + symbol.arith_expr, + symbol.term, + symbol.factor, + ] + +_names = {} +for k, v in symbol.sym_name.items(): + _names[k] = v +for k, v in token.tok_name.items(): + _names[k] = v + +def debug_tree(tree): + l = [] + for elt in tree: + if isinstance(elt, int): + l.append(_names.get(elt, elt)) + elif isinstance(elt, str): + l.append(elt) + else: + l.append(debug_tree(elt)) + return l diff --git a/src/main/resources/PythonLibs/compiler/visitor.py b/src/main/resources/PythonLibs/compiler/visitor.py new file mode 100644 index 0000000000000000000000000000000000000000..f10f56011a3ec629c1b8cdb695b4ffbbbfefce35 --- /dev/null +++ b/src/main/resources/PythonLibs/compiler/visitor.py @@ -0,0 +1,113 @@ +from compiler import ast + +# XXX should probably rename ASTVisitor to ASTWalker +# XXX can it be made even more generic? + +class ASTVisitor: + """Performs a depth-first walk of the AST + + The ASTVisitor will walk the AST, performing either a preorder or + postorder traversal depending on which method is called. + + methods: + preorder(tree, visitor) + postorder(tree, visitor) + tree: an instance of ast.Node + visitor: an instance with visitXXX methods + + The ASTVisitor is responsible for walking over the tree in the + correct order. For each node, it checks the visitor argument for + a method named 'visitNodeType' where NodeType is the name of the + node's class, e.g. Class. If the method exists, it is called + with the node as its sole argument. + + The visitor method for a particular node type can control how + child nodes are visited during a preorder walk. (It can't control + the order during a postorder walk, because it is called _after_ + the walk has occurred.) The ASTVisitor modifies the visitor + argument by adding a visit method to the visitor; this method can + be used to visit a child node of arbitrary type. + """ + + VERBOSE = 0 + + def __init__(self): + self.node = None + self._cache = {} + + def default(self, node, *args): + for child in node.getChildNodes(): + self.dispatch(child, *args) + + def dispatch(self, node, *args): + self.node = node + klass = node.__class__ + meth = self._cache.get(klass, None) + if meth is None: + className = klass.__name__ + meth = getattr(self.visitor, 'visit' + className, self.default) + self._cache[klass] = meth +## if self.VERBOSE > 0: +## className = klass.__name__ +## if self.VERBOSE == 1: +## if meth == 0: +## print "dispatch", className +## else: +## print "dispatch", className, (meth and meth.__name__ or '') + return meth(node, *args) + + def preorder(self, tree, visitor, *args): + """Do preorder walk of tree using visitor""" + self.visitor = visitor + visitor.visit = self.dispatch + self.dispatch(tree, *args) # XXX *args make sense? + +class ExampleASTVisitor(ASTVisitor): + """Prints examples of the nodes that aren't visited + + This visitor-driver is only useful for development, when it's + helpful to develop a visitor incrementally, and get feedback on what + you still have to do. + """ + examples = {} + + def dispatch(self, node, *args): + self.node = node + meth = self._cache.get(node.__class__, None) + className = node.__class__.__name__ + if meth is None: + meth = getattr(self.visitor, 'visit' + className, 0) + self._cache[node.__class__] = meth + if self.VERBOSE > 1: + print "dispatch", className, (meth and meth.__name__ or '') + if meth: + meth(node, *args) + elif self.VERBOSE > 0: + klass = node.__class__ + if klass not in self.examples: + self.examples[klass] = klass + print + print self.visitor + print klass + for attr in dir(node): + if attr[0] != '_': + print "\t", "%-12.12s" % attr, getattr(node, attr) + print + return self.default(node, *args) + +# XXX this is an API change + +_walker = ASTVisitor +def walk(tree, visitor, walker=None, verbose=None): + if walker is None: + walker = _walker() + if verbose is not None: + walker.VERBOSE = verbose + walker.preorder(tree, visitor) + return walker.visitor + +def dumpNode(node): + print node.__class__ + for attr in dir(node): + if attr[0] != '_': + print "\t", "%-10.10s" % attr, getattr(node, attr) diff --git a/src/main/resources/PythonLibs/contextlib.py b/src/main/resources/PythonLibs/contextlib.py new file mode 100644 index 0000000000000000000000000000000000000000..f05205b01c2f7c0d63b6b6026e888ffbcd176ef4 --- /dev/null +++ b/src/main/resources/PythonLibs/contextlib.py @@ -0,0 +1,154 @@ +"""Utilities for with-statement contexts. See PEP 343.""" + +import sys +from functools import wraps +from warnings import warn + +__all__ = ["contextmanager", "nested", "closing"] + +class GeneratorContextManager(object): + """Helper for @contextmanager decorator.""" + + def __init__(self, gen): + self.gen = gen + + def __enter__(self): + try: + return self.gen.next() + except StopIteration: + raise RuntimeError("generator didn't yield") + + def __exit__(self, type, value, traceback): + if type is None: + try: + self.gen.next() + except StopIteration: + return + else: + raise RuntimeError("generator didn't stop") + else: + if value is None: + # Need to force instantiation so we can reliably + # tell if we get the same exception back + value = type() + try: + self.gen.throw(type, value, traceback) + raise RuntimeError("generator didn't stop after throw()") + except StopIteration, exc: + # Suppress the exception *unless* it's the same exception that + # was passed to throw(). This prevents a StopIteration + # raised inside the "with" statement from being suppressed + return exc is not value + except: + # only re-raise if it's *not* the exception that was + # passed to throw(), because __exit__() must not raise + # an exception unless __exit__() itself failed. But throw() + # has to raise the exception to signal propagation, so this + # fixes the impedance mismatch between the throw() protocol + # and the __exit__() protocol. + # + if sys.exc_info()[1] is not value: + raise + + +def contextmanager(func): + """@contextmanager decorator. + + Typical usage: + + @contextmanager + def some_generator(<arguments>): + <setup> + try: + yield <value> + finally: + <cleanup> + + This makes this: + + with some_generator(<arguments>) as <variable>: + <body> + + equivalent to this: + + <setup> + try: + <variable> = <value> + <body> + finally: + <cleanup> + + """ + @wraps(func) + def helper(*args, **kwds): + return GeneratorContextManager(func(*args, **kwds)) + return helper + + +@contextmanager +def nested(*managers): + """Combine multiple context managers into a single nested context manager. + + This function has been deprecated in favour of the multiple manager form + of the with statement. + + The one advantage of this function over the multiple manager form of the + with statement is that argument unpacking allows it to be + used with a variable number of context managers as follows: + + with nested(*managers): + do_something() + + """ + warn("With-statements now directly support multiple context managers", + DeprecationWarning, 3) + exits = [] + vars = [] + exc = (None, None, None) + try: + for mgr in managers: + exit = mgr.__exit__ + enter = mgr.__enter__ + vars.append(enter()) + exits.append(exit) + yield vars + except: + exc = sys.exc_info() + finally: + while exits: + exit = exits.pop() + try: + if exit(*exc): + exc = (None, None, None) + except: + exc = sys.exc_info() + if exc != (None, None, None): + # Don't rely on sys.exc_info() still containing + # the right information. Another exception may + # have been raised and caught by an exit method + raise exc[0], exc[1], exc[2] + + +class closing(object): + """Context to automatically close something at the end of a block. + + Code like this: + + with closing(<module>.open(<arguments>)) as f: + <block> + + is equivalent to this: + + f = <module>.open(<arguments>) + try: + <block> + finally: + f.close() + + """ + def __init__(self, thing): + self.thing = thing + def __enter__(self): + return self.thing + def __exit__(self, *exc_info): + self.thing.close() diff --git a/src/main/resources/PythonLibs/cookielib.py b/src/main/resources/PythonLibs/cookielib.py new file mode 100644 index 0000000000000000000000000000000000000000..f9c8d2f84bd87d0f4383a3792d4ec0bee05ec850 --- /dev/null +++ b/src/main/resources/PythonLibs/cookielib.py @@ -0,0 +1,1794 @@ +r"""HTTP cookie handling for web clients. + +This module has (now fairly distant) origins in Gisle Aas' Perl module +HTTP::Cookies, from the libwww-perl library. + +Docstrings, comments and debug strings in this code refer to the +attributes of the HTTP cookie system as cookie-attributes, to distinguish +them clearly from Python attributes. + +Class diagram (note that BSDDBCookieJar and the MSIE* classes are not +distributed with the Python standard library, but are available from +http://wwwsearch.sf.net/): + + CookieJar____ + / \ \ + FileCookieJar \ \ + / | \ \ \ + MozillaCookieJar | LWPCookieJar \ \ + | | \ + | ---MSIEBase | \ + | / | | \ + | / MSIEDBCookieJar BSDDBCookieJar + |/ + MSIECookieJar + +""" + +__all__ = ['Cookie', 'CookieJar', 'CookiePolicy', 'DefaultCookiePolicy', + 'FileCookieJar', 'LWPCookieJar', 'lwp_cookie_str', 'LoadError', + 'MozillaCookieJar'] + +import re, urlparse, copy, time, urllib +try: + import threading as _threading +except ImportError: + import dummy_threading as _threading +import httplib # only for the default HTTP port +from calendar import timegm + +debug = False # set to True to enable debugging via the logging module +logger = None + +def _debug(*args): + if not debug: + return + global logger + if not logger: + import logging + logger = logging.getLogger("cookielib") + return logger.debug(*args) + + +DEFAULT_HTTP_PORT = str(httplib.HTTP_PORT) +MISSING_FILENAME_TEXT = ("a filename was not supplied (nor was the CookieJar " + "instance initialised with one)") + +def _warn_unhandled_exception(): + # There are a few catch-all except: statements in this module, for + # catching input that's bad in unexpected ways. Warn if any + # exceptions are caught there. + import warnings, traceback, StringIO + f = StringIO.StringIO() + traceback.print_exc(None, f) + msg = f.getvalue() + warnings.warn("cookielib bug!\n%s" % msg, stacklevel=2) + + +# Date/time conversion +# ----------------------------------------------------------------------------- + +EPOCH_YEAR = 1970 +def _timegm(tt): + year, month, mday, hour, min, sec = tt[:6] + if ((year >= EPOCH_YEAR) and (1 <= month <= 12) and (1 <= mday <= 31) and + (0 <= hour <= 24) and (0 <= min <= 59) and (0 <= sec <= 61)): + return timegm(tt) + else: + return None + +DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] +MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] +MONTHS_LOWER = [] +for month in MONTHS: MONTHS_LOWER.append(month.lower()) + +def time2isoz(t=None): + """Return a string representing time in seconds since epoch, t. + + If the function is called without an argument, it will use the current + time. + + The format of the returned string is like "YYYY-MM-DD hh:mm:ssZ", + representing Universal Time (UTC, aka GMT). An example of this format is: + + 1994-11-24 08:49:37Z + + """ + if t is None: t = time.time() + year, mon, mday, hour, min, sec = time.gmtime(t)[:6] + return "%04d-%02d-%02d %02d:%02d:%02dZ" % ( + year, mon, mday, hour, min, sec) + +def time2netscape(t=None): + """Return a string representing time in seconds since epoch, t. + + If the function is called without an argument, it will use the current + time. + + The format of the returned string is like this: + + Wed, DD-Mon-YYYY HH:MM:SS GMT + + """ + if t is None: t = time.time() + year, mon, mday, hour, min, sec, wday = time.gmtime(t)[:7] + return "%s %02d-%s-%04d %02d:%02d:%02d GMT" % ( + DAYS[wday], mday, MONTHS[mon-1], year, hour, min, sec) + + +UTC_ZONES = {"GMT": None, "UTC": None, "UT": None, "Z": None} + +TIMEZONE_RE = re.compile(r"^([-+])?(\d\d?):?(\d\d)?$") +def offset_from_tz_string(tz): + offset = None + if tz in UTC_ZONES: + offset = 0 + else: + m = TIMEZONE_RE.search(tz) + if m: + offset = 3600 * int(m.group(2)) + if m.group(3): + offset = offset + 60 * int(m.group(3)) + if m.group(1) == '-': + offset = -offset + return offset + +def _str2time(day, mon, yr, hr, min, sec, tz): + # translate month name to number + # month numbers start with 1 (January) + try: + mon = MONTHS_LOWER.index(mon.lower())+1 + except ValueError: + # maybe it's already a number + try: + imon = int(mon) + except ValueError: + return None + if 1 <= imon <= 12: + mon = imon + else: + return None + + # make sure clock elements are defined + if hr is None: hr = 0 + if min is None: min = 0 + if sec is None: sec = 0 + + yr = int(yr) + day = int(day) + hr = int(hr) + min = int(min) + sec = int(sec) + + if yr < 1000: + # find "obvious" year + cur_yr = time.localtime(time.time())[0] + m = cur_yr % 100 + tmp = yr + yr = yr + cur_yr - m + m = m - tmp + if abs(m) > 50: + if m > 0: yr = yr + 100 + else: yr = yr - 100 + + # convert UTC time tuple to seconds since epoch (not timezone-adjusted) + t = _timegm((yr, mon, day, hr, min, sec, tz)) + + if t is not None: + # adjust time using timezone string, to get absolute time since epoch + if tz is None: + tz = "UTC" + tz = tz.upper() + offset = offset_from_tz_string(tz) + if offset is None: + return None + t = t - offset + + return t + +STRICT_DATE_RE = re.compile( + r"^[SMTWF][a-z][a-z], (\d\d) ([JFMASOND][a-z][a-z]) " + "(\d\d\d\d) (\d\d):(\d\d):(\d\d) GMT$") +WEEKDAY_RE = re.compile( + r"^(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)[a-z]*,?\s*", re.I) +LOOSE_HTTP_DATE_RE = re.compile( + r"""^ + (\d\d?) # day + (?:\s+|[-\/]) + (\w+) # month + (?:\s+|[-\/]) + (\d+) # year + (?: + (?:\s+|:) # separator before clock + (\d\d?):(\d\d) # hour:min + (?::(\d\d))? # optional seconds + )? # optional clock + \s* + ([-+]?\d{2,4}|(?![APap][Mm]\b)[A-Za-z]+)? # timezone + \s* + (?:\(\w+\))? # ASCII representation of timezone in parens. + \s*$""", re.X) +def http2time(text): + """Returns time in seconds since epoch of time represented by a string. + + Return value is an integer. + + None is returned if the format of str is unrecognized, the time is outside + the representable range, or the timezone string is not recognized. If the + string contains no timezone, UTC is assumed. + + The timezone in the string may be numerical (like "-0800" or "+0100") or a + string timezone (like "UTC", "GMT", "BST" or "EST"). Currently, only the + timezone strings equivalent to UTC (zero offset) are known to the function. + + The function loosely parses the following formats: + + Wed, 09 Feb 1994 22:23:32 GMT -- HTTP format + Tuesday, 08-Feb-94 14:15:29 GMT -- old rfc850 HTTP format + Tuesday, 08-Feb-1994 14:15:29 GMT -- broken rfc850 HTTP format + 09 Feb 1994 22:23:32 GMT -- HTTP format (no weekday) + 08-Feb-94 14:15:29 GMT -- rfc850 format (no weekday) + 08-Feb-1994 14:15:29 GMT -- broken rfc850 format (no weekday) + + The parser ignores leading and trailing whitespace. The time may be + absent. + + If the year is given with only 2 digits, the function will select the + century that makes the year closest to the current date. + + """ + # fast exit for strictly conforming string + m = STRICT_DATE_RE.search(text) + if m: + g = m.groups() + mon = MONTHS_LOWER.index(g[1].lower()) + 1 + tt = (int(g[2]), mon, int(g[0]), + int(g[3]), int(g[4]), float(g[5])) + return _timegm(tt) + + # No, we need some messy parsing... + + # clean up + text = text.lstrip() + text = WEEKDAY_RE.sub("", text, 1) # Useless weekday + + # tz is time zone specifier string + day, mon, yr, hr, min, sec, tz = [None]*7 + + # loose regexp parse + m = LOOSE_HTTP_DATE_RE.search(text) + if m is not None: + day, mon, yr, hr, min, sec, tz = m.groups() + else: + return None # bad format + + return _str2time(day, mon, yr, hr, min, sec, tz) + +ISO_DATE_RE = re.compile( + """^ + (\d{4}) # year + [-\/]? + (\d\d?) # numerical month + [-\/]? + (\d\d?) # day + (?: + (?:\s+|[-:Tt]) # separator before clock + (\d\d?):?(\d\d) # hour:min + (?::?(\d\d(?:\.\d*)?))? # optional seconds (and fractional) + )? # optional clock + \s* + ([-+]?\d\d?:?(:?\d\d)? + |Z|z)? # timezone (Z is "zero meridian", i.e. GMT) + \s*$""", re.X) +def iso2time(text): + """ + As for http2time, but parses the ISO 8601 formats: + + 1994-02-03 14:15:29 -0100 -- ISO 8601 format + 1994-02-03 14:15:29 -- zone is optional + 1994-02-03 -- only date + 1994-02-03T14:15:29 -- Use T as separator + 19940203T141529Z -- ISO 8601 compact format + 19940203 -- only date + + """ + # clean up + text = text.lstrip() + + # tz is time zone specifier string + day, mon, yr, hr, min, sec, tz = [None]*7 + + # loose regexp parse + m = ISO_DATE_RE.search(text) + if m is not None: + # XXX there's an extra bit of the timezone I'm ignoring here: is + # this the right thing to do? + yr, mon, day, hr, min, sec, tz, _ = m.groups() + else: + return None # bad format + + return _str2time(day, mon, yr, hr, min, sec, tz) + + +# Header parsing +# ----------------------------------------------------------------------------- + +def unmatched(match): + """Return unmatched part of re.Match object.""" + start, end = match.span(0) + return match.string[:start]+match.string[end:] + +HEADER_TOKEN_RE = re.compile(r"^\s*([^=\s;,]+)") +HEADER_QUOTED_VALUE_RE = re.compile(r"^\s*=\s*\"([^\"\\]*(?:\\.[^\"\\]*)*)\"") +HEADER_VALUE_RE = re.compile(r"^\s*=\s*([^\s;,]*)") +HEADER_ESCAPE_RE = re.compile(r"\\(.)") +def split_header_words(header_values): + r"""Parse header values into a list of lists containing key,value pairs. + + The function knows how to deal with ",", ";" and "=" as well as quoted + values after "=". A list of space separated tokens are parsed as if they + were separated by ";". + + If the header_values passed as argument contains multiple values, then they + are treated as if they were a single value separated by comma ",". + + This means that this function is useful for parsing header fields that + follow this syntax (BNF as from the HTTP/1.1 specification, but we relax + the requirement for tokens). + + headers = #header + header = (token | parameter) *( [";"] (token | parameter)) + + token = 1*<any CHAR except CTLs or separators> + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + + quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) + qdtext = <any TEXT except <">> + quoted-pair = "\" CHAR + + parameter = attribute "=" value + attribute = token + value = token | quoted-string + + Each header is represented by a list of key/value pairs. The value for a + simple token (not part of a parameter) is None. Syntactically incorrect + headers will not necessarily be parsed as you would want. + + This is easier to describe with some examples: + + >>> split_header_words(['foo="bar"; port="80,81"; discard, bar=baz']) + [[('foo', 'bar'), ('port', '80,81'), ('discard', None)], [('bar', 'baz')]] + >>> split_header_words(['text/html; charset="iso-8859-1"']) + [[('text/html', None), ('charset', 'iso-8859-1')]] + >>> split_header_words([r'Basic realm="\"foo\bar\""']) + [[('Basic', None), ('realm', '"foobar"')]] + + """ + assert not isinstance(header_values, basestring) + result = [] + for text in header_values: + orig_text = text + pairs = [] + while text: + m = HEADER_TOKEN_RE.search(text) + if m: + text = unmatched(m) + name = m.group(1) + m = HEADER_QUOTED_VALUE_RE.search(text) + if m: # quoted value + text = unmatched(m) + value = m.group(1) + value = HEADER_ESCAPE_RE.sub(r"\1", value) + else: + m = HEADER_VALUE_RE.search(text) + if m: # unquoted value + text = unmatched(m) + value = m.group(1) + value = value.rstrip() + else: + # no value, a lone token + value = None + pairs.append((name, value)) + elif text.lstrip().startswith(","): + # concatenated headers, as per RFC 2616 section 4.2 + text = text.lstrip()[1:] + if pairs: result.append(pairs) + pairs = [] + else: + # skip junk + non_junk, nr_junk_chars = re.subn("^[=\s;]*", "", text) + assert nr_junk_chars > 0, ( + "split_header_words bug: '%s', '%s', %s" % + (orig_text, text, pairs)) + text = non_junk + if pairs: result.append(pairs) + return result + +HEADER_JOIN_ESCAPE_RE = re.compile(r"([\"\\])") +def join_header_words(lists): + """Do the inverse (almost) of the conversion done by split_header_words. + + Takes a list of lists of (key, value) pairs and produces a single header + value. Attribute values are quoted if needed. + + >>> join_header_words([[("text/plain", None), ("charset", "iso-8859/1")]]) + 'text/plain; charset="iso-8859/1"' + >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859/1")]]) + 'text/plain, charset="iso-8859/1"' + + """ + headers = [] + for pairs in lists: + attr = [] + for k, v in pairs: + if v is not None: + if not re.search(r"^\w+$", v): + v = HEADER_JOIN_ESCAPE_RE.sub(r"\\\1", v) # escape " and \ + v = '"%s"' % v + k = "%s=%s" % (k, v) + attr.append(k) + if attr: headers.append("; ".join(attr)) + return ", ".join(headers) + +def _strip_quotes(text): + if text.startswith('"'): + text = text[1:] + if text.endswith('"'): + text = text[:-1] + return text + +def parse_ns_headers(ns_headers): + """Ad-hoc parser for Netscape protocol cookie-attributes. + + The old Netscape cookie format for Set-Cookie can for instance contain + an unquoted "," in the expires field, so we have to use this ad-hoc + parser instead of split_header_words. + + XXX This may not make the best possible effort to parse all the crap + that Netscape Cookie headers contain. Ronald Tschalar's HTTPClient + parser is probably better, so could do worse than following that if + this ever gives any trouble. + + Currently, this is also used for parsing RFC 2109 cookies. + + """ + known_attrs = ("expires", "domain", "path", "secure", + # RFC 2109 attrs (may turn up in Netscape cookies, too) + "version", "port", "max-age") + + result = [] + for ns_header in ns_headers: + pairs = [] + version_set = False + for ii, param in enumerate(re.split(r";\s*", ns_header)): + param = param.rstrip() + if param == "": continue + if "=" not in param: + k, v = param, None + else: + k, v = re.split(r"\s*=\s*", param, 1) + k = k.lstrip() + if ii != 0: + lc = k.lower() + if lc in known_attrs: + k = lc + if k == "version": + # This is an RFC 2109 cookie. + v = _strip_quotes(v) + version_set = True + if k == "expires": + # convert expires date to seconds since epoch + v = http2time(_strip_quotes(v)) # None if invalid + pairs.append((k, v)) + + if pairs: + if not version_set: + pairs.append(("version", "0")) + result.append(pairs) + + return result + + +IPV4_RE = re.compile(r"\.\d+$") +def is_HDN(text): + """Return True if text is a host domain name.""" + # XXX + # This may well be wrong. Which RFC is HDN defined in, if any (for + # the purposes of RFC 2965)? + # For the current implementation, what about IPv6? Remember to look + # at other uses of IPV4_RE also, if change this. + if IPV4_RE.search(text): + return False + if text == "": + return False + if text[0] == "." or text[-1] == ".": + return False + return True + +def domain_match(A, B): + """Return True if domain A domain-matches domain B, according to RFC 2965. + + A and B may be host domain names or IP addresses. + + RFC 2965, section 1: + + Host names can be specified either as an IP address or a HDN string. + Sometimes we compare one host name with another. (Such comparisons SHALL + be case-insensitive.) Host A's name domain-matches host B's if + + * their host name strings string-compare equal; or + + * A is a HDN string and has the form NB, where N is a non-empty + name string, B has the form .B', and B' is a HDN string. (So, + x.y.com domain-matches .Y.com but not Y.com.) + + Note that domain-match is not a commutative operation: a.b.c.com + domain-matches .c.com, but not the reverse. + + """ + # Note that, if A or B are IP addresses, the only relevant part of the + # definition of the domain-match algorithm is the direct string-compare. + A = A.lower() + B = B.lower() + if A == B: + return True + if not is_HDN(A): + return False + i = A.rfind(B) + if i == -1 or i == 0: + # A does not have form NB, or N is the empty string + return False + if not B.startswith("."): + return False + if not is_HDN(B[1:]): + return False + return True + +def liberal_is_HDN(text): + """Return True if text is a sort-of-like a host domain name. + + For accepting/blocking domains. + + """ + if IPV4_RE.search(text): + return False + return True + +def user_domain_match(A, B): + """For blocking/accepting domains. + + A and B may be host domain names or IP addresses. + + """ + A = A.lower() + B = B.lower() + if not (liberal_is_HDN(A) and liberal_is_HDN(B)): + if A == B: + # equal IP addresses + return True + return False + initial_dot = B.startswith(".") + if initial_dot and A.endswith(B): + return True + if not initial_dot and A == B: + return True + return False + +cut_port_re = re.compile(r":\d+$") +def request_host(request): + """Return request-host, as defined by RFC 2965. + + Variation from RFC: returned value is lowercased, for convenient + comparison. + + """ + url = request.get_full_url() + host = urlparse.urlparse(url)[1] + if host == "": + host = request.get_header("Host", "") + + # remove port, if present + host = cut_port_re.sub("", host, 1) + return host.lower() + +def eff_request_host(request): + """Return a tuple (request-host, effective request-host name). + + As defined by RFC 2965, except both are lowercased. + + """ + erhn = req_host = request_host(request) + if req_host.find(".") == -1 and not IPV4_RE.search(req_host): + erhn = req_host + ".local" + return req_host, erhn + +def request_path(request): + """Path component of request-URI, as defined by RFC 2965.""" + url = request.get_full_url() + parts = urlparse.urlsplit(url) + path = escape_path(parts.path) + if not path.startswith("/"): + # fix bad RFC 2396 absoluteURI + path = "/" + path + return path + +def request_port(request): + host = request.get_host() + i = host.find(':') + if i >= 0: + port = host[i+1:] + try: + int(port) + except ValueError: + _debug("nonnumeric port: '%s'", port) + return None + else: + port = DEFAULT_HTTP_PORT + return port + +# Characters in addition to A-Z, a-z, 0-9, '_', '.', and '-' that don't +# need to be escaped to form a valid HTTP URL (RFCs 2396 and 1738). +HTTP_PATH_SAFE = "%/;:@&=+$,!~*'()" +ESCAPED_CHAR_RE = re.compile(r"%([0-9a-fA-F][0-9a-fA-F])") +def uppercase_escaped_char(match): + return "%%%s" % match.group(1).upper() +def escape_path(path): + """Escape any invalid characters in HTTP URL, and uppercase all escapes.""" + # There's no knowing what character encoding was used to create URLs + # containing %-escapes, but since we have to pick one to escape invalid + # path characters, we pick UTF-8, as recommended in the HTML 4.0 + # specification: + # http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.2.1 + # And here, kind of: draft-fielding-uri-rfc2396bis-03 + # (And in draft IRI specification: draft-duerst-iri-05) + # (And here, for new URI schemes: RFC 2718) + if isinstance(path, unicode): + path = path.encode("utf-8") + path = urllib.quote(path, HTTP_PATH_SAFE) + path = ESCAPED_CHAR_RE.sub(uppercase_escaped_char, path) + return path + +def reach(h): + """Return reach of host h, as defined by RFC 2965, section 1. + + The reach R of a host name H is defined as follows: + + * If + + - H is the host domain name of a host; and, + + - H has the form A.B; and + + - A has no embedded (that is, interior) dots; and + + - B has at least one embedded dot, or B is the string "local". + then the reach of H is .B. + + * Otherwise, the reach of H is H. + + >>> reach("www.acme.com") + '.acme.com' + >>> reach("acme.com") + 'acme.com' + >>> reach("acme.local") + '.local' + + """ + i = h.find(".") + if i >= 0: + #a = h[:i] # this line is only here to show what a is + b = h[i+1:] + i = b.find(".") + if is_HDN(h) and (i >= 0 or b == "local"): + return "."+b + return h + +def is_third_party(request): + """ + + RFC 2965, section 3.3.6: + + An unverifiable transaction is to a third-party host if its request- + host U does not domain-match the reach R of the request-host O in the + origin transaction. + + """ + req_host = request_host(request) + if not domain_match(req_host, reach(request.get_origin_req_host())): + return True + else: + return False + + +class Cookie: + """HTTP Cookie. + + This class represents both Netscape and RFC 2965 cookies. + + This is deliberately a very simple class. It just holds attributes. It's + possible to construct Cookie instances that don't comply with the cookie + standards. CookieJar.make_cookies is the factory function for Cookie + objects -- it deals with cookie parsing, supplying defaults, and + normalising to the representation used in this class. CookiePolicy is + responsible for checking them to see whether they should be accepted from + and returned to the server. + + Note that the port may be present in the headers, but unspecified ("Port" + rather than"Port=80", for example); if this is the case, port is None. + + """ + + def __init__(self, version, name, value, + port, port_specified, + domain, domain_specified, domain_initial_dot, + path, path_specified, + secure, + expires, + discard, + comment, + comment_url, + rest, + rfc2109=False, + ): + + if version is not None: version = int(version) + if expires is not None: expires = int(expires) + if port is None and port_specified is True: + raise ValueError("if port is None, port_specified must be false") + + self.version = version + self.name = name + self.value = value + self.port = port + self.port_specified = port_specified + # normalise case, as per RFC 2965 section 3.3.3 + self.domain = domain.lower() + self.domain_specified = domain_specified + # Sigh. We need to know whether the domain given in the + # cookie-attribute had an initial dot, in order to follow RFC 2965 + # (as clarified in draft errata). Needed for the returned $Domain + # value. + self.domain_initial_dot = domain_initial_dot + self.path = path + self.path_specified = path_specified + self.secure = secure + self.expires = expires + self.discard = discard + self.comment = comment + self.comment_url = comment_url + self.rfc2109 = rfc2109 + + self._rest = copy.copy(rest) + + def has_nonstandard_attr(self, name): + return name in self._rest + def get_nonstandard_attr(self, name, default=None): + return self._rest.get(name, default) + def set_nonstandard_attr(self, name, value): + self._rest[name] = value + + def is_expired(self, now=None): + if now is None: now = time.time() + if (self.expires is not None) and (self.expires <= now): + return True + return False + + def __str__(self): + if self.port is None: p = "" + else: p = ":"+self.port + limit = self.domain + p + self.path + if self.value is not None: + namevalue = "%s=%s" % (self.name, self.value) + else: + namevalue = self.name + return "<Cookie %s for %s>" % (namevalue, limit) + + def __repr__(self): + args = [] + for name in ("version", "name", "value", + "port", "port_specified", + "domain", "domain_specified", "domain_initial_dot", + "path", "path_specified", + "secure", "expires", "discard", "comment", "comment_url", + ): + attr = getattr(self, name) + args.append("%s=%s" % (name, repr(attr))) + args.append("rest=%s" % repr(self._rest)) + args.append("rfc2109=%s" % repr(self.rfc2109)) + return "Cookie(%s)" % ", ".join(args) + + +class CookiePolicy: + """Defines which cookies get accepted from and returned to server. + + May also modify cookies, though this is probably a bad idea. + + The subclass DefaultCookiePolicy defines the standard rules for Netscape + and RFC 2965 cookies -- override that if you want a customised policy. + + """ + def set_ok(self, cookie, request): + """Return true if (and only if) cookie should be accepted from server. + + Currently, pre-expired cookies never get this far -- the CookieJar + class deletes such cookies itself. + + """ + raise NotImplementedError() + + def return_ok(self, cookie, request): + """Return true if (and only if) cookie should be returned to server.""" + raise NotImplementedError() + + def domain_return_ok(self, domain, request): + """Return false if cookies should not be returned, given cookie domain. + """ + return True + + def path_return_ok(self, path, request): + """Return false if cookies should not be returned, given cookie path. + """ + return True + + +class DefaultCookiePolicy(CookiePolicy): + """Implements the standard rules for accepting and returning cookies.""" + + DomainStrictNoDots = 1 + DomainStrictNonDomain = 2 + DomainRFC2965Match = 4 + + DomainLiberal = 0 + DomainStrict = DomainStrictNoDots|DomainStrictNonDomain + + def __init__(self, + blocked_domains=None, allowed_domains=None, + netscape=True, rfc2965=False, + rfc2109_as_netscape=None, + hide_cookie2=False, + strict_domain=False, + strict_rfc2965_unverifiable=True, + strict_ns_unverifiable=False, + strict_ns_domain=DomainLiberal, + strict_ns_set_initial_dollar=False, + strict_ns_set_path=False, + ): + """Constructor arguments should be passed as keyword arguments only.""" + self.netscape = netscape + self.rfc2965 = rfc2965 + self.rfc2109_as_netscape = rfc2109_as_netscape + self.hide_cookie2 = hide_cookie2 + self.strict_domain = strict_domain + self.strict_rfc2965_unverifiable = strict_rfc2965_unverifiable + self.strict_ns_unverifiable = strict_ns_unverifiable + self.strict_ns_domain = strict_ns_domain + self.strict_ns_set_initial_dollar = strict_ns_set_initial_dollar + self.strict_ns_set_path = strict_ns_set_path + + if blocked_domains is not None: + self._blocked_domains = tuple(blocked_domains) + else: + self._blocked_domains = () + + if allowed_domains is not None: + allowed_domains = tuple(allowed_domains) + self._allowed_domains = allowed_domains + + def blocked_domains(self): + """Return the sequence of blocked domains (as a tuple).""" + return self._blocked_domains + def set_blocked_domains(self, blocked_domains): + """Set the sequence of blocked domains.""" + self._blocked_domains = tuple(blocked_domains) + + def is_blocked(self, domain): + for blocked_domain in self._blocked_domains: + if user_domain_match(domain, blocked_domain): + return True + return False + + def allowed_domains(self): + """Return None, or the sequence of allowed domains (as a tuple).""" + return self._allowed_domains + def set_allowed_domains(self, allowed_domains): + """Set the sequence of allowed domains, or None.""" + if allowed_domains is not None: + allowed_domains = tuple(allowed_domains) + self._allowed_domains = allowed_domains + + def is_not_allowed(self, domain): + if self._allowed_domains is None: + return False + for allowed_domain in self._allowed_domains: + if user_domain_match(domain, allowed_domain): + return False + return True + + def set_ok(self, cookie, request): + """ + If you override .set_ok(), be sure to call this method. If it returns + false, so should your subclass (assuming your subclass wants to be more + strict about which cookies to accept). + + """ + _debug(" - checking cookie %s=%s", cookie.name, cookie.value) + + assert cookie.name is not None + + for n in "version", "verifiability", "name", "path", "domain", "port": + fn_name = "set_ok_"+n + fn = getattr(self, fn_name) + if not fn(cookie, request): + return False + + return True + + def set_ok_version(self, cookie, request): + if cookie.version is None: + # Version is always set to 0 by parse_ns_headers if it's a Netscape + # cookie, so this must be an invalid RFC 2965 cookie. + _debug(" Set-Cookie2 without version attribute (%s=%s)", + cookie.name, cookie.value) + return False + if cookie.version > 0 and not self.rfc2965: + _debug(" RFC 2965 cookies are switched off") + return False + elif cookie.version == 0 and not self.netscape: + _debug(" Netscape cookies are switched off") + return False + return True + + def set_ok_verifiability(self, cookie, request): + if request.is_unverifiable() and is_third_party(request): + if cookie.version > 0 and self.strict_rfc2965_unverifiable: + _debug(" third-party RFC 2965 cookie during " + "unverifiable transaction") + return False + elif cookie.version == 0 and self.strict_ns_unverifiable: + _debug(" third-party Netscape cookie during " + "unverifiable transaction") + return False + return True + + def set_ok_name(self, cookie, request): + # Try and stop servers setting V0 cookies designed to hack other + # servers that know both V0 and V1 protocols. + if (cookie.version == 0 and self.strict_ns_set_initial_dollar and + cookie.name.startswith("$")): + _debug(" illegal name (starts with '$'): '%s'", cookie.name) + return False + return True + + def set_ok_path(self, cookie, request): + if cookie.path_specified: + req_path = request_path(request) + if ((cookie.version > 0 or + (cookie.version == 0 and self.strict_ns_set_path)) and + not req_path.startswith(cookie.path)): + _debug(" path attribute %s is not a prefix of request " + "path %s", cookie.path, req_path) + return False + return True + + def set_ok_domain(self, cookie, request): + if self.is_blocked(cookie.domain): + _debug(" domain %s is in user block-list", cookie.domain) + return False + if self.is_not_allowed(cookie.domain): + _debug(" domain %s is not in user allow-list", cookie.domain) + return False + if cookie.domain_specified: + req_host, erhn = eff_request_host(request) + domain = cookie.domain + if self.strict_domain and (domain.count(".") >= 2): + # XXX This should probably be compared with the Konqueror + # (kcookiejar.cpp) and Mozilla implementations, but it's a + # losing battle. + i = domain.rfind(".") + j = domain.rfind(".", 0, i) + if j == 0: # domain like .foo.bar + tld = domain[i+1:] + sld = domain[j+1:i] + if sld.lower() in ("co", "ac", "com", "edu", "org", "net", + "gov", "mil", "int", "aero", "biz", "cat", "coop", + "info", "jobs", "mobi", "museum", "name", "pro", + "travel", "eu") and len(tld) == 2: + # domain like .co.uk + _debug(" country-code second level domain %s", domain) + return False + if domain.startswith("."): + undotted_domain = domain[1:] + else: + undotted_domain = domain + embedded_dots = (undotted_domain.find(".") >= 0) + if not embedded_dots and domain != ".local": + _debug(" non-local domain %s contains no embedded dot", + domain) + return False + if cookie.version == 0: + if (not erhn.endswith(domain) and + (not erhn.startswith(".") and + not ("."+erhn).endswith(domain))): + _debug(" effective request-host %s (even with added " + "initial dot) does not end with %s", + erhn, domain) + return False + if (cookie.version > 0 or + (self.strict_ns_domain & self.DomainRFC2965Match)): + if not domain_match(erhn, domain): + _debug(" effective request-host %s does not domain-match " + "%s", erhn, domain) + return False + if (cookie.version > 0 or + (self.strict_ns_domain & self.DomainStrictNoDots)): + host_prefix = req_host[:-len(domain)] + if (host_prefix.find(".") >= 0 and + not IPV4_RE.search(req_host)): + _debug(" host prefix %s for domain %s contains a dot", + host_prefix, domain) + return False + return True + + def set_ok_port(self, cookie, request): + if cookie.port_specified: + req_port = request_port(request) + if req_port is None: + req_port = "80" + else: + req_port = str(req_port) + for p in cookie.port.split(","): + try: + int(p) + except ValueError: + _debug(" bad port %s (not numeric)", p) + return False + if p == req_port: + break + else: + _debug(" request port (%s) not found in %s", + req_port, cookie.port) + return False + return True + + def return_ok(self, cookie, request): + """ + If you override .return_ok(), be sure to call this method. If it + returns false, so should your subclass (assuming your subclass wants to + be more strict about which cookies to return). + + """ + # Path has already been checked by .path_return_ok(), and domain + # blocking done by .domain_return_ok(). + _debug(" - checking cookie %s=%s", cookie.name, cookie.value) + + for n in "version", "verifiability", "secure", "expires", "port", "domain": + fn_name = "return_ok_"+n + fn = getattr(self, fn_name) + if not fn(cookie, request): + return False + return True + + def return_ok_version(self, cookie, request): + if cookie.version > 0 and not self.rfc2965: + _debug(" RFC 2965 cookies are switched off") + return False + elif cookie.version == 0 and not self.netscape: + _debug(" Netscape cookies are switched off") + return False + return True + + def return_ok_verifiability(self, cookie, request): + if request.is_unverifiable() and is_third_party(request): + if cookie.version > 0 and self.strict_rfc2965_unverifiable: + _debug(" third-party RFC 2965 cookie during unverifiable " + "transaction") + return False + elif cookie.version == 0 and self.strict_ns_unverifiable: + _debug(" third-party Netscape cookie during unverifiable " + "transaction") + return False + return True + + def return_ok_secure(self, cookie, request): + if cookie.secure and request.get_type() != "https": + _debug(" secure cookie with non-secure request") + return False + return True + + def return_ok_expires(self, cookie, request): + if cookie.is_expired(self._now): + _debug(" cookie expired") + return False + return True + + def return_ok_port(self, cookie, request): + if cookie.port: + req_port = request_port(request) + if req_port is None: + req_port = "80" + for p in cookie.port.split(","): + if p == req_port: + break + else: + _debug(" request port %s does not match cookie port %s", + req_port, cookie.port) + return False + return True + + def return_ok_domain(self, cookie, request): + req_host, erhn = eff_request_host(request) + domain = cookie.domain + + # strict check of non-domain cookies: Mozilla does this, MSIE5 doesn't + if (cookie.version == 0 and + (self.strict_ns_domain & self.DomainStrictNonDomain) and + not cookie.domain_specified and domain != erhn): + _debug(" cookie with unspecified domain does not string-compare " + "equal to request domain") + return False + + if cookie.version > 0 and not domain_match(erhn, domain): + _debug(" effective request-host name %s does not domain-match " + "RFC 2965 cookie domain %s", erhn, domain) + return False + if cookie.version == 0 and not ("."+erhn).endswith(domain): + _debug(" request-host %s does not match Netscape cookie domain " + "%s", req_host, domain) + return False + return True + + def domain_return_ok(self, domain, request): + # Liberal check of. This is here as an optimization to avoid + # having to load lots of MSIE cookie files unless necessary. + req_host, erhn = eff_request_host(request) + if not req_host.startswith("."): + req_host = "."+req_host + if not erhn.startswith("."): + erhn = "."+erhn + if not (req_host.endswith(domain) or erhn.endswith(domain)): + #_debug(" request domain %s does not match cookie domain %s", + # req_host, domain) + return False + + if self.is_blocked(domain): + _debug(" domain %s is in user block-list", domain) + return False + if self.is_not_allowed(domain): + _debug(" domain %s is not in user allow-list", domain) + return False + + return True + + def path_return_ok(self, path, request): + _debug("- checking cookie path=%s", path) + req_path = request_path(request) + if not req_path.startswith(path): + _debug(" %s does not path-match %s", req_path, path) + return False + return True + + +def vals_sorted_by_key(adict): + keys = adict.keys() + keys.sort() + return map(adict.get, keys) + +def deepvalues(mapping): + """Iterates over nested mapping, depth-first, in sorted order by key.""" + values = vals_sorted_by_key(mapping) + for obj in values: + mapping = False + try: + obj.items + except AttributeError: + pass + else: + mapping = True + for subobj in deepvalues(obj): + yield subobj + if not mapping: + yield obj + + +# Used as second parameter to dict.get() method, to distinguish absent +# dict key from one with a None value. +class Absent: pass + +class CookieJar: + """Collection of HTTP cookies. + + You may not need to know about this class: try + urllib2.build_opener(HTTPCookieProcessor).open(url). + + """ + + non_word_re = re.compile(r"\W") + quote_re = re.compile(r"([\"\\])") + strict_domain_re = re.compile(r"\.?[^.]*") + domain_re = re.compile(r"[^.]*") + dots_re = re.compile(r"^\.+") + + magic_re = r"^\#LWP-Cookies-(\d+\.\d+)" + + def __init__(self, policy=None): + if policy is None: + policy = DefaultCookiePolicy() + self._policy = policy + + self._cookies_lock = _threading.RLock() + self._cookies = {} + + def set_policy(self, policy): + self._policy = policy + + def _cookies_for_domain(self, domain, request): + cookies = [] + if not self._policy.domain_return_ok(domain, request): + return [] + _debug("Checking %s for cookies to return", domain) + cookies_by_path = self._cookies[domain] + for path in cookies_by_path.keys(): + if not self._policy.path_return_ok(path, request): + continue + cookies_by_name = cookies_by_path[path] + for cookie in cookies_by_name.values(): + if not self._policy.return_ok(cookie, request): + _debug(" not returning cookie") + continue + _debug(" it's a match") + cookies.append(cookie) + return cookies + + def _cookies_for_request(self, request): + """Return a list of cookies to be returned to server.""" + cookies = [] + for domain in self._cookies.keys(): + cookies.extend(self._cookies_for_domain(domain, request)) + return cookies + + def _cookie_attrs(self, cookies): + """Return a list of cookie-attributes to be returned to server. + + like ['foo="bar"; $Path="/"', ...] + + The $Version attribute is also added when appropriate (currently only + once per request). + + """ + # add cookies in order of most specific (ie. longest) path first + cookies.sort(key=lambda arg: len(arg.path), reverse=True) + + version_set = False + + attrs = [] + for cookie in cookies: + # set version of Cookie header + # XXX + # What should it be if multiple matching Set-Cookie headers have + # different versions themselves? + # Answer: there is no answer; was supposed to be settled by + # RFC 2965 errata, but that may never appear... + version = cookie.version + if not version_set: + version_set = True + if version > 0: + attrs.append("$Version=%s" % version) + + # quote cookie value if necessary + # (not for Netscape protocol, which already has any quotes + # intact, due to the poorly-specified Netscape Cookie: syntax) + if ((cookie.value is not None) and + self.non_word_re.search(cookie.value) and version > 0): + value = self.quote_re.sub(r"\\\1", cookie.value) + else: + value = cookie.value + + # add cookie-attributes to be returned in Cookie header + if cookie.value is None: + attrs.append(cookie.name) + else: + attrs.append("%s=%s" % (cookie.name, value)) + if version > 0: + if cookie.path_specified: + attrs.append('$Path="%s"' % cookie.path) + if cookie.domain.startswith("."): + domain = cookie.domain + if (not cookie.domain_initial_dot and + domain.startswith(".")): + domain = domain[1:] + attrs.append('$Domain="%s"' % domain) + if cookie.port is not None: + p = "$Port" + if cookie.port_specified: + p = p + ('="%s"' % cookie.port) + attrs.append(p) + + return attrs + + def add_cookie_header(self, request): + """Add correct Cookie: header to request (urllib2.Request object). + + The Cookie2 header is also added unless policy.hide_cookie2 is true. + + """ + _debug("add_cookie_header") + self._cookies_lock.acquire() + try: + + self._policy._now = self._now = int(time.time()) + + cookies = self._cookies_for_request(request) + + attrs = self._cookie_attrs(cookies) + if attrs: + if not request.has_header("Cookie"): + request.add_unredirected_header( + "Cookie", "; ".join(attrs)) + + # if necessary, advertise that we know RFC 2965 + if (self._policy.rfc2965 and not self._policy.hide_cookie2 and + not request.has_header("Cookie2")): + for cookie in cookies: + if cookie.version != 1: + request.add_unredirected_header("Cookie2", '$Version="1"') + break + + finally: + self._cookies_lock.release() + + self.clear_expired_cookies() + + def _normalized_cookie_tuples(self, attrs_set): + """Return list of tuples containing normalised cookie information. + + attrs_set is the list of lists of key,value pairs extracted from + the Set-Cookie or Set-Cookie2 headers. + + Tuples are name, value, standard, rest, where name and value are the + cookie name and value, standard is a dictionary containing the standard + cookie-attributes (discard, secure, version, expires or max-age, + domain, path and port) and rest is a dictionary containing the rest of + the cookie-attributes. + + """ + cookie_tuples = [] + + boolean_attrs = "discard", "secure" + value_attrs = ("version", + "expires", "max-age", + "domain", "path", "port", + "comment", "commenturl") + + for cookie_attrs in attrs_set: + name, value = cookie_attrs[0] + + # Build dictionary of standard cookie-attributes (standard) and + # dictionary of other cookie-attributes (rest). + + # Note: expiry time is normalised to seconds since epoch. V0 + # cookies should have the Expires cookie-attribute, and V1 cookies + # should have Max-Age, but since V1 includes RFC 2109 cookies (and + # since V0 cookies may be a mish-mash of Netscape and RFC 2109), we + # accept either (but prefer Max-Age). + max_age_set = False + + bad_cookie = False + + standard = {} + rest = {} + for k, v in cookie_attrs[1:]: + lc = k.lower() + # don't lose case distinction for unknown fields + if lc in value_attrs or lc in boolean_attrs: + k = lc + if k in boolean_attrs and v is None: + # boolean cookie-attribute is present, but has no value + # (like "discard", rather than "port=80") + v = True + if k in standard: + # only first value is significant + continue + if k == "domain": + if v is None: + _debug(" missing value for domain attribute") + bad_cookie = True + break + # RFC 2965 section 3.3.3 + v = v.lower() + if k == "expires": + if max_age_set: + # Prefer max-age to expires (like Mozilla) + continue + if v is None: + _debug(" missing or invalid value for expires " + "attribute: treating as session cookie") + continue + if k == "max-age": + max_age_set = True + try: + v = int(v) + except ValueError: + _debug(" missing or invalid (non-numeric) value for " + "max-age attribute") + bad_cookie = True + break + # convert RFC 2965 Max-Age to seconds since epoch + # XXX Strictly you're supposed to follow RFC 2616 + # age-calculation rules. Remember that zero Max-Age is a + # is a request to discard (old and new) cookie, though. + k = "expires" + v = self._now + v + if (k in value_attrs) or (k in boolean_attrs): + if (v is None and + k not in ("port", "comment", "commenturl")): + _debug(" missing value for %s attribute" % k) + bad_cookie = True + break + standard[k] = v + else: + rest[k] = v + + if bad_cookie: + continue + + cookie_tuples.append((name, value, standard, rest)) + + return cookie_tuples + + def _cookie_from_cookie_tuple(self, tup, request): + # standard is dict of standard cookie-attributes, rest is dict of the + # rest of them + name, value, standard, rest = tup + + domain = standard.get("domain", Absent) + path = standard.get("path", Absent) + port = standard.get("port", Absent) + expires = standard.get("expires", Absent) + + # set the easy defaults + version = standard.get("version", None) + if version is not None: + try: + version = int(version) + except ValueError: + return None # invalid version, ignore cookie + secure = standard.get("secure", False) + # (discard is also set if expires is Absent) + discard = standard.get("discard", False) + comment = standard.get("comment", None) + comment_url = standard.get("commenturl", None) + + # set default path + if path is not Absent and path != "": + path_specified = True + path = escape_path(path) + else: + path_specified = False + path = request_path(request) + i = path.rfind("/") + if i != -1: + if version == 0: + # Netscape spec parts company from reality here + path = path[:i] + else: + path = path[:i+1] + if len(path) == 0: path = "/" + + # set default domain + domain_specified = domain is not Absent + # but first we have to remember whether it starts with a dot + domain_initial_dot = False + if domain_specified: + domain_initial_dot = bool(domain.startswith(".")) + if domain is Absent: + req_host, erhn = eff_request_host(request) + domain = erhn + elif not domain.startswith("."): + domain = "."+domain + + # set default port + port_specified = False + if port is not Absent: + if port is None: + # Port attr present, but has no value: default to request port. + # Cookie should then only be sent back on that port. + port = request_port(request) + else: + port_specified = True + port = re.sub(r"\s+", "", port) + else: + # No port attr present. Cookie can be sent back on any port. + port = None + + # set default expires and discard + if expires is Absent: + expires = None + discard = True + elif expires <= self._now: + # Expiry date in past is request to delete cookie. This can't be + # in DefaultCookiePolicy, because can't delete cookies there. + try: + self.clear(domain, path, name) + except KeyError: + pass + _debug("Expiring cookie, domain='%s', path='%s', name='%s'", + domain, path, name) + return None + + return Cookie(version, + name, value, + port, port_specified, + domain, domain_specified, domain_initial_dot, + path, path_specified, + secure, + expires, + discard, + comment, + comment_url, + rest) + + def _cookies_from_attrs_set(self, attrs_set, request): + cookie_tuples = self._normalized_cookie_tuples(attrs_set) + + cookies = [] + for tup in cookie_tuples: + cookie = self._cookie_from_cookie_tuple(tup, request) + if cookie: cookies.append(cookie) + return cookies + + def _process_rfc2109_cookies(self, cookies): + rfc2109_as_ns = getattr(self._policy, 'rfc2109_as_netscape', None) + if rfc2109_as_ns is None: + rfc2109_as_ns = not self._policy.rfc2965 + for cookie in cookies: + if cookie.version == 1: + cookie.rfc2109 = True + if rfc2109_as_ns: + # treat 2109 cookies as Netscape cookies rather than + # as RFC2965 cookies + cookie.version = 0 + + def make_cookies(self, response, request): + """Return sequence of Cookie objects extracted from response object.""" + # get cookie-attributes for RFC 2965 and Netscape protocols + headers = response.info() + rfc2965_hdrs = headers.getheaders("Set-Cookie2") + ns_hdrs = headers.getheaders("Set-Cookie") + + rfc2965 = self._policy.rfc2965 + netscape = self._policy.netscape + + if ((not rfc2965_hdrs and not ns_hdrs) or + (not ns_hdrs and not rfc2965) or + (not rfc2965_hdrs and not netscape) or + (not netscape and not rfc2965)): + return [] # no relevant cookie headers: quick exit + + try: + cookies = self._cookies_from_attrs_set( + split_header_words(rfc2965_hdrs), request) + except Exception: + _warn_unhandled_exception() + cookies = [] + + if ns_hdrs and netscape: + try: + # RFC 2109 and Netscape cookies + ns_cookies = self._cookies_from_attrs_set( + parse_ns_headers(ns_hdrs), request) + except Exception: + _warn_unhandled_exception() + ns_cookies = [] + self._process_rfc2109_cookies(ns_cookies) + + # Look for Netscape cookies (from Set-Cookie headers) that match + # corresponding RFC 2965 cookies (from Set-Cookie2 headers). + # For each match, keep the RFC 2965 cookie and ignore the Netscape + # cookie (RFC 2965 section 9.1). Actually, RFC 2109 cookies are + # bundled in with the Netscape cookies for this purpose, which is + # reasonable behaviour. + if rfc2965: + lookup = {} + for cookie in cookies: + lookup[(cookie.domain, cookie.path, cookie.name)] = None + + def no_matching_rfc2965(ns_cookie, lookup=lookup): + key = ns_cookie.domain, ns_cookie.path, ns_cookie.name + return key not in lookup + ns_cookies = filter(no_matching_rfc2965, ns_cookies) + + if ns_cookies: + cookies.extend(ns_cookies) + + return cookies + + def set_cookie_if_ok(self, cookie, request): + """Set a cookie if policy says it's OK to do so.""" + self._cookies_lock.acquire() + try: + self._policy._now = self._now = int(time.time()) + + if self._policy.set_ok(cookie, request): + self.set_cookie(cookie) + + + finally: + self._cookies_lock.release() + + def set_cookie(self, cookie): + """Set a cookie, without checking whether or not it should be set.""" + c = self._cookies + self._cookies_lock.acquire() + try: + if cookie.domain not in c: c[cookie.domain] = {} + c2 = c[cookie.domain] + if cookie.path not in c2: c2[cookie.path] = {} + c3 = c2[cookie.path] + c3[cookie.name] = cookie + finally: + self._cookies_lock.release() + + def extract_cookies(self, response, request): + """Extract cookies from response, where allowable given the request.""" + _debug("extract_cookies: %s", response.info()) + self._cookies_lock.acquire() + try: + self._policy._now = self._now = int(time.time()) + + for cookie in self.make_cookies(response, request): + if self._policy.set_ok(cookie, request): + _debug(" setting cookie: %s", cookie) + self.set_cookie(cookie) + finally: + self._cookies_lock.release() + + def clear(self, domain=None, path=None, name=None): + """Clear some cookies. + + Invoking this method without arguments will clear all cookies. If + given a single argument, only cookies belonging to that domain will be + removed. If given two arguments, cookies belonging to the specified + path within that domain are removed. If given three arguments, then + the cookie with the specified name, path and domain is removed. + + Raises KeyError if no matching cookie exists. + + """ + if name is not None: + if (domain is None) or (path is None): + raise ValueError( + "domain and path must be given to remove a cookie by name") + del self._cookies[domain][path][name] + elif path is not None: + if domain is None: + raise ValueError( + "domain must be given to remove cookies by path") + del self._cookies[domain][path] + elif domain is not None: + del self._cookies[domain] + else: + self._cookies = {} + + def clear_session_cookies(self): + """Discard all session cookies. + + Note that the .save() method won't save session cookies anyway, unless + you ask otherwise by passing a true ignore_discard argument. + + """ + self._cookies_lock.acquire() + try: + for cookie in self: + if cookie.discard: + self.clear(cookie.domain, cookie.path, cookie.name) + finally: + self._cookies_lock.release() + + def clear_expired_cookies(self): + """Discard all expired cookies. + + You probably don't need to call this method: expired cookies are never + sent back to the server (provided you're using DefaultCookiePolicy), + this method is called by CookieJar itself every so often, and the + .save() method won't save expired cookies anyway (unless you ask + otherwise by passing a true ignore_expires argument). + + """ + self._cookies_lock.acquire() + try: + now = time.time() + for cookie in self: + if cookie.is_expired(now): + self.clear(cookie.domain, cookie.path, cookie.name) + finally: + self._cookies_lock.release() + + def __iter__(self): + return deepvalues(self._cookies) + + def __len__(self): + """Return number of contained cookies.""" + i = 0 + for cookie in self: i = i + 1 + return i + + def __repr__(self): + r = [] + for cookie in self: r.append(repr(cookie)) + return "<%s[%s]>" % (self.__class__, ", ".join(r)) + + def __str__(self): + r = [] + for cookie in self: r.append(str(cookie)) + return "<%s[%s]>" % (self.__class__, ", ".join(r)) + + +# derives from IOError for backwards-compatibility with Python 2.4.0 +class LoadError(IOError): pass + +class FileCookieJar(CookieJar): + """CookieJar that can be loaded from and saved to a file.""" + + def __init__(self, filename=None, delayload=False, policy=None): + """ + Cookies are NOT loaded from the named file until either the .load() or + .revert() method is called. + + """ + CookieJar.__init__(self, policy) + if filename is not None: + try: + filename+"" + except: + raise ValueError("filename must be string-like") + self.filename = filename + self.delayload = bool(delayload) + + def save(self, filename=None, ignore_discard=False, ignore_expires=False): + """Save cookies to a file.""" + raise NotImplementedError() + + def load(self, filename=None, ignore_discard=False, ignore_expires=False): + """Load cookies from a file.""" + if filename is None: + if self.filename is not None: filename = self.filename + else: raise ValueError(MISSING_FILENAME_TEXT) + + f = open(filename) + try: + self._really_load(f, filename, ignore_discard, ignore_expires) + finally: + f.close() + + def revert(self, filename=None, + ignore_discard=False, ignore_expires=False): + """Clear all cookies and reload cookies from a saved file. + + Raises LoadError (or IOError) if reversion is not successful; the + object's state will not be altered if this happens. + + """ + if filename is None: + if self.filename is not None: filename = self.filename + else: raise ValueError(MISSING_FILENAME_TEXT) + + self._cookies_lock.acquire() + try: + + old_state = copy.deepcopy(self._cookies) + self._cookies = {} + try: + self.load(filename, ignore_discard, ignore_expires) + except (LoadError, IOError): + self._cookies = old_state + raise + + finally: + self._cookies_lock.release() + +from _LWPCookieJar import LWPCookieJar, lwp_cookie_str +from _MozillaCookieJar import MozillaCookieJar diff --git a/src/main/resources/PythonLibs/copy.py b/src/main/resources/PythonLibs/copy.py new file mode 100644 index 0000000000000000000000000000000000000000..c227a2e5c7cb740230652b5b871c74367b6b370d --- /dev/null +++ b/src/main/resources/PythonLibs/copy.py @@ -0,0 +1,433 @@ +"""Generic (shallow and deep) copying operations. + +Interface summary: + + import copy + + x = copy.copy(y) # make a shallow copy of y + x = copy.deepcopy(y) # make a deep copy of y + +For module specific errors, copy.Error is raised. + +The difference between shallow and deep copying is only relevant for +compound objects (objects that contain other objects, like lists or +class instances). + +- A shallow copy constructs a new compound object and then (to the + extent possible) inserts *the same objects* into it that the + original contains. + +- A deep copy constructs a new compound object and then, recursively, + inserts *copies* into it of the objects found in the original. + +Two problems often exist with deep copy operations that don't exist +with shallow copy operations: + + a) recursive objects (compound objects that, directly or indirectly, + contain a reference to themselves) may cause a recursive loop + + b) because deep copy copies *everything* it may copy too much, e.g. + administrative data structures that should be shared even between + copies + +Python's deep copy operation avoids these problems by: + + a) keeping a table of objects already copied during the current + copying pass + + b) letting user-defined classes override the copying operation or the + set of components copied + +This version does not copy types like module, class, function, method, +nor stack trace, stack frame, nor file, socket, window, nor array, nor +any similar types. + +Classes can use the same interfaces to control copying that they use +to control pickling: they can define methods called __getinitargs__(), +__getstate__() and __setstate__(). See the documentation for module +"pickle" for information on these methods. +""" + +import types +import weakref +from copy_reg import dispatch_table + +class Error(Exception): + pass +error = Error # backward compatibility + +try: + from org.python.core import PyStringMap +except ImportError: + PyStringMap = None + +__all__ = ["Error", "copy", "deepcopy"] + +def copy(x): + """Shallow copy operation on arbitrary Python objects. + + See the module's __doc__ string for more info. + """ + + cls = type(x) + + copier = _copy_dispatch.get(cls) + if copier: + return copier(x) + + copier = getattr(cls, "__copy__", None) + if copier: + return copier(x) + + reductor = dispatch_table.get(cls) + if reductor: + rv = reductor(x) + else: + reductor = getattr(x, "__reduce_ex__", None) + if reductor: + rv = reductor(2) + else: + reductor = getattr(x, "__reduce__", None) + if reductor: + rv = reductor() + else: + raise Error("un(shallow)copyable object of type %s" % cls) + + return _reconstruct(x, rv, 0) + + +_copy_dispatch = d = {} + +def _copy_immutable(x): + return x +for t in (type(None), int, long, float, bool, str, tuple, + frozenset, type, xrange, types.ClassType, + types.BuiltinFunctionType, type(Ellipsis), + types.FunctionType, weakref.ref): + d[t] = _copy_immutable +for name in ("ComplexType", "UnicodeType", "CodeType"): + t = getattr(types, name, None) + if t is not None: + d[t] = _copy_immutable + +def _copy_with_constructor(x): + return type(x)(x) +for t in (list, dict, set): + d[t] = _copy_with_constructor + +def _copy_with_copy_method(x): + return x.copy() +if PyStringMap is not None: + d[PyStringMap] = _copy_with_copy_method + +def _copy_inst(x): + if hasattr(x, '__copy__'): + return x.__copy__() + if hasattr(x, '__getinitargs__'): + args = x.__getinitargs__() + y = x.__class__(*args) + else: + y = _EmptyClass() + y.__class__ = x.__class__ + if hasattr(x, '__getstate__'): + state = x.__getstate__() + else: + state = x.__dict__ + if hasattr(y, '__setstate__'): + y.__setstate__(state) + else: + y.__dict__.update(state) + return y +d[types.InstanceType] = _copy_inst + +del d + +def deepcopy(x, memo=None, _nil=[]): + """Deep copy operation on arbitrary Python objects. + + See the module's __doc__ string for more info. + """ + + if memo is None: + memo = {} + + d = id(x) + y = memo.get(d, _nil) + if y is not _nil: + return y + + cls = type(x) + + copier = _deepcopy_dispatch.get(cls) + if copier: + y = copier(x, memo) + else: + try: + issc = issubclass(cls, type) + except TypeError: # cls is not a class (old Boost; see SF #502085) + issc = 0 + if issc: + y = _deepcopy_atomic(x, memo) + else: + copier = getattr(x, "__deepcopy__", None) + if copier: + y = copier(memo) + else: + reductor = dispatch_table.get(cls) + if reductor: + rv = reductor(x) + else: + reductor = getattr(x, "__reduce_ex__", None) + if reductor: + rv = reductor(2) + else: + reductor = getattr(x, "__reduce__", None) + if reductor: + rv = reductor() + else: + raise Error( + "un(deep)copyable object of type %s" % cls) + y = _reconstruct(x, rv, 1, memo) + + memo[d] = y + _keep_alive(x, memo) # Make sure x lives at least as long as d + return y + +_deepcopy_dispatch = d = {} + +def _deepcopy_atomic(x, memo): + return x +d[type(None)] = _deepcopy_atomic +d[type(Ellipsis)] = _deepcopy_atomic +d[int] = _deepcopy_atomic +d[long] = _deepcopy_atomic +d[float] = _deepcopy_atomic +d[bool] = _deepcopy_atomic +try: + d[complex] = _deepcopy_atomic +except NameError: + pass +d[str] = _deepcopy_atomic +try: + d[unicode] = _deepcopy_atomic +except NameError: + pass +try: + d[types.CodeType] = _deepcopy_atomic +except AttributeError: + pass +d[type] = _deepcopy_atomic +d[xrange] = _deepcopy_atomic +d[types.ClassType] = _deepcopy_atomic +d[types.BuiltinFunctionType] = _deepcopy_atomic +d[types.FunctionType] = _deepcopy_atomic +d[weakref.ref] = _deepcopy_atomic + +def _deepcopy_list(x, memo): + y = [] + memo[id(x)] = y + for a in x: + y.append(deepcopy(a, memo)) + return y +d[list] = _deepcopy_list + +def _deepcopy_tuple(x, memo): + y = [] + for a in x: + y.append(deepcopy(a, memo)) + d = id(x) + try: + return memo[d] + except KeyError: + pass + for i in range(len(x)): + if x[i] is not y[i]: + y = tuple(y) + break + else: + y = x + memo[d] = y + return y +d[tuple] = _deepcopy_tuple + +def _deepcopy_dict(x, memo): + y = {} + memo[id(x)] = y + for key, value in x.iteritems(): + y[deepcopy(key, memo)] = deepcopy(value, memo) + return y +d[dict] = _deepcopy_dict +if PyStringMap is not None: + d[PyStringMap] = _deepcopy_dict + +def _deepcopy_method(x, memo): # Copy instance methods + return type(x)(x.im_func, deepcopy(x.im_self, memo), x.im_class) +_deepcopy_dispatch[types.MethodType] = _deepcopy_method + +def _keep_alive(x, memo): + """Keeps a reference to the object x in the memo. + + Because we remember objects by their id, we have + to assure that possibly temporary objects are kept + alive by referencing them. + We store a reference at the id of the memo, which should + normally not be used unless someone tries to deepcopy + the memo itself... + """ + try: + memo[id(memo)].append(x) + except KeyError: + # aha, this is the first one :-) + memo[id(memo)]=[x] + +def _deepcopy_inst(x, memo): + if hasattr(x, '__deepcopy__'): + return x.__deepcopy__(memo) + if hasattr(x, '__getinitargs__'): + args = x.__getinitargs__() + args = deepcopy(args, memo) + y = x.__class__(*args) + else: + y = _EmptyClass() + y.__class__ = x.__class__ + memo[id(x)] = y + if hasattr(x, '__getstate__'): + state = x.__getstate__() + else: + state = x.__dict__ + state = deepcopy(state, memo) + if hasattr(y, '__setstate__'): + y.__setstate__(state) + else: + y.__dict__.update(state) + return y +d[types.InstanceType] = _deepcopy_inst + +def _reconstruct(x, info, deep, memo=None): + if isinstance(info, str): + return x + assert isinstance(info, tuple) + if memo is None: + memo = {} + n = len(info) + assert n in (2, 3, 4, 5) + callable, args = info[:2] + if n > 2: + state = info[2] + else: + state = {} + if n > 3: + listiter = info[3] + else: + listiter = None + if n > 4: + dictiter = info[4] + else: + dictiter = None + if deep: + args = deepcopy(args, memo) + y = callable(*args) + memo[id(x)] = y + + if state: + if deep: + state = deepcopy(state, memo) + if hasattr(y, '__setstate__'): + y.__setstate__(state) + else: + if isinstance(state, tuple) and len(state) == 2: + state, slotstate = state + else: + slotstate = None + if state is not None: + y.__dict__.update(state) + if slotstate is not None: + for key, value in slotstate.iteritems(): + setattr(y, key, value) + + if listiter is not None: + for item in listiter: + if deep: + item = deepcopy(item, memo) + y.append(item) + if dictiter is not None: + for key, value in dictiter: + if deep: + key = deepcopy(key, memo) + value = deepcopy(value, memo) + y[key] = value + return y + +del d + +del types + +# Helper for instance creation without calling __init__ +class _EmptyClass: + pass + +def _test(): + l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'], + {'abc': 'ABC'}, (), [], {}] + l1 = copy(l) + print l1==l + l1 = map(copy, l) + print l1==l + l1 = deepcopy(l) + print l1==l + class C: + def __init__(self, arg=None): + self.a = 1 + self.arg = arg + if __name__ == '__main__': + import sys + file = sys.argv[0] + else: + file = __file__ + self.fp = open(file) + self.fp.close() + def __getstate__(self): + return {'a': self.a, 'arg': self.arg} + def __setstate__(self, state): + for key, value in state.iteritems(): + setattr(self, key, value) + def __deepcopy__(self, memo=None): + new = self.__class__(deepcopy(self.arg, memo)) + new.a = self.a + return new + c = C('argument sketch') + l.append(c) + l2 = copy(l) + print l == l2 + print l + print l2 + l2 = deepcopy(l) + print l == l2 + print l + print l2 + l.append({l[1]: l, 'xyz': l[2]}) + l3 = copy(l) + import repr + print map(repr.repr, l) + print map(repr.repr, l1) + print map(repr.repr, l2) + print map(repr.repr, l3) + l3 = deepcopy(l) + import repr + print map(repr.repr, l) + print map(repr.repr, l1) + print map(repr.repr, l2) + print map(repr.repr, l3) + class odict(dict): + def __init__(self, d = {}): + self.a = 99 + dict.__init__(self, d) + def __setitem__(self, k, i): + dict.__setitem__(self, k, i) + self.a + o = odict({"A" : "B"}) + x = deepcopy(o) + print(o, x) + +if __name__ == '__main__': + _test() diff --git a/src/main/resources/PythonLibs/copy_reg.py b/src/main/resources/PythonLibs/copy_reg.py new file mode 100644 index 0000000000000000000000000000000000000000..db1715092c5dcd0eb1e1a22c0957ee04851b6076 --- /dev/null +++ b/src/main/resources/PythonLibs/copy_reg.py @@ -0,0 +1,201 @@ +"""Helper to provide extensibility for pickle/cPickle. + +This is only useful to add pickle support for extension types defined in +C, not for instances of user-defined classes. +""" + +from types import ClassType as _ClassType + +__all__ = ["pickle", "constructor", + "add_extension", "remove_extension", "clear_extension_cache"] + +dispatch_table = {} + +def pickle(ob_type, pickle_function, constructor_ob=None): + if type(ob_type) is _ClassType: + raise TypeError("copy_reg is not intended for use with classes") + + if not hasattr(pickle_function, '__call__'): + raise TypeError("reduction functions must be callable") + dispatch_table[ob_type] = pickle_function + + # The constructor_ob function is a vestige of safe for unpickling. + # There is no reason for the caller to pass it anymore. + if constructor_ob is not None: + constructor(constructor_ob) + +def constructor(object): + if not hasattr(object, '__call__'): + raise TypeError("constructors must be callable") + +# Example: provide pickling support for complex numbers. + +try: + complex +except NameError: + pass +else: + + def pickle_complex(c): + return complex, (c.real, c.imag) + + pickle(complex, pickle_complex, complex) + +# Support for pickling new-style objects + +def _reconstructor(cls, base, state): + if base is object: + obj = object.__new__(cls) + else: + obj = base.__new__(cls, state) + if base.__init__ != object.__init__: + base.__init__(obj, state) + return obj + +_HEAPTYPE = 1<<9 + +# Python code for object.__reduce_ex__ for protocols 0 and 1 + +def _reduce_ex(self, proto): + assert proto < 2 + for base in self.__class__.__mro__: + if hasattr(base, '__flags__') and not base.__flags__ & _HEAPTYPE: + break + else: + base = object # not really reachable + if base is object: + state = None + else: + if base is self.__class__: + raise TypeError, "can't pickle %s objects" % base.__name__ + state = base(self) + args = (self.__class__, base, state) + try: + getstate = self.__getstate__ + except AttributeError: + if getattr(self, "__slots__", None): + raise TypeError("a class that defines __slots__ without " + "defining __getstate__ cannot be pickled") + try: + dict = self.__dict__ + except AttributeError: + dict = None + else: + dict = getstate() + if dict: + return _reconstructor, args, dict + else: + return _reconstructor, args + +# Helper for __reduce_ex__ protocol 2 + +def __newobj__(cls, *args): + return cls.__new__(cls, *args) + +def _slotnames(cls): + """Return a list of slot names for a given class. + + This needs to find slots defined by the class and its bases, so we + can't simply return the __slots__ attribute. We must walk down + the Method Resolution Order and concatenate the __slots__ of each + class found there. (This assumes classes don't modify their + __slots__ attribute to misrepresent their slots after the class is + defined.) + """ + + # Get the value from a cache in the class if possible + names = cls.__dict__.get("__slotnames__") + if names is not None: + return names + + # Not cached -- calculate the value + names = [] + if not hasattr(cls, "__slots__"): + # This class has no slots + pass + else: + # Slots found -- gather slot names from all base classes + for c in cls.__mro__: + if "__slots__" in c.__dict__: + slots = c.__dict__['__slots__'] + # if class has a single slot, it can be given as a string + if isinstance(slots, basestring): + slots = (slots,) + for name in slots: + # special descriptors + if name in ("__dict__", "__weakref__"): + continue + # mangled names + elif name.startswith('__') and not name.endswith('__'): + names.append('_%s%s' % (c.__name__, name)) + else: + names.append(name) + + # Cache the outcome in the class if at all possible + try: + cls.__slotnames__ = names + except: + pass # But don't die if we can't + + return names + +# A registry of extension codes. This is an ad-hoc compression +# mechanism. Whenever a global reference to <module>, <name> is about +# to be pickled, the (<module>, <name>) tuple is looked up here to see +# if it is a registered extension code for it. Extension codes are +# universal, so that the meaning of a pickle does not depend on +# context. (There are also some codes reserved for local use that +# don't have this restriction.) Codes are positive ints; 0 is +# reserved. + +_extension_registry = {} # key -> code +_inverted_registry = {} # code -> key +_extension_cache = {} # code -> object +# Don't ever rebind those names: cPickle grabs a reference to them when +# it's initialized, and won't see a rebinding. + +def add_extension(module, name, code): + """Register an extension code.""" + code = int(code) + if not 1 <= code <= 0x7fffffff: + raise ValueError, "code out of range" + key = (module, name) + if (_extension_registry.get(key) == code and + _inverted_registry.get(code) == key): + return # Redundant registrations are benign + if key in _extension_registry: + raise ValueError("key %s is already registered with code %s" % + (key, _extension_registry[key])) + if code in _inverted_registry: + raise ValueError("code %s is already in use for key %s" % + (code, _inverted_registry[code])) + _extension_registry[key] = code + _inverted_registry[code] = key + +def remove_extension(module, name, code): + """Unregister an extension code. For testing only.""" + key = (module, name) + if (_extension_registry.get(key) != code or + _inverted_registry.get(code) != key): + raise ValueError("key %s is not registered with code %s" % + (key, code)) + del _extension_registry[key] + del _inverted_registry[code] + if code in _extension_cache: + del _extension_cache[code] + +def clear_extension_cache(): + _extension_cache.clear() + +# Standard extension code assignments + +# Reserved ranges + +# First Last Count Purpose +# 1 127 127 Reserved for Python standard library +# 128 191 64 Reserved for Zope +# 192 239 48 Reserved for 3rd parties +# 240 255 16 Reserved for private use (will never be assigned) +# 256 Inf Inf Reserved for future assignment + +# Extension codes are assigned by the Python Software Foundation. diff --git a/src/main/resources/PythonLibs/csv.py b/src/main/resources/PythonLibs/csv.py new file mode 100644 index 0000000000000000000000000000000000000000..984ed7e581b9a7ac15d47f4711081d06de1e67cf --- /dev/null +++ b/src/main/resources/PythonLibs/csv.py @@ -0,0 +1,451 @@ + +""" +csv.py - read/write/investigate CSV files +""" + +import re +from functools import reduce +from _csv import Error, __version__, writer, reader, register_dialect, \ + unregister_dialect, get_dialect, list_dialects, \ + field_size_limit, \ + QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \ + __doc__ +from _csv import Dialect as _Dialect + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +__all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", + "Error", "Dialect", "__doc__", "excel", "excel_tab", + "field_size_limit", "reader", "writer", + "register_dialect", "get_dialect", "list_dialects", "Sniffer", + "unregister_dialect", "__version__", "DictReader", "DictWriter" ] + +class Dialect: + """Describe an Excel dialect. + + This must be subclassed (see csv.excel). Valid attributes are: + delimiter, quotechar, escapechar, doublequote, skipinitialspace, + lineterminator, quoting. + + """ + _name = "" + _valid = False + # placeholders + delimiter = None + quotechar = None + escapechar = None + doublequote = None + skipinitialspace = None + lineterminator = None + quoting = None + + def __init__(self): + if self.__class__ != Dialect: + self._valid = True + self._validate() + + def _validate(self): + try: + _Dialect(self) + except TypeError, e: + # We do this for compatibility with py2.3 + raise Error(str(e)) + +class excel(Dialect): + """Describe the usual properties of Excel-generated CSV files.""" + delimiter = ',' + quotechar = '"' + doublequote = True + skipinitialspace = False + lineterminator = '\r\n' + quoting = QUOTE_MINIMAL +register_dialect("excel", excel) + +class excel_tab(excel): + """Describe the usual properties of Excel-generated TAB-delimited files.""" + delimiter = '\t' +register_dialect("excel-tab", excel_tab) + + +class DictReader: + def __init__(self, f, fieldnames=None, restkey=None, restval=None, + dialect="excel", *args, **kwds): + self._fieldnames = fieldnames # list of keys for the dict + self.restkey = restkey # key to catch long rows + self.restval = restval # default value for short rows + self.reader = reader(f, dialect, *args, **kwds) + self.dialect = dialect + self.line_num = 0 + + def __iter__(self): + return self + + @property + def fieldnames(self): + if self._fieldnames is None: + try: + self._fieldnames = self.reader.next() + except StopIteration: + pass + self.line_num = self.reader.line_num + return self._fieldnames + + @fieldnames.setter + def fieldnames(self, value): + self._fieldnames = value + + def next(self): + if self.line_num == 0: + # Used only for its side effect. + self.fieldnames + row = self.reader.next() + self.line_num = self.reader.line_num + + # unlike the basic reader, we prefer not to return blanks, + # because we will typically wind up with a dict full of None + # values + while row == []: + row = self.reader.next() + d = dict(zip(self.fieldnames, row)) + lf = len(self.fieldnames) + lr = len(row) + if lf < lr: + d[self.restkey] = row[lf:] + elif lf > lr: + for key in self.fieldnames[lr:]: + d[key] = self.restval + return d + + +class DictWriter: + def __init__(self, f, fieldnames, restval="", extrasaction="raise", + dialect="excel", *args, **kwds): + self.fieldnames = fieldnames # list of keys for the dict + self.restval = restval # for writing short dicts + if extrasaction.lower() not in ("raise", "ignore"): + raise ValueError, \ + ("extrasaction (%s) must be 'raise' or 'ignore'" % + extrasaction) + self.extrasaction = extrasaction + self.writer = writer(f, dialect, *args, **kwds) + + def writeheader(self): + header = dict(zip(self.fieldnames, self.fieldnames)) + self.writerow(header) + + def _dict_to_list(self, rowdict): + if self.extrasaction == "raise": + wrong_fields = [k for k in rowdict if k not in self.fieldnames] + if wrong_fields: + raise ValueError("dict contains fields not in fieldnames: " + + ", ".join(wrong_fields)) + return [rowdict.get(key, self.restval) for key in self.fieldnames] + + def writerow(self, rowdict): + return self.writer.writerow(self._dict_to_list(rowdict)) + + def writerows(self, rowdicts): + rows = [] + for rowdict in rowdicts: + rows.append(self._dict_to_list(rowdict)) + return self.writer.writerows(rows) + +# Guard Sniffer's type checking against builds that exclude complex() +try: + complex +except NameError: + complex = float + +class Sniffer: + ''' + "Sniffs" the format of a CSV file (i.e. delimiter, quotechar) + Returns a Dialect object. + ''' + def __init__(self): + # in case there is more than one possible delimiter + self.preferred = [',', '\t', ';', ' ', ':'] + + + def sniff(self, sample, delimiters=None): + """ + Returns a dialect (or None) corresponding to the sample + """ + + quotechar, doublequote, delimiter, skipinitialspace = \ + self._guess_quote_and_delimiter(sample, delimiters) + if not delimiter: + delimiter, skipinitialspace = self._guess_delimiter(sample, + delimiters) + + if not delimiter: + raise Error, "Could not determine delimiter" + + class dialect(Dialect): + _name = "sniffed" + lineterminator = '\r\n' + quoting = QUOTE_MINIMAL + # escapechar = '' + + dialect.doublequote = doublequote + dialect.delimiter = delimiter + # _csv.reader won't accept a quotechar of '' + dialect.quotechar = quotechar or '"' + dialect.skipinitialspace = skipinitialspace + + return dialect + + + def _guess_quote_and_delimiter(self, data, delimiters): + """ + Looks for text enclosed between two identical quotes + (the probable quotechar) which are preceded and followed + by the same character (the probable delimiter). + For example: + ,'some text', + The quote with the most wins, same with the delimiter. + If there is no quotechar the delimiter can't be determined + this way. + """ + + matches = [] + for restr in ('(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', # ,".*?", + '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\w\n"\'])(?P<space> ?)', # ".*?", + '(?P<delim>>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)', # ,".*?" + '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'): # ".*?" (no delim, no space) + regexp = re.compile(restr, re.DOTALL | re.MULTILINE) + matches = regexp.findall(data) + if matches: + break + + if not matches: + # (quotechar, doublequote, delimiter, skipinitialspace) + return ('', False, None, 0) + quotes = {} + delims = {} + spaces = 0 + for m in matches: + n = regexp.groupindex['quote'] - 1 + key = m[n] + if key: + quotes[key] = quotes.get(key, 0) + 1 + try: + n = regexp.groupindex['delim'] - 1 + key = m[n] + except KeyError: + continue + if key and (delimiters is None or key in delimiters): + delims[key] = delims.get(key, 0) + 1 + try: + n = regexp.groupindex['space'] - 1 + except KeyError: + continue + if m[n]: + spaces += 1 + + quotechar = reduce(lambda a, b, quotes = quotes: + (quotes[a] > quotes[b]) and a or b, quotes.keys()) + + if delims: + delim = reduce(lambda a, b, delims = delims: + (delims[a] > delims[b]) and a or b, delims.keys()) + skipinitialspace = delims[delim] == spaces + if delim == '\n': # most likely a file with a single column + delim = '' + else: + # there is *no* delimiter, it's a single column of quoted data + delim = '' + skipinitialspace = 0 + + # if we see an extra quote between delimiters, we've got a + # double quoted format + dq_regexp = re.compile(r"((%(delim)s)|^)\W*%(quote)s[^%(delim)s\n]*%(quote)s[^%(delim)s\n]*%(quote)s\W*((%(delim)s)|$)" % \ + {'delim':delim, 'quote':quotechar}, re.MULTILINE) + + + + if dq_regexp.search(data): + doublequote = True + else: + doublequote = False + + return (quotechar, doublequote, delim, skipinitialspace) + + + def _guess_delimiter(self, data, delimiters): + """ + The delimiter /should/ occur the same number of times on + each row. However, due to malformed data, it may not. We don't want + an all or nothing approach, so we allow for small variations in this + number. + 1) build a table of the frequency of each character on every line. + 2) build a table of frequencies of this frequency (meta-frequency?), + e.g. 'x occurred 5 times in 10 rows, 6 times in 1000 rows, + 7 times in 2 rows' + 3) use the mode of the meta-frequency to determine the /expected/ + frequency for that character + 4) find out how often the character actually meets that goal + 5) the character that best meets its goal is the delimiter + For performance reasons, the data is evaluated in chunks, so it can + try and evaluate the smallest portion of the data possible, evaluating + additional chunks as necessary. + """ + + data = filter(None, data.split('\n')) + + ascii = [chr(c) for c in range(127)] # 7-bit ASCII + + # build frequency tables + chunkLength = min(10, len(data)) + iteration = 0 + charFrequency = {} + modes = {} + delims = {} + start, end = 0, min(chunkLength, len(data)) + while start < len(data): + iteration += 1 + for line in data[start:end]: + for char in ascii: + metaFrequency = charFrequency.get(char, {}) + # must count even if frequency is 0 + freq = line.count(char) + # value is the mode + metaFrequency[freq] = metaFrequency.get(freq, 0) + 1 + charFrequency[char] = metaFrequency + + for char in charFrequency.keys(): + items = charFrequency[char].items() + if len(items) == 1 and items[0][0] == 0: + continue + # get the mode of the frequencies + if len(items) > 1: + modes[char] = reduce(lambda a, b: a[1] > b[1] and a or b, + items) + # adjust the mode - subtract the sum of all + # other frequencies + items.remove(modes[char]) + modes[char] = (modes[char][0], modes[char][1] + - reduce(lambda a, b: (0, a[1] + b[1]), + items)[1]) + else: + modes[char] = items[0] + + # build a list of possible delimiters + modeList = modes.items() + total = float(chunkLength * iteration) + # (rows of consistent data) / (number of rows) = 100% + consistency = 1.0 + # minimum consistency threshold + threshold = 0.9 + while len(delims) == 0 and consistency >= threshold: + for k, v in modeList: + if v[0] > 0 and v[1] > 0: + if ((v[1]/total) >= consistency and + (delimiters is None or k in delimiters)): + delims[k] = v + consistency -= 0.01 + + if len(delims) == 1: + delim = delims.keys()[0] + skipinitialspace = (data[0].count(delim) == + data[0].count("%c " % delim)) + return (delim, skipinitialspace) + + # analyze another chunkLength lines + start = end + end += chunkLength + + if not delims: + return ('', 0) + + # if there's more than one, fall back to a 'preferred' list + if len(delims) > 1: + for d in self.preferred: + if d in delims.keys(): + skipinitialspace = (data[0].count(d) == + data[0].count("%c " % d)) + return (d, skipinitialspace) + + # nothing else indicates a preference, pick the character that + # dominates(?) + items = [(v,k) for (k,v) in delims.items()] + items.sort() + delim = items[-1][1] + + skipinitialspace = (data[0].count(delim) == + data[0].count("%c " % delim)) + return (delim, skipinitialspace) + + + def has_header(self, sample): + # Creates a dictionary of types of data in each column. If any + # column is of a single type (say, integers), *except* for the first + # row, then the first row is presumed to be labels. If the type + # can't be determined, it is assumed to be a string in which case + # the length of the string is the determining factor: if all of the + # rows except for the first are the same length, it's a header. + # Finally, a 'vote' is taken at the end for each column, adding or + # subtracting from the likelihood of the first row being a header. + + rdr = reader(StringIO(sample), self.sniff(sample)) + + header = rdr.next() # assume first row is header + + columns = len(header) + columnTypes = {} + for i in range(columns): columnTypes[i] = None + + checked = 0 + for row in rdr: + # arbitrary number of rows to check, to keep it sane + if checked > 20: + break + checked += 1 + + if len(row) != columns: + continue # skip rows that have irregular number of columns + + for col in columnTypes.keys(): + + for thisType in [int, long, float, complex]: + try: + thisType(row[col]) + break + except (ValueError, OverflowError): + pass + else: + # fallback to length of string + thisType = len(row[col]) + + # treat longs as ints + if thisType == long: + thisType = int + + if thisType != columnTypes[col]: + if columnTypes[col] is None: # add new column type + columnTypes[col] = thisType + else: + # type is inconsistent, remove column from + # consideration + del columnTypes[col] + + # finally, compare results against first row and "vote" + # on whether it's a header + hasHeader = 0 + for col, colType in columnTypes.items(): + if type(colType) == type(0): # it's a length + if len(header[col]) != colType: + hasHeader += 1 + else: + hasHeader -= 1 + else: # attempt typecast + try: + colType(header[col]) + except (ValueError, TypeError): + hasHeader += 1 + else: + hasHeader -= 1 + + return hasHeader > 0 diff --git a/src/main/resources/PythonLibs/ctypes/__init__.py b/src/main/resources/PythonLibs/ctypes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c153bdc1e1e98f73b63fb1b42c37e3e377f91599 --- /dev/null +++ b/src/main/resources/PythonLibs/ctypes/__init__.py @@ -0,0 +1,291 @@ +import jffi + +__version__ = "0.0.1" + +_TypeMap = { + 'b': jffi.Type.BYTE, + 'B': jffi.Type.UBYTE, + 'h': jffi.Type.SHORT, + 'H': jffi.Type.USHORT, + 'i': jffi.Type.INT, + 'I': jffi.Type.UINT, + 'l': jffi.Type.LONG, + 'L': jffi.Type.ULONG, + 'q': jffi.Type.LONGLONG, + 'Q': jffi.Type.ULONGLONG, + 'f': jffi.Type.FLOAT, + 'd': jffi.Type.DOUBLE, + '?': jffi.Type.BOOL, + 'z': jffi.Type.STRING, + 'P': jffi.Type.POINTER +} + +class _CTypeMetaClass(type): + + def __new__(cls, name, bases, dict): + return type.__new__(cls, name, bases, dict) + + def __mul__(self, len): + dict = { '_jffi_type': jffi.Type.Array(self, len) } + + # Look back up the stack frame to find out the module this new type is declared in + import inspect + mod = inspect.getmodule(inspect.stack()[1][0]) + if mod is None: + name = "__main__" + else: + name = mod.__name__ + dict["__module__"] = name + return type("%s_Array_%d" % (self.__name__, len), (jffi.ArrayCData, _ArrayCData, _CData), dict) + +class _CData(object): + @classmethod + def in_dll(self, lib, name): + return self.from_address(lib[name]) + + @classmethod + def size(self): + return self._jffi_type.size() + +class _ScalarCData(jffi.ScalarCData, _CData): + __metaclass__ = _CTypeMetaClass + + +class _ArrayCData(object): + def __len__(self): + return self._jffi_type.length + +class _StructLayoutBuilder(object): + def __init__(self, union = False): + self.size = 0 + self.offset = 0 + self.fields = [] + self.union = union + + def align(self, offset, align): + return align + ((offset - 1) & ~(align - 1)); + + def add_fields(self, fields): + for f in fields: + self.add_field(f) + return self + + def add_field(self, f): + if not issubclass(f[1], _ScalarCData): + raise RuntimeError("non-scalar fields not supported") + + if len(f) != 2: + raise RuntimeError("structs with bitfields not supported") + + self.offset = self.align(self.offset, alignment(f[1])) + self.fields.append(jffi.StructLayout.ScalarField(f[0], f[1], self.offset)) + if not self.union: + self.offset += sizeof(f[1]) + self.size = max(self.offset, sizeof(f[1])) + + return self + + def build(self): + return jffi.StructLayout(fields = self.fields, union = self.union) + +class _AggregateMetaClass(type): + @staticmethod + def __new_aggregate__(cls, name, bases, dict, union = False): + if dict.has_key('_fields_'): + layout = dict['_jffi_type'] = _StructLayoutBuilder(union).add_fields(dict['_fields_']).build() + # make all fields accessible via .foo + for f in dict['_fields_']: + dict[f[0]] = layout[f[0]] + dict['__fields_'] = dict['_fields_'] + else: + dict['__fields_'] = [] + if dict.has_key('_pack_'): + raise NotImplementedError("struct packing not implemented") + if dict.has_key('_anonymous_'): + raise NotImplementedError("anonymous fields not implemented") + + return type.__new__(cls, name, bases, dict) + + def get_fields(self): + return self.__fields_ + + def set_fields(self, fields): + layout = _StructLayoutBuilder(union = issubclass(Union, self)).add_fields(fields).build() + self.__fields_ = fields + self._jffi_type = layout + # make all fields accessible via .foo + for f in fields: + setattr(self, f[0], layout[f[0]]) + + _fields_ = property(get_fields, set_fields) + # Make _pack_ and _anonymous_ throw errors if anyone tries to use them + _pack_ = property(None) + _anonymous_ = property(None) + +class _StructMetaClass(_AggregateMetaClass): + def __new__(cls, name, bases, dict): + return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = False) + +class _UnionMetaClass(_AggregateMetaClass): + def __new__(cls, name, bases, dict): + return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = True) + +class Structure(jffi.Structure, _CData): + __metaclass__ = _StructMetaClass + +class Union(jffi.Structure, _CData): + __metaclass__ = _UnionMetaClass + +def sizeof(type): + if hasattr(type, '_jffi_type'): + return type._jffi_type.size() + else: + raise TypeError("this type has no size") + +def alignment(type): + return type._jffi_type.alignment() + +def addressof(cdata): + return cdata.address() + +def byref(cdata, offset = 0): + return cdata.byref(offset) + +def pointer(cdata): + return cdata.pointer(POINTER(cdata.__class__)) + +memmove = jffi.memmove +memset = jffi.memset + +_pointer_type_cache = {} +def POINTER(ctype): + # If a pointer class for the C type has been created, re-use it + if _pointer_type_cache.has_key(ctype): + return _pointer_type_cache[ctype] + + # Create a new class for this particular C type + dict = { '_jffi_type': jffi.Type.Pointer(ctype) } + # Look back up the stack frame to find out the module this new type is declared in + import inspect + mod = inspect.getmodule(inspect.stack()[1][0]) + if mod is None: + name = "__main__" + else: + name = mod.__name__ + dict["__module__"] = name + + ptype = type("LP_%s" % (ctype.__name__,), (jffi.PointerCData, _CData), dict) + _pointer_type_cache[ctype] = ptype + return ptype + +class c_bool(_ScalarCData): + _type_ = '?' + _jffi_type = jffi.Type.BOOL + +class c_byte(_ScalarCData): + _type_ = 'b' + _jffi_type = jffi.Type.BYTE + +class c_ubyte(_ScalarCData): + _type_ = 'B' + _jffi_type = jffi.Type.UBYTE + +class c_short(_ScalarCData): + _type_ = 'h' + _jffi_type = jffi.Type.SHORT + +class c_ushort(_ScalarCData): + _type_ = 'H' + _jffi_type = jffi.Type.USHORT + +class c_int(_ScalarCData): + _type_ = 'i' + _jffi_type = jffi.Type.INT + +class c_uint(_ScalarCData): + _type_ = 'I' + _jffi_type = jffi.Type.UINT + +class c_longlong(_ScalarCData): + _type_ = 'q' + _jffi_type = jffi.Type.LONGLONG + +class c_ulonglong(_ScalarCData): + _type_ = 'Q' + _jffi_type = jffi.Type.ULONGLONG + +class c_long(_ScalarCData): + _type_ = 'l' + _jffi_type = jffi.Type.LONG + +class c_ulong(_ScalarCData): + _type_ = 'L' + _jffi_type = jffi.Type.ULONG + +class c_float(_ScalarCData): + _type_ = 'f' + _jffi_type = jffi.Type.FLOAT + +class c_double(_ScalarCData): + _type_ = 'd' + _jffi_type = jffi.Type.DOUBLE + +c_int8 = c_byte +c_uint8 = c_ubyte +c_int16 = c_short +c_uint16 = c_ushort +c_int32 = c_int +c_uint32 = c_uint +c_int64 = c_longlong +c_uint64 = c_ulonglong + +c_size_t = c_ulong +c_ssize_t = c_long + +class c_char_p(jffi.StringCData, _CData): + _type_ = 'z' + _jffi_type = jffi.Type.STRING + +class c_void_p(_ScalarCData): + _type_ = 'P' + _jffi_type = jffi.Type.POINTER + +class _Function(jffi.Function): + _restype = c_int + _argtypes = None + + +class CDLL: + DEFAULT_MODE = jffi.RTLD_GLOBAL | jffi.RTLD_LAZY + + def __init__(self, name, mode = DEFAULT_MODE, handle = None): + self._handle = jffi.dlopen(name, mode) + + 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): + return _Function(self._handle.find_symbol(name)) + +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) diff --git a/src/main/resources/PythonLibs/datetime.py b/src/main/resources/PythonLibs/datetime.py new file mode 100644 index 0000000000000000000000000000000000000000..894f941390e20d24fd930d5a9aeaf2fb93a47987 --- /dev/null +++ b/src/main/resources/PythonLibs/datetime.py @@ -0,0 +1,2074 @@ +"""Concrete date/time and related types -- prototype implemented in Python. + +See http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage + +See also http://dir.yahoo.com/Reference/calendars/ + +For a primer on DST, including many current DST rules, see +http://webexhibits.org/daylightsaving/ + +For more about DST than you ever wanted to know, see +ftp://elsie.nci.nih.gov/pub/ + +Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm + +This was originally copied from the sandbox of the CPython CVS repository. +Thanks to Tim Peters for suggesting using it. +""" + +import time as _time +import math as _math +import sys as _sys + +if _sys.platform.startswith('java'): + from java.lang import Object + from java.sql import Date, Timestamp, Time + from java.util import Calendar + from org.python.core import Py + + +MINYEAR = 1 +MAXYEAR = 9999 + +# Utility functions, adapted from Python's Demo/classes/Dates.py, which +# also assumes the current Gregorian calendar indefinitely extended in +# both directions. Difference: Dates.py calls January 1 of year 0 day +# number 1. The code here calls January 1 of year 1 day number 1. This is +# to match the definition of the "proleptic Gregorian" calendar in Dershowitz +# and Reingold's "Calendrical Calculations", where it's the base calendar +# for all computations. See the book for algorithms for converting between +# proleptic Gregorian ordinals and many other calendar systems. + +_DAYS_IN_MONTH = [None, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +_DAYS_BEFORE_MONTH = [None] +dbm = 0 +for dim in _DAYS_IN_MONTH[1:]: + _DAYS_BEFORE_MONTH.append(dbm) + dbm += dim +del dbm, dim + +def _is_leap(year): + "year -> 1 if leap year, else 0." + return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) + +def _days_in_year(year): + "year -> number of days in year (366 if a leap year, else 365)." + return 365 + _is_leap(year) + +def _days_before_year(year): + "year -> number of days before January 1st of year." + y = year - 1 + return y*365 + y//4 - y//100 + y//400 + +def _days_in_month(year, month): + "year, month -> number of days in that month in that year." + assert 1 <= month <= 12, month + if month == 2 and _is_leap(year): + return 29 + return _DAYS_IN_MONTH[month] + +def _days_before_month(year, month): + "year, month -> number of days in year preceeding first day of month." + if not 1 <= month <= 12: + raise ValueError('month must be in 1..12', month) + return _DAYS_BEFORE_MONTH[month] + (month > 2 and _is_leap(year)) + +def _ymd2ord(year, month, day): + "year, month, day -> ordinal, considering 01-Jan-0001 as day 1." + if not 1 <= month <= 12: + raise ValueError('month must be in 1..12', month) + dim = _days_in_month(year, month) + if not 1 <= day <= dim: + raise ValueError('day must be in 1..%d' % dim, day) + return (_days_before_year(year) + + _days_before_month(year, month) + + day) + +_DI400Y = _days_before_year(401) # number of days in 400 years +_DI100Y = _days_before_year(101) # " " " " 100 " +_DI4Y = _days_before_year(5) # " " " " 4 " + +# A 4-year cycle has an extra leap day over what we'd get from pasting +# together 4 single years. +assert _DI4Y == 4 * 365 + 1 + +# Similarly, a 400-year cycle has an extra leap day over what we'd get from +# pasting together 4 100-year cycles. +assert _DI400Y == 4 * _DI100Y + 1 + +# OTOH, a 100-year cycle has one fewer leap day than we'd get from +# pasting together 25 4-year cycles. +assert _DI100Y == 25 * _DI4Y - 1 + +def _ord2ymd(n): + "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1." + + # n is a 1-based index, starting at 1-Jan-1. The pattern of leap years + # repeats exactly every 400 years. The basic strategy is to find the + # closest 400-year boundary at or before n, then work with the offset + # from that boundary to n. Life is much clearer if we subtract 1 from + # n first -- then the values of n at 400-year boundaries are exactly + # those divisible by _DI400Y: + # + # D M Y n n-1 + # -- --- ---- ---------- ---------------- + # 31 Dec -400 -_DI400Y -_DI400Y -1 + # 1 Jan -399 -_DI400Y +1 -_DI400Y 400-year boundary + # ... + # 30 Dec 000 -1 -2 + # 31 Dec 000 0 -1 + # 1 Jan 001 1 0 400-year boundary + # 2 Jan 001 2 1 + # 3 Jan 001 3 2 + # ... + # 31 Dec 400 _DI400Y _DI400Y -1 + # 1 Jan 401 _DI400Y +1 _DI400Y 400-year boundary + n -= 1 + n400, n = divmod(n, _DI400Y) + year = n400 * 400 + 1 # ..., -399, 1, 401, ... + + # Now n is the (non-negative) offset, in days, from January 1 of year, to + # the desired date. Now compute how many 100-year cycles precede n. + # Note that it's possible for n100 to equal 4! In that case 4 full + # 100-year cycles precede the desired day, which implies the desired + # day is December 31 at the end of a 400-year cycle. + n100, n = divmod(n, _DI100Y) + + # Now compute how many 4-year cycles precede it. + n4, n = divmod(n, _DI4Y) + + # And now how many single years. Again n1 can be 4, and again meaning + # that the desired day is December 31 at the end of the 4-year cycle. + n1, n = divmod(n, 365) + + year += n100 * 100 + n4 * 4 + n1 + if n1 == 4 or n100 == 4: + assert n == 0 + return year-1, 12, 31 + + # Now the year is correct, and n is the offset from January 1. We find + # the month via an estimate that's either exact or one too large. + leapyear = n1 == 3 and (n4 != 24 or n100 == 3) + assert leapyear == _is_leap(year) + month = (n + 50) >> 5 + preceding = _DAYS_BEFORE_MONTH[month] + (month > 2 and leapyear) + if preceding > n: # estimate is too large + month -= 1 + preceding -= _DAYS_IN_MONTH[month] + (month == 2 and leapyear) + n -= preceding + assert 0 <= n < _days_in_month(year, month) + + # Now the year and month are correct, and n is the offset from the + # start of that month: we're done! + return year, month, n+1 + +# Month and day names. For localized versions, see the calendar module. +_MONTHNAMES = [None, "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] +_DAYNAMES = [None, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] + + +def _build_struct_time(y, m, d, hh, mm, ss, dstflag): + wday = (_ymd2ord(y, m, d) + 6) % 7 + dnum = _days_before_month(y, m) + d + return _time.struct_time((y, m, d, hh, mm, ss, wday, dnum, dstflag)) + +def _format_time(hh, mm, ss, us): + # Skip trailing microseconds when us==0. + result = "%02d:%02d:%02d" % (hh, mm, ss) + if us: + result += ".%06d" % us + return result + +# Correctly substitute for %z and %Z escapes in strftime formats. +def _wrap_strftime(object, format, timetuple): + year = timetuple[0] + if year < 1900: + raise ValueError("year=%d is before 1900; the datetime strftime() " + "methods require year >= 1900" % year) + # Don't call _utcoffset() or tzname() unless actually needed. + zreplace = None # the string to use for %z + Zreplace = None # the string to use for %Z + + # Scan format for %z and %Z escapes, replacing as needed. + newformat = [] + push = newformat.append + i, n = 0, len(format) + while i < n: + ch = format[i] + i += 1 + if ch == '%': + if i < n: + ch = format[i] + i += 1 + if ch == 'z': + if zreplace is None: + zreplace = "" + if hasattr(object, "_utcoffset"): + offset = object._utcoffset() + if offset is not None: + sign = '+' + if offset < 0: + offset = -offset + sign = '-' + h, m = divmod(offset, 60) + zreplace = '%c%02d%02d' % (sign, h, m) + assert '%' not in zreplace + newformat.append(zreplace) + elif ch == 'Z': + if Zreplace is None: + Zreplace = "" + if hasattr(object, "tzname"): + s = object.tzname() + if s is not None: + # strftime is going to have at this: escape % + Zreplace = s.replace('%', '%%') + newformat.append(Zreplace) + else: + push('%') + push(ch) + else: + push('%') + else: + push(ch) + newformat = "".join(newformat) + return _time.strftime(newformat, timetuple) + +def _call_tzinfo_method(tzinfo, methname, tzinfoarg): + if tzinfo is None: + return None + return getattr(tzinfo, methname)(tzinfoarg) + +# Just raise TypeError if the arg isn't None or a string. +def _check_tzname(name): + if name is not None and not isinstance(name, str): + raise TypeError("tzinfo.tzname() must return None or string, " + "not '%s'" % type(name)) + +# name is the offset-producing method, "utcoffset" or "dst". +# offset is what it returned. +# If offset isn't None or timedelta, raises TypeError. +# If offset is None, returns None. +# Else offset is checked for being in range, and a whole # of minutes. +# If it is, its integer value is returned. Else ValueError is raised. +def _check_utc_offset(name, offset): + assert name in ("utcoffset", "dst") + if offset is None: + return None + if not isinstance(offset, timedelta): + raise TypeError("tzinfo.%s() must return None " + "or timedelta, not '%s'" % (name, type(offset))) + days = offset.days + if days < -1 or days > 0: + offset = 1440 # trigger out-of-range + else: + seconds = days * 86400 + offset.seconds + minutes, seconds = divmod(seconds, 60) + if seconds or offset.microseconds: + raise ValueError("tzinfo.%s() must return a whole number " + "of minutes" % name) + offset = minutes + if -1440 < offset < 1440: + return offset + raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset)) + +def _check_date_fields(year, month, day): + if not MINYEAR <= year <= MAXYEAR: + raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) + if not 1 <= month <= 12: + raise ValueError('month must be in 1..12', month) + dim = _days_in_month(year, month) + if not 1 <= day <= dim: + raise ValueError('day must be in 1..%d' % dim, day) + +def _check_time_fields(hour, minute, second, microsecond): + if not 0 <= hour <= 23: + raise ValueError('hour must be in 0..23', hour) + if not 0 <= minute <= 59: + raise ValueError('minute must be in 0..59', minute) + if not 0 <= second <= 59: + raise ValueError('second must be in 0..59', second) + if not 0 <= microsecond <= 999999: + raise ValueError('microsecond must be in 0..999999', microsecond) + +def _check_tzinfo_arg(tz): + if tz is not None and not isinstance(tz, tzinfo): + raise TypeError("tzinfo argument must be None or of a tzinfo subclass") + + +# Notes on comparison: In general, datetime module comparison operators raise +# TypeError when they don't know how to do a comparison themself. If they +# returned NotImplemented instead, comparison could (silently) fall back to +# the default compare-objects-by-comparing-their-memory-addresses strategy, +# and that's not helpful. There are two exceptions: +# +# 1. For date and datetime, if the other object has a "timetuple" attr, +# NotImplemented is returned. This is a hook to allow other kinds of +# datetime-like objects a chance to intercept the comparison. +# +# 2. Else __eq__ and __ne__ return False and True, respectively. This is +# so opertaions like +# +# x == y +# x != y +# x in sequence +# x not in sequence +# dict[x] = y +# +# don't raise annoying TypeErrors just because a datetime object +# is part of a heterogeneous collection. If there's no known way to +# compare X to a datetime, saying they're not equal is reasonable. + +def _cmperror(x, y): + raise TypeError("can't compare '%s' to '%s'" % ( + type(x).__name__, type(y).__name__)) + +# This is a start at a struct tm workalike. Goals: +# +# + Works the same way across platforms. +# + Handles all the fields datetime needs handled, without 1970-2038 glitches. +# +# Note: I suspect it's best if this flavor of tm does *not* try to +# second-guess timezones or DST. Instead fold whatever adjustments you want +# into the minutes argument (and the constructor will normalize). + +_ORD1970 = _ymd2ord(1970, 1, 1) # base ordinal for UNIX epoch + +class tmxxx: + + ordinal = None + + def __init__(self, year, month, day, hour=0, minute=0, second=0, + microsecond=0): + # Normalize all the inputs, and store the normalized values. + if not 0 <= microsecond <= 999999: + carry, microsecond = divmod(microsecond, 1000000) + second += carry + if not 0 <= second <= 59: + carry, second = divmod(second, 60) + minute += carry + if not 0 <= minute <= 59: + carry, minute = divmod(minute, 60) + hour += carry + if not 0 <= hour <= 23: + carry, hour = divmod(hour, 24) + day += carry + + # That was easy. Now it gets muddy: the proper range for day + # can't be determined without knowing the correct month and year, + # but if day is, e.g., plus or minus a million, the current month + # and year values make no sense (and may also be out of bounds + # themselves). + # Saying 12 months == 1 year should be non-controversial. + if not 1 <= month <= 12: + carry, month = divmod(month-1, 12) + year += carry + month += 1 + assert 1 <= month <= 12 + + # Now only day can be out of bounds (year may also be out of bounds + # for a datetime object, but we don't care about that here). + # If day is out of bounds, what to do is arguable, but at least the + # method here is principled and explainable. + dim = _days_in_month(year, month) + if not 1 <= day <= dim: + # Move day-1 days from the first of the month. First try to + # get off cheap if we're only one day out of range (adjustments + # for timezone alone can't be worse than that). + if day == 0: # move back a day + month -= 1 + if month > 0: + day = _days_in_month(year, month) + else: + year, month, day = year-1, 12, 31 + elif day == dim + 1: # move forward a day + month += 1 + day = 1 + if month > 12: + month = 1 + year += 1 + else: + self.ordinal = _ymd2ord(year, month, 1) + (day - 1) + year, month, day = _ord2ymd(self.ordinal) + + self.year, self.month, self.day = year, month, day + self.hour, self.minute, self.second = hour, minute, second + self.microsecond = microsecond + + def toordinal(self): + """Return proleptic Gregorian ordinal for the year, month and day. + + January 1 of year 1 is day 1. Only the year, month and day values + contribute to the result. + """ + if self.ordinal is None: + self.ordinal = _ymd2ord(self.year, self.month, self.day) + return self.ordinal + + def time(self): + "Return Unixish timestamp, as a float (assuming UTC)." + days = self.toordinal() - _ORD1970 # convert to UNIX epoch + seconds = ((days * 24. + self.hour)*60. + self.minute)*60. + return seconds + self.second + self.microsecond / 1e6 + + def ctime(self): + "Return ctime() style string." + weekday = self.toordinal() % 7 or 7 + return "%s %s %2d %02d:%02d:%02d %04d" % ( + _DAYNAMES[weekday], + _MONTHNAMES[self.month], + self.day, + self.hour, self.minute, self.second, + self.year) + +class timedelta(object): + """Represent the difference between two datetime objects. + + Supported operators: + + - add, subtract timedelta + - unary plus, minus, abs + - compare to timedelta + - multiply, divide by int/long + + In addition, datetime supports subtraction of two datetime objects + returning a timedelta, and addition or subtraction of a datetime + and a timedelta giving a datetime. + + Representation: (days, seconds, microseconds). Why? Because I + felt like it. + """ + + def __new__(cls, days=0, seconds=0, microseconds=0, + # XXX The following should only be used as keyword args: + milliseconds=0, minutes=0, hours=0, weeks=0): + # Doing this efficiently and accurately in C is going to be difficult + # and error-prone, due to ubiquitous overflow possibilities, and that + # C double doesn't have enough bits of precision to represent + # microseconds over 10K years faithfully. The code here tries to make + # explicit where go-fast assumptions can be relied on, in order to + # guide the C implementation; it's way more convoluted than speed- + # ignoring auto-overflow-to-long idiomatic Python could be. + + # XXX Check that all inputs are ints, longs or floats. + + # Final values, all integer. + # s and us fit in 32-bit signed ints; d isn't bounded. + d = s = us = 0 + + # Normalize everything to days, seconds, microseconds. + days += weeks*7 + seconds += minutes*60 + hours*3600 + microseconds += milliseconds*1000 + + # Get rid of all fractions, and normalize s and us. + # Take a deep breath <wink>. + if isinstance(days, float): + dayfrac, days = _math.modf(days) + daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.)) + assert daysecondswhole == int(daysecondswhole) # can't overflow + s = int(daysecondswhole) + assert days == long(days) + d = long(days) + else: + daysecondsfrac = 0.0 + d = days + assert isinstance(daysecondsfrac, float) + assert abs(daysecondsfrac) <= 1.0 + assert isinstance(d, (int, long)) + assert abs(s) <= 24 * 3600 + # days isn't referenced again before redefinition + + if isinstance(seconds, float): + secondsfrac, seconds = _math.modf(seconds) + assert seconds == long(seconds) + seconds = long(seconds) + secondsfrac += daysecondsfrac + assert abs(secondsfrac) <= 2.0 + else: + secondsfrac = daysecondsfrac + # daysecondsfrac isn't referenced again + assert isinstance(secondsfrac, float) + assert abs(secondsfrac) <= 2.0 + + assert isinstance(seconds, (int, long)) + days, seconds = divmod(seconds, 24*3600) + d += days + s += int(seconds) # can't overflow + assert isinstance(s, int) + assert abs(s) <= 2 * 24 * 3600 + # seconds isn't referenced again before redefinition + + usdouble = secondsfrac * 1e6 + assert abs(usdouble) < 2.1e6 # exact value not critical + # secondsfrac isn't referenced again + + if isinstance(microseconds, float): + microseconds += usdouble + microseconds = round(microseconds) + seconds, microseconds = divmod(microseconds, 1e6) + assert microseconds == int(microseconds) + assert seconds == long(seconds) + days, seconds = divmod(seconds, 24.*3600.) + assert days == long(days) + assert seconds == int(seconds) + d += long(days) + s += int(seconds) # can't overflow + assert isinstance(s, int) + assert abs(s) <= 3 * 24 * 3600 + else: + seconds, microseconds = divmod(microseconds, 1000000) + days, seconds = divmod(seconds, 24*3600) + d += days + s += int(seconds) # can't overflow + assert isinstance(s, int) + assert abs(s) <= 3 * 24 * 3600 + microseconds = float(microseconds) + microseconds += usdouble + microseconds = round(microseconds) + assert abs(s) <= 3 * 24 * 3600 + assert abs(microseconds) < 3.1e6 + + # Just a little bit of carrying possible for microseconds and seconds. + assert isinstance(microseconds, float) + assert int(microseconds) == microseconds + us = int(microseconds) + seconds, us = divmod(us, 1000000) + s += seconds # cant't overflow + assert isinstance(s, int) + days, s = divmod(s, 24*3600) + d += days + + assert isinstance(d, (int, long)) + assert isinstance(s, int) and 0 <= s < 24*3600 + assert isinstance(us, int) and 0 <= us < 1000000 + + self = object.__new__(cls) + + self.__days = d + self.__seconds = s + self.__microseconds = us + if abs(d) > 999999999: + raise OverflowError("timedelta # of days is too large: %d" % d) + + return self + + def __repr__(self): + if self.__microseconds: + return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__, + self.__days, + self.__seconds, + self.__microseconds) + if self.__seconds: + return "%s(%d, %d)" % ('datetime.' + self.__class__.__name__, + self.__days, + self.__seconds) + return "%s(%d)" % ('datetime.' + self.__class__.__name__, self.__days) + + def __str__(self): + mm, ss = divmod(self.__seconds, 60) + hh, mm = divmod(mm, 60) + s = "%d:%02d:%02d" % (hh, mm, ss) + if self.__days: + def plural(n): + return n, abs(n) != 1 and "s" or "" + s = ("%d day%s, " % plural(self.__days)) + s + if self.__microseconds: + s = s + ".%06d" % self.__microseconds + return s + + days = property(lambda self: self.__days, doc="days") + seconds = property(lambda self: self.__seconds, doc="seconds") + microseconds = property(lambda self: self.__microseconds, + doc="microseconds") + + def __add__(self, other): + if isinstance(other, timedelta): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self.__days + other.__days, + self.__seconds + other.__seconds, + self.__microseconds + other.__microseconds) + return NotImplemented + + __radd__ = __add__ + + def __sub__(self, other): + if isinstance(other, timedelta): + return self + -other + return NotImplemented + + def __rsub__(self, other): + if isinstance(other, timedelta): + return -self + other + return NotImplemented + + def __neg__(self): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(-self.__days, + -self.__seconds, + -self.__microseconds) + + def __pos__(self): + return self + + def __abs__(self): + if self.__days < 0: + return -self + else: + return self + + def __mul__(self, other): + if isinstance(other, (int, long)): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self.__days * other, + self.__seconds * other, + self.__microseconds * other) + return NotImplemented + + __rmul__ = __mul__ + + def __div__(self, other): + if isinstance(other, (int, long)): + usec = ((self.__days * (24*3600L) + self.__seconds) * 1000000 + + self.__microseconds) + return timedelta(0, 0, usec // other) + return NotImplemented + + __floordiv__ = __div__ + + # Comparisons. + + def __eq__(self, other): + if isinstance(other, timedelta): + return self.__cmp(other) == 0 + else: + return False + + def __ne__(self, other): + if isinstance(other, timedelta): + return self.__cmp(other) != 0 + else: + return True + + def __le__(self, other): + if isinstance(other, timedelta): + return self.__cmp(other) <= 0 + else: + _cmperror(self, other) + + def __lt__(self, other): + if isinstance(other, timedelta): + return self.__cmp(other) < 0 + else: + _cmperror(self, other) + + def __ge__(self, other): + if isinstance(other, timedelta): + return self.__cmp(other) >= 0 + else: + _cmperror(self, other) + + def __gt__(self, other): + if isinstance(other, timedelta): + return self.__cmp(other) > 0 + else: + _cmperror(self, other) + + def __cmp(self, other): + assert isinstance(other, timedelta) + return cmp(self.__getstate(), other.__getstate()) + + def __hash__(self): + return hash(self.__getstate()) + + def __nonzero__(self): + return (self.__days != 0 or + self.__seconds != 0 or + self.__microseconds != 0) + + # Pickle support. + + __safe_for_unpickling__ = True # For Python 2.2 + + def __getstate(self): + return (self.__days, self.__seconds, self.__microseconds) + + def __reduce__(self): + return (self.__class__, self.__getstate()) + +timedelta.min = timedelta(-999999999) +timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59, + microseconds=999999) +timedelta.resolution = timedelta(microseconds=1) + +class date(object): + """Concrete date type. + + Constructors: + + __new__() + fromtimestamp() + today() + fromordinal() + + Operators: + + __repr__, __str__ + __cmp__, __hash__ + __add__, __radd__, __sub__ (add/radd only with timedelta arg) + + Methods: + + timetuple() + toordinal() + weekday() + isoweekday(), isocalendar(), isoformat() + ctime() + strftime() + + Properties (readonly): + year, month, day + """ + + def __new__(cls, year, month=None, day=None): + """Constructor. + + Arguments: + + year, month, day (required, base 1) + """ + if isinstance(year, str): + # Pickle support + self = object.__new__(cls) + self.__setstate(year) + return self + _check_date_fields(year, month, day) + self = object.__new__(cls) + self.__year = year + self.__month = month + self.__day = day + return self + + # Additional constructors + + def fromtimestamp(cls, t): + "Construct a date from a POSIX timestamp (like time.time())." + y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) + return cls(y, m, d) + fromtimestamp = classmethod(fromtimestamp) + + def today(cls): + "Construct a date from time.time()." + t = _time.time() + return cls.fromtimestamp(t) + today = classmethod(today) + + def fromordinal(cls, n): + """Contruct a date from a proleptic Gregorian ordinal. + + January 1 of year 1 is day 1. Only the year, month and day are + non-zero in the result. + """ + y, m, d = _ord2ymd(n) + return cls(y, m, d) + fromordinal = classmethod(fromordinal) + + # Conversions to string + + def __repr__(self): + "Convert to formal string, for repr()." + return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__, + self.__year, + self.__month, + self.__day) + # XXX These shouldn't depend on time.localtime(), because that + # clips the usable dates to [1970 .. 2038). At least ctime() is + # easily done without using strftime() -- that's better too because + # strftime("%c", ...) is locale specific. + + def ctime(self): + "Format a la ctime()." + return tmxxx(self.__year, self.__month, self.__day).ctime() + + def strftime(self, fmt): + "Format using strftime()." + return _wrap_strftime(self, fmt, self.timetuple()) + + def isoformat(self): + """Return the date formatted according to ISO. + + This is 'YYYY-MM-DD'. + + References: + - http://www.w3.org/TR/NOTE-datetime + - http://www.cl.cam.ac.uk/~mgk25/iso-time.html + """ + return "%04d-%02d-%02d" % (self.__year, self.__month, self.__day) + + __str__ = isoformat + + # Read-only field accessors + year = property(lambda self: self.__year, + doc="year (%d-%d)" % (MINYEAR, MAXYEAR)) + month = property(lambda self: self.__month, doc="month (1-12)") + day = property(lambda self: self.__day, doc="day (1-31)") + + # Standard conversions, __cmp__, __hash__ (and helpers) + + def timetuple(self): + "Return local time tuple compatible with time.localtime()." + return _build_struct_time(self.__year, self.__month, self.__day, + 0, 0, 0, -1) + + def toordinal(self): + """Return proleptic Gregorian ordinal for the year, month and day. + + January 1 of year 1 is day 1. Only the year, month and day values + contribute to the result. + """ + return _ymd2ord(self.__year, self.__month, self.__day) + + def replace(self, year=None, month=None, day=None): + """Return a new date with new values for the specified fields.""" + if year is None: + year = self.__year + if month is None: + month = self.__month + if day is None: + day = self.__day + _check_date_fields(year, month, day) + return date(year, month, day) + + # Comparisons. + + def __eq__(self, other): + if isinstance(other, date): + return self.__cmp(other) == 0 + elif hasattr(other, "timetuple"): + return NotImplemented + else: + return False + + def __ne__(self, other): + if isinstance(other, date): + return self.__cmp(other) != 0 + elif hasattr(other, "timetuple"): + return NotImplemented + else: + return True + + def __le__(self, other): + if isinstance(other, date): + return self.__cmp(other) <= 0 + elif hasattr(other, "timetuple"): + return NotImplemented + else: + _cmperror(self, other) + + def __lt__(self, other): + if isinstance(other, date): + return self.__cmp(other) < 0 + elif hasattr(other, "timetuple"): + return NotImplemented + else: + _cmperror(self, other) + + def __ge__(self, other): + if isinstance(other, date): + return self.__cmp(other) >= 0 + elif hasattr(other, "timetuple"): + return NotImplemented + else: + _cmperror(self, other) + + def __gt__(self, other): + if isinstance(other, date): + return self.__cmp(other) > 0 + elif hasattr(other, "timetuple"): + return NotImplemented + else: + _cmperror(self, other) + + def __cmp(self, other): + assert isinstance(other, date) + y, m, d = self.__year, self.__month, self.__day + y2, m2, d2 = other.__year, other.__month, other.__day + return cmp((y, m, d), (y2, m2, d2)) + + def __hash__(self): + "Hash." + return hash(self.__getstate()) + + # Computations + + def _checkOverflow(self, year): + if not MINYEAR <= year <= MAXYEAR: + raise OverflowError("date +/-: result year %d not in %d..%d" % + (year, MINYEAR, MAXYEAR)) + + def __add__(self, other): + "Add a date to a timedelta." + if isinstance(other, timedelta): + t = tmxxx(self.__year, + self.__month, + self.__day + other.days) + self._checkOverflow(t.year) + result = date(t.year, t.month, t.day) + return result + raise TypeError + # XXX Should be 'return NotImplemented', but there's a bug in 2.2... + + __radd__ = __add__ + + def __sub__(self, other): + """Subtract two dates, or a date and a timedelta.""" + if isinstance(other, timedelta): + return self + timedelta(-other.days) + if isinstance(other, date): + days1 = self.toordinal() + days2 = other.toordinal() + return timedelta(days1 - days2) + return NotImplemented + + def weekday(self): + "Return day of the week, where Monday == 0 ... Sunday == 6." + return (self.toordinal() + 6) % 7 + + # Day-of-the-week and week-of-the-year, according to ISO + + def isoweekday(self): + "Return day of the week, where Monday == 1 ... Sunday == 7." + # 1-Jan-0001 is a Monday + return self.toordinal() % 7 or 7 + + def isocalendar(self): + """Return a 3-tuple containing ISO year, week number, and weekday. + + The first ISO week of the year is the (Mon-Sun) week + containing the year's first Thursday; everything else derives + from that. + + The first week is 1; Monday is 1 ... Sunday is 7. + + ISO calendar algorithm taken from + http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm + """ + year = self.__year + week1monday = _isoweek1monday(year) + today = _ymd2ord(self.__year, self.__month, self.__day) + # Internally, week and day have origin 0 + week, day = divmod(today - week1monday, 7) + if week < 0: + year -= 1 + week1monday = _isoweek1monday(year) + week, day = divmod(today - week1monday, 7) + elif week >= 52: + if today >= _isoweek1monday(year+1): + year += 1 + week = 0 + return year, week+1, day+1 + + # Pickle support. + + __safe_for_unpickling__ = True # For Python 2.2 + + def __getstate(self): + yhi, ylo = divmod(self.__year, 256) + return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) + + def __setstate(self, string): + if len(string) != 4 or not (1 <= ord(string[2]) <= 12): + raise TypeError("not enough arguments") + yhi, ylo, self.__month, self.__day = map(ord, string) + self.__year = yhi * 256 + ylo + + def __reduce__(self): + return (self.__class__, self.__getstate()) + + if _sys.platform.startswith('java'): + def __tojava__(self, java_class): + if java_class not in (Calendar, Date, Object): + return Py.NoConversion + + calendar = Calendar.getInstance() + calendar.clear() + calendar.set(self.year, self.month - 1, self.day) + if java_class == Calendar: + return calendar + else: + return Date(calendar.getTimeInMillis()) + + +_date_class = date # so functions w/ args named "date" can get at the class + +date.min = date(1, 1, 1) +date.max = date(9999, 12, 31) +date.resolution = timedelta(days=1) + +class tzinfo(object): + """Abstract base class for time zone info classes. + + Subclasses must override the name(), utcoffset() and dst() methods. + """ + + def tzname(self, dt): + "datetime -> string name of time zone." + raise NotImplementedError("tzinfo subclass must override tzname()") + + def utcoffset(self, dt): + "datetime -> minutes east of UTC (negative for west of UTC)" + raise NotImplementedError("tzinfo subclass must override utcoffset()") + + def dst(self, dt): + """datetime -> DST offset in minutes east of UTC. + + Return 0 if DST not in effect. utcoffset() must include the DST + offset. + """ + raise NotImplementedError("tzinfo subclass must override dst()") + + def fromutc(self, dt): + "datetime in UTC -> datetime in local time." + + if not isinstance(dt, datetime): + raise TypeError("fromutc() requires a datetime argument") + if dt.tzinfo is not self: + raise ValueError("dt.tzinfo is not self") + + dtoff = dt.utcoffset() + if dtoff is None: + raise ValueError("fromutc() requires a non-None utcoffset() " + "result") + + # See the long comment block at the end of this file for an + # explanation of this algorithm. + dtdst = dt.dst() + if dtdst is None: + raise ValueError("fromutc() requires a non-None dst() result") + delta = dtoff - dtdst + if delta: + dt += delta + dtdst = dt.dst() + if dtdst is None: + raise ValueError("fromutc(): dt.dst gave inconsistent " + "results; cannot convert") + if dtdst: + return dt + dtdst + else: + return dt + + # Pickle support. + + __safe_for_unpickling__ = True # For Python 2.2 + + def __reduce__(self): + getinitargs = getattr(self, "__getinitargs__", None) + if getinitargs: + args = getinitargs() + else: + args = () + getstate = getattr(self, "__getstate__", None) + if getstate: + state = getstate() + else: + state = getattr(self, "__dict__", None) or None + if state is None: + return (self.__class__, args) + else: + return (self.__class__, args, state) + +_tzinfo_class = tzinfo # so functions w/ args named "tinfo" can get at it + +class time(object): + """Time with time zone. + + Constructors: + + __new__() + + Operators: + + __repr__, __str__ + __cmp__, __hash__ + + Methods: + + strftime() + isoformat() + utcoffset() + tzname() + dst() + + Properties (readonly): + hour, minute, second, microsecond, tzinfo + """ + + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): + """Constructor. + + Arguments: + + hour, minute (required) + second, microsecond (default to zero) + tzinfo (default to None) + """ + self = object.__new__(cls) + if isinstance(hour, str): + # Pickle support + self.__setstate(hour, minute or None) + return self + _check_tzinfo_arg(tzinfo) + _check_time_fields(hour, minute, second, microsecond) + self.__hour = hour + self.__minute = minute + self.__second = second + self.__microsecond = microsecond + self._tzinfo = tzinfo + return self + + # Read-only field accessors + hour = property(lambda self: self.__hour, doc="hour (0-23)") + minute = property(lambda self: self.__minute, doc="minute (0-59)") + second = property(lambda self: self.__second, doc="second (0-59)") + microsecond = property(lambda self: self.__microsecond, + doc="microsecond (0-999999)") + tzinfo = property(lambda self: self._tzinfo, doc="timezone info object") + + # Standard conversions, __hash__ (and helpers) + + # Comparisons. + + def __eq__(self, other): + if isinstance(other, time): + return self.__cmp(other) == 0 + else: + return False + + def __ne__(self, other): + if isinstance(other, time): + return self.__cmp(other) != 0 + else: + return True + + def __le__(self, other): + if isinstance(other, time): + return self.__cmp(other) <= 0 + else: + _cmperror(self, other) + + def __lt__(self, other): + if isinstance(other, time): + return self.__cmp(other) < 0 + else: + _cmperror(self, other) + + def __ge__(self, other): + if isinstance(other, time): + return self.__cmp(other) >= 0 + else: + _cmperror(self, other) + + def __gt__(self, other): + if isinstance(other, time): + return self.__cmp(other) > 0 + else: + _cmperror(self, other) + + def __cmp(self, other): + assert isinstance(other, time) + mytz = self._tzinfo + ottz = other._tzinfo + myoff = otoff = None + + if mytz is ottz: + base_compare = True + else: + myoff = self._utcoffset() + otoff = other._utcoffset() + base_compare = myoff == otoff + + if base_compare: + return cmp((self.__hour, self.__minute, self.__second, + self.__microsecond), + (other.__hour, other.__minute, other.__second, + other.__microsecond)) + if myoff is None or otoff is None: + # XXX Buggy in 2.2.2. + raise TypeError("cannot compare naive and aware times") + myhhmm = self.__hour * 60 + self.__minute - myoff + othhmm = other.__hour * 60 + other.__minute - otoff + return cmp((myhhmm, self.__second, self.__microsecond), + (othhmm, other.__second, other.__microsecond)) + + def __hash__(self): + """Hash.""" + tzoff = self._utcoffset() + if not tzoff: # zero or None + return hash(self.__getstate()[0]) + h, m = divmod(self.hour * 60 + self.minute - tzoff, 60) + if 0 <= h < 24: + return hash(time(h, m, self.second, self.microsecond)) + return hash((h, m, self.second, self.microsecond)) + + # Conversion to string + + def _tzstr(self, sep=":"): + """Return formatted timezone offset (+xx:xx) or None.""" + off = self._utcoffset() + if off is not None: + if off < 0: + sign = "-" + off = -off + else: + sign = "+" + hh, mm = divmod(off, 60) + assert 0 <= hh < 24 + off = "%s%02d%s%02d" % (sign, hh, sep, mm) + return off + + def __repr__(self): + """Convert to formal string, for repr().""" + if self.__microsecond != 0: + s = ", %d, %d" % (self.__second, self.__microsecond) + elif self.__second != 0: + s = ", %d" % self.__second + else: + s = "" + s= "%s(%d, %d%s)" % ('datetime.' + self.__class__.__name__, + self.__hour, self.__minute, s) + if self._tzinfo is not None: + assert s[-1:] == ")" + s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" + return s + + def isoformat(self): + """Return the time formatted according to ISO. + + This is 'HH:MM:SS.mmmmmm+zz:zz', or 'HH:MM:SS+zz:zz' if + self.microsecond == 0. + """ + s = _format_time(self.__hour, self.__minute, self.__second, + self.__microsecond) + tz = self._tzstr() + if tz: + s += tz + return s + + __str__ = isoformat + + def strftime(self, fmt): + """Format using strftime(). The date part of the timestamp passed + to underlying strftime should not be used. + """ + # The year must be >= 1900 else Python's strftime implementation + # can raise a bogus exception. + timetuple = (1900, 1, 1, + self.__hour, self.__minute, self.__second, + 0, 1, -1) + return _wrap_strftime(self, fmt, timetuple) + + # Timezone functions + + def utcoffset(self): + """Return the timezone offset in minutes east of UTC (negative west of + UTC).""" + offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None) + offset = _check_utc_offset("utcoffset", offset) + if offset is not None: + offset = timedelta(minutes=offset) + return offset + + # Return an integer (or None) instead of a timedelta (or None). + def _utcoffset(self): + offset = _call_tzinfo_method(self._tzinfo, "utcoffset", None) + offset = _check_utc_offset("utcoffset", offset) + return offset + + def tzname(self): + """Return the timezone name. + + Note that the name is 100% informational -- there's no requirement that + it mean anything in particular. For example, "GMT", "UTC", "-500", + "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. + """ + name = _call_tzinfo_method(self._tzinfo, "tzname", None) + _check_tzname(name) + return name + + def dst(self): + """Return 0 if DST is not in effect, or the DST offset (in minutes + eastward) if DST is in effect. + + This is purely informational; the DST offset has already been added to + the UTC offset returned by utcoffset() if applicable, so there's no + need to consult dst() unless you're interested in displaying the DST + info. + """ + offset = _call_tzinfo_method(self._tzinfo, "dst", None) + offset = _check_utc_offset("dst", offset) + if offset is not None: + offset = timedelta(minutes=offset) + return offset + + def replace(self, hour=None, minute=None, second=None, microsecond=None, + tzinfo=True): + """Return a new time with new values for the specified fields.""" + if hour is None: + hour = self.hour + if minute is None: + minute = self.minute + if second is None: + second = self.second + if microsecond is None: + microsecond = self.microsecond + if tzinfo is True: + tzinfo = self.tzinfo + _check_time_fields(hour, minute, second, microsecond) + _check_tzinfo_arg(tzinfo) + return time(hour, minute, second, microsecond, tzinfo) + + # Return an integer (or None) instead of a timedelta (or None). + def _dst(self): + offset = _call_tzinfo_method(self._tzinfo, "dst", None) + offset = _check_utc_offset("dst", offset) + return offset + + def __nonzero__(self): + if self.second or self.microsecond: + return 1 + offset = self._utcoffset() or 0 + return self.hour * 60 + self.minute - offset != 0 + + # Pickle support. + + __safe_for_unpickling__ = True # For Python 2.2 + + def __getstate(self): + us2, us3 = divmod(self.__microsecond, 256) + us1, us2 = divmod(us2, 256) + basestate = ("%c" * 6) % (self.__hour, self.__minute, self.__second, + us1, us2, us3) + if self._tzinfo is None: + return (basestate,) + else: + return (basestate, self._tzinfo) + + def __setstate(self, string, tzinfo): + if len(string) != 6 or ord(string[0]) >= 24: + raise TypeError("an integer is required") + self.__hour, self.__minute, self.__second, us1, us2, us3 = \ + map(ord, string) + self.__microsecond = (((us1 << 8) | us2) << 8) | us3 + self._tzinfo = tzinfo + + def __reduce__(self): + return (time, self.__getstate()) + + if _sys.platform.startswith('java'): + def __tojava__(self, java_class): + # TODO, if self.tzinfo is not None, convert time to UTC + if java_class not in (Calendar, Time, Object): + return Py.NoConversion + + calendar = Calendar.getInstance() + calendar.clear() + calendar.set(Calendar.HOUR_OF_DAY, self.hour) + calendar.set(Calendar.MINUTE, self.minute) + calendar.set(Calendar.SECOND, self.second) + calendar.set(Calendar.MILLISECOND, self.microsecond // 1000) + if java_class == Calendar: + return calendar + else: + return Time(calendar.getTimeInMillis()) + + +_time_class = time # so functions w/ args named "time" can get at the class + +time.min = time(0, 0, 0) +time.max = time(23, 59, 59, 999999) +time.resolution = timedelta(microseconds=1) + +class datetime(date): + + # XXX needs docstrings + # See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo + + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, + microsecond=0, tzinfo=None): + if isinstance(year, str): + # Pickle support + self = date.__new__(cls, year[:4]) + self.__setstate(year, month) + return self + _check_tzinfo_arg(tzinfo) + _check_time_fields(hour, minute, second, microsecond) + self = date.__new__(cls, year, month, day) + # XXX This duplicates __year, __month, __day for convenience :-( + self.__year = year + self.__month = month + self.__day = day + self.__hour = hour + self.__minute = minute + self.__second = second + self.__microsecond = microsecond + self._tzinfo = tzinfo + return self + + # Read-only field accessors + hour = property(lambda self: self.__hour, doc="hour (0-23)") + minute = property(lambda self: self.__minute, doc="minute (0-59)") + second = property(lambda self: self.__second, doc="second (0-59)") + microsecond = property(lambda self: self.__microsecond, + doc="microsecond (0-999999)") + tzinfo = property(lambda self: self._tzinfo, doc="timezone info object") + + def fromtimestamp(cls, t, tz=None): + """Construct a datetime from a POSIX timestamp (like time.time()). + + A timezone info object may be passed in as well. + """ + + _check_tzinfo_arg(tz) + if tz is None: + converter = _time.localtime + else: + converter = _time.gmtime + y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) + us = int((t % 1.0) * 1000000) + + if us == 1000001 or us == 999999: + us = 0 + rounded = True + else: + rounded = False + + ss = min(ss, 59) # clamp out leap seconds if the platform has them + result = cls(y, m, d, hh, mm, ss, us, tz) + if rounded: + result += timedelta(seconds=1) + if tz is not None: + result = tz.fromutc(result) + return result + fromtimestamp = classmethod(fromtimestamp) + + def utcfromtimestamp(cls, t): + "Construct a UTC datetime from a POSIX timestamp (like time.time())." + y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t) + us = int((t % 1.0) * 1000000) + ss = min(ss, 59) # clamp out leap seconds if the platform has them + return cls(y, m, d, hh, mm, ss, us) + utcfromtimestamp = classmethod(utcfromtimestamp) + + # XXX This is supposed to do better than we *can* do by using time.time(), + # XXX if the platform supports a more accurate way. The C implementation + # XXX uses gettimeofday on platforms that have it, but that isn't + # XXX available from Python. So now() may return different results + # XXX across the implementations. + def now(cls, tz=None): + "Construct a datetime from time.time() and optional time zone info." + t = _time.time() + return cls.fromtimestamp(t, tz) + now = classmethod(now) + + def utcnow(cls): + "Construct a UTC datetime from time.time()." + t = _time.time() + return cls.utcfromtimestamp(t) + utcnow = classmethod(utcnow) + + def combine(cls, date, time): + "Construct a datetime from a given date and a given time." + if not isinstance(date, _date_class): + raise TypeError("date argument must be a date instance") + if not isinstance(time, _time_class): + raise TypeError("time argument must be a time instance") + return cls(date.year, date.month, date.day, + time.hour, time.minute, time.second, time.microsecond, + time.tzinfo) + combine = classmethod(combine) + + def strptime(cls, date_string, format): + """datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]) + + The year, month and day arguments are required. tzinfo may be None, or an + instance of a tzinfo subclass. The remaining arguments may be ints or longs.""" + return cls(*(_time.strptime(date_string, format))[0:6]) + + strptime = classmethod(strptime) + + def timetuple(self): + "Return local time tuple compatible with time.localtime()." + dst = self._dst() + if dst is None: + dst = -1 + elif dst: + dst = 1 + return _build_struct_time(self.year, self.month, self.day, + self.hour, self.minute, self.second, + dst) + + def utctimetuple(self): + "Return UTC time tuple compatible with time.gmtime()." + y, m, d = self.year, self.month, self.day + hh, mm, ss = self.hour, self.minute, self.second + offset = self._utcoffset() + if offset: # neither None nor 0 + tm = tmxxx(y, m, d, hh, mm - offset) + y, m, d = tm.year, tm.month, tm.day + hh, mm = tm.hour, tm.minute + return _build_struct_time(y, m, d, hh, mm, ss, 0) + + def date(self): + "Return the date part." + return date(self.__year, self.__month, self.__day) + + def time(self): + "Return the time part, with tzinfo None." + return time(self.hour, self.minute, self.second, self.microsecond) + + def timetz(self): + "Return the time part, with same tzinfo." + return time(self.hour, self.minute, self.second, self.microsecond, + self._tzinfo) + + def replace(self, year=None, month=None, day=None, hour=None, + minute=None, second=None, microsecond=None, tzinfo=True): + """Return a new datetime with new values for the specified fields.""" + if year is None: + year = self.year + if month is None: + month = self.month + if day is None: + day = self.day + if hour is None: + hour = self.hour + if minute is None: + minute = self.minute + if second is None: + second = self.second + if microsecond is None: + microsecond = self.microsecond + if tzinfo is True: + tzinfo = self.tzinfo + _check_date_fields(year, month, day) + _check_time_fields(hour, minute, second, microsecond) + _check_tzinfo_arg(tzinfo) + return datetime(year, month, day, hour, minute, second, + microsecond, tzinfo) + + def astimezone(self, tz): + if not isinstance(tz, tzinfo): + raise TypeError("tz argument must be an instance of tzinfo") + + mytz = self.tzinfo + if mytz is None: + raise ValueError("astimezone() requires an aware datetime") + + if tz is mytz: + return self + + # Convert self to UTC, and attach the new time zone object. + myoffset = self.utcoffset() + if myoffset is None: + raise ValueError("astimezone() requires an aware datetime") + utc = (self - myoffset).replace(tzinfo=tz) + + # Convert from UTC to tz's local time. + return tz.fromutc(utc) + + # Ways to produce a string. + + def ctime(self): + "Format a la ctime()." + t = tmxxx(self.__year, self.__month, self.__day, self.__hour, + self.__minute, self.__second) + return t.ctime() + + def isoformat(self, sep='T'): + """Return the time formatted according to ISO. + + This is 'YYYY-MM-DD HH:MM:SS.mmmmmm', or 'YYYY-MM-DD HH:MM:SS' if + self.microsecond == 0. + + If self.tzinfo is not None, the UTC offset is also attached, giving + 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM' or 'YYYY-MM-DD HH:MM:SS+HH:MM'. + + Optional argument sep specifies the separator between date and + time, default 'T'. + """ + s = ("%04d-%02d-%02d%c" % (self.__year, self.__month, self.__day, + sep) + + _format_time(self.__hour, self.__minute, self.__second, + self.__microsecond)) + off = self._utcoffset() + if off is not None: + if off < 0: + sign = "-" + off = -off + else: + sign = "+" + hh, mm = divmod(off, 60) + s += "%s%02d:%02d" % (sign, hh, mm) + return s + + def __repr__(self): + "Convert to formal string, for repr()." + L = [self.__year, self.__month, self.__day, # These are never zero + self.__hour, self.__minute, self.__second, self.__microsecond] + if L[-1] == 0: + del L[-1] + if L[-1] == 0: + del L[-1] + s = ", ".join(map(str, L)) + s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s) + if self._tzinfo is not None: + assert s[-1:] == ")" + s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" + return s + + def __str__(self): + "Convert to string, for str()." + return self.isoformat(sep=' ') + + def utcoffset(self): + """Return the timezone offset in minutes east of UTC (negative west of + UTC).""" + offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self) + offset = _check_utc_offset("utcoffset", offset) + if offset is not None: + offset = timedelta(minutes=offset) + return offset + + # Return an integer (or None) instead of a timedelta (or None). + def _utcoffset(self): + offset = _call_tzinfo_method(self._tzinfo, "utcoffset", self) + offset = _check_utc_offset("utcoffset", offset) + return offset + + def tzname(self): + """Return the timezone name. + + Note that the name is 100% informational -- there's no requirement that + it mean anything in particular. For example, "GMT", "UTC", "-500", + "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. + """ + name = _call_tzinfo_method(self._tzinfo, "tzname", self) + _check_tzname(name) + return name + + def dst(self): + """Return 0 if DST is not in effect, or the DST offset (in minutes + eastward) if DST is in effect. + + This is purely informational; the DST offset has already been added to + the UTC offset returned by utcoffset() if applicable, so there's no + need to consult dst() unless you're interested in displaying the DST + info. + """ + offset = _call_tzinfo_method(self._tzinfo, "dst", self) + offset = _check_utc_offset("dst", offset) + if offset is not None: + offset = timedelta(minutes=offset) + return offset + + # Return an integer (or None) instead of a timedelta (or None).1573 + def _dst(self): + offset = _call_tzinfo_method(self._tzinfo, "dst", self) + offset = _check_utc_offset("dst", offset) + return offset + + # Comparisons. + + def __eq__(self, other): + if isinstance(other, datetime): + return self.__cmp(other) == 0 + elif hasattr(other, "timetuple") and not isinstance(other, date): + return NotImplemented + else: + return False + + def __ne__(self, other): + if isinstance(other, datetime): + return self.__cmp(other) != 0 + elif hasattr(other, "timetuple") and not isinstance(other, date): + return NotImplemented + else: + return True + + def __le__(self, other): + if isinstance(other, datetime): + return self.__cmp(other) <= 0 + elif hasattr(other, "timetuple") and not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def __lt__(self, other): + if isinstance(other, datetime): + return self.__cmp(other) < 0 + elif hasattr(other, "timetuple") and not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def __ge__(self, other): + if isinstance(other, datetime): + return self.__cmp(other) >= 0 + elif hasattr(other, "timetuple") and not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def __gt__(self, other): + if isinstance(other, datetime): + return self.__cmp(other) > 0 + elif hasattr(other, "timetuple") and not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def __cmp(self, other): + assert isinstance(other, datetime) + mytz = self._tzinfo + ottz = other._tzinfo + myoff = otoff = None + + if mytz is ottz: + base_compare = True + else: + if mytz is not None: + myoff = self._utcoffset() + if ottz is not None: + otoff = other._utcoffset() + base_compare = myoff == otoff + + if base_compare: + return cmp((self.__year, self.__month, self.__day, + self.__hour, self.__minute, self.__second, + self.__microsecond), + (other.__year, other.__month, other.__day, + other.__hour, other.__minute, other.__second, + other.__microsecond)) + if myoff is None or otoff is None: + # XXX Buggy in 2.2.2. + raise TypeError("cannot compare naive and aware datetimes") + # XXX What follows could be done more efficiently... + diff = self - other # this will take offsets into account + if diff.days < 0: + return -1 + return diff and 1 or 0 + + def __add__(self, other): + "Add a datetime and a timedelta." + if not isinstance(other, timedelta): + return NotImplemented + t = tmxxx(self.__year, + self.__month, + self.__day + other.days, + self.__hour, + self.__minute, + self.__second + other.seconds, + self.__microsecond + other.microseconds) + self._checkOverflow(t.year) + result = datetime(t.year, t.month, t.day, + t.hour, t.minute, t.second, + t.microsecond, tzinfo=self._tzinfo) + return result + + __radd__ = __add__ + + def __sub__(self, other): + "Subtract two datetimes, or a datetime and a timedelta." + if not isinstance(other, datetime): + if isinstance(other, timedelta): + return self + -other + return NotImplemented + + days1 = self.toordinal() + days2 = other.toordinal() + secs1 = self.__second + self.__minute * 60 + self.__hour * 3600 + secs2 = other.__second + other.__minute * 60 + other.__hour * 3600 + base = timedelta(days1 - days2, + secs1 - secs2, + self.__microsecond - other.__microsecond) + if self._tzinfo is other._tzinfo: + return base + myoff = self._utcoffset() + otoff = other._utcoffset() + if myoff == otoff: + return base + if myoff is None or otoff is None: + raise TypeError, "cannot mix naive and timezone-aware time" + return base + timedelta(minutes = otoff-myoff) + + def __hash__(self): + tzoff = self._utcoffset() + if tzoff is None: + return hash(self.__getstate()[0]) + days = _ymd2ord(self.year, self.month, self.day) + seconds = self.hour * 3600 + (self.minute - tzoff) * 60 + self.second + return hash(timedelta(days, seconds, self.microsecond)) + + # Pickle support. + + __safe_for_unpickling__ = True # For Python 2.2 + + def __getstate(self): + yhi, ylo = divmod(self.__year, 256) + us2, us3 = divmod(self.__microsecond, 256) + us1, us2 = divmod(us2, 256) + basestate = ("%c" * 10) % (yhi, ylo, self.__month, self.__day, + self.__hour, self.__minute, self.__second, + us1, us2, us3) + if self._tzinfo is None: + return (basestate,) + else: + return (basestate, self._tzinfo) + + def __setstate(self, string, tzinfo): + (yhi, ylo, self.__month, self.__day, self.__hour, + self.__minute, self.__second, us1, us2, us3) = map(ord, string) + self.__year = yhi * 256 + ylo + self.__microsecond = (((us1 << 8) | us2) << 8) | us3 + self._tzinfo = tzinfo + + def __reduce__(self): + return (self.__class__, self.__getstate()) + + if _sys.platform.startswith('java'): + def __tojava__(self, java_class): + # TODO, if self.tzinfo is not None, convert time to UTC + if java_class not in (Calendar, Timestamp, Object): + return Py.NoConversion + + calendar = Calendar.getInstance() + calendar.clear() + calendar.set(self.year, self.month - 1, self.day, + self.hour, self.minute, self.second) + + if java_class == Calendar: + calendar.set(Calendar.MILLISECOND, self.microsecond // 1000) + return calendar + else: + timestamp = Timestamp(calendar.getTimeInMillis()) + timestamp.setNanos(self.microsecond * 1000) + return timestamp + + +datetime.min = datetime(1, 1, 1) +datetime.max = datetime(9999, 12, 31, 23, 59, 59, 999999) +datetime.resolution = timedelta(microseconds=1) + + +def _isoweek1monday(year): + # Helper to calculate the day number of the Monday starting week 1 + # XXX This could be done more efficiently + THURSDAY = 3 + firstday = _ymd2ord(year, 1, 1) + firstweekday = (firstday + 6) % 7 # See weekday() above + week1monday = firstday - firstweekday + if firstweekday > THURSDAY: + week1monday += 7 + return week1monday + +""" +Some time zone algebra. For a datetime x, let + x.n = x stripped of its timezone -- its naive time. + x.o = x.utcoffset(), and assuming that doesn't raise an exception or + return None + x.d = x.dst(), and assuming that doesn't raise an exception or + return None + x.s = x's standard offset, x.o - x.d + +Now some derived rules, where k is a duration (timedelta). + +1. x.o = x.s + x.d + This follows from the definition of x.s. + +2. If x and y have the same tzinfo member, x.s = y.s. + This is actually a requirement, an assumption we need to make about + sane tzinfo classes. + +3. The naive UTC time corresponding to x is x.n - x.o. + This is again a requirement for a sane tzinfo class. + +4. (x+k).s = x.s + This follows from #2, and that datimetimetz+timedelta preserves tzinfo. + +5. (x+k).n = x.n + k + Again follows from how arithmetic is defined. + +Now we can explain tz.fromutc(x). Let's assume it's an interesting case +(meaning that the various tzinfo methods exist, and don't blow up or return +None when called). + +The function wants to return a datetime y with timezone tz, equivalent to x. +x is already in UTC. + +By #3, we want + + y.n - y.o = x.n [1] + +The algorithm starts by attaching tz to x.n, and calling that y. So +x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] +becomes true; in effect, we want to solve [2] for k: + + (y+k).n - (y+k).o = x.n [2] + +By #1, this is the same as + + (y+k).n - ((y+k).s + (y+k).d) = x.n [3] + +By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. +Substituting that into [3], + + x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving + k - (y+k).s - (y+k).d = 0; rearranging, + k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so + k = y.s - (y+k).d + +On the RHS, (y+k).d can't be computed directly, but y.s can be, and we +approximate k by ignoring the (y+k).d term at first. Note that k can't be +very large, since all offset-returning methods return a duration of magnitude +less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must +be 0, so ignoring it has no consequence then. + +In any case, the new value is + + z = y + y.s [4] + +It's helpful to step back at look at [4] from a higher level: it's simply +mapping from UTC to tz's standard time. + +At this point, if + + z.n - z.o = x.n [5] + +we have an equivalent time, and are almost done. The insecurity here is +at the start of daylight time. Picture US Eastern for concreteness. The wall +time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good +sense then. The docs ask that an Eastern tzinfo class consider such a time to +be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST +on the day DST starts. We want to return the 1:MM EST spelling because that's +the only spelling that makes sense on the local wall clock. + +In fact, if [5] holds at this point, we do have the standard-time spelling, +but that takes a bit of proof. We first prove a stronger result. What's the +difference between the LHS and RHS of [5]? Let + + diff = x.n - (z.n - z.o) [6] + +Now + z.n = by [4] + (y + y.s).n = by #5 + y.n + y.s = since y.n = x.n + x.n + y.s = since z and y are have the same tzinfo member, + y.s = z.s by #2 + x.n + z.s + +Plugging that back into [6] gives + + diff = + x.n - ((x.n + z.s) - z.o) = expanding + x.n - x.n - z.s + z.o = cancelling + - z.s + z.o = by #2 + z.d + +So diff = z.d. + +If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time +spelling we wanted in the endcase described above. We're done. Contrarily, +if z.d = 0, then we have a UTC equivalent, and are also done. + +If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to +add to z (in effect, z is in tz's standard time, and we need to shift the +local clock into tz's daylight time). + +Let + + z' = z + z.d = z + diff [7] + +and we can again ask whether + + z'.n - z'.o = x.n [8] + +If so, we're done. If not, the tzinfo class is insane, according to the +assumptions we've made. This also requires a bit of proof. As before, let's +compute the difference between the LHS and RHS of [8] (and skipping some of +the justifications for the kinds of substitutions we've done several times +already): + + diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] + x.n - (z.n + diff - z'.o) = replacing diff via [6] + x.n - (z.n + x.n - (z.n - z.o) - z'.o) = + x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n + - z.n + z.n - z.o + z'.o = cancel z.n + - z.o + z'.o = #1 twice + -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo + z'.d - z.d + +So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, +we've found the UTC-equivalent so are done. In fact, we stop with [7] and +return z', not bothering to compute z'.d. + +How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by +a dst() offset, and starting *from* a time already in DST (we know z.d != 0), +would have to change the result dst() returns: we start in DST, and moving +a little further into it takes us out of DST. + +There isn't a sane case where this can happen. The closest it gets is at +the end of DST, where there's an hour in UTC with no spelling in a hybrid +tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During +that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM +UTC) because the docs insist on that, but 0:MM is taken as being in daylight +time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local +clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in +standard time. Since that's what the local clock *does*, we want to map both +UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous +in local time, but so it goes -- it's the way the local clock works. + +When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, +so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. +z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] +(correctly) concludes that z' is not UTC-equivalent to x. + +Because we know z.d said z was in daylight time (else [5] would have held and +we would have stopped then), and we know z.d != z'.d (else [8] would have held +and we we have stopped then), and there are only 2 possible values dst() can +return in Eastern, it follows that z'.d must be 0 (which it is in the example, +but the reasoning doesn't depend on the example -- it depends on there being +two possible dst() outcomes, one zero and the other non-zero). Therefore +z' must be in standard time, and is the spelling we want in this case. + +Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is +concerned (because it takes z' as being in standard time rather than the +daylight time we intend here), but returning it gives the real-life "local +clock repeats an hour" behavior when mapping the "unspellable" UTC hour into +tz. + +When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with +the 1:MM standard time spelling we want. + +So how can this break? One of the assumptions must be violated. Two +possibilities: + +1) [2] effectively says that y.s is invariant across all y belong to a given + time zone. This isn't true if, for political reasons or continental drift, + a region decides to change its base offset from UTC. + +2) There may be versions of "double daylight" time where the tail end of + the analysis gives up a step too early. I haven't thought about that + enough to say. + +In any case, it's clear that the default fromutc() is strong enough to handle +"almost all" time zones: so long as the standard offset is invariant, it +doesn't matter if daylight time transition points change from year to year, or +if daylight time is skipped in some years; it doesn't matter how large or +small dst() may get within its bounds; and it doesn't even matter if some +perverse time zone returns a negative dst()). So a breaking case must be +pretty bizarre, and a tzinfo subclass can override fromutc() if it is. +""" diff --git a/src/main/resources/PythonLibs/dbexts.py b/src/main/resources/PythonLibs/dbexts.py new file mode 100644 index 0000000000000000000000000000000000000000..041331d82058857d403b486aeaaaff64db877842 --- /dev/null +++ b/src/main/resources/PythonLibs/dbexts.py @@ -0,0 +1,722 @@ +""" +This script provides platform independence by wrapping Python +Database API 2.0 compatible drivers to allow seamless database +usage across implementations. + +In order to use the C version, you need mxODBC and mxDateTime. +In order to use the Java version, you need zxJDBC. + +>>> import dbexts +>>> d = dbexts.dbexts() # use the default db +>>> d.isql('select count(*) count from player') + +count +------- +13569.0 + +1 row affected + +>>> r = d.raw('select count(*) count from player') +>>> r +([('count', 3, 17, None, 15, 0, 1)], [(13569.0,)]) +>>> + +The configuration file follows the following format in a file name dbexts.ini: + +[default] +name=mysql + +[jdbc] +name=mysql +url=jdbc:mysql://localhost/ziclix +user= +pwd= +driver=org.gjt.mm.mysql.Driver +datahandler=com.ziclix.python.sql.handler.MySQLDataHandler + +[jdbc] +name=pg +url=jdbc:postgresql://localhost:5432/ziclix +user=bzimmer +pwd= +driver=org.postgresql.Driver +datahandler=com.ziclix.python.sql.handler.PostgresqlDataHandler +""" + +import os, re +from types import StringType + +__author__ = "brian zimmer (bzimmer@ziclix.com)" +__OS__ = os.name + +choose = lambda bool, a, b: (bool and [a] or [b])[0] + +def console(rows, headers=()): + """Format the results into a list of strings (one for each row): + + <header> + <headersep> + <row1> + <row2> + ... + + headers may be given as list of strings. + + Columns are separated by colsep; the header is separated from + the result set by a line of headersep characters. + + The function calls stringify to format the value data into a string. + It defaults to calling str() and striping leading and trailing whitespace. + + - copied and modified from mxODBC + """ + + # Check row entry lengths + output = [] + headers = map(lambda header: header.upper(), list(map(lambda x: x or "", headers))) + collen = map(len,headers) + output.append(headers) + if rows and len(rows) > 0: + for row in rows: + row = map(lambda x: str(x), row) + for i in range(len(row)): + entry = row[i] + if collen[i] < len(entry): + collen[i] = len(entry) + output.append(row) + if len(output) == 1: + affected = "0 rows affected" + elif len(output) == 2: + affected = "1 row affected" + else: + affected = "%d rows affected" % (len(output) - 1) + + # Format output + for i in range(len(output)): + row = output[i] + l = [] + for j in range(len(row)): + l.append('%-*s' % (collen[j],row[j])) + output[i] = " | ".join(l) + + # Insert header separator + totallen = len(output[0]) + output[1:1] = ["-"*(totallen/len("-"))] + output.append("\n" + affected) + return output + +def html(rows, headers=()): + output = [] + output.append('<table class="results">') + output.append('<tr class="headers">') + headers = map(lambda x: '<td class="header">%s</td>' % (x.upper()), list(headers)) + map(output.append, headers) + output.append('</tr>') + if rows and len(rows) > 0: + for row in rows: + output.append('<tr class="row">') + row = map(lambda x: '<td class="value">%s</td>' % (x), row) + map(output.append, row) + output.append('</tr>') + output.append('</table>') + return output + +comments = lambda x: re.compile("{.*?}", re.S).sub("", x, 0) + +class mxODBCProxy: + """Wraps mxODBC to provide proxy support for zxJDBC's additional parameters.""" + def __init__(self, c): + self.c = c + def __getattr__(self, name): + if name == "execute": + return self.execute + elif name == "gettypeinfo": + return self.gettypeinfo + else: + return getattr(self.c, name) + def execute(self, sql, params=None, bindings=None, maxrows=None): + if params: + self.c.execute(sql, params) + else: + self.c.execute(sql) + def gettypeinfo(self, typeid=None): + if typeid: + self.c.gettypeinfo(typeid) + +class executor: + """Handles the insertion of values given dynamic data.""" + def __init__(self, table, cols): + self.cols = cols + self.table = table + if self.cols: + self.sql = "insert into %s (%s) values (%s)" % (table, ",".join(self.cols), ",".join(("?",) * len(self.cols))) + else: + self.sql = "insert into %s values (%%s)" % (table) + def execute(self, db, rows, bindings): + assert rows and len(rows) > 0, "must have at least one row" + if self.cols: + sql = self.sql + else: + sql = self.sql % (",".join(("?",) * len(rows[0]))) + db.raw(sql, rows, bindings) + +def connect(dbname): + return dbexts(dbname) + +def lookup(dbname): + return dbexts(jndiname=dbname) + +class dbexts: + def __init__(self, dbname=None, cfg=None, formatter=console, autocommit=0, jndiname=None, out=None): + self.verbose = 1 + self.results = [] + self.headers = [] + self.autocommit = autocommit + self.formatter = formatter + self.out = out + self.lastrowid = None + self.updatecount = None + + if not jndiname: + if cfg == None: + fn = os.path.join(os.path.split(__file__)[0], "dbexts.ini") + if not os.path.exists(fn): + fn = os.path.join(os.environ['HOME'], ".dbexts") + self.dbs = IniParser(fn) + elif isinstance(cfg, IniParser): + self.dbs = cfg + else: + self.dbs = IniParser(cfg) + if dbname == None: dbname = self.dbs[("default", "name")] + + if __OS__ == 'java': + + from com.ziclix.python.sql import zxJDBC + database = zxJDBC + if not jndiname: + t = self.dbs[("jdbc", dbname)] + self.dburl, dbuser, dbpwd, jdbcdriver = t['url'], t['user'], t['pwd'], t['driver'] + if t.has_key('datahandler'): + self.datahandler = [] + for dh in t['datahandler'].split(','): + classname = dh.split(".")[-1] + datahandlerclass = __import__(dh, globals(), locals(), classname) + self.datahandler.append(datahandlerclass) + keys = [x for x in t.keys() if x not in ['url', 'user', 'pwd', 'driver', 'datahandler', 'name']] + props = {} + for a in keys: + props[a] = t[a] + self.db = apply(database.connect, (self.dburl, dbuser, dbpwd, jdbcdriver), props) + else: + self.db = database.lookup(jndiname) + self.db.autocommit = self.autocommit + + elif __OS__ == 'nt': + + for modname in ["mx.ODBC.Windows", "ODBC.Windows"]: + try: + database = __import__(modname, globals(), locals(), "Windows") + break + except: + continue + else: + raise ImportError("unable to find appropriate mxODBC module") + + t = self.dbs[("odbc", dbname)] + self.dburl, dbuser, dbpwd = t['url'], t['user'], t['pwd'] + self.db = database.Connect(self.dburl, dbuser, dbpwd, clear_auto_commit=1) + + self.dbname = dbname + for a in database.sqltype.keys(): + setattr(self, database.sqltype[a], a) + for a in dir(database): + try: + p = getattr(database, a) + if issubclass(p, Exception): + setattr(self, a, p) + except: + continue + del database + + def __str__(self): + return self.dburl + + def __repr__(self): + return self.dburl + + def __getattr__(self, name): + if "cfg" == name: + return self.dbs.cfg + raise AttributeError("'dbexts' object has no attribute '%s'" % (name)) + + def close(self): + """ close the connection to the database """ + self.db.close() + + def begin(self, style=None): + """ reset ivars and return a new cursor, possibly binding an auxiliary datahandler """ + self.headers, self.results = [], [] + if style: + c = self.db.cursor(style) + else: + c = self.db.cursor() + if __OS__ == 'java': + if hasattr(self, 'datahandler'): + for dh in self.datahandler: + c.datahandler = dh(c.datahandler) + else: + c = mxODBCProxy(c) + return c + + def commit(self, cursor=None, close=1): + """ commit the cursor and create the result set """ + if cursor and cursor.description: + self.headers = cursor.description + self.results = cursor.fetchall() + if hasattr(cursor, "nextset"): + s = cursor.nextset() + while s: + self.results += cursor.fetchall() + s = cursor.nextset() + if hasattr(cursor, "lastrowid"): + self.lastrowid = cursor.lastrowid + if hasattr(cursor, "updatecount"): + self.updatecount = cursor.updatecount + if not self.autocommit or cursor is None: + if not self.db.autocommit: + self.db.commit() + if cursor and close: cursor.close() + + def rollback(self): + """ rollback the cursor """ + self.db.rollback() + + def prepare(self, sql): + """ prepare the sql statement """ + cur = self.begin() + try: + return cur.prepare(sql) + finally: + self.commit(cur) + + def display(self): + """ using the formatter, display the results """ + if self.formatter and self.verbose > 0: + res = self.results + if res: + print >> self.out, "" + for a in self.formatter(res, map(lambda x: x[0], self.headers)): + print >> self.out, a + print >> self.out, "" + + def __execute__(self, sql, params=None, bindings=None, maxrows=None): + """ the primary execution method """ + cur = self.begin() + try: + if bindings: + cur.execute(sql, params, bindings, maxrows=maxrows) + elif params: + cur.execute(sql, params, maxrows=maxrows) + else: + cur.execute(sql, maxrows=maxrows) + finally: + self.commit(cur, close=isinstance(sql, StringType)) + + def isql(self, sql, params=None, bindings=None, maxrows=None): + """ execute and display the sql """ + self.raw(sql, params, bindings, maxrows=maxrows) + self.display() + + def raw(self, sql, params=None, bindings=None, delim=None, comments=comments, maxrows=None): + """ execute the sql and return a tuple of (headers, results) """ + if delim: + headers = [] + results = [] + if type(sql) == type(StringType): + if comments: sql = comments(sql) + statements = filter(lambda x: len(x) > 0, + map(lambda statement: statement.strip(), sql.split(delim))) + else: + statements = [sql] + for a in statements: + self.__execute__(a, params, bindings, maxrows=maxrows) + headers.append(self.headers) + results.append(self.results) + self.headers = headers + self.results = results + else: + self.__execute__(sql, params, bindings, maxrows=maxrows) + return (self.headers, self.results) + + def callproc(self, procname, params=None, bindings=None, maxrows=None): + """ execute a stored procedure """ + cur = self.begin() + try: + cur.callproc(procname, params=params, bindings=bindings, maxrows=maxrows) + finally: + self.commit(cur) + self.display() + + def pk(self, table, owner=None, schema=None): + """ display the table's primary keys """ + cur = self.begin() + cur.primarykeys(schema, owner, table) + self.commit(cur) + self.display() + + def fk(self, primary_table=None, foreign_table=None, owner=None, schema=None): + """ display the table's foreign keys """ + cur = self.begin() + if primary_table and foreign_table: + cur.foreignkeys(schema, owner, primary_table, schema, owner, foreign_table) + elif primary_table: + cur.foreignkeys(schema, owner, primary_table, schema, owner, None) + elif foreign_table: + cur.foreignkeys(schema, owner, None, schema, owner, foreign_table) + self.commit(cur) + self.display() + + def table(self, table=None, types=("TABLE",), owner=None, schema=None): + """If no table argument, displays a list of all tables. If a table argument, + displays the columns of the given table.""" + cur = self.begin() + if table: + cur.columns(schema, owner, table, None) + else: + cur.tables(schema, owner, None, types) + self.commit(cur) + self.display() + + def proc(self, proc=None, owner=None, schema=None): + """If no proc argument, displays a list of all procedures. If a proc argument, + displays the parameters of the given procedure.""" + cur = self.begin() + if proc: + cur.procedurecolumns(schema, owner, proc, None) + else: + cur.procedures(schema, owner, None) + self.commit(cur) + self.display() + + def stat(self, table, qualifier=None, owner=None, unique=0, accuracy=0): + """ display the table's indicies """ + cur = self.begin() + cur.statistics(qualifier, owner, table, unique, accuracy) + self.commit(cur) + self.display() + + def typeinfo(self, sqltype=None): + """ display the types available for the database """ + cur = self.begin() + cur.gettypeinfo(sqltype) + self.commit(cur) + self.display() + + def tabletypeinfo(self): + """ display the table types available for the database """ + cur = self.begin() + cur.gettabletypeinfo() + self.commit(cur) + self.display() + + def schema(self, table, full=0, sort=1, owner=None): + """Displays a Schema object for the table. If full is true, then generates + references to the table in addition to the standard fields. If sort is true, + sort all the items in the schema, else leave them in db dependent order.""" + print >> self.out, str(Schema(self, table, owner, full, sort)) + + def bulkcopy(self, dst, table, include=[], exclude=[], autobatch=0, executor=executor): + """Returns a Bulkcopy object using the given table.""" + if type(dst) == type(""): + dst = dbexts(dst, cfg=self.dbs) + bcp = Bulkcopy(dst, table, include=include, exclude=exclude, autobatch=autobatch, executor=executor) + return bcp + + def bcp(self, src, table, where='(1=1)', params=[], include=[], exclude=[], autobatch=0, executor=executor): + """Bulkcopy of rows from a src database to the current database for a given table and where clause.""" + if type(src) == type(""): + src = dbexts(src, cfg=self.dbs) + bcp = self.bulkcopy(self, table, include, exclude, autobatch, executor) + num = bcp.transfer(src, where, params) + return num + + def unload(self, filename, sql, delimiter=",", includeheaders=1): + """ Unloads the delimited results of the query to the file specified, optionally including headers. """ + u = Unload(self, filename, delimiter, includeheaders) + u.unload(sql) + +class Bulkcopy: + """The idea for a bcp class came from http://object-craft.com.au/projects/sybase""" + def __init__(self, dst, table, include=[], exclude=[], autobatch=0, executor=executor): + self.dst = dst + self.table = table + self.total = 0 + self.rows = [] + self.autobatch = autobatch + self.bindings = {} + + include = map(lambda x: x.lower(), include) + exclude = map(lambda x: x.lower(), exclude) + + _verbose = self.dst.verbose + self.dst.verbose = 0 + try: + self.dst.table(self.table) + if self.dst.results: + colmap = {} + for a in self.dst.results: + colmap[a[3].lower()] = a[4] + cols = self.__filter__(colmap.keys(), include, exclude) + for a in zip(range(len(cols)), cols): + self.bindings[a[0]] = colmap[a[1]] + colmap = None + else: + cols = self.__filter__(include, include, exclude) + finally: + self.dst.verbose = _verbose + + self.executor = executor(table, cols) + + def __str__(self): + return "[%s].[%s]" % (self.dst, self.table) + + def __repr__(self): + return "[%s].[%s]" % (self.dst, self.table) + + def __getattr__(self, name): + if name == 'columns': + return self.executor.cols + + def __filter__(self, values, include, exclude): + cols = map(lambda col: col.lower(), values) + if exclude: + cols = filter(lambda x, ex=exclude: x not in ex, cols) + if include: + cols = filter(lambda x, inc=include: x in inc, cols) + return cols + + def format(self, column, type): + self.bindings[column] = type + + def done(self): + if len(self.rows) > 0: + return self.batch() + return 0 + + def batch(self): + self.executor.execute(self.dst, self.rows, self.bindings) + cnt = len(self.rows) + self.total += cnt + self.rows = [] + return cnt + + def rowxfer(self, line): + self.rows.append(line) + if self.autobatch: self.batch() + + def transfer(self, src, where="(1=1)", params=[]): + sql = "select %s from %s where %s" % (", ".join(self.columns), self.table, where) + h, d = src.raw(sql, params) + if d: + map(self.rowxfer, d) + return self.done() + return 0 + +class Unload: + """Unloads a sql statement to a file with optional formatting of each value.""" + def __init__(self, db, filename, delimiter=",", includeheaders=1): + self.db = db + self.filename = filename + self.delimiter = delimiter + self.includeheaders = includeheaders + self.formatters = {} + + def format(self, o): + if not o: + return "" + o = str(o) + if o.find(",") != -1: + o = "\"\"%s\"\"" % (o) + return o + + def unload(self, sql, mode="w"): + headers, results = self.db.raw(sql) + w = open(self.filename, mode) + if self.includeheaders: + w.write("%s\n" % (self.delimiter.join(map(lambda x: x[0], headers)))) + if results: + for a in results: + w.write("%s\n" % (self.delimiter.join(map(self.format, a)))) + w.flush() + w.close() + +class Schema: + """Produces a Schema object which represents the database schema for a table""" + def __init__(self, db, table, owner=None, full=0, sort=1): + self.db = db + self.table = table + self.owner = owner + self.full = full + self.sort = sort + _verbose = self.db.verbose + self.db.verbose = 0 + try: + if table: self.computeschema() + finally: + self.db.verbose = _verbose + + def computeschema(self): + self.db.table(self.table, owner=self.owner) + self.columns = [] + # (column name, type_name, size, nullable) + if self.db.results: + self.columns = map(lambda x: (x[3], x[5], x[6], x[10]), self.db.results) + if self.sort: self.columns.sort(lambda x, y: cmp(x[0], y[0])) + + self.db.fk(None, self.table) + # (pk table name, pk column name, fk column name, fk name, pk name) + self.imported = [] + if self.db.results: + self.imported = map(lambda x: (x[2], x[3], x[7], x[11], x[12]), self.db.results) + if self.sort: self.imported.sort(lambda x, y: cmp(x[2], y[2])) + + self.exported = [] + if self.full: + self.db.fk(self.table, None) + # (pk column name, fk table name, fk column name, fk name, pk name) + if self.db.results: + self.exported = map(lambda x: (x[3], x[6], x[7], x[11], x[12]), self.db.results) + if self.sort: self.exported.sort(lambda x, y: cmp(x[1], y[1])) + + self.db.pk(self.table) + self.primarykeys = [] + if self.db.results: + # (column name, key_seq, pk name) + self.primarykeys = map(lambda x: (x[3], x[4], x[5]), self.db.results) + if self.sort: self.primarykeys.sort(lambda x, y: cmp(x[1], y[1])) + + try: + self.indices = None + self.db.stat(self.table) + self.indices = [] + # (non-unique, name, type, pos, column name, asc) + if self.db.results: + idxdict = {} + # mxODBC returns a row of None's, so filter it out + idx = map(lambda x: (x[3], x[5].strip(), x[6], x[7], x[8]), filter(lambda x: x[5], self.db.results)) + def cckmp(x, y): + c = cmp(x[1], y[1]) + if c == 0: c = cmp(x[3], y[3]) + return c + # sort this regardless, this gets the indicies lined up + idx.sort(cckmp) + for a in idx: + if not idxdict.has_key(a[1]): + idxdict[a[1]] = [] + idxdict[a[1]].append(a) + self.indices = idxdict.values() + if self.sort: self.indices.sort(lambda x, y: cmp(x[0][1], y[0][1])) + except: + pass + + def __str__(self): + d = [] + d.append("Table") + d.append(" " + self.table) + d.append("\nPrimary Keys") + for a in self.primarykeys: + d.append(" %s {%s}" % (a[0], a[2])) + d.append("\nImported (Foreign) Keys") + for a in self.imported: + d.append(" %s (%s.%s) {%s}" % (a[2], a[0], a[1], a[3])) + if self.full: + d.append("\nExported (Referenced) Keys") + for a in self.exported: + d.append(" %s (%s.%s) {%s}" % (a[0], a[1], a[2], a[3])) + d.append("\nColumns") + for a in self.columns: + nullable = choose(a[3], "nullable", "non-nullable") + d.append(" %-20s %s(%s), %s" % (a[0], a[1], a[2], nullable)) + d.append("\nIndices") + if self.indices is None: + d.append(" (failed)") + else: + for a in self.indices: + unique = choose(a[0][0], "non-unique", "unique") + cname = ", ".join(map(lambda x: x[4], a)) + d.append(" %s index {%s} on (%s)" % (unique, a[0][1], cname)) + return "\n".join(d) + +class IniParser: + def __init__(self, cfg, key='name'): + self.key = key + self.records = {} + self.ctypeRE = re.compile("\[(jdbc|odbc|default)\]") + self.entryRE = re.compile("([a-zA-Z]+)[ \t]*=[ \t]*(.*)") + self.cfg = cfg + self.parse() + + def parse(self): + fp = open(self.cfg, "r") + data = fp.readlines() + fp.close() + lines = filter(lambda x: len(x) > 0 and x[0] not in ['#', ';'], map(lambda x: x.strip(), data)) + current = None + for i in range(len(lines)): + line = lines[i] + g = self.ctypeRE.match(line) + if g: # a section header + current = {} + if not self.records.has_key(g.group(1)): + self.records[g.group(1)] = [] + self.records[g.group(1)].append(current) + else: + g = self.entryRE.match(line) + if g: + current[g.group(1)] = g.group(2) + + def __getitem__(self, (ctype, skey)): + if skey == self.key: return self.records[ctype][0][skey] + t = filter(lambda x, p=self.key, s=skey: x[p] == s, self.records[ctype]) + if not t or len(t) > 1: + raise KeyError, "invalid key ('%s', '%s')" % (ctype, skey) + return t[0] + +def random_table_name(prefix, num_chars): + import random + d = [prefix, '_'] + i = 0 + while i < num_chars: + d.append(chr(int(100 * random.random()) % 26 + ord('A'))) + i += 1 + return "".join(d) + +class ResultSetRow: + def __init__(self, rs, row): + self.row = row + self.rs = rs + def __getitem__(self, i): + if type(i) == type(""): + i = self.rs.index(i) + return self.row[i] + def __getslice__(self, i, j): + if type(i) == type(""): i = self.rs.index(i) + if type(j) == type(""): j = self.rs.index(j) + return self.row[i:j] + def __len__(self): + return len(self.row) + def __repr__(self): + return str(self.row) + +class ResultSet: + def __init__(self, headers, results=[]): + self.headers = map(lambda x: x.upper(), headers) + self.results = results + def index(self, i): + return self.headers.index(i.upper()) + def __getitem__(self, i): + return ResultSetRow(self, self.results[i]) + def __getslice__(self, i, j): + return map(lambda x, rs=self: ResultSetRow(rs, x), self.results[i:j]) + def __repr__(self): + return "<%s instance {cols [%d], rows [%d]} at %s>" % (self.__class__, len(self.headers), len(self.results), id(self)) diff --git a/src/main/resources/PythonLibs/decimal.py b/src/main/resources/PythonLibs/decimal.py new file mode 100644 index 0000000000000000000000000000000000000000..9d83b498a71bd43580655503004f1d1838eb78cb --- /dev/null +++ b/src/main/resources/PythonLibs/decimal.py @@ -0,0 +1,6163 @@ +# Copyright (c) 2004 Python Software Foundation. +# All rights reserved. + +# Written by Eric Price <eprice at tjhsst.edu> +# and Facundo Batista <facundo at taniquetil.com.ar> +# and Raymond Hettinger <python at rcn.com> +# and Aahz <aahz at pobox.com> +# and Tim Peters + +# This module is currently Py2.3 compatible and should be kept that way +# unless a major compelling advantage arises. IOW, 2.3 compatibility is +# strongly preferred, but not guaranteed. + +# Also, this module should be kept in sync with the latest updates of +# the IBM specification as it evolves. Those updates will be treated +# as bug fixes (deviation from the spec is a compatibility, usability +# bug) and will be backported. At this point the spec is stabilizing +# and the updates are becoming fewer, smaller, and less significant. + +""" +This is a Py2.3 implementation of decimal floating point arithmetic based on +the General Decimal Arithmetic Specification: + + www2.hursley.ibm.com/decimal/decarith.html + +and IEEE standard 854-1987: + + www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html + +Decimal floating point has finite precision with arbitrarily large bounds. + +The purpose of this module is to support arithmetic using familiar +"schoolhouse" rules and to avoid some of the tricky representation +issues associated with binary floating point. The package is especially +useful for financial applications or for contexts where users have +expectations that are at odds with binary floating point (for instance, +in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead +of the expected Decimal('0.00') returned by decimal floating point). + +Here are some examples of using the decimal module: + +>>> from decimal import * +>>> setcontext(ExtendedContext) +>>> Decimal(0) +Decimal('0') +>>> Decimal('1') +Decimal('1') +>>> Decimal('-.0123') +Decimal('-0.0123') +>>> Decimal(123456) +Decimal('123456') +>>> Decimal('123.45e12345678901234567890') +Decimal('1.2345E+12345678901234567892') +>>> Decimal('1.33') + Decimal('1.27') +Decimal('2.60') +>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') +Decimal('-2.20') +>>> dig = Decimal(1) +>>> print dig / Decimal(3) +0.333333333 +>>> getcontext().prec = 18 +>>> print dig / Decimal(3) +0.333333333333333333 +>>> print dig.sqrt() +1 +>>> print Decimal(3).sqrt() +1.73205080756887729 +>>> print Decimal(3) ** 123 +4.85192780976896427E+58 +>>> inf = Decimal(1) / Decimal(0) +>>> print inf +Infinity +>>> neginf = Decimal(-1) / Decimal(0) +>>> print neginf +-Infinity +>>> print neginf + inf +NaN +>>> print neginf * inf +-Infinity +>>> print dig / 0 +Infinity +>>> getcontext().traps[DivisionByZero] = 1 +>>> print dig / 0 +Traceback (most recent call last): + ... + ... + ... +DivisionByZero: x / 0 +>>> c = Context() +>>> c.traps[InvalidOperation] = 0 +>>> print c.flags[InvalidOperation] +0 +>>> c.divide(Decimal(0), Decimal(0)) +Decimal('NaN') +>>> c.traps[InvalidOperation] = 1 +>>> print c.flags[InvalidOperation] +1 +>>> c.flags[InvalidOperation] = 0 +>>> print c.flags[InvalidOperation] +0 +>>> print c.divide(Decimal(0), Decimal(0)) +Traceback (most recent call last): + ... + ... + ... +InvalidOperation: 0 / 0 +>>> print c.flags[InvalidOperation] +1 +>>> c.flags[InvalidOperation] = 0 +>>> c.traps[InvalidOperation] = 0 +>>> print c.divide(Decimal(0), Decimal(0)) +NaN +>>> print c.flags[InvalidOperation] +1 +>>> +""" + +__all__ = [ + # Two major classes + 'Decimal', 'Context', + + # Contexts + 'DefaultContext', 'BasicContext', 'ExtendedContext', + + # Exceptions + 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', + 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', + + # Constants for use in setting up contexts + 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', + 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', + + # Functions for manipulating contexts + 'setcontext', 'getcontext', 'localcontext' +] + +__version__ = '1.70' # Highest version of the spec this complies with + +import copy as _copy +import math as _math +import numbers as _numbers + +try: + from collections import namedtuple as _namedtuple + DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') +except ImportError: + DecimalTuple = lambda *args: args + +# Rounding +ROUND_DOWN = 'ROUND_DOWN' +ROUND_HALF_UP = 'ROUND_HALF_UP' +ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' +ROUND_CEILING = 'ROUND_CEILING' +ROUND_FLOOR = 'ROUND_FLOOR' +ROUND_UP = 'ROUND_UP' +ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' +ROUND_05UP = 'ROUND_05UP' + +# Errors + +class DecimalException(ArithmeticError): + """Base exception class. + + Used exceptions derive from this. + If an exception derives from another exception besides this (such as + Underflow (Inexact, Rounded, Subnormal) that indicates that it is only + called if the others are present. This isn't actually used for + anything, though. + + handle -- Called when context._raise_error is called and the + trap_enabler is not set. First argument is self, second is the + context. More arguments can be given, those being after + the explanation in _raise_error (For example, + context._raise_error(NewError, '(-x)!', self._sign) would + call NewError().handle(context, self._sign).) + + To define a new exception, it should be sufficient to have it derive + from DecimalException. + """ + def handle(self, context, *args): + pass + + +class Clamped(DecimalException): + """Exponent of a 0 changed to fit bounds. + + This occurs and signals clamped if the exponent of a result has been + altered in order to fit the constraints of a specific concrete + representation. This may occur when the exponent of a zero result would + be outside the bounds of a representation, or when a large normal + number would have an encoded exponent that cannot be represented. In + this latter case, the exponent is reduced to fit and the corresponding + number of zero digits are appended to the coefficient ("fold-down"). + """ + +class InvalidOperation(DecimalException): + """An invalid operation was performed. + + Various bad things cause this: + + Something creates a signaling NaN + -INF + INF + 0 * (+-)INF + (+-)INF / (+-)INF + x % 0 + (+-)INF % x + x._rescale( non-integer ) + sqrt(-x) , x > 0 + 0 ** 0 + x ** (non-integer) + x ** (+-)INF + An operand is invalid + + The result of the operation after these is a quiet positive NaN, + except when the cause is a signaling NaN, in which case the result is + also a quiet NaN, but with the original sign, and an optional + diagnostic information. + """ + def handle(self, context, *args): + if args: + ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) + return ans._fix_nan(context) + return _NaN + +class ConversionSyntax(InvalidOperation): + """Trying to convert badly formed string. + + This occurs and signals invalid-operation if an string is being + converted to a number and it does not conform to the numeric string + syntax. The result is [0,qNaN]. + """ + def handle(self, context, *args): + return _NaN + +class DivisionByZero(DecimalException, ZeroDivisionError): + """Division by 0. + + This occurs and signals division-by-zero if division of a finite number + by zero was attempted (during a divide-integer or divide operation, or a + power operation with negative right-hand operand), and the dividend was + not zero. + + The result of the operation is [sign,inf], where sign is the exclusive + or of the signs of the operands for divide, or is 1 for an odd power of + -0, for power. + """ + + def handle(self, context, sign, *args): + return _SignedInfinity[sign] + +class DivisionImpossible(InvalidOperation): + """Cannot perform the division adequately. + + This occurs and signals invalid-operation if the integer result of a + divide-integer or remainder operation had too many digits (would be + longer than precision). The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class DivisionUndefined(InvalidOperation, ZeroDivisionError): + """Undefined result of division. + + This occurs and signals invalid-operation if division by zero was + attempted (during a divide-integer, divide, or remainder operation), and + the dividend is also zero. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class Inexact(DecimalException): + """Had to round, losing information. + + This occurs and signals inexact whenever the result of an operation is + not exact (that is, it needed to be rounded and any discarded digits + were non-zero), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The inexact signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) was inexact. + """ + +class InvalidContext(InvalidOperation): + """Invalid context. Unknown rounding, for example. + + This occurs and signals invalid-operation if an invalid context was + detected during an operation. This can occur if contexts are not checked + on creation and either the precision exceeds the capability of the + underlying concrete representation or an unknown or unsupported rounding + was specified. These aspects of the context need only be checked when + the values are required to be used. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class Rounded(DecimalException): + """Number got rounded (not necessarily changed during rounding). + + This occurs and signals rounded whenever the result of an operation is + rounded (that is, some zero or non-zero digits were discarded from the + coefficient), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The rounded signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) caused a loss of precision. + """ + +class Subnormal(DecimalException): + """Exponent < Emin before rounding. + + This occurs and signals subnormal whenever the result of a conversion or + operation is subnormal (that is, its adjusted exponent is less than + Emin, before any rounding). The result in all cases is unchanged. + + The subnormal signal may be tested (or trapped) to determine if a given + or operation (or sequence of operations) yielded a subnormal result. + """ + +class Overflow(Inexact, Rounded): + """Numerical overflow. + + This occurs and signals overflow if the adjusted exponent of a result + (from a conversion or from an operation that is not an attempt to divide + by zero), after rounding, would be greater than the largest value that + can be handled by the implementation (the value Emax). + + The result depends on the rounding mode: + + For round-half-up and round-half-even (and for round-half-down and + round-up, if implemented), the result of the operation is [sign,inf], + where sign is the sign of the intermediate result. For round-down, the + result is the largest finite number that can be represented in the + current precision, with the sign of the intermediate result. For + round-ceiling, the result is the same as for round-down if the sign of + the intermediate result is 1, or is [0,inf] otherwise. For round-floor, + the result is the same as for round-down if the sign of the intermediate + result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded + will also be raised. + """ + + def handle(self, context, sign, *args): + if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, + ROUND_HALF_DOWN, ROUND_UP): + return _SignedInfinity[sign] + if sign == 0: + if context.rounding == ROUND_CEILING: + return _SignedInfinity[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + if sign == 1: + if context.rounding == ROUND_FLOOR: + return _SignedInfinity[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + + +class Underflow(Inexact, Rounded, Subnormal): + """Numerical underflow with result rounded to 0. + + This occurs and signals underflow if a result is inexact and the + adjusted exponent of the result would be smaller (more negative) than + the smallest value that can be handled by the implementation (the value + Emin). That is, the result is both inexact and subnormal. + + The result after an underflow will be a subnormal number rounded, if + necessary, so that its exponent is not less than Etiny. This may result + in 0 with the sign of the intermediate result and an exponent of Etiny. + + In all cases, Inexact, Rounded, and Subnormal will also be raised. + """ + +# List of public traps and flags +_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, + Underflow, InvalidOperation, Subnormal] + +# Map conditions (per the spec) to signals +_condition_map = {ConversionSyntax:InvalidOperation, + DivisionImpossible:InvalidOperation, + DivisionUndefined:InvalidOperation, + InvalidContext:InvalidOperation} + +##### Context Functions ################################################## + +# The getcontext() and setcontext() function manage access to a thread-local +# current context. Py2.4 offers direct support for thread locals. If that +# is not available, use threading.currentThread() which is slower but will +# work for older Pythons. If threads are not part of the build, create a +# mock threading object with threading.local() returning the module namespace. + +try: + import threading +except ImportError: + # Python was compiled without threads; create a mock object instead + import sys + class MockThreading(object): + def local(self, sys=sys): + return sys.modules[__name__] + threading = MockThreading() + del sys, MockThreading + +try: + from java.lang import Object + from java.math import BigDecimal + from org.python.core import Py +except ImportError: + #Not Jython, ignore. + pass + +try: + threading.local + +except AttributeError: + + # To fix reloading, force it to create a new context + # Old contexts have different exceptions in their dicts, making problems. + if hasattr(threading.currentThread(), '__decimal_context__'): + del threading.currentThread().__decimal_context__ + + def setcontext(context): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + threading.currentThread().__decimal_context__ = context + + def getcontext(): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return threading.currentThread().__decimal_context__ + except AttributeError: + context = Context() + threading.currentThread().__decimal_context__ = context + return context + +else: + + local = threading.local() + if hasattr(local, '__decimal_context__'): + del local.__decimal_context__ + + def getcontext(_local=local): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return _local.__decimal_context__ + except AttributeError: + context = Context() + _local.__decimal_context__ = context + return context + + def setcontext(context, _local=local): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + _local.__decimal_context__ = context + + del threading, local # Don't contaminate the namespace + +def localcontext(ctx=None): + """Return a context manager for a copy of the supplied context + + Uses a copy of the current context if no context is specified + The returned context manager creates a local decimal context + in a with statement: + def sin(x): + with localcontext() as ctx: + ctx.prec += 2 + # Rest of sin calculation algorithm + # uses a precision 2 greater than normal + return +s # Convert result to normal precision + + def sin(x): + with localcontext(ExtendedContext): + # Rest of sin calculation algorithm + # uses the Extended Context from the + # General Decimal Arithmetic Specification + return +s # Convert result to normal context + + >>> setcontext(DefaultContext) + >>> print getcontext().prec + 28 + >>> with localcontext(): + ... ctx = getcontext() + ... ctx.prec += 2 + ... print ctx.prec + ... + 30 + >>> with localcontext(ExtendedContext): + ... print getcontext().prec + ... + 9 + >>> print getcontext().prec + 28 + """ + if ctx is None: ctx = getcontext() + return _ContextManager(ctx) + + +##### Decimal class ####################################################### + +class Decimal(object): + """Floating point class for decimal arithmetic.""" + + __slots__ = ('_exp','_int','_sign', '_is_special') + # Generally, the value of the Decimal instance is given by + # (-1)**_sign * _int * 10**_exp + # Special values are signified by _is_special == True + + # We're immutable, so use __new__ not __init__ + def __new__(cls, value="0", context=None): + """Create a decimal point instance. + + >>> Decimal('3.14') # string input + Decimal('3.14') + >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) + Decimal('3.14') + >>> Decimal(314) # int or long + Decimal('314') + >>> Decimal(Decimal(314)) # another decimal instance + Decimal('314') + >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay + Decimal('3.14') + """ + + # Note that the coefficient, self._int, is actually stored as + # a string rather than as a tuple of digits. This speeds up + # the "digits to integer" and "integer to digits" conversions + # that are used in almost every arithmetic operation on + # Decimals. This is an internal detail: the as_tuple function + # and the Decimal constructor still deal with tuples of + # digits. + + self = object.__new__(cls) + + # From a string + # REs insist on real strings, so we can too. + if isinstance(value, basestring): + m = _parser(value.strip()) + if m is None: + if context is None: + context = getcontext() + return context._raise_error(ConversionSyntax, + "Invalid literal for Decimal: %r" % value) + + if m.group('sign') == "-": + self._sign = 1 + else: + self._sign = 0 + intpart = m.group('int') + if intpart is not None: + # finite number + fracpart = m.group('frac') or '' + exp = int(m.group('exp') or '0') + self._int = str(int(intpart+fracpart)) + self._exp = exp - len(fracpart) + self._is_special = False + else: + diag = m.group('diag') + if diag is not None: + # NaN + self._int = str(int(diag or '0')).lstrip('0') + if m.group('signal'): + self._exp = 'N' + else: + self._exp = 'n' + else: + # infinity + self._int = '0' + self._exp = 'F' + self._is_special = True + return self + + # From an integer + if isinstance(value, (int,long)): + if value >= 0: + self._sign = 0 + else: + self._sign = 1 + self._exp = 0 + self._int = str(abs(value)) + self._is_special = False + return self + + # From another decimal + if isinstance(value, Decimal): + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + # From an internal working value + if isinstance(value, _WorkRep): + self._sign = value.sign + self._int = str(value.int) + self._exp = int(value.exp) + self._is_special = False + return self + + # tuple/list conversion (possibly from as_tuple()) + if isinstance(value, (list,tuple)): + if len(value) != 3: + raise ValueError('Invalid tuple size in creation of Decimal ' + 'from list or tuple. The list or tuple ' + 'should have exactly three elements.') + # process sign. The isinstance test rejects floats + if not (isinstance(value[0], (int, long)) and value[0] in (0,1)): + raise ValueError("Invalid sign. The first value in the tuple " + "should be an integer; either 0 for a " + "positive number or 1 for a negative number.") + self._sign = value[0] + if value[2] == 'F': + # infinity: value[1] is ignored + self._int = '0' + self._exp = value[2] + self._is_special = True + else: + # process and validate the digits in value[1] + digits = [] + for digit in value[1]: + if isinstance(digit, (int, long)) and 0 <= digit <= 9: + # skip leading zeros + if digits or digit != 0: + digits.append(digit) + else: + raise ValueError("The second value in the tuple must " + "be composed of integers in the range " + "0 through 9.") + if value[2] in ('n', 'N'): + # NaN: digits form the diagnostic + self._int = ''.join(map(str, digits)) + self._exp = value[2] + self._is_special = True + elif isinstance(value[2], (int, long)): + # finite number: digits give the coefficient + self._int = ''.join(map(str, digits or [0])) + self._exp = value[2] + self._is_special = False + else: + raise ValueError("The third value in the tuple must " + "be an integer, or one of the " + "strings 'F', 'n', 'N'.") + return self + + if isinstance(value, float): + value = Decimal.from_float(value) + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + raise TypeError("Cannot convert %r to Decimal" % value) + + # @classmethod, but @decorator is not valid Python 2.3 syntax, so + # don't use it (see notes on Py2.3 compatibility at top of file) + def from_float(cls, f): + """Converts a float to a decimal number, exactly. + + Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). + Since 0.1 is not exactly representable in binary floating point, the + value is stored as the nearest representable value which is + 0x1.999999999999ap-4. The exact equivalent of the value in decimal + is 0.1000000000000000055511151231257827021181583404541015625. + + >>> Decimal.from_float(0.1) + Decimal('0.1000000000000000055511151231257827021181583404541015625') + >>> Decimal.from_float(float('nan')) + Decimal('NaN') + >>> Decimal.from_float(float('inf')) + Decimal('Infinity') + >>> Decimal.from_float(-float('inf')) + Decimal('-Infinity') + >>> Decimal.from_float(-0.0) + Decimal('-0') + + """ + if isinstance(f, (int, long)): # handle integer inputs + return cls(f) + if _math.isinf(f) or _math.isnan(f): # raises TypeError if not a float + return cls(repr(f)) + if _math.copysign(1.0, f) == 1.0: + sign = 0 + else: + sign = 1 + n, d = abs(f).as_integer_ratio() + k = d.bit_length() - 1 + result = _dec_from_triple(sign, str(n*5**k), -k) + if cls is Decimal: + return result + else: + return cls(result) + from_float = classmethod(from_float) + + def _isnan(self): + """Returns whether the number is not actually one. + + 0 if a number + 1 if NaN + 2 if sNaN + """ + if self._is_special: + exp = self._exp + if exp == 'n': + return 1 + elif exp == 'N': + return 2 + return 0 + + def _isinfinity(self): + """Returns whether the number is infinite + + 0 if finite or not a number + 1 if +INF + -1 if -INF + """ + if self._exp == 'F': + if self._sign: + return -1 + return 1 + return 0 + + def _check_nans(self, other=None, context=None): + """Returns whether the number is not actually one. + + if self, other are sNaN, signal + if self, other are NaN return nan + return 0 + + Done before operations. + """ + + self_is_nan = self._isnan() + if other is None: + other_is_nan = False + else: + other_is_nan = other._isnan() + + if self_is_nan or other_is_nan: + if context is None: + context = getcontext() + + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if self_is_nan: + return self._fix_nan(context) + + return other._fix_nan(context) + return 0 + + def _compare_check_nans(self, other, context): + """Version of _check_nans used for the signaling comparisons + compare_signal, __le__, __lt__, __ge__, __gt__. + + Signal InvalidOperation if either self or other is a (quiet + or signaling) NaN. Signaling NaNs take precedence over quiet + NaNs. + + Return 0 if neither operand is a NaN. + + """ + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + if self.is_snan(): + return context._raise_error(InvalidOperation, + 'comparison involving sNaN', + self) + elif other.is_snan(): + return context._raise_error(InvalidOperation, + 'comparison involving sNaN', + other) + elif self.is_qnan(): + return context._raise_error(InvalidOperation, + 'comparison involving NaN', + self) + elif other.is_qnan(): + return context._raise_error(InvalidOperation, + 'comparison involving NaN', + other) + return 0 + + def __nonzero__(self): + """Return True if self is nonzero; otherwise return False. + + NaNs and infinities are considered nonzero. + """ + return self._is_special or self._int != '0' + + def _cmp(self, other): + """Compare the two non-NaN decimal instances self and other. + + Returns -1 if self < other, 0 if self == other and 1 + if self > other. This routine is for internal use only.""" + + if self._is_special or other._is_special: + self_inf = self._isinfinity() + other_inf = other._isinfinity() + if self_inf == other_inf: + return 0 + elif self_inf < other_inf: + return -1 + else: + return 1 + + # check for zeros; Decimal('0') == Decimal('-0') + if not self: + if not other: + return 0 + else: + return -((-1)**other._sign) + if not other: + return (-1)**self._sign + + # If different signs, neg one is less + if other._sign < self._sign: + return -1 + if self._sign < other._sign: + return 1 + + self_adjusted = self.adjusted() + other_adjusted = other.adjusted() + if self_adjusted == other_adjusted: + self_padded = self._int + '0'*(self._exp - other._exp) + other_padded = other._int + '0'*(other._exp - self._exp) + if self_padded == other_padded: + return 0 + elif self_padded < other_padded: + return -(-1)**self._sign + else: + return (-1)**self._sign + elif self_adjusted > other_adjusted: + return (-1)**self._sign + else: # self_adjusted < other_adjusted + return -((-1)**self._sign) + + # Note: The Decimal standard doesn't cover rich comparisons for + # Decimals. In particular, the specification is silent on the + # subject of what should happen for a comparison involving a NaN. + # We take the following approach: + # + # == comparisons involving a quiet NaN always return False + # != comparisons involving a quiet NaN always return True + # == or != comparisons involving a signaling NaN signal + # InvalidOperation, and return False or True as above if the + # InvalidOperation is not trapped. + # <, >, <= and >= comparisons involving a (quiet or signaling) + # NaN signal InvalidOperation, and return False if the + # InvalidOperation is not trapped. + # + # This behavior is designed to conform as closely as possible to + # that specified by IEEE 754. + + def __eq__(self, other, context=None): + other = _convert_other(other, allow_float=True) + if other is NotImplemented: + return other + if self._check_nans(other, context): + return False + return self._cmp(other) == 0 + + def __ne__(self, other, context=None): + other = _convert_other(other, allow_float=True) + if other is NotImplemented: + return other + if self._check_nans(other, context): + return True + return self._cmp(other) != 0 + + def __lt__(self, other, context=None): + other = _convert_other(other, allow_float=True) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) < 0 + + def __le__(self, other, context=None): + other = _convert_other(other, allow_float=True) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) <= 0 + + def __gt__(self, other, context=None): + other = _convert_other(other, allow_float=True) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) > 0 + + def __ge__(self, other, context=None): + other = _convert_other(other, allow_float=True) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) >= 0 + + def compare(self, other, context=None): + """Compares one to another. + + -1 => a < b + 0 => a = b + 1 => a > b + NaN => one is NaN + Like __cmp__, but returns Decimal instances. + """ + other = _convert_other(other, raiseit=True) + + # Compare(NaN, NaN) = NaN + if (self._is_special or other and other._is_special): + ans = self._check_nans(other, context) + if ans: + return ans + + return Decimal(self._cmp(other)) + + def __hash__(self): + """x.__hash__() <==> hash(x)""" + # Decimal integers must hash the same as the ints + # + # The hash of a nonspecial noninteger Decimal must depend only + # on the value of that Decimal, and not on its representation. + # For example: hash(Decimal('100E-1')) == hash(Decimal('10')). + + # Equality comparisons involving signaling nans can raise an + # exception; since equality checks are implicitly and + # unpredictably used when checking set and dict membership, we + # prevent signaling nans from being used as set elements or + # dict keys by making __hash__ raise an exception. + if self._is_special: + if self.is_snan(): + raise TypeError('Cannot hash a signaling NaN value.') + elif self.is_nan(): + # 0 to match hash(float('nan')) + return 0 + else: + # values chosen to match hash(float('inf')) and + # hash(float('-inf')). + if self._sign: + return -271828 + else: + return 314159 + + # In Python 2.7, we're allowing comparisons (but not + # arithmetic operations) between floats and Decimals; so if + # a Decimal instance is exactly representable as a float then + # its hash should match that of the float. + self_as_float = float(self) + if Decimal.from_float(self_as_float) == self: + return hash(self_as_float) + + if self._isinteger(): + # We do this differently in Jython due to the different maxint. + return hash(long(self.to_integral_value())) + # The value of a nonzero nonspecial Decimal instance is + # faithfully represented by the triple consisting of its sign, + # its adjusted exponent, and its coefficient with trailing + # zeros removed. + return hash((self._sign, + self._exp+len(self._int), + self._int.rstrip('0'))) + + def as_tuple(self): + """Represents the number as a triple tuple. + + To show the internals exactly as they are. + """ + return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) + + def __repr__(self): + """Represents the number as an instance of Decimal.""" + # Invariant: eval(repr(d)) == d + return "Decimal('%s')" % str(self) + + def __str__(self, eng=False, context=None): + """Return string representation of the number in scientific notation. + + Captures all of the information in the underlying representation. + """ + + sign = ['', '-'][self._sign] + if self._is_special: + if self._exp == 'F': + return sign + 'Infinity' + elif self._exp == 'n': + return sign + 'NaN' + self._int + else: # self._exp == 'N' + return sign + 'sNaN' + self._int + + # number of digits of self._int to left of decimal point + leftdigits = self._exp + len(self._int) + + # dotplace is number of digits of self._int to the left of the + # decimal point in the mantissa of the output string (that is, + # after adjusting the exponent) + if self._exp <= 0 and leftdigits > -6: + # no exponent required + dotplace = leftdigits + elif not eng: + # usual scientific notation: 1 digit on left of the point + dotplace = 1 + elif self._int == '0': + # engineering notation, zero + dotplace = (leftdigits + 1) % 3 - 1 + else: + # engineering notation, nonzero + dotplace = (leftdigits - 1) % 3 + 1 + + if dotplace <= 0: + intpart = '0' + fracpart = '.' + '0'*(-dotplace) + self._int + elif dotplace >= len(self._int): + intpart = self._int+'0'*(dotplace-len(self._int)) + fracpart = '' + else: + intpart = self._int[:dotplace] + fracpart = '.' + self._int[dotplace:] + if leftdigits == dotplace: + exp = '' + else: + if context is None: + context = getcontext() + exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) + + return sign + intpart + fracpart + exp + + def to_eng_string(self, context=None): + """Convert to engineering-type string. + + Engineering notation has an exponent which is a multiple of 3, so there + are up to 3 digits left of the decimal place. + + Same rules for when in exponential and when as a value as in __str__. + """ + return self.__str__(eng=True, context=context) + + def __neg__(self, context=None): + """Returns a copy with the sign switched. + + Rounds, if it has reason. + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if not self: + # -Decimal('0') is Decimal('0'), not Decimal('-0') + ans = self.copy_abs() + else: + ans = self.copy_negate() + + if context is None: + context = getcontext() + return ans._fix(context) + + def __pos__(self, context=None): + """Returns a copy, unless it is a sNaN. + + Rounds the number (if more then precision digits) + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if not self: + # + (-0) = 0 + ans = self.copy_abs() + else: + ans = Decimal(self) + + if context is None: + context = getcontext() + return ans._fix(context) + + def __abs__(self, round=True, context=None): + """Returns the absolute value of self. + + If the keyword argument 'round' is false, do not round. The + expression self.__abs__(round=False) is equivalent to + self.copy_abs(). + """ + if not round: + return self.copy_abs() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if self._sign: + ans = self.__neg__(context=context) + else: + ans = self.__pos__(context=context) + + return ans + + def __add__(self, other, context=None): + """Returns self + other. + + -INF + INF (or the reverse) cause InvalidOperation errors. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + # If both INF, same sign => same as both, opposite => error. + if self._sign != other._sign and other._isinfinity(): + return context._raise_error(InvalidOperation, '-INF + INF') + return Decimal(self) + if other._isinfinity(): + return Decimal(other) # Can't both be infinity here + + exp = min(self._exp, other._exp) + negativezero = 0 + if context.rounding == ROUND_FLOOR and self._sign != other._sign: + # If the answer is 0, the sign should be negative, in this case. + negativezero = 1 + + if not self and not other: + sign = min(self._sign, other._sign) + if negativezero: + sign = 1 + ans = _dec_from_triple(sign, '0', exp) + ans = ans._fix(context) + return ans + if not self: + exp = max(exp, other._exp - context.prec-1) + ans = other._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + if not other: + exp = max(exp, self._exp - context.prec-1) + ans = self._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + op1, op2 = _normalize(op1, op2, context.prec) + + result = _WorkRep() + if op1.sign != op2.sign: + # Equal and opposite + if op1.int == op2.int: + ans = _dec_from_triple(negativezero, '0', exp) + ans = ans._fix(context) + return ans + if op1.int < op2.int: + op1, op2 = op2, op1 + # OK, now abs(op1) > abs(op2) + if op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = op2.sign, op1.sign + else: + result.sign = 0 + # So we know the sign, and op1 > 0. + elif op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = (0, 0) + else: + result.sign = 0 + # Now, op1 > abs(op2) > 0 + + if op2.sign == 0: + result.int = op1.int + op2.int + else: + result.int = op1.int - op2.int + + result.exp = op1.exp + ans = Decimal(result) + ans = ans._fix(context) + return ans + + __radd__ = __add__ + + def __sub__(self, other, context=None): + """Return self - other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if self._is_special or other._is_special: + ans = self._check_nans(other, context=context) + if ans: + return ans + + # self - other is computed as self + other.copy_negate() + return self.__add__(other.copy_negate(), context=context) + + def __rsub__(self, other, context=None): + """Return other - self""" + other = _convert_other(other) + if other is NotImplemented: + return other + + return other.__sub__(self, context=context) + + def __mul__(self, other, context=None): + """Return self * other. + + (+-) INF * 0 (or its reverse) raise InvalidOperation. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + resultsign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if not other: + return context._raise_error(InvalidOperation, '(+-)INF * 0') + return _SignedInfinity[resultsign] + + if other._isinfinity(): + if not self: + return context._raise_error(InvalidOperation, '0 * (+-)INF') + return _SignedInfinity[resultsign] + + resultexp = self._exp + other._exp + + # Special case for multiplying by zero + if not self or not other: + ans = _dec_from_triple(resultsign, '0', resultexp) + # Fixing in case the exponent is out of bounds + ans = ans._fix(context) + return ans + + # Special case for multiplying by power of 10 + if self._int == '1': + ans = _dec_from_triple(resultsign, other._int, resultexp) + ans = ans._fix(context) + return ans + if other._int == '1': + ans = _dec_from_triple(resultsign, self._int, resultexp) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + + ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) + ans = ans._fix(context) + + return ans + __rmul__ = __mul__ + + def __truediv__(self, other, context=None): + """Return self / other.""" + other = _convert_other(other) + if other is NotImplemented: + return NotImplemented + + if context is None: + context = getcontext() + + sign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity() and other._isinfinity(): + return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') + + if self._isinfinity(): + return _SignedInfinity[sign] + + if other._isinfinity(): + context._raise_error(Clamped, 'Division by infinity') + return _dec_from_triple(sign, '0', context.Etiny()) + + # Special cases for zeroes + if not other: + if not self: + return context._raise_error(DivisionUndefined, '0 / 0') + return context._raise_error(DivisionByZero, 'x / 0', sign) + + if not self: + exp = self._exp - other._exp + coeff = 0 + else: + # OK, so neither = 0, INF or NaN + shift = len(other._int) - len(self._int) + context.prec + 1 + exp = self._exp - other._exp - shift + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if shift >= 0: + coeff, remainder = divmod(op1.int * 10**shift, op2.int) + else: + coeff, remainder = divmod(op1.int, op2.int * 10**-shift) + if remainder: + # result is not exact; adjust to ensure correct rounding + if coeff % 5 == 0: + coeff += 1 + else: + # result is exact; get as close to ideal exponent as possible + ideal_exp = self._exp - other._exp + while exp < ideal_exp and coeff % 10 == 0: + coeff //= 10 + exp += 1 + + ans = _dec_from_triple(sign, str(coeff), exp) + return ans._fix(context) + + def _divide(self, other, context): + """Return (self // other, self % other), to context.prec precision. + + Assumes that neither self nor other is a NaN, that self is not + infinite and that other is nonzero. + """ + sign = self._sign ^ other._sign + if other._isinfinity(): + ideal_exp = self._exp + else: + ideal_exp = min(self._exp, other._exp) + + expdiff = self.adjusted() - other.adjusted() + if not self or other._isinfinity() or expdiff <= -2: + return (_dec_from_triple(sign, '0', 0), + self._rescale(ideal_exp, context.rounding)) + if expdiff <= context.prec: + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + if q < 10**context.prec: + return (_dec_from_triple(sign, str(q), 0), + _dec_from_triple(self._sign, str(r), ideal_exp)) + + # Here the quotient is too large to be representable + ans = context._raise_error(DivisionImpossible, + 'quotient too large in //, % or divmod') + return ans, ans + + def __rtruediv__(self, other, context=None): + """Swaps self/other and returns __truediv__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__truediv__(self, context=context) + + __div__ = __truediv__ + __rdiv__ = __rtruediv__ + + def __divmod__(self, other, context=None): + """ + Return (self // other, self % other) + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return (ans, ans) + + sign = self._sign ^ other._sign + if self._isinfinity(): + if other._isinfinity(): + ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') + return ans, ans + else: + return (_SignedInfinity[sign], + context._raise_error(InvalidOperation, 'INF % x')) + + if not other: + if not self: + ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') + return ans, ans + else: + return (context._raise_error(DivisionByZero, 'x // 0', sign), + context._raise_error(InvalidOperation, 'x % 0')) + + quotient, remainder = self._divide(other, context) + remainder = remainder._fix(context) + return quotient, remainder + + def __rdivmod__(self, other, context=None): + """Swaps self/other and returns __divmod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__divmod__(self, context=context) + + def __mod__(self, other, context=None): + """ + self % other + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + return context._raise_error(InvalidOperation, 'INF % x') + elif not other: + if self: + return context._raise_error(InvalidOperation, 'x % 0') + else: + return context._raise_error(DivisionUndefined, '0 % 0') + + remainder = self._divide(other, context)[1] + remainder = remainder._fix(context) + return remainder + + def __rmod__(self, other, context=None): + """Swaps self/other and returns __mod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__mod__(self, context=context) + + def remainder_near(self, other, context=None): + """ + Remainder nearest to 0- abs(remainder-near) <= other/2 + """ + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + # self == +/-infinity -> InvalidOperation + if self._isinfinity(): + return context._raise_error(InvalidOperation, + 'remainder_near(infinity, x)') + + # other == 0 -> either InvalidOperation or DivisionUndefined + if not other: + if self: + return context._raise_error(InvalidOperation, + 'remainder_near(x, 0)') + else: + return context._raise_error(DivisionUndefined, + 'remainder_near(0, 0)') + + # other = +/-infinity -> remainder = self + if other._isinfinity(): + ans = Decimal(self) + return ans._fix(context) + + # self = 0 -> remainder = self, with ideal exponent + ideal_exponent = min(self._exp, other._exp) + if not self: + ans = _dec_from_triple(self._sign, '0', ideal_exponent) + return ans._fix(context) + + # catch most cases of large or small quotient + expdiff = self.adjusted() - other.adjusted() + if expdiff >= context.prec + 1: + # expdiff >= prec+1 => abs(self/other) > 10**prec + return context._raise_error(DivisionImpossible) + if expdiff <= -2: + # expdiff <= -2 => abs(self/other) < 0.1 + ans = self._rescale(ideal_exponent, context.rounding) + return ans._fix(context) + + # adjust both arguments to have the same exponent, then divide + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + # remainder is r*10**ideal_exponent; other is +/-op2.int * + # 10**ideal_exponent. Apply correction to ensure that + # abs(remainder) <= abs(other)/2 + if 2*r + (q&1) > op2.int: + r -= op2.int + q += 1 + + if q >= 10**context.prec: + return context._raise_error(DivisionImpossible) + + # result has same sign as self unless r is negative + sign = self._sign + if r < 0: + sign = 1-sign + r = -r + + ans = _dec_from_triple(sign, str(r), ideal_exponent) + return ans._fix(context) + + def __floordiv__(self, other, context=None): + """self // other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if other._isinfinity(): + return context._raise_error(InvalidOperation, 'INF // INF') + else: + return _SignedInfinity[self._sign ^ other._sign] + + if not other: + if self: + return context._raise_error(DivisionByZero, 'x // 0', + self._sign ^ other._sign) + else: + return context._raise_error(DivisionUndefined, '0 // 0') + + return self._divide(other, context)[0] + + def __rfloordiv__(self, other, context=None): + """Swaps self/other and returns __floordiv__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__floordiv__(self, context=context) + + def __float__(self): + """Float representation.""" + if self._isnan(): + if self.is_snan(): + raise ValueError("Cannot convert signaling NaN to float") + s = "-nan" if self._sign else "nan" + else: + s = str(self) + return float(s) + + def __int__(self): + """Converts self to an int, truncating if necessary.""" + if self._is_special: + if self._isnan(): + raise ValueError("Cannot convert NaN to integer") + elif self._isinfinity(): + raise OverflowError("Cannot convert infinity to integer") + s = (-1)**self._sign + if self._exp >= 0: + return s*int(self._int)*10**self._exp + else: + return s*int(self._int[:self._exp] or '0') + + __trunc__ = __int__ + + def real(self): + return self + real = property(real) + + def imag(self): + return Decimal(0) + imag = property(imag) + + def conjugate(self): + return self + + def __complex__(self): + return complex(float(self)) + + def __long__(self): + """Converts to a long. + + Equivalent to long(int(self)) + """ + return long(self.__int__()) + + def _fix_nan(self, context): + """Decapitate the payload of a NaN to fit the context""" + payload = self._int + + # maximum length of payload is precision if _clamp=0, + # precision-1 if _clamp=1. + max_payload_len = context.prec - context._clamp + if len(payload) > max_payload_len: + payload = payload[len(payload)-max_payload_len:].lstrip('0') + return _dec_from_triple(self._sign, payload, self._exp, True) + return Decimal(self) + + def _fix(self, context): + """Round if it is necessary to keep self within prec precision. + + Rounds and fixes the exponent. Does not raise on a sNaN. + + Arguments: + self - Decimal instance + context - context used. + """ + + if self._is_special: + if self._isnan(): + # decapitate payload if necessary + return self._fix_nan(context) + else: + # self is +/-Infinity; return unaltered + return Decimal(self) + + # if self is zero then exponent should be between Etiny and + # Emax if _clamp==0, and between Etiny and Etop if _clamp==1. + Etiny = context.Etiny() + Etop = context.Etop() + if not self: + exp_max = [context.Emax, Etop][context._clamp] + new_exp = min(max(self._exp, Etiny), exp_max) + if new_exp != self._exp: + context._raise_error(Clamped) + return _dec_from_triple(self._sign, '0', new_exp) + else: + return Decimal(self) + + # exp_min is the smallest allowable exponent of the result, + # equal to max(self.adjusted()-context.prec+1, Etiny) + exp_min = len(self._int) + self._exp - context.prec + if exp_min > Etop: + # overflow: exp_min > Etop iff self.adjusted() > Emax + ans = context._raise_error(Overflow, 'above Emax', self._sign) + context._raise_error(Inexact) + context._raise_error(Rounded) + return ans + + self_is_subnormal = exp_min < Etiny + if self_is_subnormal: + exp_min = Etiny + + # round if self has too many digits + if self._exp < exp_min: + digits = len(self._int) + self._exp - exp_min + if digits < 0: + self = _dec_from_triple(self._sign, '1', exp_min-1) + digits = 0 + rounding_method = self._pick_rounding_function[context.rounding] + changed = getattr(self, rounding_method)(digits) + coeff = self._int[:digits] or '0' + if changed > 0: + coeff = str(int(coeff)+1) + if len(coeff) > context.prec: + coeff = coeff[:-1] + exp_min += 1 + + # check whether the rounding pushed the exponent out of range + if exp_min > Etop: + ans = context._raise_error(Overflow, 'above Emax', self._sign) + else: + ans = _dec_from_triple(self._sign, coeff, exp_min) + + # raise the appropriate signals, taking care to respect + # the precedence described in the specification + if changed and self_is_subnormal: + context._raise_error(Underflow) + if self_is_subnormal: + context._raise_error(Subnormal) + if changed: + context._raise_error(Inexact) + context._raise_error(Rounded) + if not ans: + # raise Clamped on underflow to 0 + context._raise_error(Clamped) + return ans + + if self_is_subnormal: + context._raise_error(Subnormal) + + # fold down if _clamp == 1 and self has too few digits + if context._clamp == 1 and self._exp > Etop: + context._raise_error(Clamped) + self_padded = self._int + '0'*(self._exp - Etop) + return _dec_from_triple(self._sign, self_padded, Etop) + + # here self was representable to begin with; return unchanged + return Decimal(self) + + _pick_rounding_function = {} + + # for each of the rounding functions below: + # self is a finite, nonzero Decimal + # prec is an integer satisfying 0 <= prec < len(self._int) + # + # each function returns either -1, 0, or 1, as follows: + # 1 indicates that self should be rounded up (away from zero) + # 0 indicates that self should be truncated, and that all the + # digits to be truncated are zeros (so the value is unchanged) + # -1 indicates that there are nonzero digits to be truncated + + def _round_down(self, prec): + """Also known as round-towards-0, truncate.""" + if _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_up(self, prec): + """Rounds away from 0.""" + return -self._round_down(prec) + + def _round_half_up(self, prec): + """Rounds 5 up (away from 0)""" + if self._int[prec] in '56789': + return 1 + elif _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_half_down(self, prec): + """Round 5 down""" + if _exact_half(self._int, prec): + return -1 + else: + return self._round_half_up(prec) + + def _round_half_even(self, prec): + """Round 5 to even, rest to nearest.""" + if _exact_half(self._int, prec) and \ + (prec == 0 or self._int[prec-1] in '02468'): + return -1 + else: + return self._round_half_up(prec) + + def _round_ceiling(self, prec): + """Rounds up (not away from 0 if negative.)""" + if self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_floor(self, prec): + """Rounds down (not towards 0 if negative)""" + if not self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_05up(self, prec): + """Round down unless digit prec-1 is 0 or 5.""" + if prec and self._int[prec-1] not in '05': + return self._round_down(prec) + else: + return -self._round_down(prec) + + def fma(self, other, third, context=None): + """Fused multiply-add. + + Returns self*other+third with no rounding of the intermediate + product self*other. + + self and other are multiplied together, with no rounding of + the result. The third operand is then added to the result, + and a single final rounding is performed. + """ + + other = _convert_other(other, raiseit=True) + + # compute product; raise InvalidOperation if either operand is + # a signaling NaN or if the product is zero times infinity. + if self._is_special or other._is_special: + if context is None: + context = getcontext() + if self._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', self) + if other._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', other) + if self._exp == 'n': + product = self + elif other._exp == 'n': + product = other + elif self._exp == 'F': + if not other: + return context._raise_error(InvalidOperation, + 'INF * 0 in fma') + product = _SignedInfinity[self._sign ^ other._sign] + elif other._exp == 'F': + if not self: + return context._raise_error(InvalidOperation, + '0 * INF in fma') + product = _SignedInfinity[self._sign ^ other._sign] + else: + product = _dec_from_triple(self._sign ^ other._sign, + str(int(self._int) * int(other._int)), + self._exp + other._exp) + + third = _convert_other(third, raiseit=True) + return product.__add__(third, context) + + def _power_modulo(self, other, modulo, context=None): + """Three argument version of __pow__""" + + # if can't convert other and modulo to Decimal, raise + # TypeError; there's no point returning NotImplemented (no + # equivalent of __rpow__ for three argument pow) + other = _convert_other(other, raiseit=True) + modulo = _convert_other(modulo, raiseit=True) + + if context is None: + context = getcontext() + + # deal with NaNs: if there are any sNaNs then first one wins, + # (i.e. behaviour for NaNs is identical to that of fma) + self_is_nan = self._isnan() + other_is_nan = other._isnan() + modulo_is_nan = modulo._isnan() + if self_is_nan or other_is_nan or modulo_is_nan: + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if modulo_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + modulo) + if self_is_nan: + return self._fix_nan(context) + if other_is_nan: + return other._fix_nan(context) + return modulo._fix_nan(context) + + # check inputs: we apply same restrictions as Python's pow() + if not (self._isinteger() and + other._isinteger() and + modulo._isinteger()): + return context._raise_error(InvalidOperation, + 'pow() 3rd argument not allowed ' + 'unless all arguments are integers') + if other < 0: + return context._raise_error(InvalidOperation, + 'pow() 2nd argument cannot be ' + 'negative when 3rd argument specified') + if not modulo: + return context._raise_error(InvalidOperation, + 'pow() 3rd argument cannot be 0') + + # additional restriction for decimal: the modulus must be less + # than 10**prec in absolute value + if modulo.adjusted() >= context.prec: + return context._raise_error(InvalidOperation, + 'insufficient precision: pow() 3rd ' + 'argument must not have more than ' + 'precision digits') + + # define 0**0 == NaN, for consistency with two-argument pow + # (even though it hurts!) + if not other and not self: + return context._raise_error(InvalidOperation, + 'at least one of pow() 1st argument ' + 'and 2nd argument must be nonzero ;' + '0**0 is not defined') + + # compute sign of result + if other._iseven(): + sign = 0 + else: + sign = self._sign + + # convert modulo to a Python integer, and self and other to + # Decimal integers (i.e. force their exponents to be >= 0) + modulo = abs(int(modulo)) + base = _WorkRep(self.to_integral_value()) + exponent = _WorkRep(other.to_integral_value()) + + # compute result using integer pow() + base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo + for i in xrange(exponent.exp): + base = pow(base, 10, modulo) + base = pow(base, exponent.int, modulo) + + return _dec_from_triple(sign, str(base), 0) + + def _power_exact(self, other, p): + """Attempt to compute self**other exactly. + + Given Decimals self and other and an integer p, attempt to + compute an exact result for the power self**other, with p + digits of precision. Return None if self**other is not + exactly representable in p digits. + + Assumes that elimination of special cases has already been + performed: self and other must both be nonspecial; self must + be positive and not numerically equal to 1; other must be + nonzero. For efficiency, other._exp should not be too large, + so that 10**abs(other._exp) is a feasible calculation.""" + + # In the comments below, we write x for the value of self and + # y for the value of other. Write x = xc*10**xe and y = + # yc*10**ye. + + # The main purpose of this method is to identify the *failure* + # of x**y to be exactly representable with as little effort as + # possible. So we look for cheap and easy tests that + # eliminate the possibility of x**y being exact. Only if all + # these tests are passed do we go on to actually compute x**y. + + # Here's the main idea. First normalize both x and y. We + # express y as a rational m/n, with m and n relatively prime + # and n>0. Then for x**y to be exactly representable (at + # *any* precision), xc must be the nth power of a positive + # integer and xe must be divisible by n. If m is negative + # then additionally xc must be a power of either 2 or 5, hence + # a power of 2**n or 5**n. + # + # There's a limit to how small |y| can be: if y=m/n as above + # then: + # + # (1) if xc != 1 then for the result to be representable we + # need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So + # if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <= + # 2**(1/|y|), hence xc**|y| < 2 and the result is not + # representable. + # + # (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if + # |y| < 1/|xe| then the result is not representable. + # + # Note that since x is not equal to 1, at least one of (1) and + # (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) < + # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye. + # + # There's also a limit to how large y can be, at least if it's + # positive: the normalized result will have coefficient xc**y, + # so if it's representable then xc**y < 10**p, and y < + # p/log10(xc). Hence if y*log10(xc) >= p then the result is + # not exactly representable. + + # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye, + # so |y| < 1/xe and the result is not representable. + # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y| + # < 1/nbits(xc). + + x = _WorkRep(self) + xc, xe = x.int, x.exp + while xc % 10 == 0: + xc //= 10 + xe += 1 + + y = _WorkRep(other) + yc, ye = y.int, y.exp + while yc % 10 == 0: + yc //= 10 + ye += 1 + + # case where xc == 1: result is 10**(xe*y), with xe*y + # required to be an integer + if xc == 1: + xe *= yc + # result is now 10**(xe * 10**ye); xe * 10**ye must be integral + while xe % 10 == 0: + xe //= 10 + ye += 1 + if ye < 0: + return None + exponent = xe * 10**ye + if y.sign == 1: + exponent = -exponent + # if other is a nonnegative integer, use ideal exponent + if other._isinteger() and other._sign == 0: + ideal_exponent = self._exp*int(other) + zeros = min(exponent-ideal_exponent, p-1) + else: + zeros = 0 + return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros) + + # case where y is negative: xc must be either a power + # of 2 or a power of 5. + if y.sign == 1: + last_digit = xc % 10 + if last_digit in (2,4,6,8): + # quick test for power of 2 + if xc & -xc != xc: + return None + # now xc is a power of 2; e is its exponent + e = _nbits(xc)-1 + # find e*y and xe*y; both must be integers + if ye >= 0: + y_as_int = yc*10**ye + e = e*y_as_int + xe = xe*y_as_int + else: + ten_pow = 10**-ye + e, remainder = divmod(e*yc, ten_pow) + if remainder: + return None + xe, remainder = divmod(xe*yc, ten_pow) + if remainder: + return None + + if e*65 >= p*93: # 93/65 > log(10)/log(5) + return None + xc = 5**e + + elif last_digit == 5: + # e >= log_5(xc) if xc is a power of 5; we have + # equality all the way up to xc=5**2658 + e = _nbits(xc)*28//65 + xc, remainder = divmod(5**e, xc) + if remainder: + return None + while xc % 5 == 0: + xc //= 5 + e -= 1 + if ye >= 0: + y_as_integer = yc*10**ye + e = e*y_as_integer + xe = xe*y_as_integer + else: + ten_pow = 10**-ye + e, remainder = divmod(e*yc, ten_pow) + if remainder: + return None + xe, remainder = divmod(xe*yc, ten_pow) + if remainder: + return None + if e*3 >= p*10: # 10/3 > log(10)/log(2) + return None + xc = 2**e + else: + return None + + if xc >= 10**p: + return None + xe = -e-xe + return _dec_from_triple(0, str(xc), xe) + + # now y is positive; find m and n such that y = m/n + if ye >= 0: + m, n = yc*10**ye, 1 + else: + if xe != 0 and len(str(abs(yc*xe))) <= -ye: + return None + xc_bits = _nbits(xc) + if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye: + return None + m, n = yc, 10**(-ye) + while m % 2 == n % 2 == 0: + m //= 2 + n //= 2 + while m % 5 == n % 5 == 0: + m //= 5 + n //= 5 + + # compute nth root of xc*10**xe + if n > 1: + # if 1 < xc < 2**n then xc isn't an nth power + if xc != 1 and xc_bits <= n: + return None + + xe, rem = divmod(xe, n) + if rem != 0: + return None + + # compute nth root of xc using Newton's method + a = 1L << -(-_nbits(xc)//n) # initial estimate + while True: + q, r = divmod(xc, a**(n-1)) + if a <= q: + break + else: + a = (a*(n-1) + q)//n + if not (a == q and r == 0): + return None + xc = a + + # now xc*10**xe is the nth root of the original xc*10**xe + # compute mth power of xc*10**xe + + # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m > + # 10**p and the result is not representable. + if xc > 1 and m > p*100//_log10_lb(xc): + return None + xc = xc**m + xe *= m + if xc > 10**p: + return None + + # by this point the result *is* exactly representable + # adjust the exponent to get as close as possible to the ideal + # exponent, if necessary + str_xc = str(xc) + if other._isinteger() and other._sign == 0: + ideal_exponent = self._exp*int(other) + zeros = min(xe-ideal_exponent, p-len(str_xc)) + else: + zeros = 0 + return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros) + + def __pow__(self, other, modulo=None, context=None): + """Return self ** other [ % modulo]. + + With two arguments, compute self**other. + + With three arguments, compute (self**other) % modulo. For the + three argument form, the following restrictions on the + arguments hold: + + - all three arguments must be integral + - other must be nonnegative + - either self or other (or both) must be nonzero + - modulo must be nonzero and must have at most p digits, + where p is the context precision. + + If any of these restrictions is violated the InvalidOperation + flag is raised. + + The result of pow(self, other, modulo) is identical to the + result that would be obtained by computing (self**other) % + modulo with unbounded precision, but is computed more + efficiently. It is always exact. + """ + + if modulo is not None: + return self._power_modulo(other, modulo, context) + + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + # either argument is a NaN => result is NaN + ans = self._check_nans(other, context) + if ans: + return ans + + # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity) + if not other: + if not self: + return context._raise_error(InvalidOperation, '0 ** 0') + else: + return _One + + # result has sign 1 iff self._sign is 1 and other is an odd integer + result_sign = 0 + if self._sign == 1: + if other._isinteger(): + if not other._iseven(): + result_sign = 1 + else: + # -ve**noninteger = NaN + # (-0)**noninteger = 0**noninteger + if self: + return context._raise_error(InvalidOperation, + 'x ** y with x negative and y not an integer') + # negate self, without doing any unwanted rounding + self = self.copy_negate() + + # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity + if not self: + if other._sign == 0: + return _dec_from_triple(result_sign, '0', 0) + else: + return _SignedInfinity[result_sign] + + # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0 + if self._isinfinity(): + if other._sign == 0: + return _SignedInfinity[result_sign] + else: + return _dec_from_triple(result_sign, '0', 0) + + # 1**other = 1, but the choice of exponent and the flags + # depend on the exponent of self, and on whether other is a + # positive integer, a negative integer, or neither + if self == _One: + if other._isinteger(): + # exp = max(self._exp*max(int(other), 0), + # 1-context.prec) but evaluating int(other) directly + # is dangerous until we know other is small (other + # could be 1e999999999) + if other._sign == 1: + multiplier = 0 + elif other > context.prec: + multiplier = context.prec + else: + multiplier = int(other) + + exp = self._exp * multiplier + if exp < 1-context.prec: + exp = 1-context.prec + context._raise_error(Rounded) + else: + context._raise_error(Inexact) + context._raise_error(Rounded) + exp = 1-context.prec + + return _dec_from_triple(result_sign, '1'+'0'*-exp, exp) + + # compute adjusted exponent of self + self_adj = self.adjusted() + + # self ** infinity is infinity if self > 1, 0 if self < 1 + # self ** -infinity is infinity if self < 1, 0 if self > 1 + if other._isinfinity(): + if (other._sign == 0) == (self_adj < 0): + return _dec_from_triple(result_sign, '0', 0) + else: + return _SignedInfinity[result_sign] + + # from here on, the result always goes through the call + # to _fix at the end of this function. + ans = None + exact = False + + # crude test to catch cases of extreme overflow/underflow. If + # log10(self)*other >= 10**bound and bound >= len(str(Emax)) + # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence + # self**other >= 10**(Emax+1), so overflow occurs. The test + # for underflow is similar. + bound = self._log10_exp_bound() + other.adjusted() + if (self_adj >= 0) == (other._sign == 0): + # self > 1 and other +ve, or self < 1 and other -ve + # possibility of overflow + if bound >= len(str(context.Emax)): + ans = _dec_from_triple(result_sign, '1', context.Emax+1) + else: + # self > 1 and other -ve, or self < 1 and other +ve + # possibility of underflow to 0 + Etiny = context.Etiny() + if bound >= len(str(-Etiny)): + ans = _dec_from_triple(result_sign, '1', Etiny-1) + + # try for an exact result with precision +1 + if ans is None: + ans = self._power_exact(other, context.prec + 1) + if ans is not None: + if result_sign == 1: + ans = _dec_from_triple(1, ans._int, ans._exp) + exact = True + + # usual case: inexact result, x**y computed directly as exp(y*log(x)) + if ans is None: + p = context.prec + x = _WorkRep(self) + xc, xe = x.int, x.exp + y = _WorkRep(other) + yc, ye = y.int, y.exp + if y.sign == 1: + yc = -yc + + # compute correctly rounded result: start with precision +3, + # then increase precision until result is unambiguously roundable + extra = 3 + while True: + coeff, exp = _dpower(xc, xe, yc, ye, p+extra) + if coeff % (5*10**(len(str(coeff))-p-1)): + break + extra += 3 + + ans = _dec_from_triple(result_sign, str(coeff), exp) + + # unlike exp, ln and log10, the power function respects the + # rounding mode; no need to switch to ROUND_HALF_EVEN here + + # There's a difficulty here when 'other' is not an integer and + # the result is exact. In this case, the specification + # requires that the Inexact flag be raised (in spite of + # exactness), but since the result is exact _fix won't do this + # for us. (Correspondingly, the Underflow signal should also + # be raised for subnormal results.) We can't directly raise + # these signals either before or after calling _fix, since + # that would violate the precedence for signals. So we wrap + # the ._fix call in a temporary context, and reraise + # afterwards. + if exact and not other._isinteger(): + # pad with zeros up to length context.prec+1 if necessary; this + # ensures that the Rounded signal will be raised. + if len(ans._int) <= context.prec: + expdiff = context.prec + 1 - len(ans._int) + ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, + ans._exp-expdiff) + + # create a copy of the current context, with cleared flags/traps + newcontext = context.copy() + newcontext.clear_flags() + for exception in _signals: + newcontext.traps[exception] = 0 + + # round in the new context + ans = ans._fix(newcontext) + + # raise Inexact, and if necessary, Underflow + newcontext._raise_error(Inexact) + if newcontext.flags[Subnormal]: + newcontext._raise_error(Underflow) + + # propagate signals to the original context; _fix could + # have raised any of Overflow, Underflow, Subnormal, + # Inexact, Rounded, Clamped. Overflow needs the correct + # arguments. Note that the order of the exceptions is + # important here. + if newcontext.flags[Overflow]: + context._raise_error(Overflow, 'above Emax', ans._sign) + for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: + if newcontext.flags[exception]: + context._raise_error(exception) + + else: + ans = ans._fix(context) + + return ans + + def __rpow__(self, other, context=None): + """Swaps self/other and returns __pow__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__pow__(self, context=context) + + def normalize(self, context=None): + """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" + + if context is None: + context = getcontext() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + dup = self._fix(context) + if dup._isinfinity(): + return dup + + if not dup: + return _dec_from_triple(dup._sign, '0', 0) + exp_max = [context.Emax, context.Etop()][context._clamp] + end = len(dup._int) + exp = dup._exp + while dup._int[end-1] == '0' and exp < exp_max: + exp += 1 + end -= 1 + return _dec_from_triple(dup._sign, dup._int[:end], exp) + + def quantize(self, exp, rounding=None, context=None, watchexp=True): + """Quantize self so its exponent is the same as that of exp. + + Similar to self._rescale(exp._exp) but with error checking. + """ + exp = _convert_other(exp, raiseit=True) + + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + + if self._is_special or exp._is_special: + ans = self._check_nans(exp, context) + if ans: + return ans + + if exp._isinfinity() or self._isinfinity(): + if exp._isinfinity() and self._isinfinity(): + return Decimal(self) # if both are inf, it is OK + return context._raise_error(InvalidOperation, + 'quantize with one INF') + + # if we're not watching exponents, do a simple rescale + if not watchexp: + ans = self._rescale(exp._exp, rounding) + # raise Inexact and Rounded where appropriate + if ans._exp > self._exp: + context._raise_error(Rounded) + if ans != self: + context._raise_error(Inexact) + return ans + + # exp._exp should be between Etiny and Emax + if not (context.Etiny() <= exp._exp <= context.Emax): + return context._raise_error(InvalidOperation, + 'target exponent out of bounds in quantize') + + if not self: + ans = _dec_from_triple(self._sign, '0', exp._exp) + return ans._fix(context) + + self_adjusted = self.adjusted() + if self_adjusted > context.Emax: + return context._raise_error(InvalidOperation, + 'exponent of quantize result too large for current context') + if self_adjusted - exp._exp + 1 > context.prec: + return context._raise_error(InvalidOperation, + 'quantize result has too many digits for current context') + + ans = self._rescale(exp._exp, rounding) + if ans.adjusted() > context.Emax: + return context._raise_error(InvalidOperation, + 'exponent of quantize result too large for current context') + if len(ans._int) > context.prec: + return context._raise_error(InvalidOperation, + 'quantize result has too many digits for current context') + + # raise appropriate flags + if ans and ans.adjusted() < context.Emin: + context._raise_error(Subnormal) + if ans._exp > self._exp: + if ans != self: + context._raise_error(Inexact) + context._raise_error(Rounded) + + # call to fix takes care of any necessary folddown, and + # signals Clamped if necessary + ans = ans._fix(context) + return ans + + def same_quantum(self, other): + """Return True if self and other have the same exponent; otherwise + return False. + + If either operand is a special value, the following rules are used: + * return True if both operands are infinities + * return True if both operands are NaNs + * otherwise, return False. + """ + other = _convert_other(other, raiseit=True) + if self._is_special or other._is_special: + return (self.is_nan() and other.is_nan() or + self.is_infinite() and other.is_infinite()) + return self._exp == other._exp + + def _rescale(self, exp, rounding): + """Rescale self so that the exponent is exp, either by padding with zeros + or by truncating digits, using the given rounding mode. + + Specials are returned without change. This operation is + quiet: it raises no flags, and uses no information from the + context. + + exp = exp to scale to (an integer) + rounding = rounding mode + """ + if self._is_special: + return Decimal(self) + if not self: + return _dec_from_triple(self._sign, '0', exp) + + if self._exp >= exp: + # pad answer with zeros if necessary + return _dec_from_triple(self._sign, + self._int + '0'*(self._exp - exp), exp) + + # too many digits; round and lose data. If self.adjusted() < + # exp-1, replace self by 10**(exp-1) before rounding + digits = len(self._int) + self._exp - exp + if digits < 0: + self = _dec_from_triple(self._sign, '1', exp-1) + digits = 0 + this_function = getattr(self, self._pick_rounding_function[rounding]) + changed = this_function(digits) + coeff = self._int[:digits] or '0' + if changed == 1: + coeff = str(int(coeff)+1) + return _dec_from_triple(self._sign, coeff, exp) + + def _round(self, places, rounding): + """Round a nonzero, nonspecial Decimal to a fixed number of + significant figures, using the given rounding mode. + + Infinities, NaNs and zeros are returned unaltered. + + This operation is quiet: it raises no flags, and uses no + information from the context. + + """ + if places <= 0: + raise ValueError("argument should be at least 1 in _round") + if self._is_special or not self: + return Decimal(self) + ans = self._rescale(self.adjusted()+1-places, rounding) + # it can happen that the rescale alters the adjusted exponent; + # for example when rounding 99.97 to 3 significant figures. + # When this happens we end up with an extra 0 at the end of + # the number; a second rescale fixes this. + if ans.adjusted() != self.adjusted(): + ans = ans._rescale(ans.adjusted()+1-places, rounding) + return ans + + def to_integral_exact(self, rounding=None, context=None): + """Rounds to a nearby integer. + + If no rounding mode is specified, take the rounding mode from + the context. This method raises the Rounded and Inexact flags + when appropriate. + + See also: to_integral_value, which does exactly the same as + this method except that it doesn't raise Inexact or Rounded. + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + return Decimal(self) + if self._exp >= 0: + return Decimal(self) + if not self: + return _dec_from_triple(self._sign, '0', 0) + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + ans = self._rescale(0, rounding) + if ans != self: + context._raise_error(Inexact) + context._raise_error(Rounded) + return ans + + def to_integral_value(self, rounding=None, context=None): + """Rounds to the nearest integer, without raising inexact, rounded.""" + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + return Decimal(self) + if self._exp >= 0: + return Decimal(self) + else: + return self._rescale(0, rounding) + + # the method name changed, but we provide also the old one, for compatibility + to_integral = to_integral_value + + def sqrt(self, context=None): + """Return the square root of self.""" + if context is None: + context = getcontext() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() and self._sign == 0: + return Decimal(self) + + if not self: + # exponent = self._exp // 2. sqrt(-0) = -0 + ans = _dec_from_triple(self._sign, '0', self._exp // 2) + return ans._fix(context) + + if self._sign == 1: + return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') + + # At this point self represents a positive number. Let p be + # the desired precision and express self in the form c*100**e + # with c a positive real number and e an integer, c and e + # being chosen so that 100**(p-1) <= c < 100**p. Then the + # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1) + # <= sqrt(c) < 10**p, so the closest representable Decimal at + # precision p is n*10**e where n = round_half_even(sqrt(c)), + # the closest integer to sqrt(c) with the even integer chosen + # in the case of a tie. + # + # To ensure correct rounding in all cases, we use the + # following trick: we compute the square root to an extra + # place (precision p+1 instead of precision p), rounding down. + # Then, if the result is inexact and its last digit is 0 or 5, + # we increase the last digit to 1 or 6 respectively; if it's + # exact we leave the last digit alone. Now the final round to + # p places (or fewer in the case of underflow) will round + # correctly and raise the appropriate flags. + + # use an extra digit of precision + prec = context.prec+1 + + # write argument in the form c*100**e where e = self._exp//2 + # is the 'ideal' exponent, to be used if the square root is + # exactly representable. l is the number of 'digits' of c in + # base 100, so that 100**(l-1) <= c < 100**l. + op = _WorkRep(self) + e = op.exp >> 1 + if op.exp & 1: + c = op.int * 10 + l = (len(self._int) >> 1) + 1 + else: + c = op.int + l = len(self._int)+1 >> 1 + + # rescale so that c has exactly prec base 100 'digits' + shift = prec-l + if shift >= 0: + c *= 100**shift + exact = True + else: + c, remainder = divmod(c, 100**-shift) + exact = not remainder + e -= shift + + # find n = floor(sqrt(c)) using Newton's method + n = 10**prec + while True: + q = c//n + if n <= q: + break + else: + n = n + q >> 1 + exact = exact and n*n == c + + if exact: + # result is exact; rescale to use ideal exponent e + if shift >= 0: + # assert n % 10**shift == 0 + n //= 10**shift + else: + n *= 10**-shift + e += shift + else: + # result is not exact; fix last digit as described above + if n % 5 == 0: + n += 1 + + ans = _dec_from_triple(0, str(n), e) + + # round, and fit to current context + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + + return ans + + def max(self, other, context=None): + """Returns the larger value. + + Like max(self, other) except if one is not a number, returns + NaN (and signals if one is sNaN). Also rounds. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self._cmp(other) + if c == 0: + # If both operands are finite and equal in numerical value + # then an ordering is applied: + # + # If the signs differ then max returns the operand with the + # positive sign and min returns the operand with the negative sign + # + # If the signs are the same then the exponent is used to select + # the result. This is exactly the ordering used in compare_total. + c = self.compare_total(other) + + if c == -1: + ans = other + else: + ans = self + + return ans._fix(context) + + def min(self, other, context=None): + """Returns the smaller value. + + Like min(self, other) except if one is not a number, returns + NaN (and signals if one is sNaN). Also rounds. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self._cmp(other) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = self + else: + ans = other + + return ans._fix(context) + + def _isinteger(self): + """Returns whether self is an integer""" + if self._is_special: + return False + if self._exp >= 0: + return True + rest = self._int[self._exp:] + return rest == '0'*len(rest) + + def _iseven(self): + """Returns True if self is even. Assumes self is an integer.""" + if not self or self._exp > 0: + return True + return self._int[-1+self._exp] in '02468' + + def adjusted(self): + """Return the adjusted exponent of self""" + try: + return self._exp + len(self._int) - 1 + # If NaN or Infinity, self._exp is string + except TypeError: + return 0 + + def canonical(self, context=None): + """Returns the same Decimal object. + + As we do not have different encodings for the same number, the + received object already is in its canonical form. + """ + return self + + def compare_signal(self, other, context=None): + """Compares self to the other operand numerically. + + It's pretty much like compare(), but all NaNs signal, with signaling + NaNs taking precedence over quiet NaNs. + """ + other = _convert_other(other, raiseit = True) + ans = self._compare_check_nans(other, context) + if ans: + return ans + return self.compare(other, context=context) + + def compare_total(self, other): + """Compares self to other using the abstract representations. + + This is not like the standard compare, which use their numerical + value. Note that a total ordering is defined for all possible abstract + representations. + """ + other = _convert_other(other, raiseit=True) + + # if one is negative and the other is positive, it's easy + if self._sign and not other._sign: + return _NegativeOne + if not self._sign and other._sign: + return _One + sign = self._sign + + # let's handle both NaN types + self_nan = self._isnan() + other_nan = other._isnan() + if self_nan or other_nan: + if self_nan == other_nan: + # compare payloads as though they're integers + self_key = len(self._int), self._int + other_key = len(other._int), other._int + if self_key < other_key: + if sign: + return _One + else: + return _NegativeOne + if self_key > other_key: + if sign: + return _NegativeOne + else: + return _One + return _Zero + + if sign: + if self_nan == 1: + return _NegativeOne + if other_nan == 1: + return _One + if self_nan == 2: + return _NegativeOne + if other_nan == 2: + return _One + else: + if self_nan == 1: + return _One + if other_nan == 1: + return _NegativeOne + if self_nan == 2: + return _One + if other_nan == 2: + return _NegativeOne + + if self < other: + return _NegativeOne + if self > other: + return _One + + if self._exp < other._exp: + if sign: + return _One + else: + return _NegativeOne + if self._exp > other._exp: + if sign: + return _NegativeOne + else: + return _One + return _Zero + + + def compare_total_mag(self, other): + """Compares self to other using abstract repr., ignoring sign. + + Like compare_total, but with operand's sign ignored and assumed to be 0. + """ + other = _convert_other(other, raiseit=True) + + s = self.copy_abs() + o = other.copy_abs() + return s.compare_total(o) + + def copy_abs(self): + """Returns a copy with the sign set to 0. """ + return _dec_from_triple(0, self._int, self._exp, self._is_special) + + def copy_negate(self): + """Returns a copy with the sign inverted.""" + if self._sign: + return _dec_from_triple(0, self._int, self._exp, self._is_special) + else: + return _dec_from_triple(1, self._int, self._exp, self._is_special) + + def copy_sign(self, other): + """Returns self with the sign of other.""" + other = _convert_other(other, raiseit=True) + return _dec_from_triple(other._sign, self._int, + self._exp, self._is_special) + + def exp(self, context=None): + """Returns e ** self.""" + + if context is None: + context = getcontext() + + # exp(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # exp(-Infinity) = 0 + if self._isinfinity() == -1: + return _Zero + + # exp(0) = 1 + if not self: + return _One + + # exp(Infinity) = Infinity + if self._isinfinity() == 1: + return Decimal(self) + + # the result is now guaranteed to be inexact (the true + # mathematical result is transcendental). There's no need to + # raise Rounded and Inexact here---they'll always be raised as + # a result of the call to _fix. + p = context.prec + adj = self.adjusted() + + # we only need to do any computation for quite a small range + # of adjusted exponents---for example, -29 <= adj <= 10 for + # the default context. For smaller exponent the result is + # indistinguishable from 1 at the given precision, while for + # larger exponent the result either overflows or underflows. + if self._sign == 0 and adj > len(str((context.Emax+1)*3)): + # overflow + ans = _dec_from_triple(0, '1', context.Emax+1) + elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)): + # underflow to 0 + ans = _dec_from_triple(0, '1', context.Etiny()-1) + elif self._sign == 0 and adj < -p: + # p+1 digits; final round will raise correct flags + ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p) + elif self._sign == 1 and adj < -p-1: + # p+1 digits; final round will raise correct flags + ans = _dec_from_triple(0, '9'*(p+1), -p-1) + # general case + else: + op = _WorkRep(self) + c, e = op.int, op.exp + if op.sign == 1: + c = -c + + # compute correctly rounded result: increase precision by + # 3 digits at a time until we get an unambiguously + # roundable result + extra = 3 + while True: + coeff, exp = _dexp(c, e, p+extra) + if coeff % (5*10**(len(str(coeff))-p-1)): + break + extra += 3 + + ans = _dec_from_triple(0, str(coeff), exp) + + # at this stage, ans should round correctly with *any* + # rounding mode, not just with ROUND_HALF_EVEN + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + + return ans + + def is_canonical(self): + """Return True if self is canonical; otherwise return False. + + Currently, the encoding of a Decimal instance is always + canonical, so this method returns True for any Decimal. + """ + return True + + def is_finite(self): + """Return True if self is finite; otherwise return False. + + A Decimal instance is considered finite if it is neither + infinite nor a NaN. + """ + return not self._is_special + + def is_infinite(self): + """Return True if self is infinite; otherwise return False.""" + return self._exp == 'F' + + def is_nan(self): + """Return True if self is a qNaN or sNaN; otherwise return False.""" + return self._exp in ('n', 'N') + + def is_normal(self, context=None): + """Return True if self is a normal number; otherwise return False.""" + if self._is_special or not self: + return False + if context is None: + context = getcontext() + return context.Emin <= self.adjusted() + + def is_qnan(self): + """Return True if self is a quiet NaN; otherwise return False.""" + return self._exp == 'n' + + def is_signed(self): + """Return True if self is negative; otherwise return False.""" + return self._sign == 1 + + def is_snan(self): + """Return True if self is a signaling NaN; otherwise return False.""" + return self._exp == 'N' + + def is_subnormal(self, context=None): + """Return True if self is subnormal; otherwise return False.""" + if self._is_special or not self: + return False + if context is None: + context = getcontext() + return self.adjusted() < context.Emin + + def is_zero(self): + """Return True if self is a zero; otherwise return False.""" + return not self._is_special and self._int == '0' + + def _ln_exp_bound(self): + """Compute a lower bound for the adjusted exponent of self.ln(). + In other words, compute r such that self.ln() >= 10**r. Assumes + that self is finite and positive and that self != 1. + """ + + # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1 + adj = self._exp + len(self._int) - 1 + if adj >= 1: + # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10) + return len(str(adj*23//10)) - 1 + if adj <= -2: + # argument <= 0.1 + return len(str((-1-adj)*23//10)) - 1 + op = _WorkRep(self) + c, e = op.int, op.exp + if adj == 0: + # 1 < self < 10 + num = str(c-10**-e) + den = str(c) + return len(num) - len(den) - (num < den) + # adj == -1, 0.1 <= self < 1 + return e + len(str(10**-e - c)) - 1 + + + def ln(self, context=None): + """Returns the natural (base e) logarithm of self.""" + + if context is None: + context = getcontext() + + # ln(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # ln(0.0) == -Infinity + if not self: + return _NegativeInfinity + + # ln(Infinity) = Infinity + if self._isinfinity() == 1: + return _Infinity + + # ln(1.0) == 0.0 + if self == _One: + return _Zero + + # ln(negative) raises InvalidOperation + if self._sign == 1: + return context._raise_error(InvalidOperation, + 'ln of a negative value') + + # result is irrational, so necessarily inexact + op = _WorkRep(self) + c, e = op.int, op.exp + p = context.prec + + # correctly rounded result: repeatedly increase precision by 3 + # until we get an unambiguously roundable result + places = p - self._ln_exp_bound() + 2 # at least p+3 places + while True: + coeff = _dlog(c, e, places) + # assert len(str(abs(coeff)))-p >= 1 + if coeff % (5*10**(len(str(abs(coeff)))-p-1)): + break + places += 3 + ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) + + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + return ans + + def _log10_exp_bound(self): + """Compute a lower bound for the adjusted exponent of self.log10(). + In other words, find r such that self.log10() >= 10**r. + Assumes that self is finite and positive and that self != 1. + """ + + # For x >= 10 or x < 0.1 we only need a bound on the integer + # part of log10(self), and this comes directly from the + # exponent of x. For 0.1 <= x <= 10 we use the inequalities + # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| > + # (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0 + + adj = self._exp + len(self._int) - 1 + if adj >= 1: + # self >= 10 + return len(str(adj))-1 + if adj <= -2: + # self < 0.1 + return len(str(-1-adj))-1 + op = _WorkRep(self) + c, e = op.int, op.exp + if adj == 0: + # 1 < self < 10 + num = str(c-10**-e) + den = str(231*c) + return len(num) - len(den) - (num < den) + 2 + # adj == -1, 0.1 <= self < 1 + num = str(10**-e-c) + return len(num) + e - (num < "231") - 1 + + def log10(self, context=None): + """Returns the base 10 logarithm of self.""" + + if context is None: + context = getcontext() + + # log10(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # log10(0.0) == -Infinity + if not self: + return _NegativeInfinity + + # log10(Infinity) = Infinity + if self._isinfinity() == 1: + return _Infinity + + # log10(negative or -Infinity) raises InvalidOperation + if self._sign == 1: + return context._raise_error(InvalidOperation, + 'log10 of a negative value') + + # log10(10**n) = n + if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1): + # answer may need rounding + ans = Decimal(self._exp + len(self._int) - 1) + else: + # result is irrational, so necessarily inexact + op = _WorkRep(self) + c, e = op.int, op.exp + p = context.prec + + # correctly rounded result: repeatedly increase precision + # until result is unambiguously roundable + places = p-self._log10_exp_bound()+2 + while True: + coeff = _dlog10(c, e, places) + # assert len(str(abs(coeff)))-p >= 1 + if coeff % (5*10**(len(str(abs(coeff)))-p-1)): + break + places += 3 + ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) + + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + return ans + + def logb(self, context=None): + """ Returns the exponent of the magnitude of self's MSD. + + The result is the integer which is the exponent of the magnitude + of the most significant digit of self (as though it were truncated + to a single digit while maintaining the value of that digit and + without limiting the resulting exponent). + """ + # logb(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + if context is None: + context = getcontext() + + # logb(+/-Inf) = +Inf + if self._isinfinity(): + return _Infinity + + # logb(0) = -Inf, DivisionByZero + if not self: + return context._raise_error(DivisionByZero, 'logb(0)', 1) + + # otherwise, simply return the adjusted exponent of self, as a + # Decimal. Note that no attempt is made to fit the result + # into the current context. + ans = Decimal(self.adjusted()) + return ans._fix(context) + + def _islogical(self): + """Return True if self is a logical operand. + + For being logical, it must be a finite number with a sign of 0, + an exponent of 0, and a coefficient whose digits must all be + either 0 or 1. + """ + if self._sign != 0 or self._exp != 0: + return False + for dig in self._int: + if dig not in '01': + return False + return True + + def _fill_logical(self, context, opa, opb): + dif = context.prec - len(opa) + if dif > 0: + opa = '0'*dif + opa + elif dif < 0: + opa = opa[-context.prec:] + dif = context.prec - len(opb) + if dif > 0: + opb = '0'*dif + opb + elif dif < 0: + opb = opb[-context.prec:] + return opa, opb + + def logical_and(self, other, context=None): + """Applies an 'and' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def logical_invert(self, context=None): + """Invert all its digits.""" + if context is None: + context = getcontext() + return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0), + context) + + def logical_or(self, other, context=None): + """Applies an 'or' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def logical_xor(self, other, context=None): + """Applies an 'xor' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def max_mag(self, other, context=None): + """Compares the values numerically with their sign ignored.""" + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self.copy_abs()._cmp(other.copy_abs()) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = other + else: + ans = self + + return ans._fix(context) + + def min_mag(self, other, context=None): + """Compares the values numerically with their sign ignored.""" + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self.copy_abs()._cmp(other.copy_abs()) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = self + else: + ans = other + + return ans._fix(context) + + def next_minus(self, context=None): + """Returns the largest representable number smaller than itself.""" + if context is None: + context = getcontext() + + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() == -1: + return _NegativeInfinity + if self._isinfinity() == 1: + return _dec_from_triple(0, '9'*context.prec, context.Etop()) + + context = context.copy() + context._set_rounding(ROUND_FLOOR) + context._ignore_all_flags() + new_self = self._fix(context) + if new_self != self: + return new_self + return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1), + context) + + def next_plus(self, context=None): + """Returns the smallest representable number larger than itself.""" + if context is None: + context = getcontext() + + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() == 1: + return _Infinity + if self._isinfinity() == -1: + return _dec_from_triple(1, '9'*context.prec, context.Etop()) + + context = context.copy() + context._set_rounding(ROUND_CEILING) + context._ignore_all_flags() + new_self = self._fix(context) + if new_self != self: + return new_self + return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1), + context) + + def next_toward(self, other, context=None): + """Returns the number closest to self, in the direction towards other. + + The result is the closest representable number to self + (excluding self) that is in the direction towards other, + unless both have the same value. If the two operands are + numerically equal, then the result is a copy of self with the + sign set to be the same as the sign of other. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + comparison = self._cmp(other) + if comparison == 0: + return self.copy_sign(other) + + if comparison == -1: + ans = self.next_plus(context) + else: # comparison == 1 + ans = self.next_minus(context) + + # decide which flags to raise using value of ans + if ans._isinfinity(): + context._raise_error(Overflow, + 'Infinite result from next_toward', + ans._sign) + context._raise_error(Inexact) + context._raise_error(Rounded) + elif ans.adjusted() < context.Emin: + context._raise_error(Underflow) + context._raise_error(Subnormal) + context._raise_error(Inexact) + context._raise_error(Rounded) + # if precision == 1 then we don't raise Clamped for a + # result 0E-Etiny. + if not ans: + context._raise_error(Clamped) + + return ans + + def number_class(self, context=None): + """Returns an indication of the class of self. + + The class is one of the following strings: + sNaN + NaN + -Infinity + -Normal + -Subnormal + -Zero + +Zero + +Subnormal + +Normal + +Infinity + """ + if self.is_snan(): + return "sNaN" + if self.is_qnan(): + return "NaN" + inf = self._isinfinity() + if inf == 1: + return "+Infinity" + if inf == -1: + return "-Infinity" + if self.is_zero(): + if self._sign: + return "-Zero" + else: + return "+Zero" + if context is None: + context = getcontext() + if self.is_subnormal(context=context): + if self._sign: + return "-Subnormal" + else: + return "+Subnormal" + # just a normal, regular, boring number, :) + if self._sign: + return "-Normal" + else: + return "+Normal" + + def radix(self): + """Just returns 10, as this is Decimal, :)""" + return Decimal(10) + + def rotate(self, other, context=None): + """Returns a rotated copy of self, value-of-other times.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + if not (-context.prec <= int(other) <= context.prec): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + # get values, pad if necessary + torot = int(other) + rotdig = self._int + topad = context.prec - len(rotdig) + if topad > 0: + rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] + + # let's rotate! + rotated = rotdig[torot:] + rotdig[:torot] + return _dec_from_triple(self._sign, + rotated.lstrip('0') or '0', self._exp) + + def scaleb(self, other, context=None): + """Returns self operand after adding the second value to its exp.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + liminf = -2 * (context.Emax + context.prec) + limsup = 2 * (context.Emax + context.prec) + if not (liminf <= int(other) <= limsup): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + d = _dec_from_triple(self._sign, self._int, self._exp + int(other)) + d = d._fix(context) + return d + + def shift(self, other, context=None): + """Returns a shifted copy of self, value-of-other times.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + if not (-context.prec <= int(other) <= context.prec): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + # get values, pad if necessary + torot = int(other) + rotdig = self._int + topad = context.prec - len(rotdig) + if topad > 0: + rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] + + # let's shift! + if torot < 0: + shifted = rotdig[:torot] + else: + shifted = rotdig + '0'*torot + shifted = shifted[-context.prec:] + + return _dec_from_triple(self._sign, + shifted.lstrip('0') or '0', self._exp) + + # Support for pickling, copy, and deepcopy + def __reduce__(self): + return (self.__class__, (str(self),)) + + def __copy__(self): + if type(self) is Decimal: + return self # I'm immutable; therefore I am my own clone + return self.__class__(str(self)) + + def __deepcopy__(self, memo): + if type(self) is Decimal: + return self # My components are also immutable + return self.__class__(str(self)) + + # PEP 3101 support. the _localeconv keyword argument should be + # considered private: it's provided for ease of testing only. + def __format__(self, specifier, context=None, _localeconv=None): + """Format a Decimal instance according to the given specifier. + + The specifier should be a standard format specifier, with the + form described in PEP 3101. Formatting types 'e', 'E', 'f', + 'F', 'g', 'G', 'n' and '%' are supported. If the formatting + type is omitted it defaults to 'g' or 'G', depending on the + value of context.capitals. + """ + + # Note: PEP 3101 says that if the type is not present then + # there should be at least one digit after the decimal point. + # We take the liberty of ignoring this requirement for + # Decimal---it's presumably there to make sure that + # format(float, '') behaves similarly to str(float). + if context is None: + context = getcontext() + + spec = _parse_format_specifier(specifier, _localeconv=_localeconv) + + # special values don't care about the type or precision + if self._is_special: + sign = _format_sign(self._sign, spec) + body = str(self.copy_abs()) + return _format_align(sign, body, spec) + + # a type of None defaults to 'g' or 'G', depending on context + if spec['type'] is None: + spec['type'] = ['g', 'G'][context.capitals] + + # if type is '%', adjust exponent of self accordingly + if spec['type'] == '%': + self = _dec_from_triple(self._sign, self._int, self._exp+2) + + # round if necessary, taking rounding mode from the context + rounding = context.rounding + precision = spec['precision'] + if precision is not None: + if spec['type'] in 'eE': + self = self._round(precision+1, rounding) + elif spec['type'] in 'fF%': + self = self._rescale(-precision, rounding) + elif spec['type'] in 'gG' and len(self._int) > precision: + self = self._round(precision, rounding) + # special case: zeros with a positive exponent can't be + # represented in fixed point; rescale them to 0e0. + if not self and self._exp > 0 and spec['type'] in 'fF%': + self = self._rescale(0, rounding) + + # figure out placement of the decimal point + leftdigits = self._exp + len(self._int) + if spec['type'] in 'eE': + if not self and precision is not None: + dotplace = 1 - precision + else: + dotplace = 1 + elif spec['type'] in 'fF%': + dotplace = leftdigits + elif spec['type'] in 'gG': + if self._exp <= 0 and leftdigits > -6: + dotplace = leftdigits + else: + dotplace = 1 + + # find digits before and after decimal point, and get exponent + if dotplace < 0: + intpart = '0' + fracpart = '0'*(-dotplace) + self._int + elif dotplace > len(self._int): + intpart = self._int + '0'*(dotplace-len(self._int)) + fracpart = '' + else: + intpart = self._int[:dotplace] or '0' + fracpart = self._int[dotplace:] + exp = leftdigits-dotplace + + # done with the decimal-specific stuff; hand over the rest + # of the formatting to the _format_number function + return _format_number(self._sign, intpart, fracpart, exp, spec) + + # support for Jython __tojava__: + def __tojava__(self, java_class): + if java_class not in (BigDecimal, Object): + return Py.NoConversion + return BigDecimal(str(self)) + +def _dec_from_triple(sign, coefficient, exponent, special=False): + """Create a decimal instance directly, without any validation, + normalization (e.g. removal of leading zeros) or argument + conversion. + + This function is for *internal use only*. + """ + + self = object.__new__(Decimal) + self._sign = sign + self._int = coefficient + self._exp = exponent + self._is_special = special + + return self + +# Register Decimal as a kind of Number (an abstract base class). +# However, do not register it as Real (because Decimals are not +# interoperable with floats). +_numbers.Number.register(Decimal) + + +##### Context class ####################################################### + + +# get rounding method function: +rounding_functions = [name for name in Decimal.__dict__.keys() + if name.startswith('_round_')] +for name in rounding_functions: + # name is like _round_half_even, goes to the global ROUND_HALF_EVEN value. + globalname = name[1:].upper() + val = globals()[globalname] + Decimal._pick_rounding_function[val] = name + +del name, val, globalname, rounding_functions + +class _ContextManager(object): + """Context manager class to support localcontext(). + + Sets a copy of the supplied context in __enter__() and restores + the previous decimal context in __exit__() + """ + def __init__(self, new_context): + self.new_context = new_context.copy() + def __enter__(self): + self.saved_context = getcontext() + setcontext(self.new_context) + return self.new_context + def __exit__(self, t, v, tb): + setcontext(self.saved_context) + +class Context(object): + """Contains the context for a Decimal instance. + + Contains: + prec - precision (for use in rounding, division, square roots..) + rounding - rounding type (how you round) + traps - If traps[exception] = 1, then the exception is + raised when it is caused. Otherwise, a value is + substituted in. + flags - When an exception is caused, flags[exception] is set. + (Whether or not the trap_enabler is set) + Should be reset by user of Decimal instance. + Emin - Minimum exponent + Emax - Maximum exponent + capitals - If 1, 1*10^1 is printed as 1E+1. + If 0, printed as 1e1 + _clamp - If 1, change exponents if too high (Default 0) + """ + + def __init__(self, prec=None, rounding=None, + traps=None, flags=None, + Emin=None, Emax=None, + capitals=None, _clamp=0, + _ignored_flags=None): + # Set defaults; for everything except flags and _ignored_flags, + # inherit from DefaultContext. + try: + dc = DefaultContext + except NameError: + pass + + self.prec = prec if prec is not None else dc.prec + self.rounding = rounding if rounding is not None else dc.rounding + self.Emin = Emin if Emin is not None else dc.Emin + self.Emax = Emax if Emax is not None else dc.Emax + self.capitals = capitals if capitals is not None else dc.capitals + self._clamp = _clamp if _clamp is not None else dc._clamp + + if _ignored_flags is None: + self._ignored_flags = [] + else: + self._ignored_flags = _ignored_flags + + if traps is None: + self.traps = dc.traps.copy() + elif not isinstance(traps, dict): + self.traps = dict((s, int(s in traps)) for s in _signals) + else: + self.traps = traps + + if flags is None: + self.flags = dict.fromkeys(_signals, 0) + elif not isinstance(flags, dict): + self.flags = dict((s, int(s in flags)) for s in _signals) + else: + self.flags = flags + + def __repr__(self): + """Show the current context.""" + s = [] + s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' + 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' + % vars(self)) + names = [f.__name__ for f, v in self.flags.items() if v] + s.append('flags=[' + ', '.join(names) + ']') + names = [t.__name__ for t, v in self.traps.items() if v] + s.append('traps=[' + ', '.join(names) + ']') + return ', '.join(s) + ')' + + def clear_flags(self): + """Reset all flags to zero""" + for flag in self.flags: + self.flags[flag] = 0 + + def _shallow_copy(self): + """Returns a shallow copy from self.""" + nc = Context(self.prec, self.rounding, self.traps, + self.flags, self.Emin, self.Emax, + self.capitals, self._clamp, self._ignored_flags) + return nc + + def copy(self): + """Returns a deep copy from self.""" + nc = Context(self.prec, self.rounding, self.traps.copy(), + self.flags.copy(), self.Emin, self.Emax, + self.capitals, self._clamp, self._ignored_flags) + return nc + __copy__ = copy + + def _raise_error(self, condition, explanation = None, *args): + """Handles an error + + If the flag is in _ignored_flags, returns the default response. + Otherwise, it sets the flag, then, if the corresponding + trap_enabler is set, it reraises the exception. Otherwise, it returns + the default value after setting the flag. + """ + error = _condition_map.get(condition, condition) + if error in self._ignored_flags: + # Don't touch the flag + return error().handle(self, *args) + + self.flags[error] = 1 + if not self.traps[error]: + # The errors define how to handle themselves. + return condition().handle(self, *args) + + # Errors should only be risked on copies of the context + # self._ignored_flags = [] + raise error(explanation) + + def _ignore_all_flags(self): + """Ignore all flags, if they are raised""" + return self._ignore_flags(*_signals) + + def _ignore_flags(self, *flags): + """Ignore the flags, if they are raised""" + # Do not mutate-- This way, copies of a context leave the original + # alone. + self._ignored_flags = (self._ignored_flags + list(flags)) + return list(flags) + + def _regard_flags(self, *flags): + """Stop ignoring the flags, if they are raised""" + if flags and isinstance(flags[0], (tuple,list)): + flags = flags[0] + for flag in flags: + self._ignored_flags.remove(flag) + + # We inherit object.__hash__, so we must deny this explicitly + __hash__ = None + + def Etiny(self): + """Returns Etiny (= Emin - prec + 1)""" + return int(self.Emin - self.prec + 1) + + def Etop(self): + """Returns maximum exponent (= Emax - prec + 1)""" + return int(self.Emax - self.prec + 1) + + def _set_rounding(self, type): + """Sets the rounding type. + + Sets the rounding type, and returns the current (previous) + rounding type. Often used like: + + context = context.copy() + # so you don't change the calling context + # if an error occurs in the middle. + rounding = context._set_rounding(ROUND_UP) + val = self.__sub__(other, context=context) + context._set_rounding(rounding) + + This will make it round up for that operation. + """ + rounding = self.rounding + self.rounding= type + return rounding + + def create_decimal(self, num='0'): + """Creates a new Decimal instance but using self as context. + + This method implements the to-number operation of the + IBM Decimal specification.""" + + if isinstance(num, basestring) and num != num.strip(): + return self._raise_error(ConversionSyntax, + "no trailing or leading whitespace is " + "permitted.") + + d = Decimal(num, context=self) + if d._isnan() and len(d._int) > self.prec - self._clamp: + return self._raise_error(ConversionSyntax, + "diagnostic info too long in NaN") + return d._fix(self) + + def create_decimal_from_float(self, f): + """Creates a new Decimal instance from a float but rounding using self + as the context. + + >>> context = Context(prec=5, rounding=ROUND_DOWN) + >>> context.create_decimal_from_float(3.1415926535897932) + Decimal('3.1415') + >>> context = Context(prec=5, traps=[Inexact]) + >>> context.create_decimal_from_float(3.1415926535897932) + Traceback (most recent call last): + ... + Inexact: None + + """ + d = Decimal.from_float(f) # An exact conversion + return d._fix(self) # Apply the context rounding + + # Methods + def abs(self, a): + """Returns the absolute value of the operand. + + If the operand is negative, the result is the same as using the minus + operation on the operand. Otherwise, the result is the same as using + the plus operation on the operand. + + >>> ExtendedContext.abs(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.abs(Decimal('-100')) + Decimal('100') + >>> ExtendedContext.abs(Decimal('101.5')) + Decimal('101.5') + >>> ExtendedContext.abs(Decimal('-101.5')) + Decimal('101.5') + >>> ExtendedContext.abs(-1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.__abs__(context=self) + + def add(self, a, b): + """Return the sum of the two operands. + + >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) + Decimal('19.00') + >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) + Decimal('1.02E+4') + >>> ExtendedContext.add(1, Decimal(2)) + Decimal('3') + >>> ExtendedContext.add(Decimal(8), 5) + Decimal('13') + >>> ExtendedContext.add(5, 5) + Decimal('10') + """ + a = _convert_other(a, raiseit=True) + r = a.__add__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def _apply(self, a): + return str(a._fix(self)) + + def canonical(self, a): + """Returns the same Decimal object. + + As we do not have different encodings for the same number, the + received object already is in its canonical form. + + >>> ExtendedContext.canonical(Decimal('2.50')) + Decimal('2.50') + """ + return a.canonical(context=self) + + def compare(self, a, b): + """Compares values numerically. + + If the signs of the operands differ, a value representing each operand + ('-1' if the operand is less than zero, '0' if the operand is zero or + negative zero, or '1' if the operand is greater than zero) is used in + place of that operand for the comparison instead of the actual + operand. + + The comparison is then effected by subtracting the second operand from + the first and then returning a value according to the result of the + subtraction: '-1' if the result is less than zero, '0' if the result is + zero or negative zero, or '1' if the result is greater than zero. + + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) + Decimal('0') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) + Decimal('0') + >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) + Decimal('1') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) + Decimal('1') + >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) + Decimal('-1') + >>> ExtendedContext.compare(1, 2) + Decimal('-1') + >>> ExtendedContext.compare(Decimal(1), 2) + Decimal('-1') + >>> ExtendedContext.compare(1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare(b, context=self) + + def compare_signal(self, a, b): + """Compares the values of the two operands numerically. + + It's pretty much like compare(), but all NaNs signal, with signaling + NaNs taking precedence over quiet NaNs. + + >>> c = ExtendedContext + >>> c.compare_signal(Decimal('2.1'), Decimal('3')) + Decimal('-1') + >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) + Decimal('0') + >>> c.flags[InvalidOperation] = 0 + >>> print c.flags[InvalidOperation] + 0 + >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) + Decimal('NaN') + >>> print c.flags[InvalidOperation] + 1 + >>> c.flags[InvalidOperation] = 0 + >>> print c.flags[InvalidOperation] + 0 + >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) + Decimal('NaN') + >>> print c.flags[InvalidOperation] + 1 + >>> c.compare_signal(-1, 2) + Decimal('-1') + >>> c.compare_signal(Decimal(-1), 2) + Decimal('-1') + >>> c.compare_signal(-1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare_signal(b, context=self) + + def compare_total(self, a, b): + """Compares two operands using their abstract representation. + + This is not like the standard compare, which use their numerical + value. Note that a total ordering is defined for all possible abstract + representations. + + >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('-127'), Decimal('12')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30')) + Decimal('0') + >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('12.300')) + Decimal('1') + >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) + Decimal('-1') + >>> ExtendedContext.compare_total(1, 2) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal(1), 2) + Decimal('-1') + >>> ExtendedContext.compare_total(1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare_total(b) + + def compare_total_mag(self, a, b): + """Compares two operands using their abstract representation ignoring sign. + + Like compare_total, but with operand's sign ignored and assumed to be 0. + """ + a = _convert_other(a, raiseit=True) + return a.compare_total_mag(b) + + def copy_abs(self, a): + """Returns a copy of the operand with the sign set to 0. + + >>> ExtendedContext.copy_abs(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.copy_abs(Decimal('-100')) + Decimal('100') + >>> ExtendedContext.copy_abs(-1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_abs() + + def copy_decimal(self, a): + """Returns a copy of the decimal object. + + >>> ExtendedContext.copy_decimal(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.copy_decimal(Decimal('-1.00')) + Decimal('-1.00') + >>> ExtendedContext.copy_decimal(1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return Decimal(a) + + def copy_negate(self, a): + """Returns a copy of the operand with the sign inverted. + + >>> ExtendedContext.copy_negate(Decimal('101.5')) + Decimal('-101.5') + >>> ExtendedContext.copy_negate(Decimal('-101.5')) + Decimal('101.5') + >>> ExtendedContext.copy_negate(1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_negate() + + def copy_sign(self, a, b): + """Copies the second operand's sign to the first one. + + In detail, it returns a copy of the first operand with the sign + equal to the sign of the second operand. + + >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) + Decimal('1.50') + >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33')) + Decimal('1.50') + >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33')) + Decimal('-1.50') + >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) + Decimal('-1.50') + >>> ExtendedContext.copy_sign(1, -2) + Decimal('-1') + >>> ExtendedContext.copy_sign(Decimal(1), -2) + Decimal('-1') + >>> ExtendedContext.copy_sign(1, Decimal(-2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_sign(b) + + def divide(self, a, b): + """Decimal division in a specified context. + + >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) + Decimal('0.333333333') + >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) + Decimal('0.666666667') + >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) + Decimal('2.5') + >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) + Decimal('0.1') + >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) + Decimal('1') + >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) + Decimal('4.00') + >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) + Decimal('1.20') + >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) + Decimal('10') + >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) + Decimal('1000') + >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) + Decimal('1.20E+6') + >>> ExtendedContext.divide(5, 5) + Decimal('1') + >>> ExtendedContext.divide(Decimal(5), 5) + Decimal('1') + >>> ExtendedContext.divide(5, Decimal(5)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + r = a.__div__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def divide_int(self, a, b): + """Divides two numbers and returns the integer part of the result. + + >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) + Decimal('0') + >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) + Decimal('3') + >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) + Decimal('3') + >>> ExtendedContext.divide_int(10, 3) + Decimal('3') + >>> ExtendedContext.divide_int(Decimal(10), 3) + Decimal('3') + >>> ExtendedContext.divide_int(10, Decimal(3)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + r = a.__floordiv__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def divmod(self, a, b): + """Return (a // b, a % b). + + >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) + (Decimal('2'), Decimal('2')) + >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(8, 4) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(Decimal(8), 4) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(8, Decimal(4)) + (Decimal('2'), Decimal('0')) + """ + a = _convert_other(a, raiseit=True) + r = a.__divmod__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def exp(self, a): + """Returns e ** a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.exp(Decimal('-Infinity')) + Decimal('0') + >>> c.exp(Decimal('-1')) + Decimal('0.367879441') + >>> c.exp(Decimal('0')) + Decimal('1') + >>> c.exp(Decimal('1')) + Decimal('2.71828183') + >>> c.exp(Decimal('0.693147181')) + Decimal('2.00000000') + >>> c.exp(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.exp(10) + Decimal('22026.4658') + """ + a =_convert_other(a, raiseit=True) + return a.exp(context=self) + + def fma(self, a, b, c): + """Returns a multiplied by b, plus c. + + The first two operands are multiplied together, using multiply, + the third operand is then added to the result of that + multiplication, using add, all with only one final rounding. + + >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) + Decimal('22') + >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7')) + Decimal('-8') + >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) + Decimal('1.38435736E+12') + >>> ExtendedContext.fma(1, 3, 4) + Decimal('7') + >>> ExtendedContext.fma(1, Decimal(3), 4) + Decimal('7') + >>> ExtendedContext.fma(1, 3, Decimal(4)) + Decimal('7') + """ + a = _convert_other(a, raiseit=True) + return a.fma(b, c, context=self) + + def is_canonical(self, a): + """Return True if the operand is canonical; otherwise return False. + + Currently, the encoding of a Decimal instance is always + canonical, so this method returns True for any Decimal. + + >>> ExtendedContext.is_canonical(Decimal('2.50')) + True + """ + return a.is_canonical() + + def is_finite(self, a): + """Return True if the operand is finite; otherwise return False. + + A Decimal instance is considered finite if it is neither + infinite nor a NaN. + + >>> ExtendedContext.is_finite(Decimal('2.50')) + True + >>> ExtendedContext.is_finite(Decimal('-0.3')) + True + >>> ExtendedContext.is_finite(Decimal('0')) + True + >>> ExtendedContext.is_finite(Decimal('Inf')) + False + >>> ExtendedContext.is_finite(Decimal('NaN')) + False + >>> ExtendedContext.is_finite(1) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_finite() + + def is_infinite(self, a): + """Return True if the operand is infinite; otherwise return False. + + >>> ExtendedContext.is_infinite(Decimal('2.50')) + False + >>> ExtendedContext.is_infinite(Decimal('-Inf')) + True + >>> ExtendedContext.is_infinite(Decimal('NaN')) + False + >>> ExtendedContext.is_infinite(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_infinite() + + def is_nan(self, a): + """Return True if the operand is a qNaN or sNaN; + otherwise return False. + + >>> ExtendedContext.is_nan(Decimal('2.50')) + False + >>> ExtendedContext.is_nan(Decimal('NaN')) + True + >>> ExtendedContext.is_nan(Decimal('-sNaN')) + True + >>> ExtendedContext.is_nan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_nan() + + def is_normal(self, a): + """Return True if the operand is a normal number; + otherwise return False. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.is_normal(Decimal('2.50')) + True + >>> c.is_normal(Decimal('0.1E-999')) + False + >>> c.is_normal(Decimal('0.00')) + False + >>> c.is_normal(Decimal('-Inf')) + False + >>> c.is_normal(Decimal('NaN')) + False + >>> c.is_normal(1) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_normal(context=self) + + def is_qnan(self, a): + """Return True if the operand is a quiet NaN; otherwise return False. + + >>> ExtendedContext.is_qnan(Decimal('2.50')) + False + >>> ExtendedContext.is_qnan(Decimal('NaN')) + True + >>> ExtendedContext.is_qnan(Decimal('sNaN')) + False + >>> ExtendedContext.is_qnan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_qnan() + + def is_signed(self, a): + """Return True if the operand is negative; otherwise return False. + + >>> ExtendedContext.is_signed(Decimal('2.50')) + False + >>> ExtendedContext.is_signed(Decimal('-12')) + True + >>> ExtendedContext.is_signed(Decimal('-0')) + True + >>> ExtendedContext.is_signed(8) + False + >>> ExtendedContext.is_signed(-8) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_signed() + + def is_snan(self, a): + """Return True if the operand is a signaling NaN; + otherwise return False. + + >>> ExtendedContext.is_snan(Decimal('2.50')) + False + >>> ExtendedContext.is_snan(Decimal('NaN')) + False + >>> ExtendedContext.is_snan(Decimal('sNaN')) + True + >>> ExtendedContext.is_snan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_snan() + + def is_subnormal(self, a): + """Return True if the operand is subnormal; otherwise return False. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.is_subnormal(Decimal('2.50')) + False + >>> c.is_subnormal(Decimal('0.1E-999')) + True + >>> c.is_subnormal(Decimal('0.00')) + False + >>> c.is_subnormal(Decimal('-Inf')) + False + >>> c.is_subnormal(Decimal('NaN')) + False + >>> c.is_subnormal(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_subnormal(context=self) + + def is_zero(self, a): + """Return True if the operand is a zero; otherwise return False. + + >>> ExtendedContext.is_zero(Decimal('0')) + True + >>> ExtendedContext.is_zero(Decimal('2.50')) + False + >>> ExtendedContext.is_zero(Decimal('-0E+2')) + True + >>> ExtendedContext.is_zero(1) + False + >>> ExtendedContext.is_zero(0) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_zero() + + def ln(self, a): + """Returns the natural (base e) logarithm of the operand. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.ln(Decimal('0')) + Decimal('-Infinity') + >>> c.ln(Decimal('1.000')) + Decimal('0') + >>> c.ln(Decimal('2.71828183')) + Decimal('1.00000000') + >>> c.ln(Decimal('10')) + Decimal('2.30258509') + >>> c.ln(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.ln(1) + Decimal('0') + """ + a = _convert_other(a, raiseit=True) + return a.ln(context=self) + + def log10(self, a): + """Returns the base 10 logarithm of the operand. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.log10(Decimal('0')) + Decimal('-Infinity') + >>> c.log10(Decimal('0.001')) + Decimal('-3') + >>> c.log10(Decimal('1.000')) + Decimal('0') + >>> c.log10(Decimal('2')) + Decimal('0.301029996') + >>> c.log10(Decimal('10')) + Decimal('1') + >>> c.log10(Decimal('70')) + Decimal('1.84509804') + >>> c.log10(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.log10(0) + Decimal('-Infinity') + >>> c.log10(1) + Decimal('0') + """ + a = _convert_other(a, raiseit=True) + return a.log10(context=self) + + def logb(self, a): + """ Returns the exponent of the magnitude of the operand's MSD. + + The result is the integer which is the exponent of the magnitude + of the most significant digit of the operand (as though the + operand were truncated to a single digit while maintaining the + value of that digit and without limiting the resulting exponent). + + >>> ExtendedContext.logb(Decimal('250')) + Decimal('2') + >>> ExtendedContext.logb(Decimal('2.50')) + Decimal('0') + >>> ExtendedContext.logb(Decimal('0.03')) + Decimal('-2') + >>> ExtendedContext.logb(Decimal('0')) + Decimal('-Infinity') + >>> ExtendedContext.logb(1) + Decimal('0') + >>> ExtendedContext.logb(10) + Decimal('1') + >>> ExtendedContext.logb(100) + Decimal('2') + """ + a = _convert_other(a, raiseit=True) + return a.logb(context=self) + + def logical_and(self, a, b): + """Applies the logical operation 'and' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010')) + Decimal('1000') + >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) + Decimal('10') + >>> ExtendedContext.logical_and(110, 1101) + Decimal('100') + >>> ExtendedContext.logical_and(Decimal(110), 1101) + Decimal('100') + >>> ExtendedContext.logical_and(110, Decimal(1101)) + Decimal('100') + """ + a = _convert_other(a, raiseit=True) + return a.logical_and(b, context=self) + + def logical_invert(self, a): + """Invert all the digits in the operand. + + The operand must be a logical number. + + >>> ExtendedContext.logical_invert(Decimal('0')) + Decimal('111111111') + >>> ExtendedContext.logical_invert(Decimal('1')) + Decimal('111111110') + >>> ExtendedContext.logical_invert(Decimal('111111111')) + Decimal('0') + >>> ExtendedContext.logical_invert(Decimal('101010101')) + Decimal('10101010') + >>> ExtendedContext.logical_invert(1101) + Decimal('111110010') + """ + a = _convert_other(a, raiseit=True) + return a.logical_invert(context=self) + + def logical_or(self, a, b): + """Applies the logical operation 'or' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010')) + Decimal('1110') + >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) + Decimal('1110') + >>> ExtendedContext.logical_or(110, 1101) + Decimal('1111') + >>> ExtendedContext.logical_or(Decimal(110), 1101) + Decimal('1111') + >>> ExtendedContext.logical_or(110, Decimal(1101)) + Decimal('1111') + """ + a = _convert_other(a, raiseit=True) + return a.logical_or(b, context=self) + + def logical_xor(self, a, b): + """Applies the logical operation 'xor' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0')) + Decimal('1') + >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1')) + Decimal('0') + >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010')) + Decimal('110') + >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) + Decimal('1101') + >>> ExtendedContext.logical_xor(110, 1101) + Decimal('1011') + >>> ExtendedContext.logical_xor(Decimal(110), 1101) + Decimal('1011') + >>> ExtendedContext.logical_xor(110, Decimal(1101)) + Decimal('1011') + """ + a = _convert_other(a, raiseit=True) + return a.logical_xor(b, context=self) + + def max(self, a, b): + """max compares two values numerically and returns the maximum. + + If either operand is a NaN then the general rules apply. + Otherwise, the operands are compared as though by the compare + operation. If they are numerically equal then the left-hand operand + is chosen as the result. Otherwise the maximum (closer to positive + infinity) of the two operands is chosen as the result. + + >>> ExtendedContext.max(Decimal('3'), Decimal('2')) + Decimal('3') + >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) + Decimal('3') + >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.max(1, 2) + Decimal('2') + >>> ExtendedContext.max(Decimal(1), 2) + Decimal('2') + >>> ExtendedContext.max(1, Decimal(2)) + Decimal('2') + """ + a = _convert_other(a, raiseit=True) + return a.max(b, context=self) + + def max_mag(self, a, b): + """Compares the values numerically with their sign ignored. + + >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) + Decimal('-10') + >>> ExtendedContext.max_mag(1, -2) + Decimal('-2') + >>> ExtendedContext.max_mag(Decimal(1), -2) + Decimal('-2') + >>> ExtendedContext.max_mag(1, Decimal(-2)) + Decimal('-2') + """ + a = _convert_other(a, raiseit=True) + return a.max_mag(b, context=self) + + def min(self, a, b): + """min compares two values numerically and returns the minimum. + + If either operand is a NaN then the general rules apply. + Otherwise, the operands are compared as though by the compare + operation. If they are numerically equal then the left-hand operand + is chosen as the result. Otherwise the minimum (closer to negative + infinity) of the two operands is chosen as the result. + + >>> ExtendedContext.min(Decimal('3'), Decimal('2')) + Decimal('2') + >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) + Decimal('-10') + >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) + Decimal('1.0') + >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.min(1, 2) + Decimal('1') + >>> ExtendedContext.min(Decimal(1), 2) + Decimal('1') + >>> ExtendedContext.min(1, Decimal(29)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.min(b, context=self) + + def min_mag(self, a, b): + """Compares the values numerically with their sign ignored. + + >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) + Decimal('-2') + >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) + Decimal('-3') + >>> ExtendedContext.min_mag(1, -2) + Decimal('1') + >>> ExtendedContext.min_mag(Decimal(1), -2) + Decimal('1') + >>> ExtendedContext.min_mag(1, Decimal(-2)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.min_mag(b, context=self) + + def minus(self, a): + """Minus corresponds to unary prefix minus in Python. + + The operation is evaluated using the same rules as subtract; the + operation minus(a) is calculated as subtract('0', a) where the '0' + has the same exponent as the operand. + + >>> ExtendedContext.minus(Decimal('1.3')) + Decimal('-1.3') + >>> ExtendedContext.minus(Decimal('-1.3')) + Decimal('1.3') + >>> ExtendedContext.minus(1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.__neg__(context=self) + + def multiply(self, a, b): + """multiply multiplies two operands. + + If either operand is a special value then the general rules apply. + Otherwise, the operands are multiplied together + ('long multiplication'), resulting in a number which may be as long as + the sum of the lengths of the two operands. + + >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) + Decimal('3.60') + >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) + Decimal('21') + >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) + Decimal('0.72') + >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) + Decimal('-0.0') + >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) + Decimal('4.28135971E+11') + >>> ExtendedContext.multiply(7, 7) + Decimal('49') + >>> ExtendedContext.multiply(Decimal(7), 7) + Decimal('49') + >>> ExtendedContext.multiply(7, Decimal(7)) + Decimal('49') + """ + a = _convert_other(a, raiseit=True) + r = a.__mul__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def next_minus(self, a): + """Returns the largest representable number smaller than a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> ExtendedContext.next_minus(Decimal('1')) + Decimal('0.999999999') + >>> c.next_minus(Decimal('1E-1007')) + Decimal('0E-1007') + >>> ExtendedContext.next_minus(Decimal('-1.00000003')) + Decimal('-1.00000004') + >>> c.next_minus(Decimal('Infinity')) + Decimal('9.99999999E+999') + >>> c.next_minus(1) + Decimal('0.999999999') + """ + a = _convert_other(a, raiseit=True) + return a.next_minus(context=self) + + def next_plus(self, a): + """Returns the smallest representable number larger than a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> ExtendedContext.next_plus(Decimal('1')) + Decimal('1.00000001') + >>> c.next_plus(Decimal('-1E-1007')) + Decimal('-0E-1007') + >>> ExtendedContext.next_plus(Decimal('-1.00000003')) + Decimal('-1.00000002') + >>> c.next_plus(Decimal('-Infinity')) + Decimal('-9.99999999E+999') + >>> c.next_plus(1) + Decimal('1.00000001') + """ + a = _convert_other(a, raiseit=True) + return a.next_plus(context=self) + + def next_toward(self, a, b): + """Returns the number closest to a, in direction towards b. + + The result is the closest representable number from the first + operand (but not the first operand) that is in the direction + towards the second operand, unless the operands have the same + value. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.next_toward(Decimal('1'), Decimal('2')) + Decimal('1.00000001') + >>> c.next_toward(Decimal('-1E-1007'), Decimal('1')) + Decimal('-0E-1007') + >>> c.next_toward(Decimal('-1.00000003'), Decimal('0')) + Decimal('-1.00000002') + >>> c.next_toward(Decimal('1'), Decimal('0')) + Decimal('0.999999999') + >>> c.next_toward(Decimal('1E-1007'), Decimal('-100')) + Decimal('0E-1007') + >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10')) + Decimal('-1.00000004') + >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) + Decimal('-0.00') + >>> c.next_toward(0, 1) + Decimal('1E-1007') + >>> c.next_toward(Decimal(0), 1) + Decimal('1E-1007') + >>> c.next_toward(0, Decimal(1)) + Decimal('1E-1007') + """ + a = _convert_other(a, raiseit=True) + return a.next_toward(b, context=self) + + def normalize(self, a): + """normalize reduces an operand to its simplest form. + + Essentially a plus operation with all trailing zeros removed from the + result. + + >>> ExtendedContext.normalize(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.normalize(Decimal('-2.0')) + Decimal('-2') + >>> ExtendedContext.normalize(Decimal('1.200')) + Decimal('1.2') + >>> ExtendedContext.normalize(Decimal('-120')) + Decimal('-1.2E+2') + >>> ExtendedContext.normalize(Decimal('120.00')) + Decimal('1.2E+2') + >>> ExtendedContext.normalize(Decimal('0.00')) + Decimal('0') + >>> ExtendedContext.normalize(6) + Decimal('6') + """ + a = _convert_other(a, raiseit=True) + return a.normalize(context=self) + + def number_class(self, a): + """Returns an indication of the class of the operand. + + The class is one of the following strings: + -sNaN + -NaN + -Infinity + -Normal + -Subnormal + -Zero + +Zero + +Subnormal + +Normal + +Infinity + + >>> c = Context(ExtendedContext) + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.number_class(Decimal('Infinity')) + '+Infinity' + >>> c.number_class(Decimal('1E-10')) + '+Normal' + >>> c.number_class(Decimal('2.50')) + '+Normal' + >>> c.number_class(Decimal('0.1E-999')) + '+Subnormal' + >>> c.number_class(Decimal('0')) + '+Zero' + >>> c.number_class(Decimal('-0')) + '-Zero' + >>> c.number_class(Decimal('-0.1E-999')) + '-Subnormal' + >>> c.number_class(Decimal('-1E-10')) + '-Normal' + >>> c.number_class(Decimal('-2.50')) + '-Normal' + >>> c.number_class(Decimal('-Infinity')) + '-Infinity' + >>> c.number_class(Decimal('NaN')) + 'NaN' + >>> c.number_class(Decimal('-NaN')) + 'NaN' + >>> c.number_class(Decimal('sNaN')) + 'sNaN' + >>> c.number_class(123) + '+Normal' + """ + a = _convert_other(a, raiseit=True) + return a.number_class(context=self) + + def plus(self, a): + """Plus corresponds to unary prefix plus in Python. + + The operation is evaluated using the same rules as add; the + operation plus(a) is calculated as add('0', a) where the '0' + has the same exponent as the operand. + + >>> ExtendedContext.plus(Decimal('1.3')) + Decimal('1.3') + >>> ExtendedContext.plus(Decimal('-1.3')) + Decimal('-1.3') + >>> ExtendedContext.plus(-1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.__pos__(context=self) + + def power(self, a, b, modulo=None): + """Raises a to the power of b, to modulo if given. + + With two arguments, compute a**b. If a is negative then b + must be integral. The result will be inexact unless b is + integral and the result is finite and can be expressed exactly + in 'precision' digits. + + With three arguments, compute (a**b) % modulo. For the + three argument form, the following restrictions on the + arguments hold: + + - all three arguments must be integral + - b must be nonnegative + - at least one of a or b must be nonzero + - modulo must be nonzero and have at most 'precision' digits + + The result of pow(a, b, modulo) is identical to the result + that would be obtained by computing (a**b) % modulo with + unbounded precision, but is computed more efficiently. It is + always exact. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.power(Decimal('2'), Decimal('3')) + Decimal('8') + >>> c.power(Decimal('-2'), Decimal('3')) + Decimal('-8') + >>> c.power(Decimal('2'), Decimal('-3')) + Decimal('0.125') + >>> c.power(Decimal('1.7'), Decimal('8')) + Decimal('69.7575744') + >>> c.power(Decimal('10'), Decimal('0.301029996')) + Decimal('2.00000000') + >>> c.power(Decimal('Infinity'), Decimal('-1')) + Decimal('0') + >>> c.power(Decimal('Infinity'), Decimal('0')) + Decimal('1') + >>> c.power(Decimal('Infinity'), Decimal('1')) + Decimal('Infinity') + >>> c.power(Decimal('-Infinity'), Decimal('-1')) + Decimal('-0') + >>> c.power(Decimal('-Infinity'), Decimal('0')) + Decimal('1') + >>> c.power(Decimal('-Infinity'), Decimal('1')) + Decimal('-Infinity') + >>> c.power(Decimal('-Infinity'), Decimal('2')) + Decimal('Infinity') + >>> c.power(Decimal('0'), Decimal('0')) + Decimal('NaN') + + >>> c.power(Decimal('3'), Decimal('7'), Decimal('16')) + Decimal('11') + >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16')) + Decimal('-11') + >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16')) + Decimal('1') + >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16')) + Decimal('11') + >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789')) + Decimal('11729830') + >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729')) + Decimal('-0') + >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) + Decimal('1') + >>> ExtendedContext.power(7, 7) + Decimal('823543') + >>> ExtendedContext.power(Decimal(7), 7) + Decimal('823543') + >>> ExtendedContext.power(7, Decimal(7), 2) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + r = a.__pow__(b, modulo, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def quantize(self, a, b): + """Returns a value equal to 'a' (rounded), having the exponent of 'b'. + + The coefficient of the result is derived from that of the left-hand + operand. It may be rounded using the current rounding setting (if the + exponent is being increased), multiplied by a positive power of ten (if + the exponent is being decreased), or is unchanged (if the exponent is + already equal to that of the right-hand operand). + + Unlike other operations, if the length of the coefficient after the + quantize operation would be greater than precision then an Invalid + operation condition is raised. This guarantees that, unless there is + an error condition, the exponent of the result of a quantize is always + equal to that of the right-hand operand. + + Also unlike other operations, quantize will never raise Underflow, even + if the result is subnormal and inexact. + + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) + Decimal('2.170') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) + Decimal('2.17') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) + Decimal('2.2') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) + Decimal('2') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) + Decimal('0E+1') + >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) + Decimal('-Infinity') + >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) + Decimal('-0') + >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) + Decimal('-0E+5') + >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) + Decimal('217.0') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) + Decimal('217') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) + Decimal('2.2E+2') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) + Decimal('2E+2') + >>> ExtendedContext.quantize(1, 2) + Decimal('1') + >>> ExtendedContext.quantize(Decimal(1), 2) + Decimal('1') + >>> ExtendedContext.quantize(1, Decimal(2)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.quantize(b, context=self) + + def radix(self): + """Just returns 10, as this is Decimal, :) + + >>> ExtendedContext.radix() + Decimal('10') + """ + return Decimal(10) + + def remainder(self, a, b): + """Returns the remainder from integer division. + + The result is the residue of the dividend after the operation of + calculating integer division as described for divide-integer, rounded + to precision digits if necessary. The sign of the result, if + non-zero, is the same as that of the original dividend. + + This operation will fail under the same conditions as integer division + (that is, if integer division on the same two operands would fail, the + remainder cannot be calculated). + + >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) + Decimal('2.1') + >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) + Decimal('1') + >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) + Decimal('0.2') + >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) + Decimal('0.1') + >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) + Decimal('1.0') + >>> ExtendedContext.remainder(22, 6) + Decimal('4') + >>> ExtendedContext.remainder(Decimal(22), 6) + Decimal('4') + >>> ExtendedContext.remainder(22, Decimal(6)) + Decimal('4') + """ + a = _convert_other(a, raiseit=True) + r = a.__mod__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def remainder_near(self, a, b): + """Returns to be "a - b * n", where n is the integer nearest the exact + value of "x / b" (if two integers are equally near then the even one + is chosen). If the result is equal to 0 then its sign will be the + sign of a. + + This operation will fail under the same conditions as integer division + (that is, if integer division on the same two operands would fail, the + remainder cannot be calculated). + + >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) + Decimal('-0.9') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) + Decimal('-2') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) + Decimal('1') + >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) + Decimal('0.2') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) + Decimal('0.1') + >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) + Decimal('-0.3') + >>> ExtendedContext.remainder_near(3, 11) + Decimal('3') + >>> ExtendedContext.remainder_near(Decimal(3), 11) + Decimal('3') + >>> ExtendedContext.remainder_near(3, Decimal(11)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + return a.remainder_near(b, context=self) + + def rotate(self, a, b): + """Returns a rotated copy of a, b times. + + The coefficient of the result is a rotated copy of the digits in + the coefficient of the first operand. The number of places of + rotation is taken from the absolute value of the second operand, + with the rotation being to the left if the second operand is + positive or to the right otherwise. + + >>> ExtendedContext.rotate(Decimal('34'), Decimal('8')) + Decimal('400000003') + >>> ExtendedContext.rotate(Decimal('12'), Decimal('9')) + Decimal('12') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2')) + Decimal('891234567') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0')) + Decimal('123456789') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) + Decimal('345678912') + >>> ExtendedContext.rotate(1333333, 1) + Decimal('13333330') + >>> ExtendedContext.rotate(Decimal(1333333), 1) + Decimal('13333330') + >>> ExtendedContext.rotate(1333333, Decimal(1)) + Decimal('13333330') + """ + a = _convert_other(a, raiseit=True) + return a.rotate(b, context=self) + + def same_quantum(self, a, b): + """Returns True if the two operands have the same exponent. + + The result is never affected by either the sign or the coefficient of + either operand. + + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) + False + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) + True + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) + False + >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) + True + >>> ExtendedContext.same_quantum(10000, -1) + True + >>> ExtendedContext.same_quantum(Decimal(10000), -1) + True + >>> ExtendedContext.same_quantum(10000, Decimal(-1)) + True + """ + a = _convert_other(a, raiseit=True) + return a.same_quantum(b) + + def scaleb (self, a, b): + """Returns the first operand after adding the second value its exp. + + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2')) + Decimal('0.0750') + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0')) + Decimal('7.50') + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) + Decimal('7.50E+3') + >>> ExtendedContext.scaleb(1, 4) + Decimal('1E+4') + >>> ExtendedContext.scaleb(Decimal(1), 4) + Decimal('1E+4') + >>> ExtendedContext.scaleb(1, Decimal(4)) + Decimal('1E+4') + """ + a = _convert_other(a, raiseit=True) + return a.scaleb(b, context=self) + + def shift(self, a, b): + """Returns a shifted copy of a, b times. + + The coefficient of the result is a shifted copy of the digits + in the coefficient of the first operand. The number of places + to shift is taken from the absolute value of the second operand, + with the shift being to the left if the second operand is + positive or to the right otherwise. Digits shifted into the + coefficient are zeros. + + >>> ExtendedContext.shift(Decimal('34'), Decimal('8')) + Decimal('400000000') + >>> ExtendedContext.shift(Decimal('12'), Decimal('9')) + Decimal('0') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2')) + Decimal('1234567') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0')) + Decimal('123456789') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) + Decimal('345678900') + >>> ExtendedContext.shift(88888888, 2) + Decimal('888888800') + >>> ExtendedContext.shift(Decimal(88888888), 2) + Decimal('888888800') + >>> ExtendedContext.shift(88888888, Decimal(2)) + Decimal('888888800') + """ + a = _convert_other(a, raiseit=True) + return a.shift(b, context=self) + + def sqrt(self, a): + """Square root of a non-negative number to context precision. + + If the result must be inexact, it is rounded using the round-half-even + algorithm. + + >>> ExtendedContext.sqrt(Decimal('0')) + Decimal('0') + >>> ExtendedContext.sqrt(Decimal('-0')) + Decimal('-0') + >>> ExtendedContext.sqrt(Decimal('0.39')) + Decimal('0.624499800') + >>> ExtendedContext.sqrt(Decimal('100')) + Decimal('10') + >>> ExtendedContext.sqrt(Decimal('1')) + Decimal('1') + >>> ExtendedContext.sqrt(Decimal('1.0')) + Decimal('1.0') + >>> ExtendedContext.sqrt(Decimal('1.00')) + Decimal('1.0') + >>> ExtendedContext.sqrt(Decimal('7')) + Decimal('2.64575131') + >>> ExtendedContext.sqrt(Decimal('10')) + Decimal('3.16227766') + >>> ExtendedContext.sqrt(2) + Decimal('1.41421356') + >>> ExtendedContext.prec + 9 + """ + a = _convert_other(a, raiseit=True) + return a.sqrt(context=self) + + def subtract(self, a, b): + """Return the difference between the two operands. + + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) + Decimal('0.23') + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) + Decimal('0.00') + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) + Decimal('-0.77') + >>> ExtendedContext.subtract(8, 5) + Decimal('3') + >>> ExtendedContext.subtract(Decimal(8), 5) + Decimal('3') + >>> ExtendedContext.subtract(8, Decimal(5)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + r = a.__sub__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def to_eng_string(self, a): + """Converts a number to a string, using scientific notation. + + The operation is not affected by the context. + """ + a = _convert_other(a, raiseit=True) + return a.to_eng_string(context=self) + + def to_sci_string(self, a): + """Converts a number to a string, using scientific notation. + + The operation is not affected by the context. + """ + a = _convert_other(a, raiseit=True) + return a.__str__(context=self) + + def to_integral_exact(self, a): + """Rounds to an integer. + + When the operand has a negative exponent, the result is the same + as using the quantize() operation using the given operand as the + left-hand-operand, 1E+0 as the right-hand-operand, and the precision + of the operand as the precision setting; Inexact and Rounded flags + are allowed in this operation. The rounding mode is taken from the + context. + + >>> ExtendedContext.to_integral_exact(Decimal('2.1')) + Decimal('2') + >>> ExtendedContext.to_integral_exact(Decimal('100')) + Decimal('100') + >>> ExtendedContext.to_integral_exact(Decimal('100.0')) + Decimal('100') + >>> ExtendedContext.to_integral_exact(Decimal('101.5')) + Decimal('102') + >>> ExtendedContext.to_integral_exact(Decimal('-101.5')) + Decimal('-102') + >>> ExtendedContext.to_integral_exact(Decimal('10E+5')) + Decimal('1.0E+6') + >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77')) + Decimal('7.89E+77') + >>> ExtendedContext.to_integral_exact(Decimal('-Inf')) + Decimal('-Infinity') + """ + a = _convert_other(a, raiseit=True) + return a.to_integral_exact(context=self) + + def to_integral_value(self, a): + """Rounds to an integer. + + When the operand has a negative exponent, the result is the same + as using the quantize() operation using the given operand as the + left-hand-operand, 1E+0 as the right-hand-operand, and the precision + of the operand as the precision setting, except that no flags will + be set. The rounding mode is taken from the context. + + >>> ExtendedContext.to_integral_value(Decimal('2.1')) + Decimal('2') + >>> ExtendedContext.to_integral_value(Decimal('100')) + Decimal('100') + >>> ExtendedContext.to_integral_value(Decimal('100.0')) + Decimal('100') + >>> ExtendedContext.to_integral_value(Decimal('101.5')) + Decimal('102') + >>> ExtendedContext.to_integral_value(Decimal('-101.5')) + Decimal('-102') + >>> ExtendedContext.to_integral_value(Decimal('10E+5')) + Decimal('1.0E+6') + >>> ExtendedContext.to_integral_value(Decimal('7.89E+77')) + Decimal('7.89E+77') + >>> ExtendedContext.to_integral_value(Decimal('-Inf')) + Decimal('-Infinity') + """ + a = _convert_other(a, raiseit=True) + return a.to_integral_value(context=self) + + # the method name changed, but we provide also the old one, for compatibility + to_integral = to_integral_value + +class _WorkRep(object): + __slots__ = ('sign','int','exp') + # sign: 0 or 1 + # int: int or long + # exp: None, int, or string + + def __init__(self, value=None): + if value is None: + self.sign = None + self.int = 0 + self.exp = None + elif isinstance(value, Decimal): + self.sign = value._sign + self.int = int(value._int) + self.exp = value._exp + else: + # assert isinstance(value, tuple) + self.sign = value[0] + self.int = value[1] + self.exp = value[2] + + def __repr__(self): + return "(%r, %r, %r)" % (self.sign, self.int, self.exp) + + __str__ = __repr__ + + + +def _normalize(op1, op2, prec = 0): + """Normalizes op1, op2 to have the same exp and length of coefficient. + + Done during addition. + """ + if op1.exp < op2.exp: + tmp = op2 + other = op1 + else: + tmp = op1 + other = op2 + + # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1). + # Then adding 10**exp to tmp has the same effect (after rounding) + # as adding any positive quantity smaller than 10**exp; similarly + # for subtraction. So if other is smaller than 10**exp we replace + # it with 10**exp. This avoids tmp.exp - other.exp getting too large. + tmp_len = len(str(tmp.int)) + other_len = len(str(other.int)) + exp = tmp.exp + min(-1, tmp_len - prec - 2) + if other_len + other.exp - 1 < exp: + other.int = 1 + other.exp = exp + + tmp.int *= 10 ** (tmp.exp - other.exp) + tmp.exp = other.exp + return op1, op2 + +##### Integer arithmetic functions used by ln, log10, exp and __pow__ ##### + +# This function from Tim Peters was taken from here: +# http://mail.python.org/pipermail/python-list/1999-July/007758.html +# The correction being in the function definition is for speed, and +# the whole function is not resolved with math.log because of avoiding +# the use of floats. +def _nbits(n, correction = { + '0': 4, '1': 3, '2': 2, '3': 2, + '4': 1, '5': 1, '6': 1, '7': 1, + '8': 0, '9': 0, 'a': 0, 'b': 0, + 'c': 0, 'd': 0, 'e': 0, 'f': 0}): + """Number of bits in binary representation of the positive integer n, + or 0 if n == 0. + """ + if n < 0: + raise ValueError("The argument to _nbits should be nonnegative.") + hex_n = "%x" % n + return 4*len(hex_n) - correction[hex_n[0]] + +def _sqrt_nearest(n, a): + """Closest integer to the square root of the positive integer n. a is + an initial approximation to the square root. Any positive integer + will do for a, but the closer a is to the square root of n the + faster convergence will be. + + """ + if n <= 0 or a <= 0: + raise ValueError("Both arguments to _sqrt_nearest should be positive.") + + b=0 + while a != b: + b, a = a, a--n//a>>1 + return a + +def _rshift_nearest(x, shift): + """Given an integer x and a nonnegative integer shift, return closest + integer to x / 2**shift; use round-to-even in case of a tie. + + """ + b, q = 1L << shift, x >> shift + return q + (2*(x & (b-1)) + (q&1) > b) + +def _div_nearest(a, b): + """Closest integer to a/b, a and b positive integers; rounds to even + in the case of a tie. + + """ + q, r = divmod(a, b) + return q + (2*r + (q&1) > b) + +def _ilog(x, M, L = 8): + """Integer approximation to M*log(x/M), with absolute error boundable + in terms only of x/M. + + Given positive integers x and M, return an integer approximation to + M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference + between the approximation and the exact result is at most 22. For + L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In + both cases these are upper bounds on the error; it will usually be + much smaller.""" + + # The basic algorithm is the following: let log1p be the function + # log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use + # the reduction + # + # log1p(y) = 2*log1p(y/(1+sqrt(1+y))) + # + # repeatedly until the argument to log1p is small (< 2**-L in + # absolute value). For small y we can use the Taylor series + # expansion + # + # log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T + # + # truncating at T such that y**T is small enough. The whole + # computation is carried out in a form of fixed-point arithmetic, + # with a real number z being represented by an integer + # approximation to z*M. To avoid loss of precision, the y below + # is actually an integer approximation to 2**R*y*M, where R is the + # number of reductions performed so far. + + y = x-M + # argument reduction; R = number of reductions performed + R = 0 + while (R <= L and long(abs(y)) << L-R >= M or + R > L and abs(y) >> R-L >= M): + y = _div_nearest(long(M*y) << 1, + M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M)) + R += 1 + + # Taylor series with T terms + T = -int(-10*len(str(M))//(3*L)) + yshift = _rshift_nearest(y, R) + w = _div_nearest(M, T) + for k in xrange(T-1, 0, -1): + w = _div_nearest(M, k) - _div_nearest(yshift*w, M) + + return _div_nearest(w*y, M) + +def _dlog10(c, e, p): + """Given integers c, e and p with c > 0, p >= 0, compute an integer + approximation to 10**p * log10(c*10**e), with an absolute error of + at most 1. Assumes that c*10**e is not exactly 1.""" + + # increase precision by 2; compensate for this by dividing + # final result by 100 + p += 2 + + # write c*10**e as d*10**f with either: + # f >= 0 and 1 <= d <= 10, or + # f <= 0 and 0.1 <= d <= 1. + # Thus for c*10**e close to 1, f = 0 + l = len(str(c)) + f = e+l - (e+l >= 1) + + if p > 0: + M = 10**p + k = e+p-f + if k >= 0: + c *= 10**k + else: + c = _div_nearest(c, 10**-k) + + log_d = _ilog(c, M) # error < 5 + 22 = 27 + log_10 = _log10_digits(p) # error < 1 + log_d = _div_nearest(log_d*M, log_10) + log_tenpower = f*M # exact + else: + log_d = 0 # error < 2.31 + log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 + + return _div_nearest(log_tenpower+log_d, 100) + +def _dlog(c, e, p): + """Given integers c, e and p with c > 0, compute an integer + approximation to 10**p * log(c*10**e), with an absolute error of + at most 1. Assumes that c*10**e is not exactly 1.""" + + # Increase precision by 2. The precision increase is compensated + # for at the end with a division by 100. + p += 2 + + # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, + # or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e) + # as 10**p * log(d) + 10**p*f * log(10). + l = len(str(c)) + f = e+l - (e+l >= 1) + + # compute approximation to 10**p*log(d), with error < 27 + if p > 0: + k = e+p-f + if k >= 0: + c *= 10**k + else: + c = _div_nearest(c, 10**-k) # error of <= 0.5 in c + + # _ilog magnifies existing error in c by a factor of at most 10 + log_d = _ilog(c, 10**p) # error < 5 + 22 = 27 + else: + # p <= 0: just approximate the whole thing by 0; error < 2.31 + log_d = 0 + + # compute approximation to f*10**p*log(10), with error < 11. + if f: + extra = len(str(abs(f)))-1 + if p + extra >= 0: + # error in f * _log10_digits(p+extra) < |f| * 1 = |f| + # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 + f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra) + else: + f_log_ten = 0 + else: + f_log_ten = 0 + + # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 + return _div_nearest(f_log_ten + log_d, 100) + +class _Log10Memoize(object): + """Class to compute, store, and allow retrieval of, digits of the + constant log(10) = 2.302585.... This constant is needed by + Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" + def __init__(self): + self.digits = "23025850929940456840179914546843642076011014886" + + def getdigits(self, p): + """Given an integer p >= 0, return floor(10**p)*log(10). + + For example, self.getdigits(3) returns 2302. + """ + # digits are stored as a string, for quick conversion to + # integer in the case that we've already computed enough + # digits; the stored digits should always be correct + # (truncated, not rounded to nearest). + if p < 0: + raise ValueError("p should be nonnegative") + + if p >= len(self.digits): + # compute p+3, p+6, p+9, ... digits; continue until at + # least one of the extra digits is nonzero + extra = 3 + while True: + # compute p+extra digits, correct to within 1ulp + M = 10**(p+extra+2) + digits = str(_div_nearest(_ilog(10*M, M), 100)) + if digits[-extra:] != '0'*extra: + break + extra += 3 + # keep all reliable digits so far; remove trailing zeros + # and next nonzero digit + self.digits = digits.rstrip('0')[:-1] + return int(self.digits[:p+1]) + +_log10_digits = _Log10Memoize().getdigits + +def _iexp(x, M, L=8): + """Given integers x and M, M > 0, such that x/M is small in absolute + value, compute an integer approximation to M*exp(x/M). For 0 <= + x/M <= 2.4, the absolute error in the result is bounded by 60 (and + is usually much smaller).""" + + # Algorithm: to compute exp(z) for a real number z, first divide z + # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then + # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor + # series + # + # expm1(x) = x + x**2/2! + x**3/3! + ... + # + # Now use the identity + # + # expm1(2x) = expm1(x)*(expm1(x)+2) + # + # R times to compute the sequence expm1(z/2**R), + # expm1(z/2**(R-1)), ... , exp(z/2), exp(z). + + # Find R such that x/2**R/M <= 2**-L + R = _nbits((long(x)<<L)//M) + + # Taylor series. (2**L)**T > M + T = -int(-10*len(str(M))//(3*L)) + y = _div_nearest(x, T) + Mshift = long(M)<<R + for i in xrange(T-1, 0, -1): + y = _div_nearest(x*(Mshift + y), Mshift * i) + + # Expansion + for k in xrange(R-1, -1, -1): + Mshift = long(M)<<(k+2) + y = _div_nearest(y*(y+Mshift), Mshift) + + return M+y + +def _dexp(c, e, p): + """Compute an approximation to exp(c*10**e), with p decimal places of + precision. + + Returns integers d, f such that: + + 10**(p-1) <= d <= 10**p, and + (d-1)*10**f < exp(c*10**e) < (d+1)*10**f + + In other words, d*10**f is an approximation to exp(c*10**e) with p + digits of precision, and with an error in d of at most 1. This is + almost, but not quite, the same as the error being < 1ulp: when d + = 10**(p-1) the error could be up to 10 ulp.""" + + # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision + p += 2 + + # compute log(10) with extra precision = adjusted exponent of c*10**e + extra = max(0, e + len(str(c)) - 1) + q = p + extra + + # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q), + # rounding down + shift = e+q + if shift >= 0: + cshift = c*10**shift + else: + cshift = c//10**-shift + quot, rem = divmod(cshift, _log10_digits(q)) + + # reduce remainder back to original precision + rem = _div_nearest(rem, 10**extra) + + # error in result of _iexp < 120; error after division < 0.62 + return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 + +def _dpower(xc, xe, yc, ye, p): + """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and + y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: + + 10**(p-1) <= c <= 10**p, and + (c-1)*10**e < x**y < (c+1)*10**e + + in other words, c*10**e is an approximation to x**y with p digits + of precision, and with an error in c of at most 1. (This is + almost, but not quite, the same as the error being < 1ulp: when c + == 10**(p-1) we can only guarantee error < 10ulp.) + + We assume that: x is positive and not equal to 1, and y is nonzero. + """ + + # Find b such that 10**(b-1) <= |y| <= 10**b + b = len(str(abs(yc))) + ye + + # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point + lxc = _dlog(xc, xe, p+b+1) + + # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) + shift = ye-b + if shift >= 0: + pc = lxc*yc*10**shift + else: + pc = _div_nearest(lxc*yc, 10**-shift) + + if pc == 0: + # we prefer a result that isn't exactly 1; this makes it + # easier to compute a correctly rounded result in __pow__ + if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: + coeff, exp = 10**(p-1)+1, 1-p + else: + coeff, exp = 10**p-1, -p + else: + coeff, exp = _dexp(pc, -(p+1), p+1) + coeff = _div_nearest(coeff, 10) + exp += 1 + + return coeff, exp + +def _log10_lb(c, correction = { + '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, + '6': 23, '7': 16, '8': 10, '9': 5}): + """Compute a lower bound for 100*log10(c) for a positive integer c.""" + if c <= 0: + raise ValueError("The argument to _log10_lb should be nonnegative.") + str_c = str(c) + return 100*len(str_c) - correction[str_c[0]] + +##### Helper Functions #################################################### + +def _convert_other(other, raiseit=False, allow_float=False): + """Convert other to Decimal. + + Verifies that it's ok to use in an implicit construction. + If allow_float is true, allow conversion from float; this + is used in the comparison methods (__eq__ and friends). + + """ + if isinstance(other, Decimal): + return other + if isinstance(other, (int, long)): + return Decimal(other) + if allow_float and isinstance(other, float): + return Decimal.from_float(other) + + if raiseit: + raise TypeError("Unable to convert %s to Decimal" % other) + return NotImplemented + +##### Setup Specific Contexts ############################################ + +# The default context prototype used by Context() +# Is mutable, so that new contexts can have different default values + +DefaultContext = Context( + prec=28, rounding=ROUND_HALF_EVEN, + traps=[DivisionByZero, Overflow, InvalidOperation], + flags=[], + Emax=999999999, + Emin=-999999999, + capitals=1 +) + +# Pre-made alternate contexts offered by the specification +# Don't change these; the user should be able to select these +# contexts and be able to reproduce results from other implementations +# of the spec. + +BasicContext = Context( + prec=9, rounding=ROUND_HALF_UP, + traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], + flags=[], +) + +ExtendedContext = Context( + prec=9, rounding=ROUND_HALF_EVEN, + traps=[], + flags=[], +) + + +##### crud for parsing strings ############################################# +# +# Regular expression used for parsing numeric strings. Additional +# comments: +# +# 1. Uncomment the two '\s*' lines to allow leading and/or trailing +# whitespace. But note that the specification disallows whitespace in +# a numeric string. +# +# 2. For finite numbers (not infinities and NaNs) the body of the +# number between the optional sign and the optional exponent must have +# at least one decimal digit, possibly after the decimal point. The +# lookahead expression '(?=\d|\.\d)' checks this. + +import re +_parser = re.compile(r""" # A numeric string consists of: +# \s* + (?P<sign>[-+])? # an optional sign, followed by either... + ( + (?=\d|\.\d) # ...a number (with at least one digit) + (?P<int>\d*) # having a (possibly empty) integer part + (\.(?P<frac>\d*))? # followed by an optional fractional part + (E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or... + | + Inf(inity)? # ...an infinity, or... + | + (?P<signal>s)? # ...an (optionally signaling) + NaN # NaN + (?P<diag>\d*) # with (possibly empty) diagnostic info. + ) +# \s* + \Z +""", re.VERBOSE | re.IGNORECASE | re.UNICODE).match + +_all_zeros = re.compile('0*$').match +_exact_half = re.compile('50*$').match + +##### PEP3101 support functions ############################################## +# The functions in this section have little to do with the Decimal +# class, and could potentially be reused or adapted for other pure +# Python numeric classes that want to implement __format__ +# +# A format specifier for Decimal looks like: +# +# [[fill]align][sign][0][minimumwidth][,][.precision][type] + +_parse_format_specifier_regex = re.compile(r"""\A +(?: + (?P<fill>.)? + (?P<align>[<>=^]) +)? +(?P<sign>[-+ ])? +(?P<zeropad>0)? +(?P<minimumwidth>(?!0)\d+)? +(?P<thousands_sep>,)? +(?:\.(?P<precision>0|(?!0)\d+))? +(?P<type>[eEfFgGn%])? +\Z +""", re.VERBOSE) + +del re + +# The locale module is only needed for the 'n' format specifier. The +# rest of the PEP 3101 code functions quite happily without it, so we +# don't care too much if locale isn't present. +try: + import locale as _locale +except ImportError: + pass + +def _parse_format_specifier(format_spec, _localeconv=None): + """Parse and validate a format specifier. + + Turns a standard numeric format specifier into a dict, with the + following entries: + + fill: fill character to pad field to minimum width + align: alignment type, either '<', '>', '=' or '^' + sign: either '+', '-' or ' ' + minimumwidth: nonnegative integer giving minimum width + zeropad: boolean, indicating whether to pad with zeros + thousands_sep: string to use as thousands separator, or '' + grouping: grouping for thousands separators, in format + used by localeconv + decimal_point: string to use for decimal point + precision: nonnegative integer giving precision, or None + type: one of the characters 'eEfFgG%', or None + unicode: boolean (always True for Python 3.x) + + """ + m = _parse_format_specifier_regex.match(format_spec) + if m is None: + raise ValueError("Invalid format specifier: " + format_spec) + + # get the dictionary + format_dict = m.groupdict() + + # zeropad; defaults for fill and alignment. If zero padding + # is requested, the fill and align fields should be absent. + fill = format_dict['fill'] + align = format_dict['align'] + format_dict['zeropad'] = (format_dict['zeropad'] is not None) + if format_dict['zeropad']: + if fill is not None: + raise ValueError("Fill character conflicts with '0'" + " in format specifier: " + format_spec) + if align is not None: + raise ValueError("Alignment conflicts with '0' in " + "format specifier: " + format_spec) + format_dict['fill'] = fill or ' ' + # PEP 3101 originally specified that the default alignment should + # be left; it was later agreed that right-aligned makes more sense + # for numeric types. See http://bugs.python.org/issue6857. + format_dict['align'] = align or '>' + + # default sign handling: '-' for negative, '' for positive + if format_dict['sign'] is None: + format_dict['sign'] = '-' + + # minimumwidth defaults to 0; precision remains None if not given + format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') + if format_dict['precision'] is not None: + format_dict['precision'] = int(format_dict['precision']) + + # if format type is 'g' or 'G' then a precision of 0 makes little + # sense; convert it to 1. Same if format type is unspecified. + if format_dict['precision'] == 0: + if format_dict['type'] is None or format_dict['type'] in 'gG': + format_dict['precision'] = 1 + + # determine thousands separator, grouping, and decimal separator, and + # add appropriate entries to format_dict + if format_dict['type'] == 'n': + # apart from separators, 'n' behaves just like 'g' + format_dict['type'] = 'g' + if _localeconv is None: + _localeconv = _locale.localeconv() + if format_dict['thousands_sep'] is not None: + raise ValueError("Explicit thousands separator conflicts with " + "'n' type in format specifier: " + format_spec) + format_dict['thousands_sep'] = _localeconv['thousands_sep'] + format_dict['grouping'] = _localeconv['grouping'] + format_dict['decimal_point'] = _localeconv['decimal_point'] + else: + if format_dict['thousands_sep'] is None: + format_dict['thousands_sep'] = '' + format_dict['grouping'] = [3, 0] + format_dict['decimal_point'] = '.' + + # record whether return type should be str or unicode + format_dict['unicode'] = isinstance(format_spec, unicode) + + return format_dict + +def _format_align(sign, body, spec): + """Given an unpadded, non-aligned numeric string 'body' and sign + string 'sign', add padding and aligment conforming to the given + format specifier dictionary 'spec' (as produced by + parse_format_specifier). + + Also converts result to unicode if necessary. + + """ + # how much extra space do we have to play with? + minimumwidth = spec['minimumwidth'] + fill = spec['fill'] + padding = fill*(minimumwidth - len(sign) - len(body)) + + align = spec['align'] + if align == '<': + result = sign + body + padding + elif align == '>': + result = padding + sign + body + elif align == '=': + result = sign + padding + body + elif align == '^': + half = len(padding)//2 + result = padding[:half] + sign + body + padding[half:] + else: + raise ValueError('Unrecognised alignment field') + + # make sure that result is unicode if necessary + if spec['unicode']: + result = unicode(result) + + return result + +def _group_lengths(grouping): + """Convert a localeconv-style grouping into a (possibly infinite) + iterable of integers representing group lengths. + + """ + # The result from localeconv()['grouping'], and the input to this + # function, should be a list of integers in one of the + # following three forms: + # + # (1) an empty list, or + # (2) nonempty list of positive integers + [0] + # (3) list of positive integers + [locale.CHAR_MAX], or + + from itertools import chain, repeat + if not grouping: + return [] + elif grouping[-1] == 0 and len(grouping) >= 2: + return chain(grouping[:-1], repeat(grouping[-2])) + elif grouping[-1] == _locale.CHAR_MAX: + return grouping[:-1] + else: + raise ValueError('unrecognised format for grouping') + +def _insert_thousands_sep(digits, spec, min_width=1): + """Insert thousands separators into a digit string. + + spec is a dictionary whose keys should include 'thousands_sep' and + 'grouping'; typically it's the result of parsing the format + specifier using _parse_format_specifier. + + The min_width keyword argument gives the minimum length of the + result, which will be padded on the left with zeros if necessary. + + If necessary, the zero padding adds an extra '0' on the left to + avoid a leading thousands separator. For example, inserting + commas every three digits in '123456', with min_width=8, gives + '0,123,456', even though that has length 9. + + """ + + sep = spec['thousands_sep'] + grouping = spec['grouping'] + + groups = [] + for l in _group_lengths(grouping): + if l <= 0: + raise ValueError("group length should be positive") + # max(..., 1) forces at least 1 digit to the left of a separator + l = min(max(len(digits), min_width, 1), l) + groups.append('0'*(l - len(digits)) + digits[-l:]) + digits = digits[:-l] + min_width -= l + if not digits and min_width <= 0: + break + min_width -= len(sep) + else: + l = max(len(digits), min_width, 1) + groups.append('0'*(l - len(digits)) + digits[-l:]) + return sep.join(reversed(groups)) + +def _format_sign(is_negative, spec): + """Determine sign character.""" + + if is_negative: + return '-' + elif spec['sign'] in ' +': + return spec['sign'] + else: + return '' + +def _format_number(is_negative, intpart, fracpart, exp, spec): + """Format a number, given the following data: + + is_negative: true if the number is negative, else false + intpart: string of digits that must appear before the decimal point + fracpart: string of digits that must come after the point + exp: exponent, as an integer + spec: dictionary resulting from parsing the format specifier + + This function uses the information in spec to: + insert separators (decimal separator and thousands separators) + format the sign + format the exponent + add trailing '%' for the '%' type + zero-pad if necessary + fill and align if necessary + """ + + sign = _format_sign(is_negative, spec) + + if fracpart: + fracpart = spec['decimal_point'] + fracpart + + if exp != 0 or spec['type'] in 'eE': + echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] + fracpart += "{0}{1:+}".format(echar, exp) + if spec['type'] == '%': + fracpart += '%' + + if spec['zeropad']: + min_width = spec['minimumwidth'] - len(fracpart) - len(sign) + else: + min_width = 0 + intpart = _insert_thousands_sep(intpart, spec, min_width) + + return _format_align(sign, intpart+fracpart, spec) + + +##### Useful Constants (internal use only) ################################ + +# Reusable defaults +_Infinity = Decimal('Inf') +_NegativeInfinity = Decimal('-Inf') +_NaN = Decimal('NaN') +_Zero = Decimal(0) +_One = Decimal(1) +_NegativeOne = Decimal(-1) + +# _SignedInfinity[sign] is infinity w/ that sign +_SignedInfinity = (_Infinity, _NegativeInfinity) + + + +if __name__ == '__main__': + import doctest, sys + doctest.testmod(sys.modules[__name__]) diff --git a/src/main/resources/PythonLibs/difflib.py b/src/main/resources/PythonLibs/difflib.py new file mode 100644 index 0000000000000000000000000000000000000000..3bbcb76b7ecb3315698542acc2d8016a49f24616 --- /dev/null +++ b/src/main/resources/PythonLibs/difflib.py @@ -0,0 +1,2059 @@ +#! /usr/bin/env python + +""" +Module difflib -- helpers for computing deltas between objects. + +Function get_close_matches(word, possibilities, n=3, cutoff=0.6): + Use SequenceMatcher to return list of the best "good enough" matches. + +Function context_diff(a, b): + For two lists of strings, return a delta in context diff format. + +Function ndiff(a, b): + Return a delta: the difference between `a` and `b` (lists of strings). + +Function restore(delta, which): + Return one of the two sequences that generated an ndiff delta. + +Function unified_diff(a, b): + For two lists of strings, return a delta in unified diff format. + +Class SequenceMatcher: + A flexible class for comparing pairs of sequences of any type. + +Class Differ: + For producing human-readable deltas from sequences of lines of text. + +Class HtmlDiff: + For producing HTML side by side comparison with change highlights. +""" + +__all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher', + 'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff', + 'unified_diff', 'HtmlDiff', 'Match'] + +import heapq +from collections import namedtuple as _namedtuple +from functools import reduce + +Match = _namedtuple('Match', 'a b size') + +def _calculate_ratio(matches, length): + if length: + return 2.0 * matches / length + return 1.0 + +class SequenceMatcher: + + """ + SequenceMatcher is a flexible class for comparing pairs of sequences of + any type, so long as the sequence elements are hashable. The basic + algorithm predates, and is a little fancier than, an algorithm + published in the late 1980's by Ratcliff and Obershelp under the + hyperbolic name "gestalt pattern matching". The basic idea is to find + the longest contiguous matching subsequence that contains no "junk" + elements (R-O doesn't address junk). The same idea is then applied + recursively to the pieces of the sequences to the left and to the right + of the matching subsequence. This does not yield minimal edit + sequences, but does tend to yield matches that "look right" to people. + + SequenceMatcher tries to compute a "human-friendly diff" between two + sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the + longest *contiguous* & junk-free matching subsequence. That's what + catches peoples' eyes. The Windows(tm) windiff has another interesting + notion, pairing up elements that appear uniquely in each sequence. + That, and the method here, appear to yield more intuitive difference + reports than does diff. This method appears to be the least vulnerable + to synching up on blocks of "junk lines", though (like blank lines in + ordinary text files, or maybe "<P>" lines in HTML files). That may be + because this is the only method of the 3 that has a *concept* of + "junk" <wink>. + + Example, comparing two strings, and considering blanks to be "junk": + + >>> s = SequenceMatcher(lambda x: x == " ", + ... "private Thread currentThread;", + ... "private volatile Thread currentThread;") + >>> + + .ratio() returns a float in [0, 1], measuring the "similarity" of the + sequences. As a rule of thumb, a .ratio() value over 0.6 means the + sequences are close matches: + + >>> print round(s.ratio(), 3) + 0.866 + >>> + + If you're only interested in where the sequences match, + .get_matching_blocks() is handy: + + >>> for block in s.get_matching_blocks(): + ... print "a[%d] and b[%d] match for %d elements" % block + a[0] and b[0] match for 8 elements + a[8] and b[17] match for 21 elements + a[29] and b[38] match for 0 elements + + Note that the last tuple returned by .get_matching_blocks() is always a + dummy, (len(a), len(b), 0), and this is the only case in which the last + tuple element (number of elements matched) is 0. + + If you want to know how to change the first sequence into the second, + use .get_opcodes(): + + >>> for opcode in s.get_opcodes(): + ... print "%6s a[%d:%d] b[%d:%d]" % opcode + equal a[0:8] b[0:8] + insert a[8:8] b[8:17] + equal a[8:29] b[17:38] + + See the Differ class for a fancy human-friendly file differencer, which + uses SequenceMatcher both to compare sequences of lines, and to compare + sequences of characters within similar (near-matching) lines. + + See also function get_close_matches() in this module, which shows how + simple code building on SequenceMatcher can be used to do useful work. + + Timing: Basic R-O is cubic time worst case and quadratic time expected + case. SequenceMatcher is quadratic time for the worst case and has + expected-case behavior dependent in a complicated way on how many + elements the sequences have in common; best case time is linear. + + Methods: + + __init__(isjunk=None, a='', b='') + Construct a SequenceMatcher. + + set_seqs(a, b) + Set the two sequences to be compared. + + set_seq1(a) + Set the first sequence to be compared. + + set_seq2(b) + Set the second sequence to be compared. + + find_longest_match(alo, ahi, blo, bhi) + Find longest matching block in a[alo:ahi] and b[blo:bhi]. + + get_matching_blocks() + Return list of triples describing matching subsequences. + + get_opcodes() + Return list of 5-tuples describing how to turn a into b. + + ratio() + Return a measure of the sequences' similarity (float in [0,1]). + + quick_ratio() + Return an upper bound on .ratio() relatively quickly. + + real_quick_ratio() + Return an upper bound on ratio() very quickly. + """ + + def __init__(self, isjunk=None, a='', b='', autojunk=True): + """Construct a SequenceMatcher. + + Optional arg isjunk is None (the default), or a one-argument + function that takes a sequence element and returns true iff the + element is junk. None is equivalent to passing "lambda x: 0", i.e. + no elements are considered to be junk. For example, pass + lambda x: x in " \\t" + if you're comparing lines as sequences of characters, and don't + want to synch up on blanks or hard tabs. + + Optional arg a is the first of two sequences to be compared. By + default, an empty string. The elements of a must be hashable. See + also .set_seqs() and .set_seq1(). + + Optional arg b is the second of two sequences to be compared. By + default, an empty string. The elements of b must be hashable. See + also .set_seqs() and .set_seq2(). + + Optional arg autojunk should be set to False to disable the + "automatic junk heuristic" that treats popular elements as junk + (see module documentation for more information). + """ + + # Members: + # a + # first sequence + # b + # second sequence; differences are computed as "what do + # we need to do to 'a' to change it into 'b'?" + # b2j + # for x in b, b2j[x] is a list of the indices (into b) + # at which x appears; junk elements do not appear + # fullbcount + # for x in b, fullbcount[x] == the number of times x + # appears in b; only materialized if really needed (used + # only for computing quick_ratio()) + # matching_blocks + # a list of (i, j, k) triples, where a[i:i+k] == b[j:j+k]; + # ascending & non-overlapping in i and in j; terminated by + # a dummy (len(a), len(b), 0) sentinel + # opcodes + # a list of (tag, i1, i2, j1, j2) tuples, where tag is + # one of + # 'replace' a[i1:i2] should be replaced by b[j1:j2] + # 'delete' a[i1:i2] should be deleted + # 'insert' b[j1:j2] should be inserted + # 'equal' a[i1:i2] == b[j1:j2] + # isjunk + # a user-supplied function taking a sequence element and + # returning true iff the element is "junk" -- this has + # subtle but helpful effects on the algorithm, which I'll + # get around to writing up someday <0.9 wink>. + # DON'T USE! Only __chain_b uses this. Use isbjunk. + # isbjunk + # for x in b, isbjunk(x) == isjunk(x) but much faster; + # it's really the __contains__ method of a hidden dict. + # DOES NOT WORK for x in a! + # isbpopular + # for x in b, isbpopular(x) is true iff b is reasonably long + # (at least 200 elements) and x accounts for more than 1 + 1% of + # its elements (when autojunk is enabled). + # DOES NOT WORK for x in a! + + self.isjunk = isjunk + self.a = self.b = None + self.autojunk = autojunk + self.set_seqs(a, b) + + def set_seqs(self, a, b): + """Set the two sequences to be compared. + + >>> s = SequenceMatcher() + >>> s.set_seqs("abcd", "bcde") + >>> s.ratio() + 0.75 + """ + + self.set_seq1(a) + self.set_seq2(b) + + def set_seq1(self, a): + """Set the first sequence to be compared. + + The second sequence to be compared is not changed. + + >>> s = SequenceMatcher(None, "abcd", "bcde") + >>> s.ratio() + 0.75 + >>> s.set_seq1("bcde") + >>> s.ratio() + 1.0 + >>> + + SequenceMatcher computes and caches detailed information about the + second sequence, so if you want to compare one sequence S against + many sequences, use .set_seq2(S) once and call .set_seq1(x) + repeatedly for each of the other sequences. + + See also set_seqs() and set_seq2(). + """ + + if a is self.a: + return + self.a = a + self.matching_blocks = self.opcodes = None + + def set_seq2(self, b): + """Set the second sequence to be compared. + + The first sequence to be compared is not changed. + + >>> s = SequenceMatcher(None, "abcd", "bcde") + >>> s.ratio() + 0.75 + >>> s.set_seq2("abcd") + >>> s.ratio() + 1.0 + >>> + + SequenceMatcher computes and caches detailed information about the + second sequence, so if you want to compare one sequence S against + many sequences, use .set_seq2(S) once and call .set_seq1(x) + repeatedly for each of the other sequences. + + See also set_seqs() and set_seq1(). + """ + + if b is self.b: + return + self.b = b + self.matching_blocks = self.opcodes = None + self.fullbcount = None + self.__chain_b() + + # For each element x in b, set b2j[x] to a list of the indices in + # b where x appears; the indices are in increasing order; note that + # the number of times x appears in b is len(b2j[x]) ... + # when self.isjunk is defined, junk elements don't show up in this + # map at all, which stops the central find_longest_match method + # from starting any matching block at a junk element ... + # also creates the fast isbjunk function ... + # b2j also does not contain entries for "popular" elements, meaning + # elements that account for more than 1 + 1% of the total elements, and + # when the sequence is reasonably large (>= 200 elements); this can + # be viewed as an adaptive notion of semi-junk, and yields an enormous + # speedup when, e.g., comparing program files with hundreds of + # instances of "return NULL;" ... + # note that this is only called when b changes; so for cross-product + # kinds of matches, it's best to call set_seq2 once, then set_seq1 + # repeatedly + + def __chain_b(self): + # Because isjunk is a user-defined (not C) function, and we test + # for junk a LOT, it's important to minimize the number of calls. + # Before the tricks described here, __chain_b was by far the most + # time-consuming routine in the whole module! If anyone sees + # Jim Roskind, thank him again for profile.py -- I never would + # have guessed that. + # The first trick is to build b2j ignoring the possibility + # of junk. I.e., we don't call isjunk at all yet. Throwing + # out the junk later is much cheaper than building b2j "right" + # from the start. + b = self.b + self.b2j = b2j = {} + + for i, elt in enumerate(b): + indices = b2j.setdefault(elt, []) + indices.append(i) + + # Purge junk elements + junk = set() + isjunk = self.isjunk + if isjunk: + for elt in list(b2j.keys()): # using list() since b2j is modified + if isjunk(elt): + junk.add(elt) + del b2j[elt] + + # Purge popular elements that are not junk + popular = set() + n = len(b) + if self.autojunk and n >= 200: + ntest = n // 100 + 1 + for elt, idxs in list(b2j.items()): + if len(idxs) > ntest: + popular.add(elt) + del b2j[elt] + + # Now for x in b, isjunk(x) == x in junk, but the latter is much faster. + # Sicne the number of *unique* junk elements is probably small, the + # memory burden of keeping this set alive is likely trivial compared to + # the size of b2j. + self.isbjunk = junk.__contains__ + self.isbpopular = popular.__contains__ + + def find_longest_match(self, alo, ahi, blo, bhi): + """Find longest matching block in a[alo:ahi] and b[blo:bhi]. + + If isjunk is not defined: + + Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where + alo <= i <= i+k <= ahi + blo <= j <= j+k <= bhi + and for all (i',j',k') meeting those conditions, + k >= k' + i <= i' + and if i == i', j <= j' + + In other words, of all maximal matching blocks, return one that + starts earliest in a, and of all those maximal matching blocks that + start earliest in a, return the one that starts earliest in b. + + >>> s = SequenceMatcher(None, " abcd", "abcd abcd") + >>> s.find_longest_match(0, 5, 0, 9) + Match(a=0, b=4, size=5) + + If isjunk is defined, first the longest matching block is + determined as above, but with the additional restriction that no + junk element appears in the block. Then that block is extended as + far as possible by matching (only) junk elements on both sides. So + the resulting block never matches on junk except as identical junk + happens to be adjacent to an "interesting" match. + + Here's the same example as before, but considering blanks to be + junk. That prevents " abcd" from matching the " abcd" at the tail + end of the second sequence directly. Instead only the "abcd" can + match, and matches the leftmost "abcd" in the second sequence: + + >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd") + >>> s.find_longest_match(0, 5, 0, 9) + Match(a=1, b=0, size=4) + + If no blocks match, return (alo, blo, 0). + + >>> s = SequenceMatcher(None, "ab", "c") + >>> s.find_longest_match(0, 2, 0, 1) + Match(a=0, b=0, size=0) + """ + + # CAUTION: stripping common prefix or suffix would be incorrect. + # E.g., + # ab + # acab + # Longest matching block is "ab", but if common prefix is + # stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + # strip, so ends up claiming that ab is changed to acab by + # inserting "ca" in the middle. That's minimal but unintuitive: + # "it's obvious" that someone inserted "ac" at the front. + # Windiff ends up at the same place as diff, but by pairing up + # the unique 'b's and then matching the first two 'a's. + + a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.isbjunk + besti, bestj, bestsize = alo, blo, 0 + # find longest junk-free match + # during an iteration of the loop, j2len[j] = length of longest + # junk-free match ending with a[i-1] and b[j] + j2len = {} + nothing = [] + for i in xrange(alo, ahi): + # look at all instances of a[i] in b; note that because + # b2j has no junk keys, the loop is skipped if a[i] is junk + j2lenget = j2len.get + newj2len = {} + for j in b2j.get(a[i], nothing): + # a[i] matches b[j] + if j < blo: + continue + if j >= bhi: + break + k = newj2len[j] = j2lenget(j-1, 0) + 1 + if k > bestsize: + besti, bestj, bestsize = i-k+1, j-k+1, k + j2len = newj2len + + # Extend the best by non-junk elements on each end. In particular, + # "popular" non-junk elements aren't in b2j, which greatly speeds + # the inner loop above, but also means "the best" match so far + # doesn't contain any junk *or* popular non-junk elements. + while besti > alo and bestj > blo and \ + not isbjunk(b[bestj-1]) and \ + a[besti-1] == b[bestj-1]: + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + while besti+bestsize < ahi and bestj+bestsize < bhi and \ + not isbjunk(b[bestj+bestsize]) and \ + a[besti+bestsize] == b[bestj+bestsize]: + bestsize += 1 + + # Now that we have a wholly interesting match (albeit possibly + # empty!), we may as well suck up the matching junk on each + # side of it too. Can't think of a good reason not to, and it + # saves post-processing the (possibly considerable) expense of + # figuring out what to do with it. In the case of an empty + # interesting match, this is clearly the right thing to do, + # because no other kind of match is possible in the regions. + while besti > alo and bestj > blo and \ + isbjunk(b[bestj-1]) and \ + a[besti-1] == b[bestj-1]: + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + while besti+bestsize < ahi and bestj+bestsize < bhi and \ + isbjunk(b[bestj+bestsize]) and \ + a[besti+bestsize] == b[bestj+bestsize]: + bestsize = bestsize + 1 + + return Match(besti, bestj, bestsize) + + def get_matching_blocks(self): + """Return list of triples describing matching subsequences. + + Each triple is of the form (i, j, n), and means that + a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in + i and in j. New in Python 2.5, it's also guaranteed that if + (i, j, n) and (i', j', n') are adjacent triples in the list, and + the second is not the last triple in the list, then i+n != i' or + j+n != j'. IOW, adjacent triples never describe adjacent equal + blocks. + + The last triple is a dummy, (len(a), len(b), 0), and is the only + triple with n==0. + + >>> s = SequenceMatcher(None, "abxcd", "abcd") + >>> s.get_matching_blocks() + [Match(a=0, b=0, size=2), Match(a=3, b=2, size=2), Match(a=5, b=4, size=0)] + """ + + if self.matching_blocks is not None: + return self.matching_blocks + la, lb = len(self.a), len(self.b) + + # This is most naturally expressed as a recursive algorithm, but + # at least one user bumped into extreme use cases that exceeded + # the recursion limit on their box. So, now we maintain a list + # ('queue`) of blocks we still need to look at, and append partial + # results to `matching_blocks` in a loop; the matches are sorted + # at the end. + queue = [(0, la, 0, lb)] + matching_blocks = [] + while queue: + alo, ahi, blo, bhi = queue.pop() + i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi) + # a[alo:i] vs b[blo:j] unknown + # a[i:i+k] same as b[j:j+k] + # a[i+k:ahi] vs b[j+k:bhi] unknown + if k: # if k is 0, there was no matching block + matching_blocks.append(x) + if alo < i and blo < j: + queue.append((alo, i, blo, j)) + if i+k < ahi and j+k < bhi: + queue.append((i+k, ahi, j+k, bhi)) + matching_blocks.sort() + + # It's possible that we have adjacent equal blocks in the + # matching_blocks list now. Starting with 2.5, this code was added + # to collapse them. + i1 = j1 = k1 = 0 + non_adjacent = [] + for i2, j2, k2 in matching_blocks: + # Is this block adjacent to i1, j1, k1? + if i1 + k1 == i2 and j1 + k1 == j2: + # Yes, so collapse them -- this just increases the length of + # the first block by the length of the second, and the first + # block so lengthened remains the block to compare against. + k1 += k2 + else: + # Not adjacent. Remember the first block (k1==0 means it's + # the dummy we started with), and make the second block the + # new block to compare against. + if k1: + non_adjacent.append((i1, j1, k1)) + i1, j1, k1 = i2, j2, k2 + if k1: + non_adjacent.append((i1, j1, k1)) + + non_adjacent.append( (la, lb, 0) ) + self.matching_blocks = non_adjacent + return map(Match._make, self.matching_blocks) + + def get_opcodes(self): + """Return list of 5-tuples describing how to turn a into b. + + Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple + has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the + tuple preceding it, and likewise for j1 == the previous j2. + + The tags are strings, with these meanings: + + 'replace': a[i1:i2] should be replaced by b[j1:j2] + 'delete': a[i1:i2] should be deleted. + Note that j1==j2 in this case. + 'insert': b[j1:j2] should be inserted at a[i1:i1]. + Note that i1==i2 in this case. + 'equal': a[i1:i2] == b[j1:j2] + + >>> a = "qabxcd" + >>> b = "abycdf" + >>> s = SequenceMatcher(None, a, b) + >>> for tag, i1, i2, j1, j2 in s.get_opcodes(): + ... print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" % + ... (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2])) + delete a[0:1] (q) b[0:0] () + equal a[1:3] (ab) b[0:2] (ab) + replace a[3:4] (x) b[2:3] (y) + equal a[4:6] (cd) b[3:5] (cd) + insert a[6:6] () b[5:6] (f) + """ + + if self.opcodes is not None: + return self.opcodes + i = j = 0 + self.opcodes = answer = [] + for ai, bj, size in self.get_matching_blocks(): + # invariant: we've pumped out correct diffs to change + # a[:i] into b[:j], and the next matching block is + # a[ai:ai+size] == b[bj:bj+size]. So we need to pump + # out a diff to change a[i:ai] into b[j:bj], pump out + # the matching block, and move (i,j) beyond the match + tag = '' + if i < ai and j < bj: + tag = 'replace' + elif i < ai: + tag = 'delete' + elif j < bj: + tag = 'insert' + if tag: + answer.append( (tag, i, ai, j, bj) ) + i, j = ai+size, bj+size + # the list of matching blocks is terminated by a + # sentinel with size 0 + if size: + answer.append( ('equal', ai, i, bj, j) ) + return answer + + def get_grouped_opcodes(self, n=3): + """ Isolate change clusters by eliminating ranges with no changes. + + Return a generator of groups with upto n lines of context. + Each group is in the same format as returned by get_opcodes(). + + >>> from pprint import pprint + >>> a = map(str, range(1,40)) + >>> b = a[:] + >>> b[8:8] = ['i'] # Make an insertion + >>> b[20] += 'x' # Make a replacement + >>> b[23:28] = [] # Make a deletion + >>> b[30] += 'y' # Make another replacement + >>> pprint(list(SequenceMatcher(None,a,b).get_grouped_opcodes())) + [[('equal', 5, 8, 5, 8), ('insert', 8, 8, 8, 9), ('equal', 8, 11, 9, 12)], + [('equal', 16, 19, 17, 20), + ('replace', 19, 20, 20, 21), + ('equal', 20, 22, 21, 23), + ('delete', 22, 27, 23, 23), + ('equal', 27, 30, 23, 26)], + [('equal', 31, 34, 27, 30), + ('replace', 34, 35, 30, 31), + ('equal', 35, 38, 31, 34)]] + """ + + codes = self.get_opcodes() + if not codes: + codes = [("equal", 0, 1, 0, 1)] + # Fixup leading and trailing groups if they show no changes. + if codes[0][0] == 'equal': + tag, i1, i2, j1, j2 = codes[0] + codes[0] = tag, max(i1, i2-n), i2, max(j1, j2-n), j2 + if codes[-1][0] == 'equal': + tag, i1, i2, j1, j2 = codes[-1] + codes[-1] = tag, i1, min(i2, i1+n), j1, min(j2, j1+n) + + nn = n + n + group = [] + for tag, i1, i2, j1, j2 in codes: + # End the current group and start a new one whenever + # there is a large range with no changes. + if tag == 'equal' and i2-i1 > nn: + group.append((tag, i1, min(i2, i1+n), j1, min(j2, j1+n))) + yield group + group = [] + i1, j1 = max(i1, i2-n), max(j1, j2-n) + group.append((tag, i1, i2, j1 ,j2)) + if group and not (len(group)==1 and group[0][0] == 'equal'): + yield group + + def ratio(self): + """Return a measure of the sequences' similarity (float in [0,1]). + + Where T is the total number of elements in both sequences, and + M is the number of matches, this is 2.0*M / T. + Note that this is 1 if the sequences are identical, and 0 if + they have nothing in common. + + .ratio() is expensive to compute if you haven't already computed + .get_matching_blocks() or .get_opcodes(), in which case you may + want to try .quick_ratio() or .real_quick_ratio() first to get an + upper bound. + + >>> s = SequenceMatcher(None, "abcd", "bcde") + >>> s.ratio() + 0.75 + >>> s.quick_ratio() + 0.75 + >>> s.real_quick_ratio() + 1.0 + """ + + matches = reduce(lambda sum, triple: sum + triple[-1], + self.get_matching_blocks(), 0) + return _calculate_ratio(matches, len(self.a) + len(self.b)) + + def quick_ratio(self): + """Return an upper bound on ratio() relatively quickly. + + This isn't defined beyond that it is an upper bound on .ratio(), and + is faster to compute. + """ + + # viewing a and b as multisets, set matches to the cardinality + # of their intersection; this counts the number of matches + # without regard to order, so is clearly an upper bound + if self.fullbcount is None: + self.fullbcount = fullbcount = {} + for elt in self.b: + fullbcount[elt] = fullbcount.get(elt, 0) + 1 + fullbcount = self.fullbcount + # avail[x] is the number of times x appears in 'b' less the + # number of times we've seen it in 'a' so far ... kinda + avail = {} + availhas, matches = avail.__contains__, 0 + for elt in self.a: + if availhas(elt): + numb = avail[elt] + else: + numb = fullbcount.get(elt, 0) + avail[elt] = numb - 1 + if numb > 0: + matches = matches + 1 + return _calculate_ratio(matches, len(self.a) + len(self.b)) + + def real_quick_ratio(self): + """Return an upper bound on ratio() very quickly. + + This isn't defined beyond that it is an upper bound on .ratio(), and + is faster to compute than either .ratio() or .quick_ratio(). + """ + + la, lb = len(self.a), len(self.b) + # can't have more matches than the number of elements in the + # shorter sequence + return _calculate_ratio(min(la, lb), la + lb) + +def get_close_matches(word, possibilities, n=3, cutoff=0.6): + """Use SequenceMatcher to return list of the best "good enough" matches. + + word is a sequence for which close matches are desired (typically a + string). + + possibilities is a list of sequences against which to match word + (typically a list of strings). + + Optional arg n (default 3) is the maximum number of close matches to + return. n must be > 0. + + Optional arg cutoff (default 0.6) is a float in [0, 1]. Possibilities + that don't score at least that similar to word are ignored. + + The best (no more than n) matches among the possibilities are returned + in a list, sorted by similarity score, most similar first. + + >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"]) + ['apple', 'ape'] + >>> import keyword as _keyword + >>> get_close_matches("wheel", _keyword.kwlist) + ['while'] + >>> get_close_matches("apple", _keyword.kwlist) + [] + >>> get_close_matches("accept", _keyword.kwlist) + ['except'] + """ + + if not n > 0: + raise ValueError("n must be > 0: %r" % (n,)) + if not 0.0 <= cutoff <= 1.0: + raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,)) + result = [] + s = SequenceMatcher() + s.set_seq2(word) + for x in possibilities: + s.set_seq1(x) + if s.real_quick_ratio() >= cutoff and \ + s.quick_ratio() >= cutoff and \ + s.ratio() >= cutoff: + result.append((s.ratio(), x)) + + # Move the best scorers to head of list + result = heapq.nlargest(n, result) + # Strip scores for the best n matches + return [x for score, x in result] + +def _count_leading(line, ch): + """ + Return number of `ch` characters at the start of `line`. + + Example: + + >>> _count_leading(' abc', ' ') + 3 + """ + + i, n = 0, len(line) + while i < n and line[i] == ch: + i += 1 + return i + +class Differ: + r""" + Differ is a class for comparing sequences of lines of text, and + producing human-readable differences or deltas. Differ uses + SequenceMatcher both to compare sequences of lines, and to compare + sequences of characters within similar (near-matching) lines. + + Each line of a Differ delta begins with a two-letter code: + + '- ' line unique to sequence 1 + '+ ' line unique to sequence 2 + ' ' line common to both sequences + '? ' line not present in either input sequence + + Lines beginning with '? ' attempt to guide the eye to intraline + differences, and were not present in either input sequence. These lines + can be confusing if the sequences contain tab characters. + + Note that Differ makes no claim to produce a *minimal* diff. To the + contrary, minimal diffs are often counter-intuitive, because they synch + up anywhere possible, sometimes accidental matches 100 pages apart. + Restricting synch points to contiguous matches preserves some notion of + locality, at the occasional cost of producing a longer diff. + + Example: Comparing two texts. + + First we set up the texts, sequences of individual single-line strings + ending with newlines (such sequences can also be obtained from the + `readlines()` method of file-like objects): + + >>> text1 = ''' 1. Beautiful is better than ugly. + ... 2. Explicit is better than implicit. + ... 3. Simple is better than complex. + ... 4. Complex is better than complicated. + ... '''.splitlines(1) + >>> len(text1) + 4 + >>> text1[0][-1] + '\n' + >>> text2 = ''' 1. Beautiful is better than ugly. + ... 3. Simple is better than complex. + ... 4. Complicated is better than complex. + ... 5. Flat is better than nested. + ... '''.splitlines(1) + + Next we instantiate a Differ object: + + >>> d = Differ() + + Note that when instantiating a Differ object we may pass functions to + filter out line and character 'junk'. See Differ.__init__ for details. + + Finally, we compare the two: + + >>> result = list(d.compare(text1, text2)) + + 'result' is a list of strings, so let's pretty-print it: + + >>> from pprint import pprint as _pprint + >>> _pprint(result) + [' 1. Beautiful is better than ugly.\n', + '- 2. Explicit is better than implicit.\n', + '- 3. Simple is better than complex.\n', + '+ 3. Simple is better than complex.\n', + '? ++\n', + '- 4. Complex is better than complicated.\n', + '? ^ ---- ^\n', + '+ 4. Complicated is better than complex.\n', + '? ++++ ^ ^\n', + '+ 5. Flat is better than nested.\n'] + + As a single multi-line string it looks like this: + + >>> print ''.join(result), + 1. Beautiful is better than ugly. + - 2. Explicit is better than implicit. + - 3. Simple is better than complex. + + 3. Simple is better than complex. + ? ++ + - 4. Complex is better than complicated. + ? ^ ---- ^ + + 4. Complicated is better than complex. + ? ++++ ^ ^ + + 5. Flat is better than nested. + + Methods: + + __init__(linejunk=None, charjunk=None) + Construct a text differencer, with optional filters. + + compare(a, b) + Compare two sequences of lines; generate the resulting delta. + """ + + def __init__(self, linejunk=None, charjunk=None): + """ + Construct a text differencer, with optional filters. + + The two optional keyword parameters are for filter functions: + + - `linejunk`: A function that should accept a single string argument, + and return true iff the string is junk. The module-level function + `IS_LINE_JUNK` may be used to filter out lines without visible + characters, except for at most one splat ('#'). It is recommended + to leave linejunk None; as of Python 2.3, the underlying + SequenceMatcher class has grown an adaptive notion of "noise" lines + that's better than any static definition the author has ever been + able to craft. + + - `charjunk`: A function that should accept a string of length 1. The + module-level function `IS_CHARACTER_JUNK` may be used to filter out + whitespace characters (a blank or tab; **note**: bad idea to include + newline in this!). Use of IS_CHARACTER_JUNK is recommended. + """ + + self.linejunk = linejunk + self.charjunk = charjunk + + def compare(self, a, b): + r""" + Compare two sequences of lines; generate the resulting delta. + + Each sequence must contain individual single-line strings ending with + newlines. Such sequences can be obtained from the `readlines()` method + of file-like objects. The delta generated also consists of newline- + terminated strings, ready to be printed as-is via the writeline() + method of a file-like object. + + Example: + + >>> print ''.join(Differ().compare('one\ntwo\nthree\n'.splitlines(1), + ... 'ore\ntree\nemu\n'.splitlines(1))), + - one + ? ^ + + ore + ? ^ + - two + - three + ? - + + tree + + emu + """ + + cruncher = SequenceMatcher(self.linejunk, a, b) + for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): + if tag == 'replace': + g = self._fancy_replace(a, alo, ahi, b, blo, bhi) + elif tag == 'delete': + g = self._dump('-', a, alo, ahi) + elif tag == 'insert': + g = self._dump('+', b, blo, bhi) + elif tag == 'equal': + g = self._dump(' ', a, alo, ahi) + else: + raise ValueError, 'unknown tag %r' % (tag,) + + for line in g: + yield line + + def _dump(self, tag, x, lo, hi): + """Generate comparison results for a same-tagged range.""" + for i in xrange(lo, hi): + yield '%s %s' % (tag, x[i]) + + def _plain_replace(self, a, alo, ahi, b, blo, bhi): + assert alo < ahi and blo < bhi + # dump the shorter block first -- reduces the burden on short-term + # memory if the blocks are of very different sizes + if bhi - blo < ahi - alo: + first = self._dump('+', b, blo, bhi) + second = self._dump('-', a, alo, ahi) + else: + first = self._dump('-', a, alo, ahi) + second = self._dump('+', b, blo, bhi) + + for g in first, second: + for line in g: + yield line + + def _fancy_replace(self, a, alo, ahi, b, blo, bhi): + r""" + When replacing one block of lines with another, search the blocks + for *similar* lines; the best-matching pair (if any) is used as a + synch point, and intraline difference marking is done on the + similar pair. Lots of work, but often worth it. + + Example: + + >>> d = Differ() + >>> results = d._fancy_replace(['abcDefghiJkl\n'], 0, 1, + ... ['abcdefGhijkl\n'], 0, 1) + >>> print ''.join(results), + - abcDefghiJkl + ? ^ ^ ^ + + abcdefGhijkl + ? ^ ^ ^ + """ + + # don't synch up unless the lines have a similarity score of at + # least cutoff; best_ratio tracks the best score seen so far + best_ratio, cutoff = 0.74, 0.75 + cruncher = SequenceMatcher(self.charjunk) + eqi, eqj = None, None # 1st indices of equal lines (if any) + + # search for the pair that matches best without being identical + # (identical lines must be junk lines, & we don't want to synch up + # on junk -- unless we have to) + for j in xrange(blo, bhi): + bj = b[j] + cruncher.set_seq2(bj) + for i in xrange(alo, ahi): + ai = a[i] + if ai == bj: + if eqi is None: + eqi, eqj = i, j + continue + cruncher.set_seq1(ai) + # computing similarity is expensive, so use the quick + # upper bounds first -- have seen this speed up messy + # compares by a factor of 3. + # note that ratio() is only expensive to compute the first + # time it's called on a sequence pair; the expensive part + # of the computation is cached by cruncher + if cruncher.real_quick_ratio() > best_ratio and \ + cruncher.quick_ratio() > best_ratio and \ + cruncher.ratio() > best_ratio: + best_ratio, best_i, best_j = cruncher.ratio(), i, j + if best_ratio < cutoff: + # no non-identical "pretty close" pair + if eqi is None: + # no identical pair either -- treat it as a straight replace + for line in self._plain_replace(a, alo, ahi, b, blo, bhi): + yield line + return + # no close pair, but an identical pair -- synch up on that + best_i, best_j, best_ratio = eqi, eqj, 1.0 + else: + # there's a close pair, so forget the identical pair (if any) + eqi = None + + # a[best_i] very similar to b[best_j]; eqi is None iff they're not + # identical + + # pump out diffs from before the synch point + for line in self._fancy_helper(a, alo, best_i, b, blo, best_j): + yield line + + # do intraline marking on the synch pair + aelt, belt = a[best_i], b[best_j] + if eqi is None: + # pump out a '-', '?', '+', '?' quad for the synched lines + atags = btags = "" + cruncher.set_seqs(aelt, belt) + for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes(): + la, lb = ai2 - ai1, bj2 - bj1 + if tag == 'replace': + atags += '^' * la + btags += '^' * lb + elif tag == 'delete': + atags += '-' * la + elif tag == 'insert': + btags += '+' * lb + elif tag == 'equal': + atags += ' ' * la + btags += ' ' * lb + else: + raise ValueError, 'unknown tag %r' % (tag,) + for line in self._qformat(aelt, belt, atags, btags): + yield line + else: + # the synch pair is identical + yield ' ' + aelt + + # pump out diffs from after the synch point + for line in self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi): + yield line + + def _fancy_helper(self, a, alo, ahi, b, blo, bhi): + g = [] + if alo < ahi: + if blo < bhi: + g = self._fancy_replace(a, alo, ahi, b, blo, bhi) + else: + g = self._dump('-', a, alo, ahi) + elif blo < bhi: + g = self._dump('+', b, blo, bhi) + + for line in g: + yield line + + def _qformat(self, aline, bline, atags, btags): + r""" + Format "?" output and deal with leading tabs. + + Example: + + >>> d = Differ() + >>> results = d._qformat('\tabcDefghiJkl\n', '\tabcdefGhijkl\n', + ... ' ^ ^ ^ ', ' ^ ^ ^ ') + >>> for line in results: print repr(line) + ... + '- \tabcDefghiJkl\n' + '? \t ^ ^ ^\n' + '+ \tabcdefGhijkl\n' + '? \t ^ ^ ^\n' + """ + + # Can hurt, but will probably help most of the time. + common = min(_count_leading(aline, "\t"), + _count_leading(bline, "\t")) + common = min(common, _count_leading(atags[:common], " ")) + common = min(common, _count_leading(btags[:common], " ")) + atags = atags[common:].rstrip() + btags = btags[common:].rstrip() + + yield "- " + aline + if atags: + yield "? %s%s\n" % ("\t" * common, atags) + + yield "+ " + bline + if btags: + yield "? %s%s\n" % ("\t" * common, btags) + +# With respect to junk, an earlier version of ndiff simply refused to +# *start* a match with a junk element. The result was cases like this: +# before: private Thread currentThread; +# after: private volatile Thread currentThread; +# If you consider whitespace to be junk, the longest contiguous match +# not starting with junk is "e Thread currentThread". So ndiff reported +# that "e volatil" was inserted between the 't' and the 'e' in "private". +# While an accurate view, to people that's absurd. The current version +# looks for matching blocks that are entirely junk-free, then extends the +# longest one of those as far as possible but only with matching junk. +# So now "currentThread" is matched, then extended to suck up the +# preceding blank; then "private" is matched, and extended to suck up the +# following blank; then "Thread" is matched; and finally ndiff reports +# that "volatile " was inserted before "Thread". The only quibble +# remaining is that perhaps it was really the case that " volatile" +# was inserted after "private". I can live with that <wink>. + +import re + +def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match): + r""" + Return 1 for ignorable line: iff `line` is blank or contains a single '#'. + + Examples: + + >>> IS_LINE_JUNK('\n') + True + >>> IS_LINE_JUNK(' # \n') + True + >>> IS_LINE_JUNK('hello\n') + False + """ + + return pat(line) is not None + +def IS_CHARACTER_JUNK(ch, ws=" \t"): + r""" + Return 1 for ignorable character: iff `ch` is a space or tab. + + Examples: + + >>> IS_CHARACTER_JUNK(' ') + True + >>> IS_CHARACTER_JUNK('\t') + True + >>> IS_CHARACTER_JUNK('\n') + False + >>> IS_CHARACTER_JUNK('x') + False + """ + + return ch in ws + + +######################################################################## +### Unified Diff +######################################################################## + +def _format_range_unified(start, stop): + 'Convert range to the "ed" format' + # Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning = start + 1 # lines start numbering with one + length = stop - start + if length == 1: + return '{}'.format(beginning) + if not length: + beginning -= 1 # empty ranges begin at line just before the range + return '{},{}'.format(beginning, length) + +def unified_diff(a, b, fromfile='', tofile='', fromfiledate='', + tofiledate='', n=3, lineterm='\n'): + r""" + Compare two sequences of lines; generate the delta as a unified diff. + + Unified diffs are a compact way of showing line changes and a few + lines of context. The number of context lines is set by 'n' which + defaults to three. + + By default, the diff control lines (those with ---, +++, or @@) are + created with a trailing newline. This is helpful so that inputs + created from file.readlines() result in diffs that are suitable for + file.writelines() since both the inputs and outputs have trailing + newlines. + + For inputs that do not have trailing newlines, set the lineterm + argument to "" so that the output will be uniformly newline free. + + The unidiff format normally has a header for filenames and modification + times. Any or all of these may be specified using strings for + 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. + The modification times are normally expressed in the ISO 8601 format. + + Example: + + >>> for line in unified_diff('one two three four'.split(), + ... 'zero one tree four'.split(), 'Original', 'Current', + ... '2005-01-26 23:30:50', '2010-04-02 10:20:52', + ... lineterm=''): + ... print line # doctest: +NORMALIZE_WHITESPACE + --- Original 2005-01-26 23:30:50 + +++ Current 2010-04-02 10:20:52 + @@ -1,4 +1,4 @@ + +zero + one + -two + -three + +tree + four + """ + + started = False + for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): + if not started: + started = True + fromdate = '\t{}'.format(fromfiledate) if fromfiledate else '' + todate = '\t{}'.format(tofiledate) if tofiledate else '' + yield '--- {}{}{}'.format(fromfile, fromdate, lineterm) + yield '+++ {}{}{}'.format(tofile, todate, lineterm) + + first, last = group[0], group[-1] + file1_range = _format_range_unified(first[1], last[2]) + file2_range = _format_range_unified(first[3], last[4]) + yield '@@ -{} +{} @@{}'.format(file1_range, file2_range, lineterm) + + for tag, i1, i2, j1, j2 in group: + if tag == 'equal': + for line in a[i1:i2]: + yield ' ' + line + continue + if tag in ('replace', 'delete'): + for line in a[i1:i2]: + yield '-' + line + if tag in ('replace', 'insert'): + for line in b[j1:j2]: + yield '+' + line + + +######################################################################## +### Context Diff +######################################################################## + +def _format_range_context(start, stop): + 'Convert range to the "ed" format' + # Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning = start + 1 # lines start numbering with one + length = stop - start + if not length: + beginning -= 1 # empty ranges begin at line just before the range + if length <= 1: + return '{}'.format(beginning) + return '{},{}'.format(beginning, beginning + length - 1) + +# See http://www.unix.org/single_unix_specification/ +def context_diff(a, b, fromfile='', tofile='', + fromfiledate='', tofiledate='', n=3, lineterm='\n'): + r""" + Compare two sequences of lines; generate the delta as a context diff. + + Context diffs are a compact way of showing line changes and a few + lines of context. The number of context lines is set by 'n' which + defaults to three. + + By default, the diff control lines (those with *** or ---) are + created with a trailing newline. This is helpful so that inputs + created from file.readlines() result in diffs that are suitable for + file.writelines() since both the inputs and outputs have trailing + newlines. + + For inputs that do not have trailing newlines, set the lineterm + argument to "" so that the output will be uniformly newline free. + + The context diff format normally has a header for filenames and + modification times. Any or all of these may be specified using + strings for 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. + The modification times are normally expressed in the ISO 8601 format. + If not specified, the strings default to blanks. + + Example: + + >>> print ''.join(context_diff('one\ntwo\nthree\nfour\n'.splitlines(1), + ... 'zero\none\ntree\nfour\n'.splitlines(1), 'Original', 'Current')), + *** Original + --- Current + *************** + *** 1,4 **** + one + ! two + ! three + four + --- 1,4 ---- + + zero + one + ! tree + four + """ + + prefix = dict(insert='+ ', delete='- ', replace='! ', equal=' ') + started = False + for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): + if not started: + started = True + fromdate = '\t{}'.format(fromfiledate) if fromfiledate else '' + todate = '\t{}'.format(tofiledate) if tofiledate else '' + yield '*** {}{}{}'.format(fromfile, fromdate, lineterm) + yield '--- {}{}{}'.format(tofile, todate, lineterm) + + first, last = group[0], group[-1] + yield '***************' + lineterm + + file1_range = _format_range_context(first[1], last[2]) + yield '*** {} ****{}'.format(file1_range, lineterm) + + if any(tag in ('replace', 'delete') for tag, _, _, _, _ in group): + for tag, i1, i2, _, _ in group: + if tag != 'insert': + for line in a[i1:i2]: + yield prefix[tag] + line + + file2_range = _format_range_context(first[3], last[4]) + yield '--- {} ----{}'.format(file2_range, lineterm) + + if any(tag in ('replace', 'insert') for tag, _, _, _, _ in group): + for tag, _, _, j1, j2 in group: + if tag != 'delete': + for line in b[j1:j2]: + yield prefix[tag] + line + +def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK): + r""" + Compare `a` and `b` (lists of strings); return a `Differ`-style delta. + + Optional keyword parameters `linejunk` and `charjunk` are for filter + functions (or None): + + - linejunk: A function that should accept a single string argument, and + return true iff the string is junk. The default is None, and is + recommended; as of Python 2.3, an adaptive notion of "noise" lines is + used that does a good job on its own. + + - charjunk: A function that should accept a string of length 1. The + default is module-level function IS_CHARACTER_JUNK, which filters out + whitespace characters (a blank or tab; note: bad idea to include newline + in this!). + + Tools/scripts/ndiff.py is a command-line front-end to this function. + + Example: + + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), + ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> print ''.join(diff), + - one + ? ^ + + ore + ? ^ + - two + - three + ? - + + tree + + emu + """ + return Differ(linejunk, charjunk).compare(a, b) + +def _mdiff(fromlines, tolines, context=None, linejunk=None, + charjunk=IS_CHARACTER_JUNK): + r"""Returns generator yielding marked up from/to side by side differences. + + Arguments: + fromlines -- list of text lines to compared to tolines + tolines -- list of text lines to be compared to fromlines + context -- number of context lines to display on each side of difference, + if None, all from/to text lines will be generated. + linejunk -- passed on to ndiff (see ndiff documentation) + charjunk -- passed on to ndiff (see ndiff documentation) + + This function returns an interator which returns a tuple: + (from line tuple, to line tuple, boolean flag) + + from/to line tuple -- (line num, line text) + line num -- integer or None (to indicate a context separation) + line text -- original line text with following markers inserted: + '\0+' -- marks start of added text + '\0-' -- marks start of deleted text + '\0^' -- marks start of changed text + '\1' -- marks end of added/deleted/changed text + + boolean flag -- None indicates context separation, True indicates + either "from" or "to" line contains a change, otherwise False. + + This function/iterator was originally developed to generate side by side + file difference for making HTML pages (see HtmlDiff class for example + usage). + + Note, this function utilizes the ndiff function to generate the side by + side difference markup. Optional ndiff arguments may be passed to this + function and they in turn will be passed to ndiff. + """ + import re + + # regular expression for finding intraline change indices + change_re = re.compile('(\++|\-+|\^+)') + + # create the difference iterator to generate the differences + diff_lines_iterator = ndiff(fromlines,tolines,linejunk,charjunk) + + def _make_line(lines, format_key, side, num_lines=[0,0]): + """Returns line of text with user's change markup and line formatting. + + lines -- list of lines from the ndiff generator to produce a line of + text from. When producing the line of text to return, the + lines used are removed from this list. + format_key -- '+' return first line in list with "add" markup around + the entire line. + '-' return first line in list with "delete" markup around + the entire line. + '?' return first line in list with add/delete/change + intraline markup (indices obtained from second line) + None return first line in list with no markup + side -- indice into the num_lines list (0=from,1=to) + num_lines -- from/to current line number. This is NOT intended to be a + passed parameter. It is present as a keyword argument to + maintain memory of the current line numbers between calls + of this function. + + Note, this function is purposefully not defined at the module scope so + that data it needs from its parent function (within whose context it + is defined) does not need to be of module scope. + """ + num_lines[side] += 1 + # Handle case where no user markup is to be added, just return line of + # text with user's line format to allow for usage of the line number. + if format_key is None: + return (num_lines[side],lines.pop(0)[2:]) + # Handle case of intraline changes + if format_key == '?': + text, markers = lines.pop(0), lines.pop(0) + # find intraline changes (store change type and indices in tuples) + sub_info = [] + def record_sub_info(match_object,sub_info=sub_info): + sub_info.append([match_object.group(1)[0],match_object.span()]) + return match_object.group(1) + change_re.sub(record_sub_info,markers) + # process each tuple inserting our special marks that won't be + # noticed by an xml/html escaper. + for key,(begin,end) in sub_info[::-1]: + text = text[0:begin]+'\0'+key+text[begin:end]+'\1'+text[end:] + text = text[2:] + # Handle case of add/delete entire line + else: + text = lines.pop(0)[2:] + # if line of text is just a newline, insert a space so there is + # something for the user to highlight and see. + if not text: + text = ' ' + # insert marks that won't be noticed by an xml/html escaper. + text = '\0' + format_key + text + '\1' + # Return line of text, first allow user's line formatter to do its + # thing (such as adding the line number) then replace the special + # marks with what the user's change markup. + return (num_lines[side],text) + + def _line_iterator(): + """Yields from/to lines of text with a change indication. + + This function is an iterator. It itself pulls lines from a + differencing iterator, processes them and yields them. When it can + it yields both a "from" and a "to" line, otherwise it will yield one + or the other. In addition to yielding the lines of from/to text, a + boolean flag is yielded to indicate if the text line(s) have + differences in them. + + Note, this function is purposefully not defined at the module scope so + that data it needs from its parent function (within whose context it + is defined) does not need to be of module scope. + """ + lines = [] + num_blanks_pending, num_blanks_to_yield = 0, 0 + while True: + # Load up next 4 lines so we can look ahead, create strings which + # are a concatenation of the first character of each of the 4 lines + # so we can do some very readable comparisons. + while len(lines) < 4: + try: + lines.append(diff_lines_iterator.next()) + except StopIteration: + lines.append('X') + s = ''.join([line[0] for line in lines]) + if s.startswith('X'): + # When no more lines, pump out any remaining blank lines so the + # corresponding add/delete lines get a matching blank line so + # all line pairs get yielded at the next level. + num_blanks_to_yield = num_blanks_pending + elif s.startswith('-?+?'): + # simple intraline change + yield _make_line(lines,'?',0), _make_line(lines,'?',1), True + continue + elif s.startswith('--++'): + # in delete block, add block coming: we do NOT want to get + # caught up on blank lines yet, just process the delete line + num_blanks_pending -= 1 + yield _make_line(lines,'-',0), None, True + continue + elif s.startswith(('--?+', '--+', '- ')): + # in delete block and see a intraline change or unchanged line + # coming: yield the delete line and then blanks + from_line,to_line = _make_line(lines,'-',0), None + num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0 + elif s.startswith('-+?'): + # intraline change + yield _make_line(lines,None,0), _make_line(lines,'?',1), True + continue + elif s.startswith('-?+'): + # intraline change + yield _make_line(lines,'?',0), _make_line(lines,None,1), True + continue + elif s.startswith('-'): + # delete FROM line + num_blanks_pending -= 1 + yield _make_line(lines,'-',0), None, True + continue + elif s.startswith('+--'): + # in add block, delete block coming: we do NOT want to get + # caught up on blank lines yet, just process the add line + num_blanks_pending += 1 + yield None, _make_line(lines,'+',1), True + continue + elif s.startswith(('+ ', '+-')): + # will be leaving an add block: yield blanks then add line + from_line, to_line = None, _make_line(lines,'+',1) + num_blanks_to_yield,num_blanks_pending = num_blanks_pending+1,0 + elif s.startswith('+'): + # inside an add block, yield the add line + num_blanks_pending += 1 + yield None, _make_line(lines,'+',1), True + continue + elif s.startswith(' '): + # unchanged text, yield it to both sides + yield _make_line(lines[:],None,0),_make_line(lines,None,1),False + continue + # Catch up on the blank lines so when we yield the next from/to + # pair, they are lined up. + while(num_blanks_to_yield < 0): + num_blanks_to_yield += 1 + yield None,('','\n'),True + while(num_blanks_to_yield > 0): + num_blanks_to_yield -= 1 + yield ('','\n'),None,True + if s.startswith('X'): + raise StopIteration + else: + yield from_line,to_line,True + + def _line_pair_iterator(): + """Yields from/to lines of text with a change indication. + + This function is an iterator. It itself pulls lines from the line + iterator. Its difference from that iterator is that this function + always yields a pair of from/to text lines (with the change + indication). If necessary it will collect single from/to lines + until it has a matching pair from/to pair to yield. + + Note, this function is purposefully not defined at the module scope so + that data it needs from its parent function (within whose context it + is defined) does not need to be of module scope. + """ + line_iterator = _line_iterator() + fromlines,tolines=[],[] + while True: + # Collecting lines of text until we have a from/to pair + while (len(fromlines)==0 or len(tolines)==0): + from_line, to_line, found_diff =line_iterator.next() + if from_line is not None: + fromlines.append((from_line,found_diff)) + if to_line is not None: + tolines.append((to_line,found_diff)) + # Once we have a pair, remove them from the collection and yield it + from_line, fromDiff = fromlines.pop(0) + to_line, to_diff = tolines.pop(0) + yield (from_line,to_line,fromDiff or to_diff) + + # Handle case where user does not want context differencing, just yield + # them up without doing anything else with them. + line_pair_iterator = _line_pair_iterator() + if context is None: + while True: + yield line_pair_iterator.next() + # Handle case where user wants context differencing. We must do some + # storage of lines until we know for sure that they are to be yielded. + else: + context += 1 + lines_to_write = 0 + while True: + # Store lines up until we find a difference, note use of a + # circular queue because we only need to keep around what + # we need for context. + index, contextLines = 0, [None]*(context) + found_diff = False + while(found_diff is False): + from_line, to_line, found_diff = line_pair_iterator.next() + i = index % context + contextLines[i] = (from_line, to_line, found_diff) + index += 1 + # Yield lines that we have collected so far, but first yield + # the user's separator. + if index > context: + yield None, None, None + lines_to_write = context + else: + lines_to_write = index + index = 0 + while(lines_to_write): + i = index % context + index += 1 + yield contextLines[i] + lines_to_write -= 1 + # Now yield the context lines after the change + lines_to_write = context-1 + while(lines_to_write): + from_line, to_line, found_diff = line_pair_iterator.next() + # If another change within the context, extend the context + if found_diff: + lines_to_write = context-1 + else: + lines_to_write -= 1 + yield from_line, to_line, found_diff + + +_file_template = """ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css">%(styles)s + </style> +</head> + +<body> + %(table)s%(legend)s +</body> + +</html>""" + +_styles = """ + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa}""" + +_table_template = """ + <table class="diff" id="difflib_chg_%(prefix)s_top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + %(header_row)s + <tbody> +%(data_rows)s </tbody> + </table>""" + +_legend = """ + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table>""" + +class HtmlDiff(object): + """For producing HTML side by side comparison with change highlights. + + This class can be used to create an HTML table (or a complete HTML file + containing the table) showing a side by side, line by line comparison + of text with inter-line and intra-line change highlights. The table can + be generated in either full or contextual difference mode. + + The following methods are provided for HTML generation: + + make_table -- generates HTML for a single side by side table + make_file -- generates complete HTML file with a single side by side table + + See tools/scripts/diff.py for an example usage of this class. + """ + + _file_template = _file_template + _styles = _styles + _table_template = _table_template + _legend = _legend + _default_prefix = 0 + + def __init__(self,tabsize=8,wrapcolumn=None,linejunk=None, + charjunk=IS_CHARACTER_JUNK): + """HtmlDiff instance initializer + + Arguments: + tabsize -- tab stop spacing, defaults to 8. + wrapcolumn -- column number where lines are broken and wrapped, + defaults to None where lines are not wrapped. + linejunk,charjunk -- keyword arguments passed into ndiff() (used to by + HtmlDiff() to generate the side by side HTML differences). See + ndiff() documentation for argument default values and descriptions. + """ + self._tabsize = tabsize + self._wrapcolumn = wrapcolumn + self._linejunk = linejunk + self._charjunk = charjunk + + def make_file(self,fromlines,tolines,fromdesc='',todesc='',context=False, + numlines=5): + """Returns HTML file of side by side comparison with change highlights + + Arguments: + fromlines -- list of "from" lines + tolines -- list of "to" lines + fromdesc -- "from" file column header string + todesc -- "to" file column header string + context -- set to True for contextual differences (defaults to False + which shows full differences). + numlines -- number of context lines. When context is set True, + controls number of lines displayed before and after the change. + When context is False, controls the number of lines to place + the "next" link anchors before the next change (so click of + "next" link jumps to just before the change). + """ + + return self._file_template % dict( + styles = self._styles, + legend = self._legend, + table = self.make_table(fromlines,tolines,fromdesc,todesc, + context=context,numlines=numlines)) + + def _tab_newline_replace(self,fromlines,tolines): + """Returns from/to line lists with tabs expanded and newlines removed. + + Instead of tab characters being replaced by the number of spaces + needed to fill in to the next tab stop, this function will fill + the space with tab characters. This is done so that the difference + algorithms can identify changes in a file when tabs are replaced by + spaces and vice versa. At the end of the HTML generation, the tab + characters will be replaced with a nonbreakable space. + """ + def expand_tabs(line): + # hide real spaces + line = line.replace(' ','\0') + # expand tabs into spaces + line = line.expandtabs(self._tabsize) + # replace spaces from expanded tabs back into tab characters + # (we'll replace them with markup after we do differencing) + line = line.replace(' ','\t') + return line.replace('\0',' ').rstrip('\n') + fromlines = [expand_tabs(line) for line in fromlines] + tolines = [expand_tabs(line) for line in tolines] + return fromlines,tolines + + def _split_line(self,data_list,line_num,text): + """Builds list of text lines by splitting text lines at wrap point + + This function will determine if the input text line needs to be + wrapped (split) into separate lines. If so, the first wrap point + will be determined and the first line appended to the output + text line list. This function is used recursively to handle + the second part of the split line to further split it. + """ + # if blank line or context separator, just add it to the output list + if not line_num: + data_list.append((line_num,text)) + return + + # if line text doesn't need wrapping, just add it to the output list + size = len(text) + max = self._wrapcolumn + if (size <= max) or ((size -(text.count('\0')*3)) <= max): + data_list.append((line_num,text)) + return + + # scan text looking for the wrap point, keeping track if the wrap + # point is inside markers + i = 0 + n = 0 + mark = '' + while n < max and i < size: + if text[i] == '\0': + i += 1 + mark = text[i] + i += 1 + elif text[i] == '\1': + i += 1 + mark = '' + else: + i += 1 + n += 1 + + # wrap point is inside text, break it up into separate lines + line1 = text[:i] + line2 = text[i:] + + # if wrap point is inside markers, place end marker at end of first + # line and start marker at beginning of second line because each + # line will have its own table tag markup around it. + if mark: + line1 = line1 + '\1' + line2 = '\0' + mark + line2 + + # tack on first line onto the output list + data_list.append((line_num,line1)) + + # use this routine again to wrap the remaining text + self._split_line(data_list,'>',line2) + + def _line_wrapper(self,diffs): + """Returns iterator that splits (wraps) mdiff text lines""" + + # pull from/to data and flags from mdiff iterator + for fromdata,todata,flag in diffs: + # check for context separators and pass them through + if flag is None: + yield fromdata,todata,flag + continue + (fromline,fromtext),(toline,totext) = fromdata,todata + # for each from/to line split it at the wrap column to form + # list of text lines. + fromlist,tolist = [],[] + self._split_line(fromlist,fromline,fromtext) + self._split_line(tolist,toline,totext) + # yield from/to line in pairs inserting blank lines as + # necessary when one side has more wrapped lines + while fromlist or tolist: + if fromlist: + fromdata = fromlist.pop(0) + else: + fromdata = ('',' ') + if tolist: + todata = tolist.pop(0) + else: + todata = ('',' ') + yield fromdata,todata,flag + + def _collect_lines(self,diffs): + """Collects mdiff output into separate lists + + Before storing the mdiff from/to data into a list, it is converted + into a single line of text with HTML markup. + """ + + fromlist,tolist,flaglist = [],[],[] + # pull from/to data and flags from mdiff style iterator + for fromdata,todata,flag in diffs: + try: + # store HTML markup of the lines into the lists + fromlist.append(self._format_line(0,flag,*fromdata)) + tolist.append(self._format_line(1,flag,*todata)) + except TypeError: + # exceptions occur for lines where context separators go + fromlist.append(None) + tolist.append(None) + flaglist.append(flag) + return fromlist,tolist,flaglist + + def _format_line(self,side,flag,linenum,text): + """Returns HTML markup of "from" / "to" text lines + + side -- 0 or 1 indicating "from" or "to" text + flag -- indicates if difference on line + linenum -- line number (used for line number column) + text -- line text to be marked up + """ + try: + linenum = '%d' % linenum + id = ' id="%s%s"' % (self._prefix[side],linenum) + except TypeError: + # handle blank lines where linenum is '>' or '' + id = '' + # replace those things that would get confused with HTML symbols + text=text.replace("&","&").replace(">",">").replace("<","<") + + # make space non-breakable so they don't get compressed or line wrapped + text = text.replace(' ',' ').rstrip() + + return '<td class="diff_header"%s>%s</td><td nowrap="nowrap">%s</td>' \ + % (id,linenum,text) + + def _make_prefix(self): + """Create unique anchor prefixes""" + + # Generate a unique anchor prefix so multiple tables + # can exist on the same HTML page without conflicts. + fromprefix = "from%d_" % HtmlDiff._default_prefix + toprefix = "to%d_" % HtmlDiff._default_prefix + HtmlDiff._default_prefix += 1 + # store prefixes so line format method has access + self._prefix = [fromprefix,toprefix] + + def _convert_flags(self,fromlist,tolist,flaglist,context,numlines): + """Makes list of "next" links""" + + # all anchor names will be generated using the unique "to" prefix + toprefix = self._prefix[1] + + # process change flags, generating middle column of next anchors/links + next_id = ['']*len(flaglist) + next_href = ['']*len(flaglist) + num_chg, in_change = 0, False + last = 0 + for i,flag in enumerate(flaglist): + if flag: + if not in_change: + in_change = True + last = i + # at the beginning of a change, drop an anchor a few lines + # (the context lines) before the change for the previous + # link + i = max([0,i-numlines]) + next_id[i] = ' id="difflib_chg_%s_%d"' % (toprefix,num_chg) + # at the beginning of a change, drop a link to the next + # change + num_chg += 1 + next_href[last] = '<a href="#difflib_chg_%s_%d">n</a>' % ( + toprefix,num_chg) + else: + in_change = False + # check for cases where there is no content to avoid exceptions + if not flaglist: + flaglist = [False] + next_id = [''] + next_href = [''] + last = 0 + if context: + fromlist = ['<td></td><td> No Differences Found </td>'] + tolist = fromlist + else: + fromlist = tolist = ['<td></td><td> Empty File </td>'] + # if not a change on first line, drop a link + if not flaglist[0]: + next_href[0] = '<a href="#difflib_chg_%s_0">f</a>' % toprefix + # redo the last link to link to the top + next_href[last] = '<a href="#difflib_chg_%s_top">t</a>' % (toprefix) + + return fromlist,tolist,flaglist,next_href,next_id + + def make_table(self,fromlines,tolines,fromdesc='',todesc='',context=False, + numlines=5): + """Returns HTML table of side by side comparison with change highlights + + Arguments: + fromlines -- list of "from" lines + tolines -- list of "to" lines + fromdesc -- "from" file column header string + todesc -- "to" file column header string + context -- set to True for contextual differences (defaults to False + which shows full differences). + numlines -- number of context lines. When context is set True, + controls number of lines displayed before and after the change. + When context is False, controls the number of lines to place + the "next" link anchors before the next change (so click of + "next" link jumps to just before the change). + """ + + # make unique anchor prefixes so that multiple tables may exist + # on the same page without conflict. + self._make_prefix() + + # change tabs to spaces before it gets more difficult after we insert + # markkup + fromlines,tolines = self._tab_newline_replace(fromlines,tolines) + + # create diffs iterator which generates side by side from/to data + if context: + context_lines = numlines + else: + context_lines = None + diffs = _mdiff(fromlines,tolines,context_lines,linejunk=self._linejunk, + charjunk=self._charjunk) + + # set up iterator to wrap lines that exceed desired width + if self._wrapcolumn: + diffs = self._line_wrapper(diffs) + + # collect up from/to lines and flags into lists (also format the lines) + fromlist,tolist,flaglist = self._collect_lines(diffs) + + # process change flags, generating middle column of next anchors/links + fromlist,tolist,flaglist,next_href,next_id = self._convert_flags( + fromlist,tolist,flaglist,context,numlines) + + s = [] + fmt = ' <tr><td class="diff_next"%s>%s</td>%s' + \ + '<td class="diff_next">%s</td>%s</tr>\n' + for i in range(len(flaglist)): + if flaglist[i] is None: + # mdiff yields None on separator lines skip the bogus ones + # generated for the first line + if i > 0: + s.append(' </tbody> \n <tbody>\n') + else: + s.append( fmt % (next_id[i],next_href[i],fromlist[i], + next_href[i],tolist[i])) + if fromdesc or todesc: + header_row = '<thead><tr>%s%s%s%s</tr></thead>' % ( + '<th class="diff_next"><br /></th>', + '<th colspan="2" class="diff_header">%s</th>' % fromdesc, + '<th class="diff_next"><br /></th>', + '<th colspan="2" class="diff_header">%s</th>' % todesc) + else: + header_row = '' + + table = self._table_template % dict( + data_rows=''.join(s), + header_row=header_row, + prefix=self._prefix[1]) + + return table.replace('\0+','<span class="diff_add">'). \ + replace('\0-','<span class="diff_sub">'). \ + replace('\0^','<span class="diff_chg">'). \ + replace('\1','</span>'). \ + replace('\t',' ') + +del re + +def restore(delta, which): + r""" + Generate one of the two sequences that generated a delta. + + Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract + lines originating from file 1 or 2 (parameter `which`), stripping off line + prefixes. + + Examples: + + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), + ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> diff = list(diff) + >>> print ''.join(restore(diff, 1)), + one + two + three + >>> print ''.join(restore(diff, 2)), + ore + tree + emu + """ + try: + tag = {1: "- ", 2: "+ "}[int(which)] + except KeyError: + raise ValueError, ('unknown delta choice (must be 1 or 2): %r' + % which) + prefixes = (" ", tag) + for line in delta: + if line[:2] in prefixes: + yield line[2:] + +def _test(): + import doctest, difflib + return doctest.testmod(difflib) + +if __name__ == "__main__": + _test() diff --git a/src/main/resources/PythonLibs/dircache.py b/src/main/resources/PythonLibs/dircache.py new file mode 100644 index 0000000000000000000000000000000000000000..7e4f0b508ac74e47495622472b2382370fa3d9d9 --- /dev/null +++ b/src/main/resources/PythonLibs/dircache.py @@ -0,0 +1,41 @@ +"""Read and cache directory listings. + +The listdir() routine returns a sorted list of the files in a directory, +using a cache to avoid reading the directory more often than necessary. +The annotate() routine appends slashes to directories.""" +from warnings import warnpy3k +warnpy3k("the dircache module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +import os + +__all__ = ["listdir", "opendir", "annotate", "reset"] + +cache = {} + +def reset(): + """Reset the cache completely.""" + global cache + cache = {} + +def listdir(path): + """List directory contents, using cache.""" + try: + cached_mtime, list = cache[path] + del cache[path] + except KeyError: + cached_mtime, list = -1, [] + mtime = os.stat(path).st_mtime + if mtime != cached_mtime: + list = os.listdir(path) + list.sort() + cache[path] = mtime, list + return list + +opendir = listdir # XXX backward compatibility + +def annotate(head, list): + """Add '/' suffixes to directories.""" + for i in range(len(list)): + if os.path.isdir(os.path.join(head, list[i])): + list[i] = list[i] + '/' diff --git a/src/main/resources/PythonLibs/dis.py b/src/main/resources/PythonLibs/dis.py new file mode 100644 index 0000000000000000000000000000000000000000..5aa09c95b6d8df8354e38be0d5163e9796302cb3 --- /dev/null +++ b/src/main/resources/PythonLibs/dis.py @@ -0,0 +1,224 @@ +"""Disassembler of Python byte code into mnemonics.""" + +import sys +import types + +from opcode import * +from opcode import __all__ as _opcodes_all + +__all__ = ["dis", "disassemble", "distb", "disco", + "findlinestarts", "findlabels"] + _opcodes_all +del _opcodes_all + +_have_code = (types.MethodType, types.FunctionType, types.CodeType, + types.ClassType, type) + +def dis(x=None): + """Disassemble classes, methods, functions, or code. + + With no argument, disassemble the last traceback. + + """ + if x is None: + distb() + return + if isinstance(x, types.InstanceType): + x = x.__class__ + if hasattr(x, 'im_func'): + x = x.im_func + if hasattr(x, 'func_code'): + x = x.func_code + if hasattr(x, '__dict__'): + items = x.__dict__.items() + items.sort() + for name, x1 in items: + if isinstance(x1, _have_code): + print "Disassembly of %s:" % name + try: + dis(x1) + except TypeError, msg: + print "Sorry:", msg + print + elif hasattr(x, 'co_code'): + disassemble(x) + elif isinstance(x, str): + disassemble_string(x) + else: + raise TypeError, \ + "don't know how to disassemble %s objects" % \ + type(x).__name__ + +def distb(tb=None): + """Disassemble a traceback (default: last traceback).""" + if tb is None: + try: + tb = sys.last_traceback + except AttributeError: + raise RuntimeError, "no last traceback to disassemble" + while tb.tb_next: tb = tb.tb_next + disassemble(tb.tb_frame.f_code, tb.tb_lasti) + +def disassemble(co, lasti=-1): + """Disassemble a code object.""" + code = co.co_code + labels = findlabels(code) + linestarts = dict(findlinestarts(co)) + n = len(code) + i = 0 + extended_arg = 0 + free = None + while i < n: + c = code[i] + op = ord(c) + if i in linestarts: + if i > 0: + print + print "%3d" % linestarts[i], + else: + print ' ', + + if i == lasti: print '-->', + else: print ' ', + if i in labels: print '>>', + else: print ' ', + print repr(i).rjust(4), + print opname[op].ljust(20), + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg + extended_arg = 0 + i = i+2 + if op == EXTENDED_ARG: + extended_arg = oparg*65536L + print repr(oparg).rjust(5), + if op in hasconst: + print '(' + repr(co.co_consts[oparg]) + ')', + elif op in hasname: + print '(' + co.co_names[oparg] + ')', + elif op in hasjrel: + print '(to ' + repr(i + oparg) + ')', + elif op in haslocal: + print '(' + co.co_varnames[oparg] + ')', + elif op in hascompare: + print '(' + cmp_op[oparg] + ')', + elif op in hasfree: + if free is None: + free = co.co_cellvars + co.co_freevars + print '(' + free[oparg] + ')', + print + +def disassemble_string(code, lasti=-1, varnames=None, names=None, + constants=None): + labels = findlabels(code) + n = len(code) + i = 0 + while i < n: + c = code[i] + op = ord(c) + if i == lasti: print '-->', + else: print ' ', + if i in labels: print '>>', + else: print ' ', + print repr(i).rjust(4), + print opname[op].ljust(15), + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + print repr(oparg).rjust(5), + if op in hasconst: + if constants: + print '(' + repr(constants[oparg]) + ')', + else: + print '(%d)'%oparg, + elif op in hasname: + if names is not None: + print '(' + names[oparg] + ')', + else: + print '(%d)'%oparg, + elif op in hasjrel: + print '(to ' + repr(i + oparg) + ')', + elif op in haslocal: + if varnames: + print '(' + varnames[oparg] + ')', + else: + print '(%d)' % oparg, + elif op in hascompare: + print '(' + cmp_op[oparg] + ')', + print + +disco = disassemble # XXX For backwards compatibility + +def findlabels(code): + """Detect all offsets in a byte code which are jump targets. + + Return the list of offsets. + + """ + labels = [] + n = len(code) + i = 0 + while i < n: + c = code[i] + op = ord(c) + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + label = -1 + if op in hasjrel: + label = i+oparg + elif op in hasjabs: + label = oparg + if label >= 0: + if label not in labels: + labels.append(label) + return labels + +def findlinestarts(code): + """Find the offsets in a byte code which are start of lines in the source. + + Generate pairs (offset, lineno) as described in Python/compile.c. + + """ + byte_increments = [ord(c) for c in code.co_lnotab[0::2]] + line_increments = [ord(c) for c in code.co_lnotab[1::2]] + + lastlineno = None + lineno = code.co_firstlineno + addr = 0 + for byte_incr, line_incr in zip(byte_increments, line_increments): + if byte_incr: + if lineno != lastlineno: + yield (addr, lineno) + lastlineno = lineno + addr += byte_incr + lineno += line_incr + if lineno != lastlineno: + yield (addr, lineno) + +def _test(): + """Simple test program to disassemble a file.""" + if sys.argv[1:]: + if sys.argv[2:]: + sys.stderr.write("usage: python dis.py [-|file]\n") + sys.exit(2) + fn = sys.argv[1] + if not fn or fn == "-": + fn = None + else: + fn = None + if fn is None: + f = sys.stdin + else: + f = open(fn) + source = f.read() + if fn is not None: + f.close() + else: + fn = "<stdin>" + code = compile(source, fn, "exec") + dis(code) + +if __name__ == "__main__": + _test() diff --git a/src/main/resources/PythonLibs/distutils/README b/src/main/resources/PythonLibs/distutils/README new file mode 100644 index 0000000000000000000000000000000000000000..408a203b85d5ffd0d5447e27207e2b99dc49078f --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/README @@ -0,0 +1,13 @@ +This directory contains the Distutils package. + +There's a full documentation available at: + + http://docs.python.org/distutils/ + +The Distutils-SIG web page is also a good starting point: + + http://www.python.org/sigs/distutils-sig/ + +WARNING : Distutils must remain compatible with 2.3 + +$Id$ diff --git a/src/main/resources/PythonLibs/distutils/__init__.py b/src/main/resources/PythonLibs/distutils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..036062cc337aa081758f85f9c8378b8d758fa2fb --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/__init__.py @@ -0,0 +1,19 @@ +"""distutils + +The main package for the Python Module Distribution Utilities. Normally +used from a setup script as + + from distutils.core import setup + + setup (...) +""" + +__revision__ = "$Id$" + +# Distutils version +# +# Updated automatically by the Python release process. +# +#--start constants-- +__version__ = "2.7.3" +#--end constants-- diff --git a/src/main/resources/PythonLibs/distutils/archive_util.py b/src/main/resources/PythonLibs/distutils/archive_util.py new file mode 100644 index 0000000000000000000000000000000000000000..834b722ed3f140784e308231f667794c9c2a4b43 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/archive_util.py @@ -0,0 +1,243 @@ +"""distutils.archive_util + +Utility functions for creating archive files (tarballs, zip files, +that sort of thing).""" + +__revision__ = "$Id$" + +import os +from warnings import warn +import sys + +from distutils.errors import DistutilsExecError +from distutils.spawn import spawn +from distutils.dir_util import mkpath +from distutils import log + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "compress", "bzip2", or None. + (compress will be deprecated in Python 3.2) + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_dir' + ".tar", possibly plus + the appropriate compression extension (".gz", ".bz2" or ".Z"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: '', 'compress': ''} + compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'compress': '.Z'} + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext.keys(): + raise ValueError, \ + ("bad value for 'compress': must be None, 'gzip', 'bzip2' " + "or 'compress'") + + archive_name = base_name + '.tar' + if compress != 'compress': + archive_name += compress_ext.get(compress, '') + + mkpath(os.path.dirname(archive_name), dry_run=dry_run) + + # creating the tarball + import tarfile # late import so Python build itself doesn't break + + log.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + # compression using `compress` + if compress == 'compress': + warn("'compress' will be deprecated.", PendingDeprecationWarning) + # the option varies depending on the platform + compressed_name = archive_name + compress_ext[compress] + if sys.platform == 'win32': + cmd = [compress, archive_name, compressed_name] + else: + cmd = [compress, '-f', archive_name] + spawn(cmd, dry_run=dry_run) + return compressed_name + + return archive_name + +def make_zipfile(base_name, base_dir, verbose=0, dry_run=0): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises DistutilsExecError. Returns the name of the output zip + file. + """ + try: + import zipfile + except ImportError: + zipfile = None + + zip_filename = base_name + ".zip" + mkpath(os.path.dirname(zip_filename), dry_run=dry_run) + + # If zipfile module is not available, try spawning an external + # 'zip' command. + if zipfile is None: + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + + try: + spawn(["zip", zipoptions, zip_filename, base_dir], + dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise DistutilsExecError, \ + ("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + + else: + log.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + log.info("adding '%s'" % path) + zip.close() + + return zip_filename + +ARCHIVE_FORMATS = { + 'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'ztar': (make_tarball, [('compress', 'compress')], "compressed tar file"), + 'tar': (make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (make_zipfile, [],"ZIP file") + } + +def check_archive_formats(formats): + """Returns the first format from the 'format' list that is unknown. + + If all formats are known, returns None + """ + for format in formats: + if format not in ARCHIVE_FORMATS: + return format + return None + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "ztar", + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + log.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run} + + try: + format_info = ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError, "unknown archive format '%s'" % format + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + log.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename diff --git a/src/main/resources/PythonLibs/distutils/bcppcompiler.py b/src/main/resources/PythonLibs/distutils/bcppcompiler.py new file mode 100644 index 0000000000000000000000000000000000000000..f26e7ae4673bd4bb477a4a0e117d8e30c4f62126 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/bcppcompiler.py @@ -0,0 +1,394 @@ +"""distutils.bcppcompiler + +Contains BorlandCCompiler, an implementation of the abstract CCompiler class +for the Borland C++ compiler. +""" + +# This implementation by Lyle Johnson, based on the original msvccompiler.py +# module and using the directions originally published by Gordon Williams. + +# XXX looks like there's a LOT of overlap between these two classes: +# someone should sit down and factor out the common code as +# WindowsCCompiler! --GPW + +__revision__ = "$Id$" + +import os + +from distutils.errors import (DistutilsExecError, CompileError, LibError, + LinkError, UnknownFileError) +from distutils.ccompiler import CCompiler, gen_preprocess_options +from distutils.file_util import write_file +from distutils.dep_util import newer +from distutils import log + +class BCPPCompiler(CCompiler) : + """Concrete class that implements an interface to the Borland C/C++ + compiler, as defined by the CCompiler abstract class. + """ + + compiler_type = 'bcpp' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = _c_extensions + _cpp_extensions + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + CCompiler.__init__ (self, verbose, dry_run, force) + + # These executables are assumed to all be in the path. + # Borland doesn't seem to use any special registry settings to + # indicate their installation locations. + + self.cc = "bcc32.exe" + self.linker = "ilink32.exe" + self.lib = "tlib.exe" + + self.preprocess_options = None + self.compile_options = ['/tWM', '/O2', '/q', '/g0'] + self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0'] + + self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x'] + self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x'] + self.ldflags_static = [] + self.ldflags_exe = ['/Gn', '/q', '/x'] + self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r'] + + + # -- Worker methods ------------------------------------------------ + + def compile(self, sources, + output_dir=None, macros=None, include_dirs=None, debug=0, + extra_preargs=None, extra_postargs=None, depends=None): + + macros, objects, extra_postargs, pp_opts, build = \ + self._setup_compile(output_dir, macros, include_dirs, sources, + depends, extra_postargs) + compile_opts = extra_preargs or [] + compile_opts.append ('-c') + if debug: + compile_opts.extend (self.compile_options_debug) + else: + compile_opts.extend (self.compile_options) + + for obj in objects: + try: + src, ext = build[obj] + except KeyError: + continue + # XXX why do the normpath here? + src = os.path.normpath(src) + obj = os.path.normpath(obj) + # XXX _setup_compile() did a mkpath() too but before the normpath. + # Is it possible to skip the normpath? + self.mkpath(os.path.dirname(obj)) + + if ext == '.res': + # This is already a binary file -- skip it. + continue # the 'for' loop + if ext == '.rc': + # This needs to be compiled to a .res file -- do it now. + try: + self.spawn (["brcc32", "-fo", obj, src]) + except DistutilsExecError, msg: + raise CompileError, msg + continue # the 'for' loop + + # The next two are both for the real compiler. + if ext in self._c_extensions: + input_opt = "" + elif ext in self._cpp_extensions: + input_opt = "-P" + else: + # Unknown file type -- no extra options. The compiler + # will probably fail, but let it just in case this is a + # file the compiler recognizes even if we don't. + input_opt = "" + + output_opt = "-o" + obj + + # Compiler command line syntax is: "bcc32 [options] file(s)". + # Note that the source file names must appear at the end of + # the command line. + try: + self.spawn ([self.cc] + compile_opts + pp_opts + + [input_opt, output_opt] + + extra_postargs + [src]) + except DistutilsExecError, msg: + raise CompileError, msg + + return objects + + # compile () + + + def create_static_lib (self, + objects, + output_libname, + output_dir=None, + debug=0, + target_lang=None): + + (objects, output_dir) = self._fix_object_args (objects, output_dir) + output_filename = \ + self.library_filename (output_libname, output_dir=output_dir) + + if self._need_link (objects, output_filename): + lib_args = [output_filename, '/u'] + objects + if debug: + pass # XXX what goes here? + try: + self.spawn ([self.lib] + lib_args) + except DistutilsExecError, msg: + raise LibError, msg + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # create_static_lib () + + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + # XXX this ignores 'build_temp'! should follow the lead of + # msvccompiler.py + + (objects, output_dir) = self._fix_object_args (objects, output_dir) + (libraries, library_dirs, runtime_library_dirs) = \ + self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) + + if runtime_library_dirs: + log.warn("I don't know what to do with 'runtime_library_dirs': %s", + str(runtime_library_dirs)) + + if output_dir is not None: + output_filename = os.path.join (output_dir, output_filename) + + if self._need_link (objects, output_filename): + + # Figure out linker args based on type of target. + if target_desc == CCompiler.EXECUTABLE: + startup_obj = 'c0w32' + if debug: + ld_args = self.ldflags_exe_debug[:] + else: + ld_args = self.ldflags_exe[:] + else: + startup_obj = 'c0d32' + if debug: + ld_args = self.ldflags_shared_debug[:] + else: + ld_args = self.ldflags_shared[:] + + + # Create a temporary exports file for use by the linker + if export_symbols is None: + def_file = '' + else: + head, tail = os.path.split (output_filename) + modname, ext = os.path.splitext (tail) + temp_dir = os.path.dirname(objects[0]) # preserve tree structure + def_file = os.path.join (temp_dir, '%s.def' % modname) + contents = ['EXPORTS'] + for sym in (export_symbols or []): + contents.append(' %s=_%s' % (sym, sym)) + self.execute(write_file, (def_file, contents), + "writing %s" % def_file) + + # Borland C++ has problems with '/' in paths + objects2 = map(os.path.normpath, objects) + # split objects in .obj and .res files + # Borland C++ needs them at different positions in the command line + objects = [startup_obj] + resources = [] + for file in objects2: + (base, ext) = os.path.splitext(os.path.normcase(file)) + if ext == '.res': + resources.append(file) + else: + objects.append(file) + + + for l in library_dirs: + ld_args.append("/L%s" % os.path.normpath(l)) + ld_args.append("/L.") # we sometimes use relative paths + + # list of object files + ld_args.extend(objects) + + # XXX the command-line syntax for Borland C++ is a bit wonky; + # certain filenames are jammed together in one big string, but + # comma-delimited. This doesn't mesh too well with the + # Unix-centric attitude (with a DOS/Windows quoting hack) of + # 'spawn()', so constructing the argument list is a bit + # awkward. Note that doing the obvious thing and jamming all + # the filenames and commas into one argument would be wrong, + # because 'spawn()' would quote any filenames with spaces in + # them. Arghghh!. Apparently it works fine as coded... + + # name of dll/exe file + ld_args.extend([',',output_filename]) + # no map file and start libraries + ld_args.append(',,') + + for lib in libraries: + # see if we find it and if there is a bcpp specific lib + # (xxx_bcpp.lib) + libfile = self.find_library_file(library_dirs, lib, debug) + if libfile is None: + ld_args.append(lib) + # probably a BCPP internal library -- don't warn + else: + # full name which prefers bcpp_xxx.lib over xxx.lib + ld_args.append(libfile) + + # some default libraries + ld_args.append ('import32') + ld_args.append ('cw32mt') + + # def file for export symbols + ld_args.extend([',',def_file]) + # add resource files + ld_args.append(',') + ld_args.extend(resources) + + + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + + self.mkpath (os.path.dirname (output_filename)) + try: + self.spawn ([self.linker] + ld_args) + except DistutilsExecError, msg: + raise LinkError, msg + + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # link () + + # -- Miscellaneous methods ----------------------------------------- + + + def find_library_file (self, dirs, lib, debug=0): + # List of effective library names to try, in order of preference: + # xxx_bcpp.lib is better than xxx.lib + # and xxx_d.lib is better than xxx.lib if debug is set + # + # The "_bcpp" suffix is to handle a Python installation for people + # with multiple compilers (primarily Distutils hackers, I suspect + # ;-). The idea is they'd have one static library for each + # compiler they care about, since (almost?) every Windows compiler + # seems to have a different format for static libraries. + if debug: + dlib = (lib + "_d") + try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib) + else: + try_names = (lib + "_bcpp", lib) + + for dir in dirs: + for name in try_names: + libfile = os.path.join(dir, self.library_filename(name)) + if os.path.exists(libfile): + return libfile + else: + # Oops, didn't find it in *any* of 'dirs' + return None + + # overwrite the one from CCompiler to support rc and res-files + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + # use normcase to make sure '.rc' is really '.rc' and not '.RC' + (base, ext) = os.path.splitext (os.path.normcase(src_name)) + if ext not in (self.src_extensions + ['.rc','.res']): + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % \ + (ext, src_name) + if strip_dir: + base = os.path.basename (base) + if ext == '.res': + # these can go unchanged + obj_names.append (os.path.join (output_dir, base + ext)) + elif ext == '.rc': + # these need to be compiled to .res-files + obj_names.append (os.path.join (output_dir, base + '.res')) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + def preprocess (self, + source, + output_file=None, + macros=None, + include_dirs=None, + extra_preargs=None, + extra_postargs=None): + + (_, macros, include_dirs) = \ + self._fix_compile_args(None, macros, include_dirs) + pp_opts = gen_preprocess_options(macros, include_dirs) + pp_args = ['cpp32.exe'] + pp_opts + if output_file is not None: + pp_args.append('-o' + output_file) + if extra_preargs: + pp_args[:0] = extra_preargs + if extra_postargs: + pp_args.extend(extra_postargs) + pp_args.append(source) + + # We need to preprocess: either we're being forced to, or the + # source file is newer than the target (or the target doesn't + # exist). + if self.force or output_file is None or newer(source, output_file): + if output_file: + self.mkpath(os.path.dirname(output_file)) + try: + self.spawn(pp_args) + except DistutilsExecError, msg: + print msg + raise CompileError, msg + + # preprocess() diff --git a/src/main/resources/PythonLibs/distutils/ccompiler.py b/src/main/resources/PythonLibs/distutils/ccompiler.py new file mode 100644 index 0000000000000000000000000000000000000000..fac13c7e8a5689f0bf965e0ffd73c7edeb67c2ac --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/ccompiler.py @@ -0,0 +1,1148 @@ +"""distutils.ccompiler + +Contains CCompiler, an abstract base class that defines the interface +for the Distutils compiler abstraction model.""" + +__revision__ = "$Id: ccompiler.py 86238 2010-11-06 04:06:18Z eric.araujo $" + +import sys +import os +import re + +from distutils.errors import (CompileError, LinkError, UnknownFileError, + DistutilsPlatformError, DistutilsModuleError) +from distutils.spawn import spawn +from distutils.file_util import move_file +from distutils.dir_util import mkpath +from distutils.dep_util import newer_group +from distutils.util import split_quoted, execute +from distutils import log + +_sysconfig = __import__('sysconfig') + +def customize_compiler(compiler): + """Do any platform-specific customization of a CCompiler instance. + + Mainly needed on Unix, so we can plug in the information that + varies across Unices and is stored in Python's Makefile. + """ + if compiler.compiler_type == "unix": + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ + _sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', + 'CCSHARED', 'LDSHARED', 'SO', 'AR', + 'ARFLAGS') + + if 'CC' in os.environ: + cc = os.environ['CC'] + if 'CXX' in os.environ: + cxx = os.environ['CXX'] + if 'LDSHARED' in os.environ: + ldshared = os.environ['LDSHARED'] + if 'CPP' in os.environ: + cpp = os.environ['CPP'] + else: + cpp = cc + " -E" # not always + if 'LDFLAGS' in os.environ: + ldshared = ldshared + ' ' + os.environ['LDFLAGS'] + if 'CFLAGS' in os.environ: + cflags = opt + ' ' + os.environ['CFLAGS'] + ldshared = ldshared + ' ' + os.environ['CFLAGS'] + if 'CPPFLAGS' in os.environ: + cpp = cpp + ' ' + os.environ['CPPFLAGS'] + cflags = cflags + ' ' + os.environ['CPPFLAGS'] + ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + if 'AR' in os.environ: + ar = os.environ['AR'] + if 'ARFLAGS' in os.environ: + archiver = ar + ' ' + os.environ['ARFLAGS'] + else: + archiver = ar + ' ' + ar_flags + + cc_cmd = cc + ' ' + cflags + compiler.set_executables( + preprocessor=cpp, + compiler=cc_cmd, + compiler_so=cc_cmd + ' ' + ccshared, + compiler_cxx=cxx, + linker_so=ldshared, + linker_exe=cc, + archiver=archiver) + + compiler.shared_lib_extension = so_ext + +class CCompiler: + """Abstract base class to define the interface that must be implemented + by real compiler classes. Also has some utility methods used by + several compiler classes. + + The basic idea behind a compiler abstraction class is that each + instance can be used for all the compile/link steps in building a + single project. Thus, attributes common to all of those compile and + link steps -- include directories, macros to define, libraries to link + against, etc. -- are attributes of the compiler instance. To allow for + variability in how individual files are treated, most of those + attributes may be varied on a per-compilation or per-link basis. + """ + + # 'compiler_type' is a class attribute that identifies this class. It + # keeps code that wants to know what kind of compiler it's dealing with + # from having to import all possible compiler classes just to do an + # 'isinstance'. In concrete CCompiler subclasses, 'compiler_type' + # should really, really be one of the keys of the 'compiler_class' + # dictionary (see below -- used by the 'new_compiler()' factory + # function) -- authors of new compiler interface classes are + # responsible for updating 'compiler_class'! + compiler_type = None + + # XXX things not handled by this compiler abstraction model: + # * client can't provide additional options for a compiler, + # e.g. warning, optimization, debugging flags. Perhaps this + # should be the domain of concrete compiler abstraction classes + # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base + # class should have methods for the common ones. + # * can't completely override the include or library searchg + # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2". + # I'm not sure how widely supported this is even by Unix + # compilers, much less on other platforms. And I'm even less + # sure how useful it is; maybe for cross-compiling, but + # support for that is a ways off. (And anyways, cross + # compilers probably have a dedicated binary with the + # right paths compiled in. I hope.) + # * can't do really freaky things with the library list/library + # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against + # different versions of libfoo.a in different locations. I + # think this is useless without the ability to null out the + # library search path anyways. + + + # Subclasses that rely on the standard filename generation methods + # implemented below should override these; see the comment near + # those methods ('object_filenames()' et. al.) for details: + src_extensions = None # list of strings + obj_extension = None # string + static_lib_extension = None + shared_lib_extension = None # string + static_lib_format = None # format string + shared_lib_format = None # prob. same as static_lib_format + exe_extension = None # string + + # Default language settings. language_map is used to detect a source + # file or Extension target language, checking source filenames. + # language_order is used to detect the language precedence, when deciding + # what language to use when mixing source types. For example, if some + # extension has two files with ".c" extension, and one with ".cpp", it + # is still linked as c++. + language_map = {".c" : "c", + ".cc" : "c++", + ".cpp" : "c++", + ".cxx" : "c++", + ".m" : "objc", + } + language_order = ["c++", "objc", "c"] + + def __init__ (self, verbose=0, dry_run=0, force=0): + self.dry_run = dry_run + self.force = force + self.verbose = verbose + + # 'output_dir': a common output directory for object, library, + # shared object, and shared library files + self.output_dir = None + + # 'macros': a list of macro definitions (or undefinitions). A + # macro definition is a 2-tuple (name, value), where the value is + # either a string or None (no explicit value). A macro + # undefinition is a 1-tuple (name,). + self.macros = [] + + # 'include_dirs': a list of directories to search for include files + self.include_dirs = [] + + # 'libraries': a list of libraries to include in any link + # (library names, not filenames: eg. "foo" not "libfoo.a") + self.libraries = [] + + # 'library_dirs': a list of directories to search for libraries + self.library_dirs = [] + + # 'runtime_library_dirs': a list of directories to search for + # shared libraries/objects at runtime + self.runtime_library_dirs = [] + + # 'objects': a list of object files (or similar, such as explicitly + # named library files) to include on any link + self.objects = [] + + for key in self.executables.keys(): + self.set_executable(key, self.executables[key]) + + def set_executables(self, **args): + """Define the executables (and options for them) that will be run + to perform the various stages of compilation. The exact set of + executables that may be specified here depends on the compiler + class (via the 'executables' class attribute), but most will have: + compiler the C/C++ compiler + linker_so linker used to create shared objects and libraries + linker_exe linker used to create binary executables + archiver static library creator + + On platforms with a command-line (Unix, DOS/Windows), each of these + is a string that will be split into executable name and (optional) + list of arguments. (Splitting the string is done similarly to how + Unix shells operate: words are delimited by spaces, but quotes and + backslashes can override this. See + 'distutils.util.split_quoted()'.) + """ + + # Note that some CCompiler implementation classes will define class + # attributes 'cpp', 'cc', etc. with hard-coded executable names; + # this is appropriate when a compiler class is for exactly one + # compiler/OS combination (eg. MSVCCompiler). Other compiler + # classes (UnixCCompiler, in particular) are driven by information + # discovered at run-time, since there are many different ways to do + # basically the same things with Unix C compilers. + + for key in args.keys(): + if key not in self.executables: + raise ValueError, \ + "unknown executable '%s' for class %s" % \ + (key, self.__class__.__name__) + self.set_executable(key, args[key]) + + def set_executable(self, key, value): + if isinstance(value, str): + setattr(self, key, split_quoted(value)) + else: + setattr(self, key, value) + + def _find_macro(self, name): + i = 0 + for defn in self.macros: + if defn[0] == name: + return i + i = i + 1 + return None + + def _check_macro_definitions(self, definitions): + """Ensures that every element of 'definitions' is a valid macro + definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do + nothing if all definitions are OK, raise TypeError otherwise. + """ + for defn in definitions: + if not (isinstance(defn, tuple) and + (len (defn) == 1 or + (len (defn) == 2 and + (isinstance(defn[1], str) or defn[1] is None))) and + isinstance(defn[0], str)): + raise TypeError, \ + ("invalid macro definition '%s': " % defn) + \ + "must be tuple (string,), (string, string), or " + \ + "(string, None)" + + + # -- Bookkeeping methods ------------------------------------------- + + def define_macro(self, name, value=None): + """Define a preprocessor macro for all compilations driven by this + compiler object. The optional parameter 'value' should be a + string; if it is not supplied, then the macro will be defined + without an explicit value and the exact outcome depends on the + compiler used (XXX true? does ANSI say anything about this?) + """ + # Delete from the list of macro definitions/undefinitions if + # already there (so that this one will take precedence). + i = self._find_macro (name) + if i is not None: + del self.macros[i] + + defn = (name, value) + self.macros.append (defn) + + def undefine_macro(self, name): + """Undefine a preprocessor macro for all compilations driven by + this compiler object. If the same macro is defined by + 'define_macro()' and undefined by 'undefine_macro()' the last call + takes precedence (including multiple redefinitions or + undefinitions). If the macro is redefined/undefined on a + per-compilation basis (ie. in the call to 'compile()'), then that + takes precedence. + """ + # Delete from the list of macro definitions/undefinitions if + # already there (so that this one will take precedence). + i = self._find_macro (name) + if i is not None: + del self.macros[i] + + undefn = (name,) + self.macros.append (undefn) + + def add_include_dir(self, dir): + """Add 'dir' to the list of directories that will be searched for + header files. The compiler is instructed to search directories in + the order in which they are supplied by successive calls to + 'add_include_dir()'. + """ + self.include_dirs.append (dir) + + def set_include_dirs(self, dirs): + """Set the list of directories that will be searched to 'dirs' (a + list of strings). Overrides any preceding calls to + 'add_include_dir()'; subsequence calls to 'add_include_dir()' add + to the list passed to 'set_include_dirs()'. This does not affect + any list of standard include directories that the compiler may + search by default. + """ + self.include_dirs = dirs[:] + + def add_library(self, libname): + """Add 'libname' to the list of libraries that will be included in + all links driven by this compiler object. Note that 'libname' + should *not* be the name of a file containing a library, but the + name of the library itself: the actual filename will be inferred by + the linker, the compiler, or the compiler class (depending on the + platform). + + The linker will be instructed to link against libraries in the + order they were supplied to 'add_library()' and/or + 'set_libraries()'. It is perfectly valid to duplicate library + names; the linker will be instructed to link against libraries as + many times as they are mentioned. + """ + self.libraries.append (libname) + + def set_libraries(self, libnames): + """Set the list of libraries to be included in all links driven by + this compiler object to 'libnames' (a list of strings). This does + not affect any standard system libraries that the linker may + include by default. + """ + self.libraries = libnames[:] + + + def add_library_dir(self, dir): + """Add 'dir' to the list of directories that will be searched for + libraries specified to 'add_library()' and 'set_libraries()'. The + linker will be instructed to search for libraries in the order they + are supplied to 'add_library_dir()' and/or 'set_library_dirs()'. + """ + self.library_dirs.append(dir) + + def set_library_dirs(self, dirs): + """Set the list of library search directories to 'dirs' (a list of + strings). This does not affect any standard library search path + that the linker may search by default. + """ + self.library_dirs = dirs[:] + + def add_runtime_library_dir(self, dir): + """Add 'dir' to the list of directories that will be searched for + shared libraries at runtime. + """ + self.runtime_library_dirs.append(dir) + + def set_runtime_library_dirs(self, dirs): + """Set the list of directories to search for shared libraries at + runtime to 'dirs' (a list of strings). This does not affect any + standard search path that the runtime linker may search by + default. + """ + self.runtime_library_dirs = dirs[:] + + def add_link_object(self, object): + """Add 'object' to the list of object files (or analogues, such as + explicitly named library files or the output of "resource + compilers") to be included in every link driven by this compiler + object. + """ + self.objects.append(object) + + def set_link_objects(self, objects): + """Set the list of object files (or analogues) to be included in + every link to 'objects'. This does not affect any standard object + files that the linker may include by default (such as system + libraries). + """ + self.objects = objects[:] + + + # -- Private utility methods -------------------------------------- + # (here for the convenience of subclasses) + + # Helper method to prep compiler in subclass compile() methods + + def _setup_compile(self, outdir, macros, incdirs, sources, depends, + extra): + """Process arguments and decide which source files to compile.""" + if outdir is None: + outdir = self.output_dir + elif not isinstance(outdir, str): + raise TypeError, "'output_dir' must be a string or None" + + if macros is None: + macros = self.macros + elif isinstance(macros, list): + macros = macros + (self.macros or []) + else: + raise TypeError, "'macros' (if supplied) must be a list of tuples" + + if incdirs is None: + incdirs = self.include_dirs + elif isinstance(incdirs, (list, tuple)): + incdirs = list(incdirs) + (self.include_dirs or []) + else: + raise TypeError, \ + "'include_dirs' (if supplied) must be a list of strings" + + if extra is None: + extra = [] + + # Get the list of expected output (object) files + objects = self.object_filenames(sources, + strip_dir=0, + output_dir=outdir) + assert len(objects) == len(sources) + + pp_opts = gen_preprocess_options(macros, incdirs) + + build = {} + for i in range(len(sources)): + src = sources[i] + obj = objects[i] + ext = os.path.splitext(src)[1] + self.mkpath(os.path.dirname(obj)) + build[obj] = (src, ext) + + return macros, objects, extra, pp_opts, build + + def _get_cc_args(self, pp_opts, debug, before): + # works for unixccompiler, emxccompiler, cygwinccompiler + cc_args = pp_opts + ['-c'] + if debug: + cc_args[:0] = ['-g'] + if before: + cc_args[:0] = before + return cc_args + + def _fix_compile_args(self, output_dir, macros, include_dirs): + """Typecheck and fix-up some of the arguments to the 'compile()' + method, and return fixed-up values. Specifically: if 'output_dir' + is None, replaces it with 'self.output_dir'; ensures that 'macros' + is a list, and augments it with 'self.macros'; ensures that + 'include_dirs' is a list, and augments it with 'self.include_dirs'. + Guarantees that the returned values are of the correct type, + i.e. for 'output_dir' either string or None, and for 'macros' and + 'include_dirs' either list or None. + """ + if output_dir is None: + output_dir = self.output_dir + elif not isinstance(output_dir, str): + raise TypeError, "'output_dir' must be a string or None" + + if macros is None: + macros = self.macros + elif isinstance(macros, list): + macros = macros + (self.macros or []) + else: + raise TypeError, "'macros' (if supplied) must be a list of tuples" + + if include_dirs is None: + include_dirs = self.include_dirs + elif isinstance(include_dirs, (list, tuple)): + include_dirs = list (include_dirs) + (self.include_dirs or []) + else: + raise TypeError, \ + "'include_dirs' (if supplied) must be a list of strings" + + return output_dir, macros, include_dirs + + def _fix_object_args(self, objects, output_dir): + """Typecheck and fix up some arguments supplied to various methods. + Specifically: ensure that 'objects' is a list; if output_dir is + None, replace with self.output_dir. Return fixed versions of + 'objects' and 'output_dir'. + """ + if not isinstance(objects, (list, tuple)): + raise TypeError, \ + "'objects' must be a list or tuple of strings" + objects = list (objects) + + if output_dir is None: + output_dir = self.output_dir + elif not isinstance(output_dir, str): + raise TypeError, "'output_dir' must be a string or None" + + return (objects, output_dir) + + def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs): + """Typecheck and fix up some of the arguments supplied to the + 'link_*' methods. Specifically: ensure that all arguments are + lists, and augment them with their permanent versions + (eg. 'self.libraries' augments 'libraries'). Return a tuple with + fixed versions of all arguments. + """ + if libraries is None: + libraries = self.libraries + elif isinstance(libraries, (list, tuple)): + libraries = list (libraries) + (self.libraries or []) + else: + raise TypeError, \ + "'libraries' (if supplied) must be a list of strings" + + if library_dirs is None: + library_dirs = self.library_dirs + elif isinstance(library_dirs, (list, tuple)): + library_dirs = list (library_dirs) + (self.library_dirs or []) + else: + raise TypeError, \ + "'library_dirs' (if supplied) must be a list of strings" + + if runtime_library_dirs is None: + runtime_library_dirs = self.runtime_library_dirs + elif isinstance(runtime_library_dirs, (list, tuple)): + runtime_library_dirs = (list (runtime_library_dirs) + + (self.runtime_library_dirs or [])) + else: + raise TypeError, \ + "'runtime_library_dirs' (if supplied) " + \ + "must be a list of strings" + + return (libraries, library_dirs, runtime_library_dirs) + + def _need_link(self, objects, output_file): + """Return true if we need to relink the files listed in 'objects' + to recreate 'output_file'. + """ + if self.force: + return 1 + else: + if self.dry_run: + newer = newer_group (objects, output_file, missing='newer') + else: + newer = newer_group (objects, output_file) + return newer + + def detect_language(self, sources): + """Detect the language of a given file, or list of files. Uses + language_map, and language_order to do the job. + """ + if not isinstance(sources, list): + sources = [sources] + lang = None + index = len(self.language_order) + for source in sources: + base, ext = os.path.splitext(source) + extlang = self.language_map.get(ext) + try: + extindex = self.language_order.index(extlang) + if extindex < index: + lang = extlang + index = extindex + except ValueError: + pass + return lang + + # -- Worker methods ------------------------------------------------ + # (must be implemented by subclasses) + + def preprocess(self, source, output_file=None, macros=None, + include_dirs=None, extra_preargs=None, extra_postargs=None): + """Preprocess a single C/C++ source file, named in 'source'. + Output will be written to file named 'output_file', or stdout if + 'output_file' not supplied. 'macros' is a list of macro + definitions as for 'compile()', which will augment the macros set + with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a + list of directory names that will be added to the default list. + + Raises PreprocessError on failure. + """ + pass + + def compile(self, sources, output_dir=None, macros=None, + include_dirs=None, debug=0, extra_preargs=None, + extra_postargs=None, depends=None): + """Compile one or more source files. + + 'sources' must be a list of filenames, most likely C/C++ + files, but in reality anything that can be handled by a + particular compiler and compiler class (eg. MSVCCompiler can + handle resource files in 'sources'). Return a list of object + filenames, one per source filename in 'sources'. Depending on + the implementation, not all source files will necessarily be + compiled, but all corresponding object filenames will be + returned. + + If 'output_dir' is given, object files will be put under it, while + retaining their original path component. That is, "foo/bar.c" + normally compiles to "foo/bar.o" (for a Unix implementation); if + 'output_dir' is "build", then it would compile to + "build/foo/bar.o". + + 'macros', if given, must be a list of macro definitions. A macro + definition is either a (name, value) 2-tuple or a (name,) 1-tuple. + The former defines a macro; if the value is None, the macro is + defined without an explicit value. The 1-tuple case undefines a + macro. Later definitions/redefinitions/ undefinitions take + precedence. + + 'include_dirs', if given, must be a list of strings, the + directories to add to the default include file search path for this + compilation only. + + 'debug' is a boolean; if true, the compiler will be instructed to + output debug symbols in (or alongside) the object file(s). + + 'extra_preargs' and 'extra_postargs' are implementation- dependent. + On platforms that have the notion of a command-line (e.g. Unix, + DOS/Windows), they are most likely lists of strings: extra + command-line arguments to prepand/append to the compiler command + line. On other platforms, consult the implementation class + documentation. In any event, they are intended as an escape hatch + for those occasions when the abstract compiler framework doesn't + cut the mustard. + + 'depends', if given, is a list of filenames that all targets + depend on. If a source file is older than any file in + depends, then the source file will be recompiled. This + supports dependency tracking, but only at a coarse + granularity. + + Raises CompileError on failure. + """ + # A concrete compiler class can either override this method + # entirely or implement _compile(). + + macros, objects, extra_postargs, pp_opts, build = \ + self._setup_compile(output_dir, macros, include_dirs, sources, + depends, extra_postargs) + cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) + + for obj in objects: + try: + src, ext = build[obj] + except KeyError: + continue + self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) + + # Return *all* object filenames, not just the ones we just built. + return objects + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + """Compile 'src' to product 'obj'.""" + + # A concrete compiler class that does not override compile() + # should implement _compile(). + pass + + def create_static_lib(self, objects, output_libname, output_dir=None, + debug=0, target_lang=None): + """Link a bunch of stuff together to create a static library file. + The "bunch of stuff" consists of the list of object files supplied + as 'objects', the extra object files supplied to + 'add_link_object()' and/or 'set_link_objects()', the libraries + supplied to 'add_library()' and/or 'set_libraries()', and the + libraries supplied as 'libraries' (if any). + + 'output_libname' should be a library name, not a filename; the + filename will be inferred from the library name. 'output_dir' is + the directory where the library file will be put. + + 'debug' is a boolean; if true, debugging information will be + included in the library (note that on most platforms, it is the + compile step where this matters: the 'debug' flag is included here + just for consistency). + + 'target_lang' is the target language for which the given objects + are being compiled. This allows specific linkage time treatment of + certain languages. + + Raises LibError on failure. + """ + pass + + # values for target_desc parameter in link() + SHARED_OBJECT = "shared_object" + SHARED_LIBRARY = "shared_library" + EXECUTABLE = "executable" + + def link(self, target_desc, objects, output_filename, output_dir=None, + libraries=None, library_dirs=None, runtime_library_dirs=None, + export_symbols=None, debug=0, extra_preargs=None, + extra_postargs=None, build_temp=None, target_lang=None): + """Link a bunch of stuff together to create an executable or + shared library file. + + The "bunch of stuff" consists of the list of object files supplied + as 'objects'. 'output_filename' should be a filename. If + 'output_dir' is supplied, 'output_filename' is relative to it + (i.e. 'output_filename' can provide directory components if + needed). + + 'libraries' is a list of libraries to link against. These are + library names, not filenames, since they're translated into + filenames in a platform-specific way (eg. "foo" becomes "libfoo.a" + on Unix and "foo.lib" on DOS/Windows). However, they can include a + directory component, which means the linker will look in that + specific directory rather than searching all the normal locations. + + 'library_dirs', if supplied, should be a list of directories to + search for libraries that were specified as bare library names + (ie. no directory component). These are on top of the system + default and those supplied to 'add_library_dir()' and/or + 'set_library_dirs()'. 'runtime_library_dirs' is a list of + directories that will be embedded into the shared library and used + to search for other shared libraries that *it* depends on at + run-time. (This may only be relevant on Unix.) + + 'export_symbols' is a list of symbols that the shared library will + export. (This appears to be relevant only on Windows.) + + 'debug' is as for 'compile()' and 'create_static_lib()', with the + slight distinction that it actually matters on most platforms (as + opposed to 'create_static_lib()', which includes a 'debug' flag + mostly for form's sake). + + 'extra_preargs' and 'extra_postargs' are as for 'compile()' (except + of course that they supply command-line arguments for the + particular linker being used). + + 'target_lang' is the target language for which the given objects + are being compiled. This allows specific linkage time treatment of + certain languages. + + Raises LinkError on failure. + """ + raise NotImplementedError + + + # Old 'link_*()' methods, rewritten to use the new 'link()' method. + + def link_shared_lib(self, objects, output_libname, output_dir=None, + libraries=None, library_dirs=None, + runtime_library_dirs=None, export_symbols=None, + debug=0, extra_preargs=None, extra_postargs=None, + build_temp=None, target_lang=None): + self.link(CCompiler.SHARED_LIBRARY, objects, + self.library_filename(output_libname, lib_type='shared'), + output_dir, + libraries, library_dirs, runtime_library_dirs, + export_symbols, debug, + extra_preargs, extra_postargs, build_temp, target_lang) + + + def link_shared_object(self, objects, output_filename, output_dir=None, + libraries=None, library_dirs=None, + runtime_library_dirs=None, export_symbols=None, + debug=0, extra_preargs=None, extra_postargs=None, + build_temp=None, target_lang=None): + self.link(CCompiler.SHARED_OBJECT, objects, + output_filename, output_dir, + libraries, library_dirs, runtime_library_dirs, + export_symbols, debug, + extra_preargs, extra_postargs, build_temp, target_lang) + + def link_executable(self, objects, output_progname, output_dir=None, + libraries=None, library_dirs=None, + runtime_library_dirs=None, debug=0, extra_preargs=None, + extra_postargs=None, target_lang=None): + self.link(CCompiler.EXECUTABLE, objects, + self.executable_filename(output_progname), output_dir, + libraries, library_dirs, runtime_library_dirs, None, + debug, extra_preargs, extra_postargs, None, target_lang) + + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function; there is + # no appropriate default implementation so subclasses should + # implement all of these. + + def library_dir_option(self, dir): + """Return the compiler option to add 'dir' to the list of + directories searched for libraries. + """ + raise NotImplementedError + + def runtime_library_dir_option(self, dir): + """Return the compiler option to add 'dir' to the list of + directories searched for runtime libraries. + """ + raise NotImplementedError + + def library_option(self, lib): + """Return the compiler option to add 'dir' to the list of libraries + linked into the shared library or executable. + """ + raise NotImplementedError + + def has_function(self, funcname, includes=None, include_dirs=None, + libraries=None, library_dirs=None): + """Return a boolean indicating whether funcname is supported on + the current platform. The optional arguments can be used to + augment the compilation environment. + """ + + # this can't be included at module scope because it tries to + # import math which might not be available at that point - maybe + # the necessary logic should just be inlined? + import tempfile + if includes is None: + includes = [] + if include_dirs is None: + include_dirs = [] + if libraries is None: + libraries = [] + if library_dirs is None: + library_dirs = [] + fd, fname = tempfile.mkstemp(".c", funcname, text=True) + f = os.fdopen(fd, "w") + try: + for incl in includes: + f.write("""#include "%s"\n""" % incl) + f.write("""\ +main (int argc, char **argv) { + %s(); +} +""" % funcname) + finally: + f.close() + try: + objects = self.compile([fname], include_dirs=include_dirs) + except CompileError: + return False + + try: + self.link_executable(objects, "a.out", + libraries=libraries, + library_dirs=library_dirs) + except (LinkError, TypeError): + return False + return True + + def find_library_file (self, dirs, lib, debug=0): + """Search the specified list of directories for a static or shared + library file 'lib' and return the full path to that file. If + 'debug' true, look for a debugging version (if that makes sense on + the current platform). Return None if 'lib' wasn't found in any of + the specified directories. + """ + raise NotImplementedError + + # -- Filename generation methods ----------------------------------- + + # The default implementation of the filename generating methods are + # prejudiced towards the Unix/DOS/Windows view of the world: + # * object files are named by replacing the source file extension + # (eg. .c/.cpp -> .o/.obj) + # * library files (shared or static) are named by plugging the + # library name and extension into a format string, eg. + # "lib%s.%s" % (lib_name, ".a") for Unix static libraries + # * executables are named by appending an extension (possibly + # empty) to the program name: eg. progname + ".exe" for + # Windows + # + # To reduce redundant code, these methods expect to find + # several attributes in the current object (presumably defined + # as class attributes): + # * src_extensions - + # list of C/C++ source file extensions, eg. ['.c', '.cpp'] + # * obj_extension - + # object file extension, eg. '.o' or '.obj' + # * static_lib_extension - + # extension for static library files, eg. '.a' or '.lib' + # * shared_lib_extension - + # extension for shared library/object files, eg. '.so', '.dll' + # * static_lib_format - + # format string for generating static library filenames, + # eg. 'lib%s.%s' or '%s.%s' + # * shared_lib_format + # format string for generating shared library filenames + # (probably same as static_lib_format, since the extension + # is one of the intended parameters to the format string) + # * exe_extension - + # extension for executable files, eg. '' or '.exe' + + def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): + if output_dir is None: + output_dir = '' + obj_names = [] + for src_name in source_filenames: + base, ext = os.path.splitext(src_name) + base = os.path.splitdrive(base)[1] # Chop off the drive + base = base[os.path.isabs(base):] # If abs, chop off leading / + if ext not in self.src_extensions: + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % (ext, src_name) + if strip_dir: + base = os.path.basename(base) + obj_names.append(os.path.join(output_dir, + base + self.obj_extension)) + return obj_names + + def shared_object_filename(self, basename, strip_dir=0, output_dir=''): + assert output_dir is not None + if strip_dir: + basename = os.path.basename (basename) + return os.path.join(output_dir, basename + self.shared_lib_extension) + + def executable_filename(self, basename, strip_dir=0, output_dir=''): + assert output_dir is not None + if strip_dir: + basename = os.path.basename (basename) + return os.path.join(output_dir, basename + (self.exe_extension or '')) + + def library_filename(self, libname, lib_type='static', # or 'shared' + strip_dir=0, output_dir=''): + assert output_dir is not None + if lib_type not in ("static", "shared", "dylib"): + raise ValueError, "'lib_type' must be \"static\", \"shared\" or \"dylib\"" + fmt = getattr(self, lib_type + "_lib_format") + ext = getattr(self, lib_type + "_lib_extension") + + dir, base = os.path.split (libname) + filename = fmt % (base, ext) + if strip_dir: + dir = '' + + return os.path.join(output_dir, dir, filename) + + + # -- Utility methods ----------------------------------------------- + + def announce(self, msg, level=1): + log.debug(msg) + + def debug_print(self, msg): + from distutils.debug import DEBUG + if DEBUG: + print msg + + def warn(self, msg): + sys.stderr.write("warning: %s\n" % msg) + + def execute(self, func, args, msg=None, level=1): + execute(func, args, msg, self.dry_run) + + def spawn(self, cmd): + spawn(cmd, dry_run=self.dry_run) + + def move_file(self, src, dst): + return move_file(src, dst, dry_run=self.dry_run) + + def mkpath(self, name, mode=0777): + mkpath(name, mode, dry_run=self.dry_run) + + +# class CCompiler + + +# Map a sys.platform/os.name ('posix', 'nt') to the default compiler +# type for that platform. Keys are interpreted as re match +# patterns. Order is important; platform mappings are preferred over +# OS names. +_default_compilers = ( + + # Platform string mappings + + # on a cygwin built python we can use gcc like an ordinary UNIXish + # compiler + ('cygwin.*', 'unix'), + ('os2emx', 'emx'), + ('java.*', 'jython'), + + # OS name mappings + ('posix', 'unix'), + ('nt', 'msvc'), + + ) + +def get_default_compiler(osname=None, platform=None): + """ Determine the default compiler to use for the given platform. + + osname should be one of the standard Python OS names (i.e. the + ones returned by os.name) and platform the common value + returned by sys.platform for the platform in question. + + The default values are os.name and sys.platform in case the + parameters are not given. + + """ + if osname is None: + osname = os.name + if platform is None: + platform = sys.platform + for pattern, compiler in _default_compilers: + if re.match(pattern, platform) is not None or \ + re.match(pattern, osname) is not None: + return compiler + # Default to Unix compiler + return 'unix' + +# Map compiler types to (module_name, class_name) pairs -- ie. where to +# find the code that implements an interface to this compiler. (The module +# is assumed to be in the 'distutils' package.) +compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', + "standard UNIX-style compiler"), + 'msvc': ('msvccompiler', 'MSVCCompiler', + "Microsoft Visual C++"), + 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', + "Cygwin port of GNU C Compiler for Win32"), + 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', + "Mingw32 port of GNU C Compiler for Win32"), + 'bcpp': ('bcppcompiler', 'BCPPCompiler', + "Borland C++ Compiler"), + 'emx': ('emxccompiler', 'EMXCCompiler', + "EMX port of GNU C Compiler for OS/2"), + 'jython': ('jythoncompiler', 'JythonCompiler', + "Compiling is not supported on Jython"), + } + +def show_compilers(): + """Print list of available compilers (used by the "--help-compiler" + options to "build", "build_ext", "build_clib"). + """ + # XXX this "knows" that the compiler option it's describing is + # "--compiler", which just happens to be the case for the three + # commands that use it. + from distutils.fancy_getopt import FancyGetopt + compilers = [] + for compiler in compiler_class.keys(): + compilers.append(("compiler="+compiler, None, + compiler_class[compiler][2])) + compilers.sort() + pretty_printer = FancyGetopt(compilers) + pretty_printer.print_help("List of available compilers:") + + +def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0): + """Generate an instance of some CCompiler subclass for the supplied + platform/compiler combination. 'plat' defaults to 'os.name' + (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler + for that platform. Currently only 'posix' and 'nt' are supported, and + the default compilers are "traditional Unix interface" (UnixCCompiler + class) and Visual C++ (MSVCCompiler class). Note that it's perfectly + possible to ask for a Unix compiler object under Windows, and a + Microsoft compiler object under Unix -- if you supply a value for + 'compiler', 'plat' is ignored. + """ + if plat is None: + plat = os.name + + try: + if compiler is None: + compiler = get_default_compiler(plat) + + (module_name, class_name, long_description) = compiler_class[compiler] + except KeyError: + msg = "don't know how to compile C/C++ code on platform '%s'" % plat + if compiler is not None: + msg = msg + " with '%s' compiler" % compiler + raise DistutilsPlatformError, msg + + try: + module_name = "distutils." + module_name + __import__ (module_name) + module = sys.modules[module_name] + klass = vars(module)[class_name] + except ImportError: + raise DistutilsModuleError, \ + "can't compile C/C++ code: unable to load module '%s'" % \ + module_name + except KeyError: + raise DistutilsModuleError, \ + ("can't compile C/C++ code: unable to find class '%s' " + + "in module '%s'") % (class_name, module_name) + + # XXX The None is necessary to preserve backwards compatibility + # with classes that expect verbose to be the first positional + # argument. + return klass(None, dry_run, force) + + +def gen_preprocess_options(macros, include_dirs): + """Generate C pre-processor options (-D, -U, -I) as used by at least + two types of compilers: the typical Unix compiler and Visual C++. + 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) + means undefine (-U) macro 'name', and (name,value) means define (-D) + macro 'name' to 'value'. 'include_dirs' is just a list of directory + names to be added to the header file search path (-I). Returns a list + of command-line options suitable for either Unix compilers or Visual + C++. + """ + # XXX it would be nice (mainly aesthetic, and so we don't generate + # stupid-looking command lines) to go over 'macros' and eliminate + # redundant definitions/undefinitions (ie. ensure that only the + # latest mention of a particular macro winds up on the command + # line). I don't think it's essential, though, since most (all?) + # Unix C compilers only pay attention to the latest -D or -U + # mention of a macro on their command line. Similar situation for + # 'include_dirs'. I'm punting on both for now. Anyways, weeding out + # redundancies like this should probably be the province of + # CCompiler, since the data structures used are inherited from it + # and therefore common to all CCompiler classes. + + pp_opts = [] + for macro in macros: + + if not (isinstance(macro, tuple) and + 1 <= len (macro) <= 2): + raise TypeError, \ + ("bad macro definition '%s': " + + "each element of 'macros' list must be a 1- or 2-tuple") % \ + macro + + if len (macro) == 1: # undefine this macro + pp_opts.append ("-U%s" % macro[0]) + elif len (macro) == 2: + if macro[1] is None: # define with no explicit value + pp_opts.append ("-D%s" % macro[0]) + else: + # XXX *don't* need to be clever about quoting the + # macro value here, because we're going to avoid the + # shell at all costs when we spawn the command! + pp_opts.append ("-D%s=%s" % macro) + + for dir in include_dirs: + pp_opts.append ("-I%s" % dir) + + return pp_opts + + +def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries): + """Generate linker options for searching library directories and + linking with specific libraries. + + 'libraries' and 'library_dirs' are, respectively, lists of library names + (not filenames!) and search directories. Returns a list of command-line + options suitable for use with some compiler (depending on the two format + strings passed in). + """ + lib_opts = [] + + for dir in library_dirs: + lib_opts.append(compiler.library_dir_option(dir)) + + for dir in runtime_library_dirs: + opt = compiler.runtime_library_dir_option(dir) + if isinstance(opt, list): + lib_opts.extend(opt) + else: + lib_opts.append(opt) + + # XXX it's important that we *not* remove redundant library mentions! + # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to + # resolve all symbols. I just hope we never have to say "-lfoo obj.o + # -lbar" to get things to work -- that's certainly a possibility, but a + # pretty nasty way to arrange your C code. + + for lib in libraries: + lib_dir, lib_name = os.path.split(lib) + if lib_dir != '': + lib_file = compiler.find_library_file([lib_dir], lib_name) + if lib_file is not None: + lib_opts.append(lib_file) + else: + compiler.warn("no library file corresponding to " + "'%s' found (skipping)" % lib) + else: + lib_opts.append(compiler.library_option(lib)) + + return lib_opts diff --git a/src/main/resources/PythonLibs/distutils/cmd.py b/src/main/resources/PythonLibs/distutils/cmd.py new file mode 100644 index 0000000000000000000000000000000000000000..9ad5657e40a59c081f70052f3fe43814f45cdd98 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/cmd.py @@ -0,0 +1,457 @@ +"""distutils.cmd + +Provides the Command class, the base class for the command classes +in the distutils.command package. +""" + +__revision__ = "$Id$" + +import sys, os, re +from distutils.errors import DistutilsOptionError +from distutils import util, dir_util, file_util, archive_util, dep_util +from distutils import log + +class Command: + """Abstract base class for defining command classes, the "worker bees" + of the Distutils. A useful analogy for command classes is to think of + them as subroutines with local variables called "options". The options + are "declared" in 'initialize_options()' and "defined" (given their + final values, aka "finalized") in 'finalize_options()', both of which + must be defined by every command class. The distinction between the + two is necessary because option values might come from the outside + world (command line, config file, ...), and any options dependent on + other options must be computed *after* these outside influences have + been processed -- hence 'finalize_options()'. The "body" of the + subroutine, where it does all its work based on the values of its + options, is the 'run()' method, which must also be implemented by every + command class. + """ + + # 'sub_commands' formalizes the notion of a "family" of commands, + # eg. "install" as the parent with sub-commands "install_lib", + # "install_headers", etc. The parent of a family of commands + # defines 'sub_commands' as a class attribute; it's a list of + # (command_name : string, predicate : unbound_method | string | None) + # tuples, where 'predicate' is a method of the parent command that + # determines whether the corresponding command is applicable in the + # current situation. (Eg. we "install_headers" is only applicable if + # we have any C header files to install.) If 'predicate' is None, + # that command is always applicable. + # + # 'sub_commands' is usually defined at the *end* of a class, because + # predicates can be unbound methods, so they must already have been + # defined. The canonical example is the "install" command. + sub_commands = [] + + + # -- Creation/initialization methods ------------------------------- + + def __init__(self, dist): + """Create and initialize a new Command object. Most importantly, + invokes the 'initialize_options()' method, which is the real + initializer and depends on the actual command being + instantiated. + """ + # late import because of mutual dependence between these classes + from distutils.dist import Distribution + + if not isinstance(dist, Distribution): + raise TypeError, "dist must be a Distribution instance" + if self.__class__ is Command: + raise RuntimeError, "Command is an abstract class" + + self.distribution = dist + self.initialize_options() + + # Per-command versions of the global flags, so that the user can + # customize Distutils' behaviour command-by-command and let some + # commands fall back on the Distribution's behaviour. None means + # "not defined, check self.distribution's copy", while 0 or 1 mean + # false and true (duh). Note that this means figuring out the real + # value of each flag is a touch complicated -- hence "self._dry_run" + # will be handled by __getattr__, below. + # XXX This needs to be fixed. + self._dry_run = None + + # verbose is largely ignored, but needs to be set for + # backwards compatibility (I think)? + self.verbose = dist.verbose + + # Some commands define a 'self.force' option to ignore file + # timestamps, but methods defined *here* assume that + # 'self.force' exists for all commands. So define it here + # just to be safe. + self.force = None + + # The 'help' flag is just used for command-line parsing, so + # none of that complicated bureaucracy is needed. + self.help = 0 + + # 'finalized' records whether or not 'finalize_options()' has been + # called. 'finalize_options()' itself should not pay attention to + # this flag: it is the business of 'ensure_finalized()', which + # always calls 'finalize_options()', to respect/update it. + self.finalized = 0 + + # XXX A more explicit way to customize dry_run would be better. + def __getattr__(self, attr): + if attr == 'dry_run': + myval = getattr(self, "_" + attr) + if myval is None: + return getattr(self.distribution, attr) + else: + return myval + else: + raise AttributeError, attr + + def ensure_finalized(self): + if not self.finalized: + self.finalize_options() + self.finalized = 1 + + # Subclasses must define: + # initialize_options() + # provide default values for all options; may be customized by + # setup script, by options from config file(s), or by command-line + # options + # finalize_options() + # decide on the final values for all options; this is called + # after all possible intervention from the outside world + # (command-line, option file, etc.) has been processed + # run() + # run the command: do whatever it is we're here to do, + # controlled by the command's various option values + + def initialize_options(self): + """Set default values for all the options that this command + supports. Note that these defaults may be overridden by other + commands, by the setup script, by config files, or by the + command-line. Thus, this is not the place to code dependencies + between options; generally, 'initialize_options()' implementations + are just a bunch of "self.foo = None" assignments. + + This method must be implemented by all command classes. + """ + raise RuntimeError, \ + "abstract method -- subclass %s must override" % self.__class__ + + def finalize_options(self): + """Set final values for all the options that this command supports. + This is always called as late as possible, ie. after any option + assignments from the command-line or from other commands have been + done. Thus, this is the place to code option dependencies: if + 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as + long as 'foo' still has the same value it was assigned in + 'initialize_options()'. + + This method must be implemented by all command classes. + """ + raise RuntimeError, \ + "abstract method -- subclass %s must override" % self.__class__ + + + def dump_options(self, header=None, indent=""): + from distutils.fancy_getopt import longopt_xlate + if header is None: + header = "command options for '%s':" % self.get_command_name() + self.announce(indent + header, level=log.INFO) + indent = indent + " " + for (option, _, _) in self.user_options: + option = option.translate(longopt_xlate) + if option[-1] == "=": + option = option[:-1] + value = getattr(self, option) + self.announce(indent + "%s = %s" % (option, value), + level=log.INFO) + + def run(self): + """A command's raison d'etre: carry out the action it exists to + perform, controlled by the options initialized in + 'initialize_options()', customized by other commands, the setup + script, the command-line, and config files, and finalized in + 'finalize_options()'. All terminal output and filesystem + interaction should be done by 'run()'. + + This method must be implemented by all command classes. + """ + raise RuntimeError, \ + "abstract method -- subclass %s must override" % self.__class__ + + def announce(self, msg, level=1): + """If the current verbosity level is of greater than or equal to + 'level' print 'msg' to stdout. + """ + log.log(level, msg) + + def debug_print(self, msg): + """Print 'msg' to stdout if the global DEBUG (taken from the + DISTUTILS_DEBUG environment variable) flag is true. + """ + from distutils.debug import DEBUG + if DEBUG: + print msg + sys.stdout.flush() + + + # -- Option validation methods ------------------------------------- + # (these are very handy in writing the 'finalize_options()' method) + # + # NB. the general philosophy here is to ensure that a particular option + # value meets certain type and value constraints. If not, we try to + # force it into conformance (eg. if we expect a list but have a string, + # split the string on comma and/or whitespace). If we can't force the + # option into conformance, raise DistutilsOptionError. Thus, command + # classes need do nothing more than (eg.) + # self.ensure_string_list('foo') + # and they can be guaranteed that thereafter, self.foo will be + # a list of strings. + + def _ensure_stringlike(self, option, what, default=None): + val = getattr(self, option) + if val is None: + setattr(self, option, default) + return default + elif not isinstance(val, str): + raise DistutilsOptionError, \ + "'%s' must be a %s (got `%s`)" % (option, what, val) + return val + + def ensure_string(self, option, default=None): + """Ensure that 'option' is a string; if not defined, set it to + 'default'. + """ + self._ensure_stringlike(option, "string", default) + + def ensure_string_list(self, option): + """Ensure that 'option' is a list of strings. If 'option' is + currently a string, we split it either on /,\s*/ or /\s+/, so + "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become + ["foo", "bar", "baz"]. + """ + val = getattr(self, option) + if val is None: + return + elif isinstance(val, str): + setattr(self, option, re.split(r',\s*|\s+', val)) + else: + if isinstance(val, list): + # checks if all elements are str + ok = 1 + for element in val: + if not isinstance(element, str): + ok = 0 + break + else: + ok = 0 + + if not ok: + raise DistutilsOptionError, \ + "'%s' must be a list of strings (got %r)" % \ + (option, val) + + + def _ensure_tested_string(self, option, tester, + what, error_fmt, default=None): + val = self._ensure_stringlike(option, what, default) + if val is not None and not tester(val): + raise DistutilsOptionError, \ + ("error in '%s' option: " + error_fmt) % (option, val) + + def ensure_filename(self, option): + """Ensure that 'option' is the name of an existing file.""" + self._ensure_tested_string(option, os.path.isfile, + "filename", + "'%s' does not exist or is not a file") + + def ensure_dirname(self, option): + self._ensure_tested_string(option, os.path.isdir, + "directory name", + "'%s' does not exist or is not a directory") + + + # -- Convenience methods for commands ------------------------------ + + def get_command_name(self): + if hasattr(self, 'command_name'): + return self.command_name + else: + return self.__class__.__name__ + + def set_undefined_options(self, src_cmd, *option_pairs): + """Set the values of any "undefined" options from corresponding + option values in some other command object. "Undefined" here means + "is None", which is the convention used to indicate that an option + has not been changed between 'initialize_options()' and + 'finalize_options()'. Usually called from 'finalize_options()' for + options that depend on some other command rather than another + option of the same command. 'src_cmd' is the other command from + which option values will be taken (a command object will be created + for it if necessary); the remaining arguments are + '(src_option,dst_option)' tuples which mean "take the value of + 'src_option' in the 'src_cmd' command object, and copy it to + 'dst_option' in the current command object". + """ + + # Option_pairs: list of (src_option, dst_option) tuples + + src_cmd_obj = self.distribution.get_command_obj(src_cmd) + src_cmd_obj.ensure_finalized() + for (src_option, dst_option) in option_pairs: + if getattr(self, dst_option) is None: + setattr(self, dst_option, + getattr(src_cmd_obj, src_option)) + + + def get_finalized_command(self, command, create=1): + """Wrapper around Distribution's 'get_command_obj()' method: find + (create if necessary and 'create' is true) the command object for + 'command', call its 'ensure_finalized()' method, and return the + finalized command object. + """ + cmd_obj = self.distribution.get_command_obj(command, create) + cmd_obj.ensure_finalized() + return cmd_obj + + # XXX rename to 'get_reinitialized_command()'? (should do the + # same in dist.py, if so) + def reinitialize_command(self, command, reinit_subcommands=0): + return self.distribution.reinitialize_command( + command, reinit_subcommands) + + def run_command(self, command): + """Run some other command: uses the 'run_command()' method of + Distribution, which creates and finalizes the command object if + necessary and then invokes its 'run()' method. + """ + self.distribution.run_command(command) + + def get_sub_commands(self): + """Determine the sub-commands that are relevant in the current + distribution (ie., that need to be run). This is based on the + 'sub_commands' class attribute: each tuple in that list may include + a method that we call to determine if the subcommand needs to be + run for the current distribution. Return a list of command names. + """ + commands = [] + for (cmd_name, method) in self.sub_commands: + if method is None or method(self): + commands.append(cmd_name) + return commands + + + # -- External world manipulation ----------------------------------- + + def warn(self, msg): + log.warn("warning: %s: %s\n" % + (self.get_command_name(), msg)) + + def execute(self, func, args, msg=None, level=1): + util.execute(func, args, msg, dry_run=self.dry_run) + + def mkpath(self, name, mode=0777): + dir_util.mkpath(name, mode, dry_run=self.dry_run) + + def copy_file(self, infile, outfile, + preserve_mode=1, preserve_times=1, link=None, level=1): + """Copy a file respecting verbose, dry-run and force flags. (The + former two default to whatever is in the Distribution object, and + the latter defaults to false for commands that don't define it.)""" + + return file_util.copy_file( + infile, outfile, + preserve_mode, preserve_times, + not self.force, + link, + dry_run=self.dry_run) + + def copy_tree(self, infile, outfile, + preserve_mode=1, preserve_times=1, preserve_symlinks=0, + level=1): + """Copy an entire directory tree respecting verbose, dry-run, + and force flags. + """ + return dir_util.copy_tree( + infile, outfile, + preserve_mode,preserve_times,preserve_symlinks, + not self.force, + dry_run=self.dry_run) + + def move_file (self, src, dst, level=1): + """Move a file respecting dry-run flag.""" + return file_util.move_file(src, dst, dry_run = self.dry_run) + + def spawn (self, cmd, search_path=1, level=1): + """Spawn an external command respecting dry-run flag.""" + from distutils.spawn import spawn + spawn(cmd, search_path, dry_run= self.dry_run) + + def make_archive(self, base_name, format, root_dir=None, base_dir=None, + owner=None, group=None): + return archive_util.make_archive(base_name, format, root_dir, + base_dir, dry_run=self.dry_run, + owner=owner, group=group) + + def make_file(self, infiles, outfile, func, args, + exec_msg=None, skip_msg=None, level=1): + """Special case of 'execute()' for operations that process one or + more input files and generate one output file. Works just like + 'execute()', except the operation is skipped and a different + message printed if 'outfile' already exists and is newer than all + files listed in 'infiles'. If the command defined 'self.force', + and it is true, then the command is unconditionally run -- does no + timestamp checks. + """ + if skip_msg is None: + skip_msg = "skipping %s (inputs unchanged)" % outfile + + # Allow 'infiles' to be a single string + if isinstance(infiles, str): + infiles = (infiles,) + elif not isinstance(infiles, (list, tuple)): + raise TypeError, \ + "'infiles' must be a string, or a list or tuple of strings" + + if exec_msg is None: + exec_msg = "generating %s from %s" % \ + (outfile, ', '.join(infiles)) + + # If 'outfile' must be regenerated (either because it doesn't + # exist, is out-of-date, or the 'force' flag is true) then + # perform the action that presumably regenerates it + if self.force or dep_util.newer_group(infiles, outfile): + self.execute(func, args, exec_msg, level) + + # Otherwise, print the "skip" message + else: + log.debug(skip_msg) + +# XXX 'install_misc' class not currently used -- it was the base class for +# both 'install_scripts' and 'install_data', but they outgrew it. It might +# still be useful for 'install_headers', though, so I'm keeping it around +# for the time being. + +class install_misc(Command): + """Common base class for installing some files in a subdirectory. + Currently used by install_data and install_scripts. + """ + + user_options = [('install-dir=', 'd', "directory to install the files to")] + + def initialize_options (self): + self.install_dir = None + self.outfiles = [] + + def _install_dir_from(self, dirname): + self.set_undefined_options('install', (dirname, 'install_dir')) + + def _copy_files(self, filelist): + self.outfiles = [] + if not filelist: + return + self.mkpath(self.install_dir) + for f in filelist: + self.copy_file(f, self.install_dir) + self.outfiles.append(os.path.join(self.install_dir, f)) + + def get_outputs(self): + return self.outfiles diff --git a/src/main/resources/PythonLibs/distutils/command/__init__.py b/src/main/resources/PythonLibs/distutils/command/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..20b159f74ecfc6a49498240066a77de4b0f3f5ce --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/__init__.py @@ -0,0 +1,33 @@ +"""distutils.command + +Package containing implementation of all the standard Distutils +commands.""" + +__revision__ = "$Id$" + +__all__ = ['build', + 'build_py', + 'build_ext', + 'build_clib', + 'build_scripts', + 'clean', + 'install', + 'install_lib', + 'install_headers', + 'install_scripts', + 'install_data', + 'sdist', + 'register', + 'bdist', + 'bdist_dumb', + 'bdist_rpm', + 'bdist_wininst', + 'upload', + 'check', + # These two are reserved for future use: + #'bdist_sdux', + #'bdist_pkgtool', + # Note: + # bdist_packager is not included because it only provides + # an abstract base class + ] diff --git a/src/main/resources/PythonLibs/distutils/command/bdist.py b/src/main/resources/PythonLibs/distutils/command/bdist.py new file mode 100644 index 0000000000000000000000000000000000000000..b23331032888691f4c722289974458948e5703f4 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/bdist.py @@ -0,0 +1,153 @@ +"""distutils.command.bdist + +Implements the Distutils 'bdist' command (create a built [binary] +distribution).""" + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id: bdist.py 62197 2008-04-07 01:53:39Z mark.hammond $" + +import os +from types import * +from distutils.core import Command +from distutils.errors import * +from distutils.util import get_platform + + +def show_formats (): + """Print list of available formats (arguments to "--format" option). + """ + from distutils.fancy_getopt import FancyGetopt + formats=[] + for format in bdist.format_commands: + formats.append(("formats=" + format, None, + bdist.format_command[format][1])) + pretty_printer = FancyGetopt(formats) + pretty_printer.print_help("List of available distribution formats:") + + +class bdist (Command): + + description = "create a built (binary) distribution" + + user_options = [('bdist-base=', 'b', + "temporary directory for creating built distributions"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform()), + ('formats=', None, + "formats for distribution (comma-separated list)"), + ('dist-dir=', 'd', + "directory to put final built distributions in " + "[default: dist]"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ] + + boolean_options = ['skip-build'] + + help_options = [ + ('help-formats', None, + "lists available distribution formats", show_formats), + ] + + # The following commands do not take a format option from bdist + no_format_option = ('bdist_rpm', + #'bdist_sdux', 'bdist_pkgtool' + ) + + # This won't do in reality: will need to distinguish RPM-ish Linux, + # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. + default_format = { 'posix': 'gztar', + 'java': 'gztar', + 'nt': 'zip', + 'os2': 'zip', } + + # Establish the preferred order (for the --help-formats option). + format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', + 'wininst', 'zip', + #'pkgtool', 'sdux' + ] + + # And the real information. + format_command = { 'rpm': ('bdist_rpm', "RPM distribution"), + 'zip': ('bdist_dumb', "ZIP file"), + 'gztar': ('bdist_dumb', "gzip'ed tar file"), + 'bztar': ('bdist_dumb', "bzip2'ed tar file"), + 'ztar': ('bdist_dumb', "compressed tar file"), + 'tar': ('bdist_dumb', "tar file"), + 'wininst': ('bdist_wininst', + "Windows executable installer"), + 'zip': ('bdist_dumb', "ZIP file"), + #'pkgtool': ('bdist_pkgtool', + # "Solaris pkgtool distribution"), + #'sdux': ('bdist_sdux', "HP-UX swinstall depot"), + } + + + def initialize_options (self): + self.bdist_base = None + self.plat_name = None + self.formats = None + self.dist_dir = None + self.skip_build = 0 + + # initialize_options() + + + def finalize_options (self): + # have to finalize 'plat_name' before 'bdist_base' + if self.plat_name is None: + if self.skip_build: + self.plat_name = get_platform() + else: + self.plat_name = self.get_finalized_command('build').plat_name + + # 'bdist_base' -- parent of per-built-distribution-format + # temporary directories (eg. we'll probably have + # "build/bdist.<plat>/dumb", "build/bdist.<plat>/rpm", etc.) + if self.bdist_base is None: + build_base = self.get_finalized_command('build').build_base + self.bdist_base = os.path.join(build_base, + 'bdist.' + self.plat_name) + + self.ensure_string_list('formats') + if self.formats is None: + try: + self.formats = [self.default_format[os.name]] + except KeyError: + raise DistutilsPlatformError, \ + "don't know how to create built distributions " + \ + "on platform %s" % os.name + + if self.dist_dir is None: + self.dist_dir = "dist" + + # finalize_options() + + def run (self): + + # Figure out which sub-commands we need to run. + commands = [] + for format in self.formats: + try: + commands.append(self.format_command[format][0]) + except KeyError: + raise DistutilsOptionError, "invalid format '%s'" % format + + # Reinitialize and run each command. + for i in range(len(self.formats)): + cmd_name = commands[i] + sub_cmd = self.reinitialize_command(cmd_name) + if cmd_name not in self.no_format_option: + sub_cmd.format = self.formats[i] + + # If we're going to need to run this command again, tell it to + # keep its temporary files around so subsequent runs go faster. + if cmd_name in commands[i+1:]: + sub_cmd.keep_temp = 1 + self.run_command(cmd_name) + + # run() + +# class bdist diff --git a/src/main/resources/PythonLibs/distutils/command/bdist_dumb.py b/src/main/resources/PythonLibs/distutils/command/bdist_dumb.py new file mode 100644 index 0000000000000000000000000000000000000000..7a2540465d6940123701e024c53b0c4bbaf544d1 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/bdist_dumb.py @@ -0,0 +1,133 @@ +"""distutils.command.bdist_dumb + +Implements the Distutils 'bdist_dumb' command (create a "dumb" built +distribution -- i.e., just an archive to be unpacked under $prefix or +$exec_prefix).""" + +__revision__ = "$Id: bdist_dumb.py 77761 2010-01-26 22:46:15Z tarek.ziade $" + +import os + +from sysconfig import get_python_version + +from distutils.util import get_platform +from distutils.core import Command +from distutils.dir_util import remove_tree, ensure_relative +from distutils.errors import DistutilsPlatformError +from distutils import log + +class bdist_dumb (Command): + + description = 'create a "dumb" built distribution' + + user_options = [('bdist-dir=', 'd', + "temporary directory for creating the distribution"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform()), + ('format=', 'f', + "archive format to create (tar, ztar, gztar, zip)"), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('relative', None, + "build the archive using relative paths" + "(default: false)"), + ('owner=', 'u', + "Owner name used when creating a tar file" + " [default: current user]"), + ('group=', 'g', + "Group name used when creating a tar file" + " [default: current group]"), + ] + + boolean_options = ['keep-temp', 'skip-build', 'relative'] + + default_format = { 'posix': 'gztar', + 'java': 'gztar', + 'nt': 'zip', + 'os2': 'zip' } + + + def initialize_options (self): + self.bdist_dir = None + self.plat_name = None + self.format = None + self.keep_temp = 0 + self.dist_dir = None + self.skip_build = 0 + self.relative = 0 + self.owner = None + self.group = None + + def finalize_options(self): + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'dumb') + + if self.format is None: + try: + self.format = self.default_format[os.name] + except KeyError: + raise DistutilsPlatformError, \ + ("don't know how to create dumb built distributions " + + "on platform %s") % os.name + + self.set_undefined_options('bdist', + ('dist_dir', 'dist_dir'), + ('plat_name', 'plat_name')) + + def run(self): + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', reinit_subcommands=1) + install.root = self.bdist_dir + install.skip_build = self.skip_build + install.warn_dir = 0 + + log.info("installing to %s" % self.bdist_dir) + self.run_command('install') + + # And make an archive relative to the root of the + # pseudo-installation tree. + archive_basename = "%s.%s" % (self.distribution.get_fullname(), + self.plat_name) + + # OS/2 objects to any ":" characters in a filename (such as when + # a timestamp is used in a version) so change them to hyphens. + if os.name == "os2": + archive_basename = archive_basename.replace(":", "-") + + pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) + if not self.relative: + archive_root = self.bdist_dir + else: + if (self.distribution.has_ext_modules() and + (install.install_base != install.install_platbase)): + raise DistutilsPlatformError, \ + ("can't make a dumb built distribution where " + "base and platbase are different (%s, %s)" + % (repr(install.install_base), + repr(install.install_platbase))) + else: + archive_root = os.path.join(self.bdist_dir, + ensure_relative(install.install_base)) + + # Make the archive + filename = self.make_archive(pseudoinstall_root, + self.format, root_dir=archive_root, + owner=self.owner, group=self.group) + if self.distribution.has_ext_modules(): + pyversion = get_python_version() + else: + pyversion = 'any' + self.distribution.dist_files.append(('bdist_dumb', pyversion, + filename)) + + if not self.keep_temp: + remove_tree(self.bdist_dir, dry_run=self.dry_run) diff --git a/src/main/resources/PythonLibs/distutils/command/bdist_msi.py b/src/main/resources/PythonLibs/distutils/command/bdist_msi.py new file mode 100644 index 0000000000000000000000000000000000000000..703f873b164e895988ef100de8561ed7dd7e6f41 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/bdist_msi.py @@ -0,0 +1,742 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2005, 2006 Martin von Löwis +# Licensed to PSF under a Contributor Agreement. +# The bdist_wininst command proper +# based on bdist_wininst +""" +Implements the bdist_msi command. +""" +import sys, os +from sysconfig import get_python_version + +from distutils.core import Command +from distutils.dir_util import remove_tree +from distutils.version import StrictVersion +from distutils.errors import DistutilsOptionError +from distutils import log +from distutils.util import get_platform + +import msilib +from msilib import schema, sequence, text +from msilib import Directory, Feature, Dialog, add_data + +class PyDialog(Dialog): + """Dialog class with a fixed layout: controls at the top, then a ruler, + then a list of buttons: back, next, cancel. Optionally a bitmap at the + left.""" + def __init__(self, *args, **kw): + """Dialog(database, name, x, y, w, h, attributes, title, first, + default, cancel, bitmap=true)""" + Dialog.__init__(self, *args) + ruler = self.h - 36 + #if kw.get("bitmap", True): + # self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin") + self.line("BottomLine", 0, ruler, self.w, 0) + + def title(self, title): + "Set the title text of the dialog at the top." + # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix, + # text, in VerdanaBold10 + self.text("Title", 15, 10, 320, 60, 0x30003, + r"{\VerdanaBold10}%s" % title) + + def back(self, title, next, name = "Back", active = 1): + """Add a back button with a given title, the tab-next button, + its name in the Control table, possibly initially disabled. + + Return the button, so that events can be associated""" + if active: + flags = 3 # Visible|Enabled + else: + flags = 1 # Visible + return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next) + + def cancel(self, title, next, name = "Cancel", active = 1): + """Add a cancel button with a given title, the tab-next button, + its name in the Control table, possibly initially disabled. + + Return the button, so that events can be associated""" + if active: + flags = 3 # Visible|Enabled + else: + flags = 1 # Visible + return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next) + + def next(self, title, next, name = "Next", active = 1): + """Add a Next button with a given title, the tab-next button, + its name in the Control table, possibly initially disabled. + + Return the button, so that events can be associated""" + if active: + flags = 3 # Visible|Enabled + else: + flags = 1 # Visible + return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next) + + def xbutton(self, name, title, next, xpos): + """Add a button with a given title, the tab-next button, + its name in the Control table, giving its x position; the + y-position is aligned with the other buttons. + + Return the button, so that events can be associated""" + return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next) + +class bdist_msi (Command): + + description = "create a Microsoft Installer (.msi) binary distribution" + + user_options = [('bdist-dir=', None, + "temporary directory for creating the distribution"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform()), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('target-version=', None, + "require a specific python version" + + " on the target system"), + ('no-target-compile', 'c', + "do not compile .py to .pyc on the target system"), + ('no-target-optimize', 'o', + "do not compile .py to .pyo (optimized)" + "on the target system"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('install-script=', None, + "basename of installation script to be run after" + "installation or before deinstallation"), + ('pre-install-script=', None, + "Fully qualified filename of a script to be run before " + "any files are installed. This script need not be in the " + "distribution"), + ] + + boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', + 'skip-build'] + + all_versions = ['2.0', '2.1', '2.2', '2.3', '2.4', + '2.5', '2.6', '2.7', '2.8', '2.9', + '3.0', '3.1', '3.2', '3.3', '3.4', + '3.5', '3.6', '3.7', '3.8', '3.9'] + other_version = 'X' + + def initialize_options (self): + self.bdist_dir = None + self.plat_name = None + self.keep_temp = 0 + self.no_target_compile = 0 + self.no_target_optimize = 0 + self.target_version = None + self.dist_dir = None + self.skip_build = None + self.install_script = None + self.pre_install_script = None + self.versions = None + + def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'msi') + + short_version = get_python_version() + if (not self.target_version) and self.distribution.has_ext_modules(): + self.target_version = short_version + + if self.target_version: + self.versions = [self.target_version] + if not self.skip_build and self.distribution.has_ext_modules()\ + and self.target_version != short_version: + raise DistutilsOptionError, \ + "target version can only be %s, or the '--skip-build'" \ + " option must be specified" % (short_version,) + else: + self.versions = list(self.all_versions) + + self.set_undefined_options('bdist', + ('dist_dir', 'dist_dir'), + ('plat_name', 'plat_name'), + ) + + if self.pre_install_script: + raise DistutilsOptionError, "the pre-install-script feature is not yet implemented" + + if self.install_script: + for script in self.distribution.scripts: + if self.install_script == os.path.basename(script): + break + else: + raise DistutilsOptionError, \ + "install_script '%s' not found in scripts" % \ + self.install_script + self.install_script_key = None + # finalize_options() + + + def run (self): + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', reinit_subcommands=1) + install.prefix = self.bdist_dir + install.skip_build = self.skip_build + install.warn_dir = 0 + + install_lib = self.reinitialize_command('install_lib') + # we do not want to include pyc or pyo files + install_lib.compile = 0 + install_lib.optimize = 0 + + if self.distribution.has_ext_modules(): + # If we are building an installer for a Python version other + # than the one we are currently running, then we need to ensure + # our build_lib reflects the other Python version rather than ours. + # Note that for target_version!=sys.version, we must have skipped the + # build step, so there is no issue with enforcing the build of this + # version. + target_version = self.target_version + if not target_version: + assert self.skip_build, "Should have already checked this" + target_version = sys.version[0:3] + plat_specifier = ".%s-%s" % (self.plat_name, target_version) + build = self.get_finalized_command('build') + build.build_lib = os.path.join(build.build_base, + 'lib' + plat_specifier) + + log.info("installing to %s", self.bdist_dir) + install.ensure_finalized() + + # avoid warning of 'install_lib' about installing + # into a directory not in sys.path + sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) + + install.run() + + del sys.path[0] + + self.mkpath(self.dist_dir) + fullname = self.distribution.get_fullname() + installer_name = self.get_installer_filename(fullname) + installer_name = os.path.abspath(installer_name) + if os.path.exists(installer_name): os.unlink(installer_name) + + metadata = self.distribution.metadata + author = metadata.author + if not author: + author = metadata.maintainer + if not author: + author = "UNKNOWN" + version = metadata.get_version() + # ProductVersion must be strictly numeric + # XXX need to deal with prerelease versions + sversion = "%d.%d.%d" % StrictVersion(version).version + # Prefix ProductName with Python x.y, so that + # it sorts together with the other Python packages + # in Add-Remove-Programs (APR) + fullname = self.distribution.get_fullname() + if self.target_version: + product_name = "Python %s %s" % (self.target_version, fullname) + else: + product_name = "Python %s" % (fullname) + self.db = msilib.init_database(installer_name, schema, + product_name, msilib.gen_uuid(), + sversion, author) + msilib.add_tables(self.db, sequence) + props = [('DistVersion', version)] + email = metadata.author_email or metadata.maintainer_email + if email: + props.append(("ARPCONTACT", email)) + if metadata.url: + props.append(("ARPURLINFOABOUT", metadata.url)) + if props: + add_data(self.db, 'Property', props) + + self.add_find_python() + self.add_files() + self.add_scripts() + self.add_ui() + self.db.Commit() + + if hasattr(self.distribution, 'dist_files'): + tup = 'bdist_msi', self.target_version or 'any', fullname + self.distribution.dist_files.append(tup) + + if not self.keep_temp: + remove_tree(self.bdist_dir, dry_run=self.dry_run) + + def add_files(self): + db = self.db + cab = msilib.CAB("distfiles") + rootdir = os.path.abspath(self.bdist_dir) + + root = Directory(db, cab, None, rootdir, "TARGETDIR", "SourceDir") + f = Feature(db, "Python", "Python", "Everything", + 0, 1, directory="TARGETDIR") + + items = [(f, root, '')] + for version in self.versions + [self.other_version]: + target = "TARGETDIR" + version + name = default = "Python" + version + desc = "Everything" + if version is self.other_version: + title = "Python from another location" + level = 2 + else: + title = "Python %s from registry" % version + level = 1 + f = Feature(db, name, title, desc, 1, level, directory=target) + dir = Directory(db, cab, root, rootdir, target, default) + items.append((f, dir, version)) + db.Commit() + + seen = {} + for feature, dir, version in items: + todo = [dir] + while todo: + dir = todo.pop() + for file in os.listdir(dir.absolute): + afile = os.path.join(dir.absolute, file) + if os.path.isdir(afile): + short = "%s|%s" % (dir.make_short(file), file) + default = file + version + newdir = Directory(db, cab, dir, file, default, short) + todo.append(newdir) + else: + if not dir.component: + dir.start_component(dir.logical, feature, 0) + if afile not in seen: + key = seen[afile] = dir.add_file(file) + if file==self.install_script: + if self.install_script_key: + raise DistutilsOptionError( + "Multiple files with name %s" % file) + self.install_script_key = '[#%s]' % key + else: + key = seen[afile] + add_data(self.db, "DuplicateFile", + [(key + version, dir.component, key, None, dir.logical)]) + db.Commit() + cab.commit(db) + + def add_find_python(self): + """Adds code to the installer to compute the location of Python. + + Properties PYTHON.MACHINE.X.Y and PYTHON.USER.X.Y will be set from the + registry for each version of Python. + + Properties TARGETDIRX.Y will be set from PYTHON.USER.X.Y if defined, + else from PYTHON.MACHINE.X.Y. + + Properties PYTHONX.Y will be set to TARGETDIRX.Y\\python.exe""" + + start = 402 + for ver in self.versions: + install_path = r"SOFTWARE\Python\PythonCore\%s\InstallPath" % ver + machine_reg = "python.machine." + ver + user_reg = "python.user." + ver + machine_prop = "PYTHON.MACHINE." + ver + user_prop = "PYTHON.USER." + ver + machine_action = "PythonFromMachine" + ver + user_action = "PythonFromUser" + ver + exe_action = "PythonExe" + ver + target_dir_prop = "TARGETDIR" + ver + exe_prop = "PYTHON" + ver + if msilib.Win64: + # type: msidbLocatorTypeRawValue + msidbLocatorType64bit + Type = 2+16 + else: + Type = 2 + add_data(self.db, "RegLocator", + [(machine_reg, 2, install_path, None, Type), + (user_reg, 1, install_path, None, Type)]) + add_data(self.db, "AppSearch", + [(machine_prop, machine_reg), + (user_prop, user_reg)]) + add_data(self.db, "CustomAction", + [(machine_action, 51+256, target_dir_prop, "[" + machine_prop + "]"), + (user_action, 51+256, target_dir_prop, "[" + user_prop + "]"), + (exe_action, 51+256, exe_prop, "[" + target_dir_prop + "]\\python.exe"), + ]) + add_data(self.db, "InstallExecuteSequence", + [(machine_action, machine_prop, start), + (user_action, user_prop, start + 1), + (exe_action, None, start + 2), + ]) + add_data(self.db, "InstallUISequence", + [(machine_action, machine_prop, start), + (user_action, user_prop, start + 1), + (exe_action, None, start + 2), + ]) + add_data(self.db, "Condition", + [("Python" + ver, 0, "NOT TARGETDIR" + ver)]) + start += 4 + assert start < 500 + + def add_scripts(self): + if self.install_script: + start = 6800 + for ver in self.versions + [self.other_version]: + install_action = "install_script." + ver + exe_prop = "PYTHON" + ver + add_data(self.db, "CustomAction", + [(install_action, 50, exe_prop, self.install_script_key)]) + add_data(self.db, "InstallExecuteSequence", + [(install_action, "&Python%s=3" % ver, start)]) + start += 1 + # XXX pre-install scripts are currently refused in finalize_options() + # but if this feature is completed, it will also need to add + # entries for each version as the above code does + if self.pre_install_script: + scriptfn = os.path.join(self.bdist_dir, "preinstall.bat") + f = open(scriptfn, "w") + # The batch file will be executed with [PYTHON], so that %1 + # is the path to the Python interpreter; %0 will be the path + # of the batch file. + # rem =""" + # %1 %0 + # exit + # """ + # <actual script> + f.write('rem ="""\n%1 %0\nexit\n"""\n') + f.write(open(self.pre_install_script).read()) + f.close() + add_data(self.db, "Binary", + [("PreInstall", msilib.Binary(scriptfn)) + ]) + add_data(self.db, "CustomAction", + [("PreInstall", 2, "PreInstall", None) + ]) + add_data(self.db, "InstallExecuteSequence", + [("PreInstall", "NOT Installed", 450)]) + + + def add_ui(self): + db = self.db + x = y = 50 + w = 370 + h = 300 + title = "[ProductName] Setup" + + # see "Dialog Style Bits" + modal = 3 # visible | modal + modeless = 1 # visible + + # UI customization properties + add_data(db, "Property", + # See "DefaultUIFont Property" + [("DefaultUIFont", "DlgFont8"), + # See "ErrorDialog Style Bit" + ("ErrorDialog", "ErrorDlg"), + ("Progress1", "Install"), # modified in maintenance type dlg + ("Progress2", "installs"), + ("MaintenanceForm_Action", "Repair"), + # possible values: ALL, JUSTME + ("WhichUsers", "ALL") + ]) + + # Fonts, see "TextStyle Table" + add_data(db, "TextStyle", + [("DlgFont8", "Tahoma", 9, None, 0), + ("DlgFontBold8", "Tahoma", 8, None, 1), #bold + ("VerdanaBold10", "Verdana", 10, None, 1), + ("VerdanaRed9", "Verdana", 9, 255, 0), + ]) + + # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table" + # Numbers indicate sequence; see sequence.py for how these action integrate + add_data(db, "InstallUISequence", + [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140), + ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141), + # In the user interface, assume all-users installation if privileged. + ("SelectFeaturesDlg", "Not Installed", 1230), + # XXX no support for resume installations yet + #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240), + ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250), + ("ProgressDlg", None, 1280)]) + + add_data(db, 'ActionText', text.ActionText) + add_data(db, 'UIText', text.UIText) + ##################################################################### + # Standard dialogs: FatalError, UserExit, ExitDialog + fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title, + "Finish", "Finish", "Finish") + fatal.title("[ProductName] Installer ended prematurely") + fatal.back("< Back", "Finish", active = 0) + fatal.cancel("Cancel", "Back", active = 0) + fatal.text("Description1", 15, 70, 320, 80, 0x30003, + "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.") + fatal.text("Description2", 15, 155, 320, 20, 0x30003, + "Click the Finish button to exit the Installer.") + c=fatal.next("Finish", "Cancel", name="Finish") + c.event("EndDialog", "Exit") + + user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title, + "Finish", "Finish", "Finish") + user_exit.title("[ProductName] Installer was interrupted") + user_exit.back("< Back", "Finish", active = 0) + user_exit.cancel("Cancel", "Back", active = 0) + user_exit.text("Description1", 15, 70, 320, 80, 0x30003, + "[ProductName] setup was interrupted. Your system has not been modified. " + "To install this program at a later time, please run the installation again.") + user_exit.text("Description2", 15, 155, 320, 20, 0x30003, + "Click the Finish button to exit the Installer.") + c = user_exit.next("Finish", "Cancel", name="Finish") + c.event("EndDialog", "Exit") + + exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title, + "Finish", "Finish", "Finish") + exit_dialog.title("Completing the [ProductName] Installer") + exit_dialog.back("< Back", "Finish", active = 0) + exit_dialog.cancel("Cancel", "Back", active = 0) + exit_dialog.text("Description", 15, 235, 320, 20, 0x30003, + "Click the Finish button to exit the Installer.") + c = exit_dialog.next("Finish", "Cancel", name="Finish") + c.event("EndDialog", "Return") + + ##################################################################### + # Required dialog: FilesInUse, ErrorDlg + inuse = PyDialog(db, "FilesInUse", + x, y, w, h, + 19, # KeepModeless|Modal|Visible + title, + "Retry", "Retry", "Retry", bitmap=False) + inuse.text("Title", 15, 6, 200, 15, 0x30003, + r"{\DlgFontBold8}Files in Use") + inuse.text("Description", 20, 23, 280, 20, 0x30003, + "Some files that need to be updated are currently in use.") + inuse.text("Text", 20, 55, 330, 50, 3, + "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.") + inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess", + None, None, None) + c=inuse.back("Exit", "Ignore", name="Exit") + c.event("EndDialog", "Exit") + c=inuse.next("Ignore", "Retry", name="Ignore") + c.event("EndDialog", "Ignore") + c=inuse.cancel("Retry", "Exit", name="Retry") + c.event("EndDialog","Retry") + + # See "Error Dialog". See "ICE20" for the required names of the controls. + error = Dialog(db, "ErrorDlg", + 50, 10, 330, 101, + 65543, # Error|Minimize|Modal|Visible + title, + "ErrorText", None, None) + error.text("ErrorText", 50,9,280,48,3, "") + #error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None) + error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo") + error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes") + error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort") + error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel") + error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore") + error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk") + error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry") + + ##################################################################### + # Global "Query Cancel" dialog + cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title, + "No", "No", "No") + cancel.text("Text", 48, 15, 194, 30, 3, + "Are you sure you want to cancel [ProductName] installation?") + #cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None, + # "py.ico", None, None) + c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No") + c.event("EndDialog", "Exit") + + c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes") + c.event("EndDialog", "Return") + + ##################################################################### + # Global "Wait for costing" dialog + costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title, + "Return", "Return", "Return") + costing.text("Text", 48, 15, 194, 30, 3, + "Please wait while the installer finishes determining your disk space requirements.") + c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None) + c.event("EndDialog", "Exit") + + ##################################################################### + # Preparation dialog: no user input except cancellation + prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title, + "Cancel", "Cancel", "Cancel") + prep.text("Description", 15, 70, 320, 40, 0x30003, + "Please wait while the Installer prepares to guide you through the installation.") + prep.title("Welcome to the [ProductName] Installer") + c=prep.text("ActionText", 15, 110, 320, 20, 0x30003, "Pondering...") + c.mapping("ActionText", "Text") + c=prep.text("ActionData", 15, 135, 320, 30, 0x30003, None) + c.mapping("ActionData", "Text") + prep.back("Back", None, active=0) + prep.next("Next", None, active=0) + c=prep.cancel("Cancel", None) + c.event("SpawnDialog", "CancelDlg") + + ##################################################################### + # Feature (Python directory) selection + seldlg = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal, title, + "Next", "Next", "Cancel") + seldlg.title("Select Python Installations") + + seldlg.text("Hint", 15, 30, 300, 20, 3, + "Select the Python locations where %s should be installed." + % self.distribution.get_fullname()) + + seldlg.back("< Back", None, active=0) + c = seldlg.next("Next >", "Cancel") + order = 1 + c.event("[TARGETDIR]", "[SourceDir]", ordering=order) + for version in self.versions + [self.other_version]: + order += 1 + c.event("[TARGETDIR]", "[TARGETDIR%s]" % version, + "FEATURE_SELECTED AND &Python%s=3" % version, + ordering=order) + c.event("SpawnWaitDialog", "WaitForCostingDlg", ordering=order + 1) + c.event("EndDialog", "Return", ordering=order + 2) + c = seldlg.cancel("Cancel", "Features") + c.event("SpawnDialog", "CancelDlg") + + c = seldlg.control("Features", "SelectionTree", 15, 60, 300, 120, 3, + "FEATURE", None, "PathEdit", None) + c.event("[FEATURE_SELECTED]", "1") + ver = self.other_version + install_other_cond = "FEATURE_SELECTED AND &Python%s=3" % ver + dont_install_other_cond = "FEATURE_SELECTED AND &Python%s<>3" % ver + + c = seldlg.text("Other", 15, 200, 300, 15, 3, + "Provide an alternate Python location") + c.condition("Enable", install_other_cond) + c.condition("Show", install_other_cond) + c.condition("Disable", dont_install_other_cond) + c.condition("Hide", dont_install_other_cond) + + c = seldlg.control("PathEdit", "PathEdit", 15, 215, 300, 16, 1, + "TARGETDIR" + ver, None, "Next", None) + c.condition("Enable", install_other_cond) + c.condition("Show", install_other_cond) + c.condition("Disable", dont_install_other_cond) + c.condition("Hide", dont_install_other_cond) + + ##################################################################### + # Disk cost + cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title, + "OK", "OK", "OK", bitmap=False) + cost.text("Title", 15, 6, 200, 15, 0x30003, + "{\DlgFontBold8}Disk Space Requirements") + cost.text("Description", 20, 20, 280, 20, 0x30003, + "The disk space required for the installation of the selected features.") + cost.text("Text", 20, 53, 330, 60, 3, + "The highlighted volumes (if any) do not have enough disk space " + "available for the currently selected features. You can either " + "remove some files from the highlighted volumes, or choose to " + "install less features onto local drive(s), or select different " + "destination drive(s).") + cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223, + None, "{120}{70}{70}{70}{70}", None, None) + cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return") + + ##################################################################### + # WhichUsers Dialog. Only available on NT, and for privileged users. + # This must be run before FindRelatedProducts, because that will + # take into account whether the previous installation was per-user + # or per-machine. We currently don't support going back to this + # dialog after "Next" was selected; to support this, we would need to + # find how to reset the ALLUSERS property, and how to re-run + # FindRelatedProducts. + # On Windows9x, the ALLUSERS property is ignored on the command line + # and in the Property table, but installer fails according to the documentation + # if a dialog attempts to set ALLUSERS. + whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title, + "AdminInstall", "Next", "Cancel") + whichusers.title("Select whether to install [ProductName] for all users of this computer.") + # A radio group with two options: allusers, justme + g = whichusers.radiogroup("AdminInstall", 15, 60, 260, 50, 3, + "WhichUsers", "", "Next") + g.add("ALL", 0, 5, 150, 20, "Install for all users") + g.add("JUSTME", 0, 25, 150, 20, "Install just for me") + + whichusers.back("Back", None, active=0) + + c = whichusers.next("Next >", "Cancel") + c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1) + c.event("EndDialog", "Return", ordering = 2) + + c = whichusers.cancel("Cancel", "AdminInstall") + c.event("SpawnDialog", "CancelDlg") + + ##################################################################### + # Installation Progress dialog (modeless) + progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title, + "Cancel", "Cancel", "Cancel", bitmap=False) + progress.text("Title", 20, 15, 200, 15, 0x30003, + "{\DlgFontBold8}[Progress1] [ProductName]") + progress.text("Text", 35, 65, 300, 30, 3, + "Please wait while the Installer [Progress2] [ProductName]. " + "This may take several minutes.") + progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:") + + c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...") + c.mapping("ActionText", "Text") + + #c=progress.text("ActionData", 35, 140, 300, 20, 3, None) + #c.mapping("ActionData", "Text") + + c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537, + None, "Progress done", None, None) + c.mapping("SetProgress", "Progress") + + progress.back("< Back", "Next", active=False) + progress.next("Next >", "Cancel", active=False) + progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg") + + ################################################################### + # Maintenance type: repair/uninstall + maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title, + "Next", "Next", "Cancel") + maint.title("Welcome to the [ProductName] Setup Wizard") + maint.text("BodyText", 15, 63, 330, 42, 3, + "Select whether you want to repair or remove [ProductName].") + g=maint.radiogroup("RepairRadioGroup", 15, 108, 330, 60, 3, + "MaintenanceForm_Action", "", "Next") + #g.add("Change", 0, 0, 200, 17, "&Change [ProductName]") + g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]") + g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]") + + maint.back("< Back", None, active=False) + c=maint.next("Finish", "Cancel") + # Change installation: Change progress dialog to "Change", then ask + # for feature selection + #c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1) + #c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2) + + # Reinstall: Change progress dialog to "Repair", then invoke reinstall + # Also set list of reinstalled features to "ALL" + c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5) + c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6) + c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7) + c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8) + + # Uninstall: Change progress to "Remove", then invoke uninstall + # Also set list of removed features to "ALL" + c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11) + c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12) + c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13) + c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14) + + # Close dialog when maintenance action scheduled + c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20) + #c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21) + + maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg") + + def get_installer_filename(self, fullname): + # Factored out to allow overriding in subclasses + if self.target_version: + base_name = "%s.%s-py%s.msi" % (fullname, self.plat_name, + self.target_version) + else: + base_name = "%s.%s.msi" % (fullname, self.plat_name) + installer_name = os.path.join(self.dist_dir, base_name) + return installer_name diff --git a/src/main/resources/PythonLibs/distutils/command/bdist_rpm.py b/src/main/resources/PythonLibs/distutils/command/bdist_rpm.py new file mode 100644 index 0000000000000000000000000000000000000000..595824367e336769b109e1546baf481a92e55186 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/bdist_rpm.py @@ -0,0 +1,587 @@ +"""distutils.command.bdist_rpm + +Implements the Distutils 'bdist_rpm' command (create RPM source and binary +distributions).""" + +__revision__ = "$Id$" + +import sys +import os +import string + +from distutils.core import Command +from distutils.debug import DEBUG +from distutils.file_util import write_file +from distutils.errors import (DistutilsOptionError, DistutilsPlatformError, + DistutilsFileError, DistutilsExecError) +from distutils import log + +class bdist_rpm (Command): + + description = "create an RPM distribution" + + user_options = [ + ('bdist-base=', None, + "base directory for creating built distributions"), + ('rpm-base=', None, + "base directory for creating RPMs (defaults to \"rpm\" under " + "--bdist-base; must be specified for RPM 2)"), + ('dist-dir=', 'd', + "directory to put final RPM files in " + "(and .spec files if --spec-only)"), + ('python=', None, + "path to Python interpreter to hard-code in the .spec file " + "(default: \"python\")"), + ('fix-python', None, + "hard-code the exact path to the current Python interpreter in " + "the .spec file"), + ('spec-only', None, + "only regenerate spec file"), + ('source-only', None, + "only generate source RPM"), + ('binary-only', None, + "only generate binary RPM"), + ('use-bzip2', None, + "use bzip2 instead of gzip to create source distribution"), + + # More meta-data: too RPM-specific to put in the setup script, + # but needs to go in the .spec file -- so we make these options + # to "bdist_rpm". The idea is that packagers would put this + # info in setup.cfg, although they are of course free to + # supply it on the command line. + ('distribution-name=', None, + "name of the (Linux) distribution to which this " + "RPM applies (*not* the name of the module distribution!)"), + ('group=', None, + "package classification [default: \"Development/Libraries\"]"), + ('release=', None, + "RPM release number"), + ('serial=', None, + "RPM serial number"), + ('vendor=', None, + "RPM \"vendor\" (eg. \"Joe Blow <joe@example.com>\") " + "[default: maintainer or author from setup script]"), + ('packager=', None, + "RPM packager (eg. \"Jane Doe <jane@example.net>\")" + "[default: vendor]"), + ('doc-files=', None, + "list of documentation files (space or comma-separated)"), + ('changelog=', None, + "RPM changelog"), + ('icon=', None, + "name of icon file"), + ('provides=', None, + "capabilities provided by this package"), + ('requires=', None, + "capabilities required by this package"), + ('conflicts=', None, + "capabilities which conflict with this package"), + ('build-requires=', None, + "capabilities required to build this package"), + ('obsoletes=', None, + "capabilities made obsolete by this package"), + ('no-autoreq', None, + "do not automatically calculate dependencies"), + + # Actions to take when building RPM + ('keep-temp', 'k', + "don't clean up RPM build directory"), + ('no-keep-temp', None, + "clean up RPM build directory [default]"), + ('use-rpm-opt-flags', None, + "compile with RPM_OPT_FLAGS when building from source RPM"), + ('no-rpm-opt-flags', None, + "do not pass any RPM CFLAGS to compiler"), + ('rpm3-mode', None, + "RPM 3 compatibility mode (default)"), + ('rpm2-mode', None, + "RPM 2 compatibility mode"), + + # Add the hooks necessary for specifying custom scripts + ('prep-script=', None, + "Specify a script for the PREP phase of RPM building"), + ('build-script=', None, + "Specify a script for the BUILD phase of RPM building"), + + ('pre-install=', None, + "Specify a script for the pre-INSTALL phase of RPM building"), + ('install-script=', None, + "Specify a script for the INSTALL phase of RPM building"), + ('post-install=', None, + "Specify a script for the post-INSTALL phase of RPM building"), + + ('pre-uninstall=', None, + "Specify a script for the pre-UNINSTALL phase of RPM building"), + ('post-uninstall=', None, + "Specify a script for the post-UNINSTALL phase of RPM building"), + + ('clean-script=', None, + "Specify a script for the CLEAN phase of RPM building"), + + ('verify-script=', None, + "Specify a script for the VERIFY phase of the RPM build"), + + # Allow a packager to explicitly force an architecture + ('force-arch=', None, + "Force an architecture onto the RPM build process"), + + ('quiet', 'q', + "Run the INSTALL phase of RPM building in quiet mode"), + ] + + boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode', + 'no-autoreq', 'quiet'] + + negative_opt = {'no-keep-temp': 'keep-temp', + 'no-rpm-opt-flags': 'use-rpm-opt-flags', + 'rpm2-mode': 'rpm3-mode'} + + + def initialize_options (self): + self.bdist_base = None + self.rpm_base = None + self.dist_dir = None + self.python = None + self.fix_python = None + self.spec_only = None + self.binary_only = None + self.source_only = None + self.use_bzip2 = None + + self.distribution_name = None + self.group = None + self.release = None + self.serial = None + self.vendor = None + self.packager = None + self.doc_files = None + self.changelog = None + self.icon = None + + self.prep_script = None + self.build_script = None + self.install_script = None + self.clean_script = None + self.verify_script = None + self.pre_install = None + self.post_install = None + self.pre_uninstall = None + self.post_uninstall = None + self.prep = None + self.provides = None + self.requires = None + self.conflicts = None + self.build_requires = None + self.obsoletes = None + + self.keep_temp = 0 + self.use_rpm_opt_flags = 1 + self.rpm3_mode = 1 + self.no_autoreq = 0 + + self.force_arch = None + self.quiet = 0 + + # initialize_options() + + + def finalize_options (self): + self.set_undefined_options('bdist', ('bdist_base', 'bdist_base')) + if self.rpm_base is None: + if not self.rpm3_mode: + raise DistutilsOptionError, \ + "you must specify --rpm-base in RPM 2 mode" + self.rpm_base = os.path.join(self.bdist_base, "rpm") + + if self.python is None: + if self.fix_python: + self.python = sys.executable + else: + self.python = "python" + elif self.fix_python: + raise DistutilsOptionError, \ + "--python and --fix-python are mutually exclusive options" + + if os.name != 'posix': + raise DistutilsPlatformError, \ + ("don't know how to create RPM " + "distributions on platform %s" % os.name) + if self.binary_only and self.source_only: + raise DistutilsOptionError, \ + "cannot supply both '--source-only' and '--binary-only'" + + # don't pass CFLAGS to pure python distributions + if not self.distribution.has_ext_modules(): + self.use_rpm_opt_flags = 0 + + self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) + self.finalize_package_data() + + # finalize_options() + + def finalize_package_data (self): + self.ensure_string('group', "Development/Libraries") + self.ensure_string('vendor', + "%s <%s>" % (self.distribution.get_contact(), + self.distribution.get_contact_email())) + self.ensure_string('packager') + self.ensure_string_list('doc_files') + if isinstance(self.doc_files, list): + for readme in ('README', 'README.txt'): + if os.path.exists(readme) and readme not in self.doc_files: + self.doc_files.append(readme) + + self.ensure_string('release', "1") + self.ensure_string('serial') # should it be an int? + + self.ensure_string('distribution_name') + + self.ensure_string('changelog') + # Format changelog correctly + self.changelog = self._format_changelog(self.changelog) + + self.ensure_filename('icon') + + self.ensure_filename('prep_script') + self.ensure_filename('build_script') + self.ensure_filename('install_script') + self.ensure_filename('clean_script') + self.ensure_filename('verify_script') + self.ensure_filename('pre_install') + self.ensure_filename('post_install') + self.ensure_filename('pre_uninstall') + self.ensure_filename('post_uninstall') + + # XXX don't forget we punted on summaries and descriptions -- they + # should be handled here eventually! + + # Now *this* is some meta-data that belongs in the setup script... + self.ensure_string_list('provides') + self.ensure_string_list('requires') + self.ensure_string_list('conflicts') + self.ensure_string_list('build_requires') + self.ensure_string_list('obsoletes') + + self.ensure_string('force_arch') + # finalize_package_data () + + + def run (self): + + if DEBUG: + print "before _get_package_data():" + print "vendor =", self.vendor + print "packager =", self.packager + print "doc_files =", self.doc_files + print "changelog =", self.changelog + + # make directories + if self.spec_only: + spec_dir = self.dist_dir + self.mkpath(spec_dir) + else: + rpm_dir = {} + for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'): + rpm_dir[d] = os.path.join(self.rpm_base, d) + self.mkpath(rpm_dir[d]) + spec_dir = rpm_dir['SPECS'] + + # Spec file goes into 'dist_dir' if '--spec-only specified', + # build/rpm.<plat> otherwise. + spec_path = os.path.join(spec_dir, + "%s.spec" % self.distribution.get_name()) + self.execute(write_file, + (spec_path, + self._make_spec_file()), + "writing '%s'" % spec_path) + + if self.spec_only: # stop if requested + return + + # Make a source distribution and copy to SOURCES directory with + # optional icon. + saved_dist_files = self.distribution.dist_files[:] + sdist = self.reinitialize_command('sdist') + if self.use_bzip2: + sdist.formats = ['bztar'] + else: + sdist.formats = ['gztar'] + self.run_command('sdist') + self.distribution.dist_files = saved_dist_files + + source = sdist.get_archive_files()[0] + source_dir = rpm_dir['SOURCES'] + self.copy_file(source, source_dir) + + if self.icon: + if os.path.exists(self.icon): + self.copy_file(self.icon, source_dir) + else: + raise DistutilsFileError, \ + "icon file '%s' does not exist" % self.icon + + + # build package + log.info("building RPMs") + rpm_cmd = ['rpm'] + if os.path.exists('/usr/bin/rpmbuild') or \ + os.path.exists('/bin/rpmbuild'): + rpm_cmd = ['rpmbuild'] + + if self.source_only: # what kind of RPMs? + rpm_cmd.append('-bs') + elif self.binary_only: + rpm_cmd.append('-bb') + else: + rpm_cmd.append('-ba') + if self.rpm3_mode: + rpm_cmd.extend(['--define', + '_topdir %s' % os.path.abspath(self.rpm_base)]) + if not self.keep_temp: + rpm_cmd.append('--clean') + + if self.quiet: + rpm_cmd.append('--quiet') + + rpm_cmd.append(spec_path) + # Determine the binary rpm names that should be built out of this spec + # file + # Note that some of these may not be really built (if the file + # list is empty) + nvr_string = "%{name}-%{version}-%{release}" + src_rpm = nvr_string + ".src.rpm" + non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm" + q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % ( + src_rpm, non_src_rpm, spec_path) + + out = os.popen(q_cmd) + try: + binary_rpms = [] + source_rpm = None + while 1: + line = out.readline() + if not line: + break + l = string.split(string.strip(line)) + assert(len(l) == 2) + binary_rpms.append(l[1]) + # The source rpm is named after the first entry in the spec file + if source_rpm is None: + source_rpm = l[0] + + status = out.close() + if status: + raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd)) + + finally: + out.close() + + self.spawn(rpm_cmd) + + if not self.dry_run: + if self.distribution.has_ext_modules(): + pyversion = get_python_version() + else: + pyversion = 'any' + + if not self.binary_only: + srpm = os.path.join(rpm_dir['SRPMS'], source_rpm) + assert(os.path.exists(srpm)) + self.move_file(srpm, self.dist_dir) + filename = os.path.join(self.dist_dir, source_rpm) + self.distribution.dist_files.append( + ('bdist_rpm', pyversion, filename)) + + if not self.source_only: + for rpm in binary_rpms: + rpm = os.path.join(rpm_dir['RPMS'], rpm) + if os.path.exists(rpm): + self.move_file(rpm, self.dist_dir) + filename = os.path.join(self.dist_dir, + os.path.basename(rpm)) + self.distribution.dist_files.append( + ('bdist_rpm', pyversion, filename)) + # run() + + def _dist_path(self, path): + return os.path.join(self.dist_dir, os.path.basename(path)) + + def _make_spec_file(self): + """Generate the text of an RPM spec file and return it as a + list of strings (one per line). + """ + # definitions and headers + spec_file = [ + '%define name ' + self.distribution.get_name(), + '%define version ' + self.distribution.get_version().replace('-','_'), + '%define unmangled_version ' + self.distribution.get_version(), + '%define release ' + self.release.replace('-','_'), + '', + 'Summary: ' + self.distribution.get_description(), + ] + + # put locale summaries into spec file + # XXX not supported for now (hard to put a dictionary + # in a config file -- arg!) + #for locale in self.summaries.keys(): + # spec_file.append('Summary(%s): %s' % (locale, + # self.summaries[locale])) + + spec_file.extend([ + 'Name: %{name}', + 'Version: %{version}', + 'Release: %{release}',]) + + # XXX yuck! this filename is available from the "sdist" command, + # but only after it has run: and we create the spec file before + # running "sdist", in case of --spec-only. + if self.use_bzip2: + spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2') + else: + spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz') + + spec_file.extend([ + 'License: ' + self.distribution.get_license(), + 'Group: ' + self.group, + 'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot', + 'Prefix: %{_prefix}', ]) + + if not self.force_arch: + # noarch if no extension modules + if not self.distribution.has_ext_modules(): + spec_file.append('BuildArch: noarch') + else: + spec_file.append( 'BuildArch: %s' % self.force_arch ) + + for field in ('Vendor', + 'Packager', + 'Provides', + 'Requires', + 'Conflicts', + 'Obsoletes', + ): + val = getattr(self, string.lower(field)) + if isinstance(val, list): + spec_file.append('%s: %s' % (field, string.join(val))) + elif val is not None: + spec_file.append('%s: %s' % (field, val)) + + + if self.distribution.get_url() != 'UNKNOWN': + spec_file.append('Url: ' + self.distribution.get_url()) + + if self.distribution_name: + spec_file.append('Distribution: ' + self.distribution_name) + + if self.build_requires: + spec_file.append('BuildRequires: ' + + string.join(self.build_requires)) + + if self.icon: + spec_file.append('Icon: ' + os.path.basename(self.icon)) + + if self.no_autoreq: + spec_file.append('AutoReq: 0') + + spec_file.extend([ + '', + '%description', + self.distribution.get_long_description() + ]) + + # put locale descriptions into spec file + # XXX again, suppressed because config file syntax doesn't + # easily support this ;-( + #for locale in self.descriptions.keys(): + # spec_file.extend([ + # '', + # '%description -l ' + locale, + # self.descriptions[locale], + # ]) + + # rpm scripts + # figure out default build script + def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0])) + def_build = "%s build" % def_setup_call + if self.use_rpm_opt_flags: + def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build + + # insert contents of files + + # XXX this is kind of misleading: user-supplied options are files + # that we open and interpolate into the spec file, but the defaults + # are just text that we drop in as-is. Hmmm. + + install_cmd = ('%s install -O1 --root=$RPM_BUILD_ROOT ' + '--record=INSTALLED_FILES') % def_setup_call + + script_options = [ + ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"), + ('build', 'build_script', def_build), + ('install', 'install_script', install_cmd), + ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"), + ('verifyscript', 'verify_script', None), + ('pre', 'pre_install', None), + ('post', 'post_install', None), + ('preun', 'pre_uninstall', None), + ('postun', 'post_uninstall', None), + ] + + for (rpm_opt, attr, default) in script_options: + # Insert contents of file referred to, if no file is referred to + # use 'default' as contents of script + val = getattr(self, attr) + if val or default: + spec_file.extend([ + '', + '%' + rpm_opt,]) + if val: + spec_file.extend(string.split(open(val, 'r').read(), '\n')) + else: + spec_file.append(default) + + + # files section + spec_file.extend([ + '', + '%files -f INSTALLED_FILES', + '%defattr(-,root,root)', + ]) + + if self.doc_files: + spec_file.append('%doc ' + string.join(self.doc_files)) + + if self.changelog: + spec_file.extend([ + '', + '%changelog',]) + spec_file.extend(self.changelog) + + return spec_file + + # _make_spec_file () + + def _format_changelog(self, changelog): + """Format the changelog correctly and convert it to a list of strings + """ + if not changelog: + return changelog + new_changelog = [] + for line in string.split(string.strip(changelog), '\n'): + line = string.strip(line) + if line[0] == '*': + new_changelog.extend(['', line]) + elif line[0] == '-': + new_changelog.append(line) + else: + new_changelog.append(' ' + line) + + # strip trailing newline inserted by first changelog entry + if not new_changelog[0]: + del new_changelog[0] + + return new_changelog + + # _format_changelog() + +# class bdist_rpm diff --git a/src/main/resources/PythonLibs/distutils/command/bdist_wininst.py b/src/main/resources/PythonLibs/distutils/command/bdist_wininst.py new file mode 100644 index 0000000000000000000000000000000000000000..aa9383af98b641fd5041aacbd1c2d142b434deb7 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/bdist_wininst.py @@ -0,0 +1,368 @@ +"""distutils.command.bdist_wininst + +Implements the Distutils 'bdist_wininst' command: create a windows installer +exe-program.""" + +__revision__ = "$Id$" + +import sys +import os +import string + +from sysconfig import get_python_version + +from distutils.core import Command +from distutils.dir_util import remove_tree +from distutils.errors import DistutilsOptionError, DistutilsPlatformError +from distutils import log +from distutils.util import get_platform + +class bdist_wininst (Command): + + description = "create an executable installer for MS Windows" + + user_options = [('bdist-dir=', None, + "temporary directory for creating the distribution"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform()), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('target-version=', None, + "require a specific python version" + + " on the target system"), + ('no-target-compile', 'c', + "do not compile .py to .pyc on the target system"), + ('no-target-optimize', 'o', + "do not compile .py to .pyo (optimized)" + "on the target system"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('bitmap=', 'b', + "bitmap to use for the installer instead of python-powered logo"), + ('title=', 't', + "title to display on the installer background instead of default"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('install-script=', None, + "basename of installation script to be run after" + "installation or before deinstallation"), + ('pre-install-script=', None, + "Fully qualified filename of a script to be run before " + "any files are installed. This script need not be in the " + "distribution"), + ('user-access-control=', None, + "specify Vista's UAC handling - 'none'/default=no " + "handling, 'auto'=use UAC if target Python installed for " + "all users, 'force'=always use UAC"), + ] + + boolean_options = ['keep-temp', 'no-target-compile', 'no-target-optimize', + 'skip-build'] + + def initialize_options (self): + self.bdist_dir = None + self.plat_name = None + self.keep_temp = 0 + self.no_target_compile = 0 + self.no_target_optimize = 0 + self.target_version = None + self.dist_dir = None + self.bitmap = None + self.title = None + self.skip_build = None + self.install_script = None + self.pre_install_script = None + self.user_access_control = None + + # initialize_options() + + + def finalize_options (self): + self.set_undefined_options('bdist', ('skip_build', 'skip_build')) + + if self.bdist_dir is None: + if self.skip_build and self.plat_name: + # If build is skipped and plat_name is overridden, bdist will + # not see the correct 'plat_name' - so set that up manually. + bdist = self.distribution.get_command_obj('bdist') + bdist.plat_name = self.plat_name + # next the command will be initialized using that name + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'wininst') + + if not self.target_version: + self.target_version = "" + + if not self.skip_build and self.distribution.has_ext_modules(): + short_version = get_python_version() + if self.target_version and self.target_version != short_version: + raise DistutilsOptionError, \ + "target version can only be %s, or the '--skip-build'" \ + " option must be specified" % (short_version,) + self.target_version = short_version + + self.set_undefined_options('bdist', + ('dist_dir', 'dist_dir'), + ('plat_name', 'plat_name'), + ) + + if self.install_script: + for script in self.distribution.scripts: + if self.install_script == os.path.basename(script): + break + else: + raise DistutilsOptionError, \ + "install_script '%s' not found in scripts" % \ + self.install_script + # finalize_options() + + + def run (self): + if (sys.platform != "win32" and + (self.distribution.has_ext_modules() or + self.distribution.has_c_libraries())): + raise DistutilsPlatformError \ + ("distribution contains extensions and/or C libraries; " + "must be compiled on a Windows 32 platform") + + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', reinit_subcommands=1) + install.root = self.bdist_dir + install.skip_build = self.skip_build + install.warn_dir = 0 + install.plat_name = self.plat_name + + install_lib = self.reinitialize_command('install_lib') + # we do not want to include pyc or pyo files + install_lib.compile = 0 + install_lib.optimize = 0 + + if self.distribution.has_ext_modules(): + # If we are building an installer for a Python version other + # than the one we are currently running, then we need to ensure + # our build_lib reflects the other Python version rather than ours. + # Note that for target_version!=sys.version, we must have skipped the + # build step, so there is no issue with enforcing the build of this + # version. + target_version = self.target_version + if not target_version: + assert self.skip_build, "Should have already checked this" + target_version = sys.version[0:3] + plat_specifier = ".%s-%s" % (self.plat_name, target_version) + build = self.get_finalized_command('build') + build.build_lib = os.path.join(build.build_base, + 'lib' + plat_specifier) + + # Use a custom scheme for the zip-file, because we have to decide + # at installation time which scheme to use. + for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): + value = string.upper(key) + if key == 'headers': + value = value + '/Include/$dist_name' + setattr(install, + 'install_' + key, + value) + + log.info("installing to %s", self.bdist_dir) + install.ensure_finalized() + + # avoid warning of 'install_lib' about installing + # into a directory not in sys.path + sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) + + install.run() + + del sys.path[0] + + # And make an archive relative to the root of the + # pseudo-installation tree. + from tempfile import mktemp + archive_basename = mktemp() + fullname = self.distribution.get_fullname() + arcname = self.make_archive(archive_basename, "zip", + root_dir=self.bdist_dir) + # create an exe containing the zip-file + self.create_exe(arcname, fullname, self.bitmap) + if self.distribution.has_ext_modules(): + pyversion = get_python_version() + else: + pyversion = 'any' + self.distribution.dist_files.append(('bdist_wininst', pyversion, + self.get_installer_filename(fullname))) + # remove the zip-file again + log.debug("removing temporary file '%s'", arcname) + os.remove(arcname) + + if not self.keep_temp: + remove_tree(self.bdist_dir, dry_run=self.dry_run) + + # run() + + def get_inidata (self): + # Return data describing the installation. + + lines = [] + metadata = self.distribution.metadata + + # Write the [metadata] section. + lines.append("[metadata]") + + # 'info' will be displayed in the installer's dialog box, + # describing the items to be installed. + info = (metadata.long_description or '') + '\n' + + # Escape newline characters + def escape(s): + return string.replace(s, "\n", "\\n") + + for name in ["author", "author_email", "description", "maintainer", + "maintainer_email", "name", "url", "version"]: + data = getattr(metadata, name, "") + if data: + info = info + ("\n %s: %s" % \ + (string.capitalize(name), escape(data))) + lines.append("%s=%s" % (name, escape(data))) + + # The [setup] section contains entries controlling + # the installer runtime. + lines.append("\n[Setup]") + if self.install_script: + lines.append("install_script=%s" % self.install_script) + lines.append("info=%s" % escape(info)) + lines.append("target_compile=%d" % (not self.no_target_compile)) + lines.append("target_optimize=%d" % (not self.no_target_optimize)) + if self.target_version: + lines.append("target_version=%s" % self.target_version) + if self.user_access_control: + lines.append("user_access_control=%s" % self.user_access_control) + + title = self.title or self.distribution.get_fullname() + lines.append("title=%s" % escape(title)) + import time + import distutils + build_info = "Built %s with distutils-%s" % \ + (time.ctime(time.time()), distutils.__version__) + lines.append("build_info=%s" % build_info) + return string.join(lines, "\n") + + # get_inidata() + + def create_exe (self, arcname, fullname, bitmap=None): + import struct + + self.mkpath(self.dist_dir) + + cfgdata = self.get_inidata() + + installer_name = self.get_installer_filename(fullname) + self.announce("creating %s" % installer_name) + + if bitmap: + bitmapdata = open(bitmap, "rb").read() + bitmaplen = len(bitmapdata) + else: + bitmaplen = 0 + + file = open(installer_name, "wb") + file.write(self.get_exe_bytes()) + if bitmap: + file.write(bitmapdata) + + # Convert cfgdata from unicode to ascii, mbcs encoded + try: + unicode + except NameError: + pass + else: + if isinstance(cfgdata, unicode): + cfgdata = cfgdata.encode("mbcs") + + # Append the pre-install script + cfgdata = cfgdata + "\0" + if self.pre_install_script: + script_data = open(self.pre_install_script, "r").read() + cfgdata = cfgdata + script_data + "\n\0" + else: + # empty pre-install script + cfgdata = cfgdata + "\0" + file.write(cfgdata) + + # The 'magic number' 0x1234567B is used to make sure that the + # binary layout of 'cfgdata' is what the wininst.exe binary + # expects. If the layout changes, increment that number, make + # the corresponding changes to the wininst.exe sources, and + # recompile them. + header = struct.pack("<iii", + 0x1234567B, # tag + len(cfgdata), # length + bitmaplen, # number of bytes in bitmap + ) + file.write(header) + file.write(open(arcname, "rb").read()) + + # create_exe() + + def get_installer_filename(self, fullname): + # Factored out to allow overriding in subclasses + if self.target_version: + # if we create an installer for a specific python version, + # it's better to include this in the name + installer_name = os.path.join(self.dist_dir, + "%s.%s-py%s.exe" % + (fullname, self.plat_name, self.target_version)) + else: + installer_name = os.path.join(self.dist_dir, + "%s.%s.exe" % (fullname, self.plat_name)) + return installer_name + # get_installer_filename() + + def get_exe_bytes (self): + from distutils.msvccompiler import get_build_version + # If a target-version other than the current version has been + # specified, then using the MSVC version from *this* build is no good. + # Without actually finding and executing the target version and parsing + # its sys.version, we just hard-code our knowledge of old versions. + # NOTE: Possible alternative is to allow "--target-version" to + # specify a Python executable rather than a simple version string. + # We can then execute this program to obtain any info we need, such + # as the real sys.version string for the build. + cur_version = get_python_version() + if self.target_version and self.target_version != cur_version: + # If the target version is *later* than us, then we assume they + # use what we use + # string compares seem wrong, but are what sysconfig.py itself uses + if self.target_version > cur_version: + bv = get_build_version() + else: + if self.target_version < "2.4": + bv = 6.0 + else: + bv = 7.1 + else: + # for current version - use authoritative check. + bv = get_build_version() + + # wininst-x.y.exe is in the same directory as this file + directory = os.path.dirname(__file__) + # we must use a wininst-x.y.exe built with the same C compiler + # used for python. XXX What about mingw, borland, and so on? + + # if plat_name starts with "win" but is not "win32" + # we want to strip "win" and leave the rest (e.g. -amd64) + # for all other cases, we don't want any suffix + if self.plat_name != 'win32' and self.plat_name[:3] == 'win': + sfix = self.plat_name[3:] + else: + sfix = '' + + filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix)) + f = open(filename, "rb") + try: + return f.read() + finally: + f.close() +# class bdist_wininst diff --git a/src/main/resources/PythonLibs/distutils/command/build.py b/src/main/resources/PythonLibs/distutils/command/build.py new file mode 100644 index 0000000000000000000000000000000000000000..f84bf359dc60938e79e1be7beca84051929aa2c7 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/build.py @@ -0,0 +1,147 @@ +"""distutils.command.build + +Implements the Distutils 'build' command.""" + +__revision__ = "$Id$" + +import sys, os + +from distutils.util import get_platform +from distutils.core import Command +from distutils.errors import DistutilsOptionError + +def show_compilers(): + from distutils.ccompiler import show_compilers + show_compilers() + +class build(Command): + + description = "build everything needed to install" + + user_options = [ + ('build-base=', 'b', + "base directory for build library"), + ('build-purelib=', None, + "build directory for platform-neutral distributions"), + ('build-platlib=', None, + "build directory for platform-specific distributions"), + ('build-lib=', None, + "build directory for all distribution (defaults to either " + + "build-purelib or build-platlib"), + ('build-scripts=', None, + "build directory for scripts"), + ('build-temp=', 't', + "temporary build directory"), + ('plat-name=', 'p', + "platform name to build for, if supported " + "(default: %s)" % get_platform()), + ('compiler=', 'c', + "specify the compiler type"), + ('debug', 'g', + "compile extensions and libraries with debugging information"), + ('force', 'f', + "forcibly build everything (ignore file timestamps)"), + ('executable=', 'e', + "specify final destination interpreter path (build.py)"), + ] + + boolean_options = ['debug', 'force'] + + help_options = [ + ('help-compiler', None, + "list available compilers", show_compilers), + ] + + def initialize_options(self): + self.build_base = 'build' + # these are decided only after 'build_base' has its final value + # (unless overridden by the user or client) + self.build_purelib = None + self.build_platlib = None + self.build_lib = None + self.build_temp = None + self.build_scripts = None + self.compiler = None + self.plat_name = None + self.debug = None + self.force = 0 + self.executable = None + + def finalize_options(self): + if self.plat_name is None: + self.plat_name = get_platform() + else: + # plat-name only supported for windows (other platforms are + # supported via ./configure flags, if at all). Avoid misleading + # other platforms. + if os.name != 'nt': + raise DistutilsOptionError( + "--plat-name only supported on Windows (try " + "using './configure --help' on your platform)") + + plat_specifier = ".%s-%s" % (self.plat_name, sys.version[0:3]) + + # Make it so Python 2.x and Python 2.x with --with-pydebug don't + # share the same build directories. Doing so confuses the build + # process for C modules + if hasattr(sys, 'gettotalrefcount'): + plat_specifier += '-pydebug' + + # 'build_purelib' and 'build_platlib' just default to 'lib' and + # 'lib.<plat>' under the base build directory. We only use one of + # them for a given distribution, though -- + if self.build_purelib is None: + self.build_purelib = os.path.join(self.build_base, 'lib') + if self.build_platlib is None: + self.build_platlib = os.path.join(self.build_base, + 'lib' + plat_specifier) + + # 'build_lib' is the actual directory that we will use for this + # particular module distribution -- if user didn't supply it, pick + # one of 'build_purelib' or 'build_platlib'. + if self.build_lib is None: + if self.distribution.ext_modules: + self.build_lib = self.build_platlib + else: + self.build_lib = self.build_purelib + + # 'build_temp' -- temporary directory for compiler turds, + # "build/temp.<plat>" + if self.build_temp is None: + self.build_temp = os.path.join(self.build_base, + 'temp' + plat_specifier) + if self.build_scripts is None: + self.build_scripts = os.path.join(self.build_base, + 'scripts-' + sys.version[0:3]) + + if self.executable is None: + self.executable = os.path.normpath(sys.executable) + + def run(self): + # Run all relevant sub-commands. This will be some subset of: + # - build_py - pure Python modules + # - build_clib - standalone C libraries + # - build_ext - Python extensions + # - build_scripts - (Python) scripts + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + # -- Predicates for the sub-command list --------------------------- + + def has_pure_modules (self): + return self.distribution.has_pure_modules() + + def has_c_libraries (self): + return self.distribution.has_c_libraries() + + def has_ext_modules (self): + return self.distribution.has_ext_modules() + + def has_scripts (self): + return self.distribution.has_scripts() + + sub_commands = [('build_py', has_pure_modules), + ('build_clib', has_c_libraries), + ('build_ext', has_ext_modules), + ('build_scripts', has_scripts), + ] diff --git a/src/main/resources/PythonLibs/distutils/command/build_clib.py b/src/main/resources/PythonLibs/distutils/command/build_clib.py new file mode 100644 index 0000000000000000000000000000000000000000..205587e7fc96826da43641d748ed4a068928732c --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/build_clib.py @@ -0,0 +1,209 @@ +"""distutils.command.build_clib + +Implements the Distutils 'build_clib' command, to build a C/C++ library +that is included in the module distribution and needed by an extension +module.""" + +__revision__ = "$Id$" + + +# XXX this module has *lots* of code ripped-off quite transparently from +# build_ext.py -- not surprisingly really, as the work required to build +# a static library from a collection of C source files is not really all +# that different from what's required to build a shared object file from +# a collection of C source files. Nevertheless, I haven't done the +# necessary refactoring to account for the overlap in code between the +# two modules, mainly because a number of subtle details changed in the +# cut 'n paste. Sigh. + +import os +from distutils.core import Command +from distutils.errors import DistutilsSetupError +from distutils.sysconfig import customize_compiler +from distutils import log + +def show_compilers(): + from distutils.ccompiler import show_compilers + show_compilers() + + +class build_clib(Command): + + description = "build C/C++ libraries used by Python extensions" + + user_options = [ + ('build-clib=', 'b', + "directory to build C/C++ libraries to"), + ('build-temp=', 't', + "directory to put temporary build by-products"), + ('debug', 'g', + "compile with debugging information"), + ('force', 'f', + "forcibly build everything (ignore file timestamps)"), + ('compiler=', 'c', + "specify the compiler type"), + ] + + boolean_options = ['debug', 'force'] + + help_options = [ + ('help-compiler', None, + "list available compilers", show_compilers), + ] + + def initialize_options(self): + self.build_clib = None + self.build_temp = None + + # List of libraries to build + self.libraries = None + + # Compilation options for all libraries + self.include_dirs = None + self.define = None + self.undef = None + self.debug = None + self.force = 0 + self.compiler = None + + + def finalize_options(self): + # This might be confusing: both build-clib and build-temp default + # to build-temp as defined by the "build" command. This is because + # I think that C libraries are really just temporary build + # by-products, at least from the point of view of building Python + # extensions -- but I want to keep my options open. + self.set_undefined_options('build', + ('build_temp', 'build_clib'), + ('build_temp', 'build_temp'), + ('compiler', 'compiler'), + ('debug', 'debug'), + ('force', 'force')) + + self.libraries = self.distribution.libraries + if self.libraries: + self.check_library_list(self.libraries) + + if self.include_dirs is None: + self.include_dirs = self.distribution.include_dirs or [] + if isinstance(self.include_dirs, str): + self.include_dirs = self.include_dirs.split(os.pathsep) + + # XXX same as for build_ext -- what about 'self.define' and + # 'self.undef' ? + + def run(self): + if not self.libraries: + return + + # Yech -- this is cut 'n pasted from build_ext.py! + from distutils.ccompiler import new_compiler + self.compiler = new_compiler(compiler=self.compiler, + dry_run=self.dry_run, + force=self.force) + customize_compiler(self.compiler) + + if self.include_dirs is not None: + self.compiler.set_include_dirs(self.include_dirs) + if self.define is not None: + # 'define' option is a list of (name,value) tuples + for (name,value) in self.define: + self.compiler.define_macro(name, value) + if self.undef is not None: + for macro in self.undef: + self.compiler.undefine_macro(macro) + + self.build_libraries(self.libraries) + + + def check_library_list(self, libraries): + """Ensure that the list of libraries is valid. + + `library` is presumably provided as a command option 'libraries'. + This method checks that it is a list of 2-tuples, where the tuples + are (library_name, build_info_dict). + + Raise DistutilsSetupError if the structure is invalid anywhere; + just returns otherwise. + """ + if not isinstance(libraries, list): + raise DistutilsSetupError, \ + "'libraries' option must be a list of tuples" + + for lib in libraries: + if not isinstance(lib, tuple) and len(lib) != 2: + raise DistutilsSetupError, \ + "each element of 'libraries' must a 2-tuple" + + name, build_info = lib + + if not isinstance(name, str): + raise DistutilsSetupError, \ + "first element of each tuple in 'libraries' " + \ + "must be a string (the library name)" + if '/' in name or (os.sep != '/' and os.sep in name): + raise DistutilsSetupError, \ + ("bad library name '%s': " + + "may not contain directory separators") % \ + lib[0] + + if not isinstance(build_info, dict): + raise DistutilsSetupError, \ + "second element of each tuple in 'libraries' " + \ + "must be a dictionary (build info)" + + def get_library_names(self): + # Assume the library list is valid -- 'check_library_list()' is + # called from 'finalize_options()', so it should be! + if not self.libraries: + return None + + lib_names = [] + for (lib_name, build_info) in self.libraries: + lib_names.append(lib_name) + return lib_names + + + def get_source_files(self): + self.check_library_list(self.libraries) + filenames = [] + for (lib_name, build_info) in self.libraries: + sources = build_info.get('sources') + if sources is None or not isinstance(sources, (list, tuple)): + raise DistutilsSetupError, \ + ("in 'libraries' option (library '%s'), " + "'sources' must be present and must be " + "a list of source filenames") % lib_name + + filenames.extend(sources) + return filenames + + def build_libraries(self, libraries): + for (lib_name, build_info) in libraries: + sources = build_info.get('sources') + if sources is None or not isinstance(sources, (list, tuple)): + raise DistutilsSetupError, \ + ("in 'libraries' option (library '%s'), " + + "'sources' must be present and must be " + + "a list of source filenames") % lib_name + sources = list(sources) + + log.info("building '%s' library", lib_name) + + # First, compile the source code to object files in the library + # directory. (This should probably change to putting object + # files in a temporary build directory.) + macros = build_info.get('macros') + include_dirs = build_info.get('include_dirs') + objects = self.compiler.compile(sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + debug=self.debug) + + # Now "link" the object files together into a static library. + # (On Unix at least, this isn't really linking -- it just + # builds an archive. Whatever.) + self.compiler.create_static_lib(objects, lib_name, + output_dir=self.build_clib, + debug=self.debug) diff --git a/src/main/resources/PythonLibs/distutils/command/build_ext.py b/src/main/resources/PythonLibs/distutils/command/build_ext.py new file mode 100644 index 0000000000000000000000000000000000000000..923197bac43674e86fdfb3970c8a730c8893c63a --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/build_ext.py @@ -0,0 +1,768 @@ +"""distutils.command.build_ext + +Implements the Distutils 'build_ext' command, for building extension +modules (currently limited to C extensions, should accommodate C++ +extensions ASAP).""" + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id$" + +import sys, os, string, re +from types import * +from site import USER_BASE, USER_SITE +from distutils.core import Command +from distutils.errors import * +from distutils.sysconfig import customize_compiler, get_python_version +from distutils.dep_util import newer_group +from distutils.extension import Extension +from distutils.util import get_platform +from distutils import log + +if os.name == 'nt': + from distutils.msvccompiler import get_build_version + MSVC_VERSION = int(get_build_version()) + +# An extension name is just a dot-separated list of Python NAMEs (ie. +# the same as a fully-qualified module name). +extension_name_re = re.compile \ + (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$') + + +def show_compilers (): + from distutils.ccompiler import show_compilers + show_compilers() + + +class build_ext (Command): + + description = "build C/C++ extensions (compile/link to build directory)" + + # XXX thoughts on how to deal with complex command-line options like + # these, i.e. how to make it so fancy_getopt can suck them off the + # command line and make it look like setup.py defined the appropriate + # lists of tuples of what-have-you. + # - each command needs a callback to process its command-line options + # - Command.__init__() needs access to its share of the whole + # command line (must ultimately come from + # Distribution.parse_command_line()) + # - it then calls the current command class' option-parsing + # callback to deal with weird options like -D, which have to + # parse the option text and churn out some custom data + # structure + # - that data structure (in this case, a list of 2-tuples) + # will then be present in the command object by the time + # we get to finalize_options() (i.e. the constructor + # takes care of both command-line and client options + # in between initialize_options() and finalize_options()) + + sep_by = " (separated by '%s')" % os.pathsep + user_options = [ + ('build-lib=', 'b', + "directory for compiled extension modules"), + ('build-temp=', 't', + "directory for temporary files (build by-products)"), + ('plat-name=', 'p', + "platform name to cross-compile for, if supported " + "(default: %s)" % get_platform()), + ('inplace', 'i', + "ignore build-lib and put compiled extensions into the source " + + "directory alongside your pure Python modules"), + ('include-dirs=', 'I', + "list of directories to search for header files" + sep_by), + ('define=', 'D', + "C preprocessor macros to define"), + ('undef=', 'U', + "C preprocessor macros to undefine"), + ('libraries=', 'l', + "external C libraries to link with"), + ('library-dirs=', 'L', + "directories to search for external C libraries" + sep_by), + ('rpath=', 'R', + "directories to search for shared C libraries at runtime"), + ('link-objects=', 'O', + "extra explicit link objects to include in the link"), + ('debug', 'g', + "compile/link with debugging information"), + ('force', 'f', + "forcibly build everything (ignore file timestamps)"), + ('compiler=', 'c', + "specify the compiler type"), + ('swig-cpp', None, + "make SWIG create C++ files (default is C)"), + ('swig-opts=', None, + "list of SWIG command line options"), + ('swig=', None, + "path to the SWIG executable"), + ('user', None, + "add user include, library and rpath"), + ] + + boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user'] + + help_options = [ + ('help-compiler', None, + "list available compilers", show_compilers), + ] + + def initialize_options (self): + self.extensions = None + self.build_lib = None + self.plat_name = None + self.build_temp = None + self.inplace = 0 + self.package = None + + self.include_dirs = None + self.define = None + self.undef = None + self.libraries = None + self.library_dirs = None + self.rpath = None + self.link_objects = None + self.debug = None + self.force = None + self.compiler = None + self.swig = None + self.swig_cpp = None + self.swig_opts = None + self.user = None + + def finalize_options(self): + from distutils import sysconfig + + self.set_undefined_options('build', + ('build_lib', 'build_lib'), + ('build_temp', 'build_temp'), + ('compiler', 'compiler'), + ('debug', 'debug'), + ('force', 'force'), + ('plat_name', 'plat_name'), + ) + + if self.package is None: + self.package = self.distribution.ext_package + + self.extensions = self.distribution.ext_modules + + # Make sure Python's include directories (for Python.h, pyconfig.h, + # etc.) are in the include search path. + py_include = sysconfig.get_python_inc() + plat_py_include = sysconfig.get_python_inc(plat_specific=1) + if self.include_dirs is None: + self.include_dirs = self.distribution.include_dirs or [] + if isinstance(self.include_dirs, str): + self.include_dirs = self.include_dirs.split(os.pathsep) + + # Put the Python "system" include dir at the end, so that + # any local include dirs take precedence. + self.include_dirs.append(py_include) + if plat_py_include != py_include: + self.include_dirs.append(plat_py_include) + + self.ensure_string_list('libraries') + + # Life is easier if we're not forever checking for None, so + # simplify these options to empty lists if unset + if self.libraries is None: + self.libraries = [] + if self.library_dirs is None: + self.library_dirs = [] + elif type(self.library_dirs) is StringType: + self.library_dirs = string.split(self.library_dirs, os.pathsep) + + if self.rpath is None: + self.rpath = [] + elif type(self.rpath) is StringType: + self.rpath = string.split(self.rpath, os.pathsep) + + # for extensions under windows use different directories + # for Release and Debug builds. + # also Python's library directory must be appended to library_dirs + if os.name == 'nt': + # the 'libs' directory is for binary installs - we assume that + # must be the *native* platform. But we don't really support + # cross-compiling via a binary install anyway, so we let it go. + self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs')) + if self.debug: + self.build_temp = os.path.join(self.build_temp, "Debug") + else: + self.build_temp = os.path.join(self.build_temp, "Release") + + # Append the source distribution include and library directories, + # this allows distutils on windows to work in the source tree + self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC')) + if MSVC_VERSION == 9: + # Use the .lib files for the correct architecture + if self.plat_name == 'win32': + suffix = '' + else: + # win-amd64 or win-ia64 + suffix = self.plat_name[4:] + new_lib = os.path.join(sys.exec_prefix, 'PCbuild') + if suffix: + new_lib = os.path.join(new_lib, suffix) + self.library_dirs.append(new_lib) + + elif MSVC_VERSION == 8: + self.library_dirs.append(os.path.join(sys.exec_prefix, + 'PC', 'VS8.0')) + elif MSVC_VERSION == 7: + self.library_dirs.append(os.path.join(sys.exec_prefix, + 'PC', 'VS7.1')) + else: + self.library_dirs.append(os.path.join(sys.exec_prefix, + 'PC', 'VC6')) + + # OS/2 (EMX) doesn't support Debug vs Release builds, but has the + # import libraries in its "Config" subdirectory + if os.name == 'os2': + self.library_dirs.append(os.path.join(sys.exec_prefix, 'Config')) + + # for extensions under Cygwin and AtheOS Python's library directory must be + # appended to library_dirs + if sys.platform[:6] == 'cygwin' or sys.platform[:6] == 'atheos': + if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): + # building third party extensions + self.library_dirs.append(os.path.join(sys.prefix, "lib", + "python" + get_python_version(), + "config")) + else: + # building python standard extensions + self.library_dirs.append('.') + + # for extensions under Linux or Solaris with a shared Python library, + # Python's library directory must be appended to library_dirs + sysconfig.get_config_var('Py_ENABLE_SHARED') + if ((sys.platform.startswith('linux') or sys.platform.startswith('gnu') + or sys.platform.startswith('sunos')) + and sysconfig.get_config_var('Py_ENABLE_SHARED')): + if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): + # building third party extensions + self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) + else: + # building python standard extensions + self.library_dirs.append('.') + + # The argument parsing will result in self.define being a string, but + # it has to be a list of 2-tuples. All the preprocessor symbols + # specified by the 'define' option will be set to '1'. Multiple + # symbols can be separated with commas. + + if self.define: + defines = self.define.split(',') + self.define = map(lambda symbol: (symbol, '1'), defines) + + # The option for macros to undefine is also a string from the + # option parsing, but has to be a list. Multiple symbols can also + # be separated with commas here. + if self.undef: + self.undef = self.undef.split(',') + + if self.swig_opts is None: + self.swig_opts = [] + else: + self.swig_opts = self.swig_opts.split(' ') + + # Finally add the user include and library directories if requested + if self.user: + user_include = os.path.join(USER_BASE, "include") + user_lib = os.path.join(USER_BASE, "lib") + if os.path.isdir(user_include): + self.include_dirs.append(user_include) + if os.path.isdir(user_lib): + self.library_dirs.append(user_lib) + self.rpath.append(user_lib) + + def run(self): + from distutils.ccompiler import new_compiler + + # 'self.extensions', as supplied by setup.py, is a list of + # Extension instances. See the documentation for Extension (in + # distutils.extension) for details. + # + # For backwards compatibility with Distutils 0.8.2 and earlier, we + # also allow the 'extensions' list to be a list of tuples: + # (ext_name, build_info) + # where build_info is a dictionary containing everything that + # Extension instances do except the name, with a few things being + # differently named. We convert these 2-tuples to Extension + # instances as needed. + + if not self.extensions: + return + + # If we were asked to build any C/C++ libraries, make sure that the + # directory where we put them is in the library search path for + # linking extensions. + if self.distribution.has_c_libraries(): + build_clib = self.get_finalized_command('build_clib') + self.libraries.extend(build_clib.get_library_names() or []) + self.library_dirs.append(build_clib.build_clib) + + # Setup the CCompiler object that we'll use to do all the + # compiling and linking + self.compiler = new_compiler(compiler=self.compiler, + verbose=self.verbose, + dry_run=self.dry_run, + force=self.force) + customize_compiler(self.compiler) + # If we are cross-compiling, init the compiler now (if we are not + # cross-compiling, init would not hurt, but people may rely on + # late initialization of compiler even if they shouldn't...) + if os.name == 'nt' and self.plat_name != get_platform(): + self.compiler.initialize(self.plat_name) + + # And make sure that any compile/link-related options (which might + # come from the command-line or from the setup script) are set in + # that CCompiler object -- that way, they automatically apply to + # all compiling and linking done here. + if self.include_dirs is not None: + self.compiler.set_include_dirs(self.include_dirs) + if self.define is not None: + # 'define' option is a list of (name,value) tuples + for (name, value) in self.define: + self.compiler.define_macro(name, value) + if self.undef is not None: + for macro in self.undef: + self.compiler.undefine_macro(macro) + if self.libraries is not None: + self.compiler.set_libraries(self.libraries) + if self.library_dirs is not None: + self.compiler.set_library_dirs(self.library_dirs) + if self.rpath is not None: + self.compiler.set_runtime_library_dirs(self.rpath) + if self.link_objects is not None: + self.compiler.set_link_objects(self.link_objects) + + # Now actually compile and link everything. + self.build_extensions() + + def check_extensions_list(self, extensions): + """Ensure that the list of extensions (presumably provided as a + command option 'extensions') is valid, i.e. it is a list of + Extension objects. We also support the old-style list of 2-tuples, + where the tuples are (ext_name, build_info), which are converted to + Extension instances here. + + Raise DistutilsSetupError if the structure is invalid anywhere; + just returns otherwise. + """ + if not isinstance(extensions, list): + raise DistutilsSetupError, \ + "'ext_modules' option must be a list of Extension instances" + + for i, ext in enumerate(extensions): + if isinstance(ext, Extension): + continue # OK! (assume type-checking done + # by Extension constructor) + + if not isinstance(ext, tuple) or len(ext) != 2: + raise DistutilsSetupError, \ + ("each element of 'ext_modules' option must be an " + "Extension instance or 2-tuple") + + ext_name, build_info = ext + + log.warn(("old-style (ext_name, build_info) tuple found in " + "ext_modules for extension '%s'" + "-- please convert to Extension instance" % ext_name)) + + if not (isinstance(ext_name, str) and + extension_name_re.match(ext_name)): + raise DistutilsSetupError, \ + ("first element of each tuple in 'ext_modules' " + "must be the extension name (a string)") + + if not isinstance(build_info, dict): + raise DistutilsSetupError, \ + ("second element of each tuple in 'ext_modules' " + "must be a dictionary (build info)") + + # OK, the (ext_name, build_info) dict is type-safe: convert it + # to an Extension instance. + ext = Extension(ext_name, build_info['sources']) + + # Easy stuff: one-to-one mapping from dict elements to + # instance attributes. + for key in ('include_dirs', 'library_dirs', 'libraries', + 'extra_objects', 'extra_compile_args', + 'extra_link_args'): + val = build_info.get(key) + if val is not None: + setattr(ext, key, val) + + # Medium-easy stuff: same syntax/semantics, different names. + ext.runtime_library_dirs = build_info.get('rpath') + if 'def_file' in build_info: + log.warn("'def_file' element of build info dict " + "no longer supported") + + # Non-trivial stuff: 'macros' split into 'define_macros' + # and 'undef_macros'. + macros = build_info.get('macros') + if macros: + ext.define_macros = [] + ext.undef_macros = [] + for macro in macros: + if not (isinstance(macro, tuple) and len(macro) in (1, 2)): + raise DistutilsSetupError, \ + ("'macros' element of build info dict " + "must be 1- or 2-tuple") + if len(macro) == 1: + ext.undef_macros.append(macro[0]) + elif len(macro) == 2: + ext.define_macros.append(macro) + + extensions[i] = ext + + def get_source_files(self): + self.check_extensions_list(self.extensions) + filenames = [] + + # Wouldn't it be neat if we knew the names of header files too... + for ext in self.extensions: + filenames.extend(ext.sources) + + return filenames + + def get_outputs(self): + # Sanity check the 'extensions' list -- can't assume this is being + # done in the same run as a 'build_extensions()' call (in fact, we + # can probably assume that it *isn't*!). + self.check_extensions_list(self.extensions) + + # And build the list of output (built) filenames. Note that this + # ignores the 'inplace' flag, and assumes everything goes in the + # "build" tree. + outputs = [] + for ext in self.extensions: + outputs.append(self.get_ext_fullpath(ext.name)) + return outputs + + def build_extensions(self): + # First, sanity-check the 'extensions' list + self.check_extensions_list(self.extensions) + + for ext in self.extensions: + self.build_extension(ext) + + def build_extension(self, ext): + sources = ext.sources + if sources is None or type(sources) not in (ListType, TupleType): + raise DistutilsSetupError, \ + ("in 'ext_modules' option (extension '%s'), " + + "'sources' must be present and must be " + + "a list of source filenames") % ext.name + sources = list(sources) + + ext_path = self.get_ext_fullpath(ext.name) + depends = sources + ext.depends + if not (self.force or newer_group(depends, ext_path, 'newer')): + log.debug("skipping '%s' extension (up-to-date)", ext.name) + return + else: + log.info("building '%s' extension", ext.name) + + # First, scan the sources for SWIG definition files (.i), run + # SWIG on 'em to create .c files, and modify the sources list + # accordingly. + sources = self.swig_sources(sources, ext) + + # Next, compile the source code to object files. + + # XXX not honouring 'define_macros' or 'undef_macros' -- the + # CCompiler API needs to change to accommodate this, and I + # want to do one thing at a time! + + # Two possible sources for extra compiler arguments: + # - 'extra_compile_args' in Extension object + # - CFLAGS environment variable (not particularly + # elegant, but people seem to expect it and I + # guess it's useful) + # The environment variable should take precedence, and + # any sensible compiler will give precedence to later + # command line args. Hence we combine them in order: + extra_args = ext.extra_compile_args or [] + + macros = ext.define_macros[:] + for undef in ext.undef_macros: + macros.append((undef,)) + + objects = self.compiler.compile(sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=ext.include_dirs, + debug=self.debug, + extra_postargs=extra_args, + depends=ext.depends) + + # XXX -- this is a Vile HACK! + # + # The setup.py script for Python on Unix needs to be able to + # get this list so it can perform all the clean up needed to + # avoid keeping object files around when cleaning out a failed + # build of an extension module. Since Distutils does not + # track dependencies, we have to get rid of intermediates to + # ensure all the intermediates will be properly re-built. + # + self._built_objects = objects[:] + + # Now link the object files together into a "shared object" -- + # of course, first we have to figure out all the other things + # that go into the mix. + if ext.extra_objects: + objects.extend(ext.extra_objects) + extra_args = ext.extra_link_args or [] + + # Detect target language, if not provided + language = ext.language or self.compiler.detect_language(sources) + + self.compiler.link_shared_object( + objects, ext_path, + libraries=self.get_libraries(ext), + library_dirs=ext.library_dirs, + runtime_library_dirs=ext.runtime_library_dirs, + extra_postargs=extra_args, + export_symbols=self.get_export_symbols(ext), + debug=self.debug, + build_temp=self.build_temp, + target_lang=language) + + + def swig_sources (self, sources, extension): + + """Walk the list of source files in 'sources', looking for SWIG + interface (.i) files. Run SWIG on all that are found, and + return a modified 'sources' list with SWIG source files replaced + by the generated C (or C++) files. + """ + + new_sources = [] + swig_sources = [] + swig_targets = {} + + # XXX this drops generated C/C++ files into the source tree, which + # is fine for developers who want to distribute the generated + # source -- but there should be an option to put SWIG output in + # the temp dir. + + if self.swig_cpp: + log.warn("--swig-cpp is deprecated - use --swig-opts=-c++") + + if self.swig_cpp or ('-c++' in self.swig_opts) or \ + ('-c++' in extension.swig_opts): + target_ext = '.cpp' + else: + target_ext = '.c' + + for source in sources: + (base, ext) = os.path.splitext(source) + if ext == ".i": # SWIG interface file + new_sources.append(base + '_wrap' + target_ext) + swig_sources.append(source) + swig_targets[source] = new_sources[-1] + else: + new_sources.append(source) + + if not swig_sources: + return new_sources + + swig = self.swig or self.find_swig() + swig_cmd = [swig, "-python"] + swig_cmd.extend(self.swig_opts) + if self.swig_cpp: + swig_cmd.append("-c++") + + # Do not override commandline arguments + if not self.swig_opts: + for o in extension.swig_opts: + swig_cmd.append(o) + + for source in swig_sources: + target = swig_targets[source] + log.info("swigging %s to %s", source, target) + self.spawn(swig_cmd + ["-o", target, source]) + + return new_sources + + # swig_sources () + + def find_swig (self): + """Return the name of the SWIG executable. On Unix, this is + just "swig" -- it should be in the PATH. Tries a bit harder on + Windows. + """ + + if os.name == "posix": + return "swig" + elif os.name == "nt": + + # Look for SWIG in its standard installation directory on + # Windows (or so I presume!). If we find it there, great; + # if not, act like Unix and assume it's in the PATH. + for vers in ("1.3", "1.2", "1.1"): + fn = os.path.join("c:\\swig%s" % vers, "swig.exe") + if os.path.isfile(fn): + return fn + else: + return "swig.exe" + + elif os.name == "os2": + # assume swig available in the PATH. + return "swig.exe" + + else: + raise DistutilsPlatformError, \ + ("I don't know how to find (much less run) SWIG " + "on platform '%s'") % os.name + + # find_swig () + + # -- Name generators ----------------------------------------------- + # (extension names, filenames, whatever) + def get_ext_fullpath(self, ext_name): + """Returns the path of the filename for a given extension. + + The file is located in `build_lib` or directly in the package + (inplace option). + """ + # makes sure the extension name is only using dots + all_dots = string.maketrans('/'+os.sep, '..') + ext_name = ext_name.translate(all_dots) + + fullname = self.get_ext_fullname(ext_name) + modpath = fullname.split('.') + filename = self.get_ext_filename(ext_name) + filename = os.path.split(filename)[-1] + + if not self.inplace: + # no further work needed + # returning : + # build_dir/package/path/filename + filename = os.path.join(*modpath[:-1]+[filename]) + return os.path.join(self.build_lib, filename) + + # the inplace option requires to find the package directory + # using the build_py command for that + package = '.'.join(modpath[0:-1]) + build_py = self.get_finalized_command('build_py') + package_dir = os.path.abspath(build_py.get_package_dir(package)) + + # returning + # package_dir/filename + return os.path.join(package_dir, filename) + + def get_ext_fullname(self, ext_name): + """Returns the fullname of a given extension name. + + Adds the `package.` prefix""" + if self.package is None: + return ext_name + else: + return self.package + '.' + ext_name + + def get_ext_filename(self, ext_name): + r"""Convert the name of an extension (eg. "foo.bar") into the name + of the file from which it will be loaded (eg. "foo/bar.so", or + "foo\bar.pyd"). + """ + from distutils.sysconfig import get_config_var + ext_path = string.split(ext_name, '.') + # OS/2 has an 8 character module (extension) limit :-( + if os.name == "os2": + ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8] + # extensions in debug_mode are named 'module_d.pyd' under windows + so_ext = get_config_var('SO') + if os.name == 'nt' and self.debug: + return os.path.join(*ext_path) + '_d' + so_ext + return os.path.join(*ext_path) + so_ext + + def get_export_symbols (self, ext): + """Return the list of symbols that a shared extension has to + export. This either uses 'ext.export_symbols' or, if it's not + provided, "init" + module_name. Only relevant on Windows, where + the .pyd file (DLL) must export the module "init" function. + """ + initfunc_name = "init" + ext.name.split('.')[-1] + if initfunc_name not in ext.export_symbols: + ext.export_symbols.append(initfunc_name) + return ext.export_symbols + + def get_libraries (self, ext): + """Return the list of libraries to link against when building a + shared extension. On most platforms, this is just 'ext.libraries'; + on Windows and OS/2, we add the Python library (eg. python20.dll). + """ + # The python library is always needed on Windows. For MSVC, this + # is redundant, since the library is mentioned in a pragma in + # pyconfig.h that MSVC groks. The other Windows compilers all seem + # to need it mentioned explicitly, though, so that's what we do. + # Append '_d' to the python import library on debug builds. + if sys.platform == "win32": + from distutils.msvccompiler import MSVCCompiler + if not isinstance(self.compiler, MSVCCompiler): + template = "python%d%d" + if self.debug: + template = template + '_d' + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib] + else: + return ext.libraries + elif sys.platform == "os2emx": + # EMX/GCC requires the python library explicitly, and I + # believe VACPP does as well (though not confirmed) - AIM Apr01 + template = "python%d%d" + # debug versions of the main DLL aren't supported, at least + # not at this time - AIM Apr01 + #if self.debug: + # template = template + '_d' + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib] + elif sys.platform[:6] == "cygwin": + template = "python%d.%d" + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib] + elif sys.platform[:6] == "atheos": + from distutils import sysconfig + + template = "python%d.%d" + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + # Get SHLIBS from Makefile + extra = [] + for lib in sysconfig.get_config_var('SHLIBS').split(): + if lib.startswith('-l'): + extra.append(lib[2:]) + else: + extra.append(lib) + # don't extend ext.libraries, it may be shared with other + # extensions, it is a reference to the original list + return ext.libraries + [pythonlib, "m"] + extra + + elif sys.platform == 'darwin': + # Don't use the default code below + return ext.libraries + elif sys.platform[:3] == 'aix': + # Don't use the default code below + return ext.libraries + else: + from distutils import sysconfig + if sysconfig.get_config_var('Py_ENABLE_SHARED'): + template = "python%d.%d" + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) + return ext.libraries + [pythonlib] + else: + return ext.libraries + +# class build_ext diff --git a/src/main/resources/PythonLibs/distutils/command/build_py.py b/src/main/resources/PythonLibs/distutils/command/build_py.py new file mode 100644 index 0000000000000000000000000000000000000000..04c455f0eb9a2efda0d6d199010f96bff26f3fe5 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/build_py.py @@ -0,0 +1,393 @@ +"""distutils.command.build_py + +Implements the Distutils 'build_py' command.""" + +__revision__ = "$Id$" + +import os +import sys +from glob import glob + +from distutils.core import Command +from distutils.errors import DistutilsOptionError, DistutilsFileError +from distutils.util import convert_path +from distutils import log + +class build_py(Command): + + description = "\"build\" pure Python modules (copy to build directory)" + + user_options = [ + ('build-lib=', 'd', "directory to \"build\" (copy) to"), + ('compile', 'c', "compile .py to .pyc"), + ('no-compile', None, "don't compile .py files [default]"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + ('force', 'f', "forcibly build everything (ignore file timestamps)"), + ] + + boolean_options = ['compile', 'force'] + negative_opt = {'no-compile' : 'compile'} + + def initialize_options(self): + self.build_lib = None + self.py_modules = None + self.package = None + self.package_data = None + self.package_dir = None + self.compile = 0 + self.optimize = 0 + self.force = None + + def finalize_options(self): + self.set_undefined_options('build', + ('build_lib', 'build_lib'), + ('force', 'force')) + + # Get the distribution options that are aliases for build_py + # options -- list of packages and list of modules. + self.packages = self.distribution.packages + self.py_modules = self.distribution.py_modules + self.package_data = self.distribution.package_data + self.package_dir = {} + if self.distribution.package_dir: + for name, path in self.distribution.package_dir.items(): + self.package_dir[name] = convert_path(path) + self.data_files = self.get_data_files() + + # Ick, copied straight from install_lib.py (fancy_getopt needs a + # type system! Hell, *everything* needs a type system!!!) + if not isinstance(self.optimize, int): + try: + self.optimize = int(self.optimize) + assert 0 <= self.optimize <= 2 + except (ValueError, AssertionError): + raise DistutilsOptionError("optimize must be 0, 1, or 2") + + def run(self): + # XXX copy_file by default preserves atime and mtime. IMHO this is + # the right thing to do, but perhaps it should be an option -- in + # particular, a site administrator might want installed files to + # reflect the time of installation rather than the last + # modification time before the installed release. + + # XXX copy_file by default preserves mode, which appears to be the + # wrong thing to do: if a file is read-only in the working + # directory, we want it to be installed read/write so that the next + # installation of the same module distribution can overwrite it + # without problems. (This might be a Unix-specific issue.) Thus + # we turn off 'preserve_mode' when copying to the build directory, + # since the build directory is supposed to be exactly what the + # installation will look like (ie. we preserve mode when + # installing). + + # Two options control which modules will be installed: 'packages' + # and 'py_modules'. The former lets us work with whole packages, not + # specifying individual modules at all; the latter is for + # specifying modules one-at-a-time. + + if self.py_modules: + self.build_modules() + if self.packages: + self.build_packages() + self.build_package_data() + + self.byte_compile(self.get_outputs(include_bytecode=0)) + + def get_data_files(self): + """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" + data = [] + if not self.packages: + return data + for package in self.packages: + # Locate package source directory + src_dir = self.get_package_dir(package) + + # Compute package build directory + build_dir = os.path.join(*([self.build_lib] + package.split('.'))) + + # Length of path to strip from found files + plen = 0 + if src_dir: + plen = len(src_dir)+1 + + # Strip directory from globbed filenames + filenames = [ + file[plen:] for file in self.find_data_files(package, src_dir) + ] + data.append((package, src_dir, build_dir, filenames)) + return data + + def find_data_files(self, package, src_dir): + """Return filenames for package's data files in 'src_dir'""" + globs = (self.package_data.get('', []) + + self.package_data.get(package, [])) + files = [] + for pattern in globs: + # Each pattern has to be converted to a platform-specific path + filelist = glob(os.path.join(src_dir, convert_path(pattern))) + # Files that match more than one pattern are only added once + files.extend([fn for fn in filelist if fn not in files]) + return files + + def build_package_data(self): + """Copy data files into build directory""" + for package, src_dir, build_dir, filenames in self.data_files: + for filename in filenames: + target = os.path.join(build_dir, filename) + self.mkpath(os.path.dirname(target)) + self.copy_file(os.path.join(src_dir, filename), target, + preserve_mode=False) + + def get_package_dir(self, package): + """Return the directory, relative to the top of the source + distribution, where package 'package' should be found + (at least according to the 'package_dir' option, if any).""" + + path = package.split('.') + + if not self.package_dir: + if path: + return os.path.join(*path) + else: + return '' + else: + tail = [] + while path: + try: + pdir = self.package_dir['.'.join(path)] + except KeyError: + tail.insert(0, path[-1]) + del path[-1] + else: + tail.insert(0, pdir) + return os.path.join(*tail) + else: + # Oops, got all the way through 'path' without finding a + # match in package_dir. If package_dir defines a directory + # for the root (nameless) package, then fallback on it; + # otherwise, we might as well have not consulted + # package_dir at all, as we just use the directory implied + # by 'tail' (which should be the same as the original value + # of 'path' at this point). + pdir = self.package_dir.get('') + if pdir is not None: + tail.insert(0, pdir) + + if tail: + return os.path.join(*tail) + else: + return '' + + def check_package(self, package, package_dir): + # Empty dir name means current directory, which we can probably + # assume exists. Also, os.path.exists and isdir don't know about + # my "empty string means current dir" convention, so we have to + # circumvent them. + if package_dir != "": + if not os.path.exists(package_dir): + raise DistutilsFileError( + "package directory '%s' does not exist" % package_dir) + if not os.path.isdir(package_dir): + raise DistutilsFileError( + "supposed package directory '%s' exists, " + "but is not a directory" % package_dir) + + # Require __init__.py for all but the "root package" + if package: + init_py = os.path.join(package_dir, "__init__.py") + if os.path.isfile(init_py): + return init_py + else: + log.warn(("package init file '%s' not found " + + "(or not a regular file)"), init_py) + + # Either not in a package at all (__init__.py not expected), or + # __init__.py doesn't exist -- so don't return the filename. + return None + + def check_module(self, module, module_file): + if not os.path.isfile(module_file): + log.warn("file %s (for module %s) not found", module_file, module) + return False + else: + return True + + def find_package_modules(self, package, package_dir): + self.check_package(package, package_dir) + module_files = glob(os.path.join(package_dir, "*.py")) + modules = [] + setup_script = os.path.abspath(self.distribution.script_name) + + for f in module_files: + abs_f = os.path.abspath(f) + if abs_f != setup_script: + module = os.path.splitext(os.path.basename(f))[0] + modules.append((package, module, f)) + else: + self.debug_print("excluding %s" % setup_script) + return modules + + def find_modules(self): + """Finds individually-specified Python modules, ie. those listed by + module name in 'self.py_modules'. Returns a list of tuples (package, + module_base, filename): 'package' is a tuple of the path through + package-space to the module; 'module_base' is the bare (no + packages, no dots) module name, and 'filename' is the path to the + ".py" file (relative to the distribution root) that implements the + module. + """ + # Map package names to tuples of useful info about the package: + # (package_dir, checked) + # package_dir - the directory where we'll find source files for + # this package + # checked - true if we have checked that the package directory + # is valid (exists, contains __init__.py, ... ?) + packages = {} + + # List of (package, module, filename) tuples to return + modules = [] + + # We treat modules-in-packages almost the same as toplevel modules, + # just the "package" for a toplevel is empty (either an empty + # string or empty list, depending on context). Differences: + # - don't check for __init__.py in directory for empty package + for module in self.py_modules: + path = module.split('.') + package = '.'.join(path[0:-1]) + module_base = path[-1] + + try: + (package_dir, checked) = packages[package] + except KeyError: + package_dir = self.get_package_dir(package) + checked = 0 + + if not checked: + init_py = self.check_package(package, package_dir) + packages[package] = (package_dir, 1) + if init_py: + modules.append((package, "__init__", init_py)) + + # XXX perhaps we should also check for just .pyc files + # (so greedy closed-source bastards can distribute Python + # modules too) + module_file = os.path.join(package_dir, module_base + ".py") + if not self.check_module(module, module_file): + continue + + modules.append((package, module_base, module_file)) + + return modules + + def find_all_modules(self): + """Compute the list of all modules that will be built, whether + they are specified one-module-at-a-time ('self.py_modules') or + by whole packages ('self.packages'). Return a list of tuples + (package, module, module_file), just like 'find_modules()' and + 'find_package_modules()' do.""" + modules = [] + if self.py_modules: + modules.extend(self.find_modules()) + if self.packages: + for package in self.packages: + package_dir = self.get_package_dir(package) + m = self.find_package_modules(package, package_dir) + modules.extend(m) + return modules + + def get_source_files(self): + return [module[-1] for module in self.find_all_modules()] + + def get_module_outfile(self, build_dir, package, module): + outfile_path = [build_dir] + list(package) + [module + ".py"] + return os.path.join(*outfile_path) + + def get_outputs(self, include_bytecode=1): + modules = self.find_all_modules() + outputs = [] + for (package, module, module_file) in modules: + package = package.split('.') + filename = self.get_module_outfile(self.build_lib, package, module) + outputs.append(filename) + if include_bytecode: + if self.compile: + outputs.append(filename + "c") + if self.optimize > 0: + outputs.append(filename + "o") + + outputs += [ + os.path.join(build_dir, filename) + for package, src_dir, build_dir, filenames in self.data_files + for filename in filenames + ] + + return outputs + + def build_module(self, module, module_file, package): + if isinstance(package, str): + package = package.split('.') + elif not isinstance(package, (list, tuple)): + raise TypeError( + "'package' must be a string (dot-separated), list, or tuple") + + # Now put the module source file into the "build" area -- this is + # easy, we just copy it somewhere under self.build_lib (the build + # directory for Python source). + outfile = self.get_module_outfile(self.build_lib, package, module) + dir = os.path.dirname(outfile) + self.mkpath(dir) + return self.copy_file(module_file, outfile, preserve_mode=0) + + def build_modules(self): + modules = self.find_modules() + for (package, module, module_file) in modules: + + # Now "build" the module -- ie. copy the source file to + # self.build_lib (the build directory for Python source). + # (Actually, it gets copied to the directory for this package + # under self.build_lib.) + self.build_module(module, module_file, package) + + def build_packages(self): + for package in self.packages: + + # Get list of (package, module, module_file) tuples based on + # scanning the package directory. 'package' is only included + # in the tuple so that 'find_modules()' and + # 'find_package_tuples()' have a consistent interface; it's + # ignored here (apart from a sanity check). Also, 'module' is + # the *unqualified* module name (ie. no dots, no package -- we + # already know its package!), and 'module_file' is the path to + # the .py file, relative to the current directory + # (ie. including 'package_dir'). + package_dir = self.get_package_dir(package) + modules = self.find_package_modules(package, package_dir) + + # Now loop over the modules we found, "building" each one (just + # copy it to self.build_lib). + for (package_, module, module_file) in modules: + assert package == package_ + self.build_module(module, module_file, package) + + def byte_compile(self, files): + if sys.dont_write_bytecode: + self.warn('byte-compiling is disabled, skipping.') + return + + from distutils.util import byte_compile + prefix = self.build_lib + if prefix[-1] != os.sep: + prefix = prefix + os.sep + + # XXX this code is essentially the same as the 'byte_compile() + # method of the "install_lib" command, except for the determination + # of the 'prefix' string. Hmmm. + + if self.compile: + byte_compile(files, optimize=0, + force=self.force, prefix=prefix, dry_run=self.dry_run) + if self.optimize > 0: + byte_compile(files, optimize=self.optimize, + force=self.force, prefix=prefix, dry_run=self.dry_run) diff --git a/src/main/resources/PythonLibs/distutils/command/build_scripts.py b/src/main/resources/PythonLibs/distutils/command/build_scripts.py new file mode 100644 index 0000000000000000000000000000000000000000..35755a1a7de469076776074d1e49a9dd6ed4affc --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/build_scripts.py @@ -0,0 +1,158 @@ +"""distutils.command.build_scripts + +Implements the Distutils 'build_scripts' command.""" + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id: build_scripts.py 59668 2008-01-02 18:59:36Z guido.van.rossum $" + +import sys, os, re +from stat import ST_MODE +from distutils import sysconfig +from distutils.core import Command +from distutils.dep_util import newer +from distutils.util import convert_path +from distutils import log + +# check if Python is called on the first line with this expression +first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$') + +class build_scripts (Command): + + description = "\"build\" scripts (copy and fixup #! line)" + + user_options = [ + ('build-dir=', 'd', "directory to \"build\" (copy) to"), + ('force', 'f', "forcibly build everything (ignore file timestamps"), + ('executable=', 'e', "specify final destination interpreter path"), + ] + + boolean_options = ['force'] + + + def initialize_options (self): + self.build_dir = None + self.scripts = None + self.force = None + self.executable = None + self.outfiles = None + + def finalize_options (self): + self.set_undefined_options('build', + ('build_scripts', 'build_dir'), + ('force', 'force'), + ('executable', 'executable')) + self.scripts = self.distribution.scripts + + def get_source_files(self): + return self.scripts + + def run (self): + if not self.scripts: + return + self.copy_scripts() + + + def copy_scripts (self): + """Copy each script listed in 'self.scripts'; if it's marked as a + Python script in the Unix way (first line matches 'first_line_re', + ie. starts with "\#!" and contains "python"), then adjust the first + line to refer to the current Python interpreter as we copy. + """ + self.mkpath(self.build_dir) + outfiles = [] + for script in self.scripts: + adjust = 0 + script = convert_path(script) + outfile = os.path.join(self.build_dir, os.path.basename(script)) + outfiles.append(outfile) + + if not self.force and not newer(script, outfile): + log.debug("not copying %s (up-to-date)", script) + continue + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, "r") + except IOError: + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: + self.warn("%s is an empty file (skipping)" % script) + continue + + match = first_line_re.match(first_line) + if match: + adjust = 1 + post_interp = match.group(1) or '' + + if adjust: + log.info("copying and adjusting %s -> %s", script, + self.build_dir) + if not sysconfig.python_build: + executable = self.executable + else: + executable = os.path.join( + sysconfig.get_config_var("BINDIR"), + "python" + sysconfig.get_config_var("EXE")) + executable = fix_jython_executable(executable, post_interp) + if not self.dry_run: + outf = open(outfile, "w") + outf.write("#!%s%s\n" % + (executable, + post_interp)) + outf.writelines(f.readlines()) + outf.close() + if f: + f.close() + else: + if f: + f.close() + self.copy_file(script, outfile) + + if hasattr(os, 'chmod'): + for file in outfiles: + if self.dry_run: + log.info("changing mode of %s", file) + else: + oldmode = os.stat(file)[ST_MODE] & 07777 + newmode = (oldmode | 0555) & 07777 + if newmode != oldmode: + log.info("changing mode of %s from %o to %o", + file, oldmode, newmode) + os.chmod(file, newmode) + + # copy_scripts () + +# class build_scripts + + +def is_sh(executable): + """Determine if the specified executable is a .sh (contains a #! line)""" + try: + fp = open(executable) + magic = fp.read(2) + fp.close() + except IOError, OSError: + return executable + return magic == '#!' + + +def fix_jython_executable(executable, options): + if sys.platform.startswith('java') and is_sh(executable): + # Workaround Jython's sys.executable being a .sh (an invalid + # shebang line interpreter) + if options: + # Can't apply the workaround, leave it broken + log.warn("WARNING: Unable to adapt shebang line for Jython," + " the following script is NOT executable\n" + " see http://bugs.jython.org/issue1112 for" + " more information.") + else: + return '/usr/bin/env %s' % executable + return executable diff --git a/src/main/resources/PythonLibs/distutils/command/check.py b/src/main/resources/PythonLibs/distutils/command/check.py new file mode 100644 index 0000000000000000000000000000000000000000..152bf0de98bf705261dc5b7a3ab9f5ed4ad82652 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/check.py @@ -0,0 +1,149 @@ +"""distutils.command.check + +Implements the Distutils 'check' command. +""" +__revision__ = "$Id$" + +from distutils.core import Command +from distutils.dist import PKG_INFO_ENCODING +from distutils.errors import DistutilsSetupError + +try: + # docutils is installed + from docutils.utils import Reporter + from docutils.parsers.rst import Parser + from docutils import frontend + from docutils import nodes + from StringIO import StringIO + + class SilentReporter(Reporter): + + def __init__(self, source, report_level, halt_level, stream=None, + debug=0, encoding='ascii', error_handler='replace'): + self.messages = [] + Reporter.__init__(self, source, report_level, halt_level, stream, + debug, encoding, error_handler) + + def system_message(self, level, message, *children, **kwargs): + self.messages.append((level, message, children, kwargs)) + return nodes.system_message(message, level=level, + type=self.levels[level], + *children, **kwargs) + + HAS_DOCUTILS = True +except ImportError: + # docutils is not installed + HAS_DOCUTILS = False + +class check(Command): + """This command checks the meta-data of the package. + """ + description = ("perform some checks on the package") + user_options = [('metadata', 'm', 'Verify meta-data'), + ('restructuredtext', 'r', + ('Checks if long string meta-data syntax ' + 'are reStructuredText-compliant')), + ('strict', 's', + 'Will exit with an error if a check fails')] + + boolean_options = ['metadata', 'restructuredtext', 'strict'] + + def initialize_options(self): + """Sets default values for options.""" + self.restructuredtext = 0 + self.metadata = 1 + self.strict = 0 + self._warnings = 0 + + def finalize_options(self): + pass + + def warn(self, msg): + """Counts the number of warnings that occurs.""" + self._warnings += 1 + return Command.warn(self, msg) + + def run(self): + """Runs the command.""" + # perform the various tests + if self.metadata: + self.check_metadata() + if self.restructuredtext: + if HAS_DOCUTILS: + self.check_restructuredtext() + elif self.strict: + raise DistutilsSetupError('The docutils package is needed.') + + # let's raise an error in strict mode, if we have at least + # one warning + if self.strict and self._warnings > 0: + raise DistutilsSetupError('Please correct your package.') + + def check_metadata(self): + """Ensures that all required elements of meta-data are supplied. + + name, version, URL, (author and author_email) or + (maintainer and maintainer_email)). + + Warns if any are missing. + """ + metadata = self.distribution.metadata + + missing = [] + for attr in ('name', 'version', 'url'): + if not (hasattr(metadata, attr) and getattr(metadata, attr)): + missing.append(attr) + + if missing: + self.warn("missing required meta-data: %s" % ', '.join(missing)) + if metadata.author: + if not metadata.author_email: + self.warn("missing meta-data: if 'author' supplied, " + + "'author_email' must be supplied too") + elif metadata.maintainer: + if not metadata.maintainer_email: + self.warn("missing meta-data: if 'maintainer' supplied, " + + "'maintainer_email' must be supplied too") + else: + self.warn("missing meta-data: either (author and author_email) " + + "or (maintainer and maintainer_email) " + + "must be supplied") + + def check_restructuredtext(self): + """Checks if the long string fields are reST-compliant.""" + data = self.distribution.get_long_description() + if not isinstance(data, unicode): + data = data.decode(PKG_INFO_ENCODING) + for warning in self._check_rst_data(data): + line = warning[-1].get('line') + if line is None: + warning = warning[1] + else: + warning = '%s (line %s)' % (warning[1], line) + self.warn(warning) + + def _check_rst_data(self, data): + """Returns warnings when the provided data doesn't compile.""" + source_path = StringIO() + parser = Parser() + settings = frontend.OptionParser().get_default_values() + settings.tab_width = 4 + settings.pep_references = None + settings.rfc_references = None + reporter = SilentReporter(source_path, + settings.report_level, + settings.halt_level, + stream=settings.warning_stream, + debug=settings.debug, + encoding=settings.error_encoding, + error_handler=settings.error_encoding_error_handler) + + document = nodes.document(settings, reporter, source=source_path) + document.note_source(source_path, -1) + try: + parser.parse(data, document) + except AttributeError: + reporter.messages.append((-1, 'Could not finish the parsing.', + '', {})) + + return reporter.messages diff --git a/src/main/resources/PythonLibs/distutils/command/clean.py b/src/main/resources/PythonLibs/distutils/command/clean.py new file mode 100644 index 0000000000000000000000000000000000000000..90ef35f1ca74018c2f2936b714b24ea38f904054 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/clean.py @@ -0,0 +1,80 @@ +"""distutils.command.clean + +Implements the Distutils 'clean' command.""" + +# contributed by Bastian Kleineidam <calvin@cs.uni-sb.de>, added 2000-03-18 + +__revision__ = "$Id$" + +import os +from distutils.core import Command +from distutils.dir_util import remove_tree +from distutils import log + +class clean(Command): + + description = "clean up temporary files from 'build' command" + user_options = [ + ('build-base=', 'b', + "base build directory (default: 'build.build-base')"), + ('build-lib=', None, + "build directory for all modules (default: 'build.build-lib')"), + ('build-temp=', 't', + "temporary build directory (default: 'build.build-temp')"), + ('build-scripts=', None, + "build directory for scripts (default: 'build.build-scripts')"), + ('bdist-base=', None, + "temporary directory for built distributions"), + ('all', 'a', + "remove all build output, not just temporary by-products") + ] + + boolean_options = ['all'] + + def initialize_options(self): + self.build_base = None + self.build_lib = None + self.build_temp = None + self.build_scripts = None + self.bdist_base = None + self.all = None + + def finalize_options(self): + self.set_undefined_options('build', + ('build_base', 'build_base'), + ('build_lib', 'build_lib'), + ('build_scripts', 'build_scripts'), + ('build_temp', 'build_temp')) + self.set_undefined_options('bdist', + ('bdist_base', 'bdist_base')) + + def run(self): + # remove the build/temp.<plat> directory (unless it's already + # gone) + if os.path.exists(self.build_temp): + remove_tree(self.build_temp, dry_run=self.dry_run) + else: + log.debug("'%s' does not exist -- can't clean it", + self.build_temp) + + if self.all: + # remove build directories + for directory in (self.build_lib, + self.bdist_base, + self.build_scripts): + if os.path.exists(directory): + remove_tree(directory, dry_run=self.dry_run) + else: + log.warn("'%s' does not exist -- can't clean it", + directory) + + # just for the heck of it, try to remove the base build directory: + # we might have emptied it right now, but if not we don't care + if not self.dry_run: + try: + os.rmdir(self.build_base) + log.info("removing '%s'", self.build_base) + except OSError: + pass + +# class clean diff --git a/src/main/resources/PythonLibs/distutils/command/command_template b/src/main/resources/PythonLibs/distutils/command/command_template new file mode 100644 index 0000000000000000000000000000000000000000..50bbab7b6ec0d44120f3e978164ceceedb267e14 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/command_template @@ -0,0 +1,45 @@ +"""distutils.command.x + +Implements the Distutils 'x' command. +""" + +# created 2000/mm/dd, John Doe + +__revision__ = "$Id$" + +from distutils.core import Command + + +class x (Command): + + # Brief (40-50 characters) description of the command + description = "" + + # List of option tuples: long name, short name (None if no short + # name), and help string. + user_options = [('', '', + ""), + ] + + + def initialize_options (self): + self. = None + self. = None + self. = None + + # initialize_options() + + + def finalize_options (self): + if self.x is None: + self.x = + + # finalize_options() + + + def run (self): + + + # run() + +# class x diff --git a/src/main/resources/PythonLibs/distutils/command/config.py b/src/main/resources/PythonLibs/distutils/command/config.py new file mode 100644 index 0000000000000000000000000000000000000000..b084913563a3e234521a746be24b4fb2b4837c4a --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/config.py @@ -0,0 +1,357 @@ +"""distutils.command.config + +Implements the Distutils 'config' command, a (mostly) empty command class +that exists mainly to be sub-classed by specific module distributions and +applications. The idea is that while every "config" command is different, +at least they're all named the same, and users always see "config" in the +list of standard commands. Also, this is a good place to put common +configure-like tasks: "try to compile this C code", or "figure out where +this header file lives". +""" + +__revision__ = "$Id$" + +import os +import re + +from distutils.core import Command +from distutils.errors import DistutilsExecError +from distutils.sysconfig import customize_compiler +from distutils import log + +LANG_EXT = {'c': '.c', 'c++': '.cxx'} + +class config(Command): + + description = "prepare to build" + + user_options = [ + ('compiler=', None, + "specify the compiler type"), + ('cc=', None, + "specify the compiler executable"), + ('include-dirs=', 'I', + "list of directories to search for header files"), + ('define=', 'D', + "C preprocessor macros to define"), + ('undef=', 'U', + "C preprocessor macros to undefine"), + ('libraries=', 'l', + "external C libraries to link with"), + ('library-dirs=', 'L', + "directories to search for external C libraries"), + + ('noisy', None, + "show every action (compile, link, run, ...) taken"), + ('dump-source', None, + "dump generated source files before attempting to compile them"), + ] + + + # The three standard command methods: since the "config" command + # does nothing by default, these are empty. + + def initialize_options(self): + self.compiler = None + self.cc = None + self.include_dirs = None + self.libraries = None + self.library_dirs = None + + # maximal output for now + self.noisy = 1 + self.dump_source = 1 + + # list of temporary files generated along-the-way that we have + # to clean at some point + self.temp_files = [] + + def finalize_options(self): + if self.include_dirs is None: + self.include_dirs = self.distribution.include_dirs or [] + elif isinstance(self.include_dirs, str): + self.include_dirs = self.include_dirs.split(os.pathsep) + + if self.libraries is None: + self.libraries = [] + elif isinstance(self.libraries, str): + self.libraries = [self.libraries] + + if self.library_dirs is None: + self.library_dirs = [] + elif isinstance(self.library_dirs, str): + self.library_dirs = self.library_dirs.split(os.pathsep) + + def run(self): + pass + + + # Utility methods for actual "config" commands. The interfaces are + # loosely based on Autoconf macros of similar names. Sub-classes + # may use these freely. + + def _check_compiler(self): + """Check that 'self.compiler' really is a CCompiler object; + if not, make it one. + """ + # We do this late, and only on-demand, because this is an expensive + # import. + from distutils.ccompiler import CCompiler, new_compiler + if not isinstance(self.compiler, CCompiler): + self.compiler = new_compiler(compiler=self.compiler, + dry_run=self.dry_run, force=1) + customize_compiler(self.compiler) + if self.include_dirs: + self.compiler.set_include_dirs(self.include_dirs) + if self.libraries: + self.compiler.set_libraries(self.libraries) + if self.library_dirs: + self.compiler.set_library_dirs(self.library_dirs) + + + def _gen_temp_sourcefile(self, body, headers, lang): + filename = "_configtest" + LANG_EXT[lang] + file = open(filename, "w") + if headers: + for header in headers: + file.write("#include <%s>\n" % header) + file.write("\n") + file.write(body) + if body[-1] != "\n": + file.write("\n") + file.close() + return filename + + def _preprocess(self, body, headers, include_dirs, lang): + src = self._gen_temp_sourcefile(body, headers, lang) + out = "_configtest.i" + self.temp_files.extend([src, out]) + self.compiler.preprocess(src, out, include_dirs=include_dirs) + return (src, out) + + def _compile(self, body, headers, include_dirs, lang): + src = self._gen_temp_sourcefile(body, headers, lang) + if self.dump_source: + dump_file(src, "compiling '%s':" % src) + (obj,) = self.compiler.object_filenames([src]) + self.temp_files.extend([src, obj]) + self.compiler.compile([src], include_dirs=include_dirs) + return (src, obj) + + def _link(self, body, headers, include_dirs, libraries, library_dirs, + lang): + (src, obj) = self._compile(body, headers, include_dirs, lang) + prog = os.path.splitext(os.path.basename(src))[0] + self.compiler.link_executable([obj], prog, + libraries=libraries, + library_dirs=library_dirs, + target_lang=lang) + + if self.compiler.exe_extension is not None: + prog = prog + self.compiler.exe_extension + self.temp_files.append(prog) + + return (src, obj, prog) + + def _clean(self, *filenames): + if not filenames: + filenames = self.temp_files + self.temp_files = [] + log.info("removing: %s", ' '.join(filenames)) + for filename in filenames: + try: + os.remove(filename) + except OSError: + pass + + + # XXX these ignore the dry-run flag: what to do, what to do? even if + # you want a dry-run build, you still need some sort of configuration + # info. My inclination is to make it up to the real config command to + # consult 'dry_run', and assume a default (minimal) configuration if + # true. The problem with trying to do it here is that you'd have to + # return either true or false from all the 'try' methods, neither of + # which is correct. + + # XXX need access to the header search path and maybe default macros. + + def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"): + """Construct a source file from 'body' (a string containing lines + of C/C++ code) and 'headers' (a list of header files to include) + and run it through the preprocessor. Return true if the + preprocessor succeeded, false if there were any errors. + ('body' probably isn't of much use, but what the heck.) + """ + from distutils.ccompiler import CompileError + self._check_compiler() + ok = 1 + try: + self._preprocess(body, headers, include_dirs, lang) + except CompileError: + ok = 0 + + self._clean() + return ok + + def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, + lang="c"): + """Construct a source file (just like 'try_cpp()'), run it through + the preprocessor, and return true if any line of the output matches + 'pattern'. 'pattern' should either be a compiled regex object or a + string containing a regex. If both 'body' and 'headers' are None, + preprocesses an empty file -- which can be useful to determine the + symbols the preprocessor and compiler set by default. + """ + self._check_compiler() + src, out = self._preprocess(body, headers, include_dirs, lang) + + if isinstance(pattern, str): + pattern = re.compile(pattern) + + file = open(out) + match = 0 + while 1: + line = file.readline() + if line == '': + break + if pattern.search(line): + match = 1 + break + + file.close() + self._clean() + return match + + def try_compile(self, body, headers=None, include_dirs=None, lang="c"): + """Try to compile a source file built from 'body' and 'headers'. + Return true on success, false otherwise. + """ + from distutils.ccompiler import CompileError + self._check_compiler() + try: + self._compile(body, headers, include_dirs, lang) + ok = 1 + except CompileError: + ok = 0 + + log.info(ok and "success!" or "failure.") + self._clean() + return ok + + def try_link(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): + """Try to compile and link a source file, built from 'body' and + 'headers', to executable form. Return true on success, false + otherwise. + """ + from distutils.ccompiler import CompileError, LinkError + self._check_compiler() + try: + self._link(body, headers, include_dirs, + libraries, library_dirs, lang) + ok = 1 + except (CompileError, LinkError): + ok = 0 + + log.info(ok and "success!" or "failure.") + self._clean() + return ok + + def try_run(self, body, headers=None, include_dirs=None, libraries=None, + library_dirs=None, lang="c"): + """Try to compile, link to an executable, and run a program + built from 'body' and 'headers'. Return true on success, false + otherwise. + """ + from distutils.ccompiler import CompileError, LinkError + self._check_compiler() + try: + src, obj, exe = self._link(body, headers, include_dirs, + libraries, library_dirs, lang) + self.spawn([exe]) + ok = 1 + except (CompileError, LinkError, DistutilsExecError): + ok = 0 + + log.info(ok and "success!" or "failure.") + self._clean() + return ok + + + # -- High-level methods -------------------------------------------- + # (these are the ones that are actually likely to be useful + # when implementing a real-world config command!) + + def check_func(self, func, headers=None, include_dirs=None, + libraries=None, library_dirs=None, decl=0, call=0): + + """Determine if function 'func' is available by constructing a + source file that refers to 'func', and compiles and links it. + If everything succeeds, returns true; otherwise returns false. + + The constructed source file starts out by including the header + files listed in 'headers'. If 'decl' is true, it then declares + 'func' (as "int func()"); you probably shouldn't supply 'headers' + and set 'decl' true in the same call, or you might get errors about + a conflicting declarations for 'func'. Finally, the constructed + 'main()' function either references 'func' or (if 'call' is true) + calls it. 'libraries' and 'library_dirs' are used when + linking. + """ + + self._check_compiler() + body = [] + if decl: + body.append("int %s ();" % func) + body.append("int main () {") + if call: + body.append(" %s();" % func) + else: + body.append(" %s;" % func) + body.append("}") + body = "\n".join(body) + "\n" + + return self.try_link(body, headers, include_dirs, + libraries, library_dirs) + + # check_func () + + def check_lib(self, library, library_dirs=None, headers=None, + include_dirs=None, other_libraries=[]): + """Determine if 'library' is available to be linked against, + without actually checking that any particular symbols are provided + by it. 'headers' will be used in constructing the source file to + be compiled, but the only effect of this is to check if all the + header files listed are available. Any libraries listed in + 'other_libraries' will be included in the link, in case 'library' + has symbols that depend on other libraries. + """ + self._check_compiler() + return self.try_link("int main (void) { }", + headers, include_dirs, + [library]+other_libraries, library_dirs) + + def check_header(self, header, include_dirs=None, library_dirs=None, + lang="c"): + """Determine if the system header file named by 'header_file' + exists and can be found by the preprocessor; return true if so, + false otherwise. + """ + return self.try_cpp(body="/* No body */", headers=[header], + include_dirs=include_dirs) + + +def dump_file(filename, head=None): + """Dumps a file content into log.info. + + If head is not None, will be dumped before the file content. + """ + if head is None: + log.info('%s' % filename) + else: + log.info(head) + file = open(filename) + try: + log.info(file.read()) + finally: + file.close() diff --git a/src/main/resources/PythonLibs/distutils/command/install.py b/src/main/resources/PythonLibs/distutils/command/install.py new file mode 100644 index 0000000000000000000000000000000000000000..baffa1d019bb615eef87b7ef4c73a68481ad7345 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/install.py @@ -0,0 +1,614 @@ +"""distutils.command.install + +Implements the Distutils 'install' command.""" + +from distutils import log + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id: install.py 43363 2006-03-27 21:55:21Z phillip.eby $" + +import sys, os, string +from types import * +from distutils.core import Command +from distutils.debug import DEBUG +from distutils.sysconfig import get_config_vars +from distutils.errors import DistutilsPlatformError +from distutils.file_util import write_file +from distutils.util import convert_path, subst_vars, change_root +from distutils.errors import DistutilsOptionError +from glob import glob + +if sys.version < "2.2": + WINDOWS_SCHEME = { + 'purelib': '$base', + 'platlib': '$base', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } +else: + WINDOWS_SCHEME = { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } + +INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', + 'platlib': '$platbase/lib/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', + 'platlib': '$base/lib/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'nt': WINDOWS_SCHEME, + 'mac': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, + 'os2': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + }, + 'java': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + } + } + +# The keys to an installation scheme; if any new types of files are to be +# installed, be sure to add an entry to every installation scheme above, +# and to SCHEME_KEYS here. +SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') + + +class install (Command): + + description = "install everything from build directory" + + user_options = [ + # Select installation scheme and set base director(y|ies) + ('prefix=', None, + "installation prefix"), + ('exec-prefix=', None, + "(Unix only) prefix for platform-specific files"), + ('home=', None, + "(Unix only) home directory to install under"), + + # Or, just set the base director(y|ies) + ('install-base=', None, + "base installation directory (instead of --prefix or --home)"), + ('install-platbase=', None, + "base installation directory for platform-specific files " + + "(instead of --exec-prefix or --home)"), + ('root=', None, + "install everything relative to this alternate root directory"), + + # Or, explicitly set the installation scheme + ('install-purelib=', None, + "installation directory for pure Python module distributions"), + ('install-platlib=', None, + "installation directory for non-pure module distributions"), + ('install-lib=', None, + "installation directory for all module distributions " + + "(overrides --install-purelib and --install-platlib)"), + + ('install-headers=', None, + "installation directory for C/C++ headers"), + ('install-scripts=', None, + "installation directory for Python scripts"), + ('install-data=', None, + "installation directory for data files"), + + # Byte-compilation options -- see install_lib.py for details, as + # these are duplicated from there (but only install_lib does + # anything with them). + ('compile', 'c', "compile .py to .pyc [default]"), + ('no-compile', None, "don't compile .py files"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + + # Miscellaneous control options + ('force', 'f', + "force installation (overwrite any existing files)"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + + # Where to install documentation (eventually!) + #('doc-format=', None, "format of documentation to generate"), + #('install-man=', None, "directory for Unix man pages"), + #('install-html=', None, "directory for HTML documentation"), + #('install-info=', None, "directory for GNU info files"), + + ('record=', None, + "filename in which to record list of installed files"), + ] + + boolean_options = ['compile', 'force', 'skip-build'] + negative_opt = {'no-compile' : 'compile'} + + + def initialize_options (self): + + # High-level options: these select both an installation base + # and scheme. + self.prefix = None + self.exec_prefix = None + self.home = None + + # These select only the installation base; it's up to the user to + # specify the installation scheme (currently, that means supplying + # the --install-{platlib,purelib,scripts,data} options). + self.install_base = None + self.install_platbase = None + self.root = None + + # These options are the actual installation directories; if not + # supplied by the user, they are filled in using the installation + # scheme implied by prefix/exec-prefix/home and the contents of + # that installation scheme. + self.install_purelib = None # for pure module distributions + self.install_platlib = None # non-pure (dists w/ extensions) + self.install_headers = None # for C/C++ headers + self.install_lib = None # set to either purelib or platlib + self.install_scripts = None + self.install_data = None + + self.compile = None + self.optimize = None + + # These two are for putting non-packagized distributions into their + # own directory and creating a .pth file if it makes sense. + # 'extra_path' comes from the setup file; 'install_path_file' can + # be turned off if it makes no sense to install a .pth file. (But + # better to install it uselessly than to guess wrong and not + # install it when it's necessary and would be used!) Currently, + # 'install_path_file' is always true unless some outsider meddles + # with it. + self.extra_path = None + self.install_path_file = 1 + + # 'force' forces installation, even if target files are not + # out-of-date. 'skip_build' skips running the "build" command, + # handy if you know it's not necessary. 'warn_dir' (which is *not* + # a user option, it's just there so the bdist_* commands can turn + # it off) determines whether we warn about installing to a + # directory not in sys.path. + self.force = 0 + self.skip_build = 0 + self.warn_dir = 1 + + # These are only here as a conduit from the 'build' command to the + # 'install_*' commands that do the real work. ('build_base' isn't + # actually used anywhere, but it might be useful in future.) They + # are not user options, because if the user told the install + # command where the build directory is, that wouldn't affect the + # build command. + self.build_base = None + self.build_lib = None + + # Not defined yet because we don't know anything about + # documentation yet. + #self.install_man = None + #self.install_html = None + #self.install_info = None + + self.record = None + + + # -- Option finalizing methods ------------------------------------- + # (This is rather more involved than for most commands, + # because this is where the policy for installing third- + # party Python modules on various platforms given a wide + # array of user input is decided. Yes, it's quite complex!) + + def finalize_options (self): + + # This method (and its pliant slaves, like 'finalize_unix()', + # 'finalize_other()', and 'select_scheme()') is where the default + # installation directories for modules, extension modules, and + # anything else we care to install from a Python module + # distribution. Thus, this code makes a pretty important policy + # statement about how third-party stuff is added to a Python + # installation! Note that the actual work of installation is done + # by the relatively simple 'install_*' commands; they just take + # their orders from the installation directory options determined + # here. + + # Check for errors/inconsistencies in the options; first, stuff + # that's wrong on any platform. + + if ((self.prefix or self.exec_prefix or self.home) and + (self.install_base or self.install_platbase)): + raise DistutilsOptionError, \ + ("must supply either prefix/exec-prefix/home or " + + "install-base/install-platbase -- not both") + + if self.home and (self.prefix or self.exec_prefix): + raise DistutilsOptionError, \ + "must supply either home or prefix/exec-prefix -- not both" + + # Next, stuff that's wrong (or dubious) only on certain platforms. + if os.name != "posix": + if self.exec_prefix: + self.warn("exec-prefix option ignored on this platform") + self.exec_prefix = None + + # Now the interesting logic -- so interesting that we farm it out + # to other methods. The goal of these methods is to set the final + # values for the install_{lib,scripts,data,...} options, using as + # input a heady brew of prefix, exec_prefix, home, install_base, + # install_platbase, user-supplied versions of + # install_{purelib,platlib,lib,scripts,data,...}, and the + # INSTALL_SCHEME dictionary above. Phew! + + self.dump_dirs("pre-finalize_{unix,other}") + + if os.name == 'posix': + self.finalize_unix() + else: + self.finalize_other() + + self.dump_dirs("post-finalize_{unix,other}()") + + # Expand configuration variables, tilde, etc. in self.install_base + # and self.install_platbase -- that way, we can use $base or + # $platbase in the other installation directories and not worry + # about needing recursive variable expansion (shudder). + + py_version = (string.split(sys.version))[0] + (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') + self.config_vars = {'dist_name': self.distribution.get_name(), + 'dist_version': self.distribution.get_version(), + 'dist_fullname': self.distribution.get_fullname(), + 'py_version': py_version, + 'py_version_short': py_version[0:3], + 'sys_prefix': prefix, + 'prefix': prefix, + 'sys_exec_prefix': exec_prefix, + 'exec_prefix': exec_prefix, + } + self.expand_basedirs() + + self.dump_dirs("post-expand_basedirs()") + + # Now define config vars for the base directories so we can expand + # everything else. + self.config_vars['base'] = self.install_base + self.config_vars['platbase'] = self.install_platbase + + if DEBUG: + from pprint import pprint + print "config vars:" + pprint(self.config_vars) + + # Expand "~" and configuration variables in the installation + # directories. + self.expand_dirs() + + self.dump_dirs("post-expand_dirs()") + + # Pick the actual directory to install all modules to: either + # install_purelib or install_platlib, depending on whether this + # module distribution is pure or not. Of course, if the user + # already specified install_lib, use their selection. + if self.install_lib is None: + if self.distribution.ext_modules: # has extensions: non-pure + self.install_lib = self.install_platlib + else: + self.install_lib = self.install_purelib + + + # Convert directories from Unix /-separated syntax to the local + # convention. + self.convert_paths('lib', 'purelib', 'platlib', + 'scripts', 'data', 'headers') + + # Well, we're not actually fully completely finalized yet: we still + # have to deal with 'extra_path', which is the hack for allowing + # non-packagized module distributions (hello, Numerical Python!) to + # get their own directories. + self.handle_extra_path() + self.install_libbase = self.install_lib # needed for .pth file + self.install_lib = os.path.join(self.install_lib, self.extra_dirs) + + # If a new root directory was supplied, make all the installation + # dirs relative to it. + if self.root is not None: + self.change_roots('libbase', 'lib', 'purelib', 'platlib', + 'scripts', 'data', 'headers') + + self.dump_dirs("after prepending root") + + # Find out the build directories, ie. where to install from. + self.set_undefined_options('build', + ('build_base', 'build_base'), + ('build_lib', 'build_lib')) + + # Punt on doc directories for now -- after all, we're punting on + # documentation completely! + + # finalize_options () + + + def dump_dirs (self, msg): + if DEBUG: + from distutils.fancy_getopt import longopt_xlate + print msg + ":" + for opt in self.user_options: + opt_name = opt[0] + if opt_name[-1] == "=": + opt_name = opt_name[0:-1] + if self.negative_opt.has_key(opt_name): + opt_name = string.translate(self.negative_opt[opt_name], + longopt_xlate) + val = not getattr(self, opt_name) + else: + opt_name = string.translate(opt_name, longopt_xlate) + val = getattr(self, opt_name) + print " %s: %s" % (opt_name, val) + + + def finalize_unix (self): + + if self.install_base is not None or self.install_platbase is not None: + if ((self.install_lib is None and + self.install_purelib is None and + self.install_platlib is None) or + self.install_headers is None or + self.install_scripts is None or + self.install_data is None): + raise DistutilsOptionError, \ + ("install-base or install-platbase supplied, but " + "installation scheme is incomplete") + return + + if self.home is not None: + self.install_base = self.install_platbase = self.home + self.select_scheme("unix_home") + else: + if self.prefix is None: + if self.exec_prefix is not None: + raise DistutilsOptionError, \ + "must not supply exec-prefix without prefix" + + self.prefix = os.path.normpath(sys.prefix) + self.exec_prefix = os.path.normpath(sys.exec_prefix) + + else: + if self.exec_prefix is None: + self.exec_prefix = self.prefix + + self.install_base = self.prefix + self.install_platbase = self.exec_prefix + self.select_scheme("unix_prefix") + + # finalize_unix () + + + def finalize_other (self): # Windows and Mac OS for now + + if self.home is not None: + self.install_base = self.install_platbase = self.home + self.select_scheme("unix_home") + else: + if self.prefix is None: + self.prefix = os.path.normpath(sys.prefix) + + self.install_base = self.install_platbase = self.prefix + try: + self.select_scheme(os.name) + except KeyError: + raise DistutilsPlatformError, \ + "I don't know how to install stuff on '%s'" % os.name + + # finalize_other () + + + def select_scheme (self, name): + # it's the caller's problem if they supply a bad name! + scheme = INSTALL_SCHEMES[name] + for key in SCHEME_KEYS: + attrname = 'install_' + key + if getattr(self, attrname) is None: + setattr(self, attrname, scheme[key]) + + + def _expand_attrs (self, attrs): + for attr in attrs: + val = getattr(self, attr) + if val is not None: + if os.name == 'posix': + val = os.path.expanduser(val) + val = subst_vars(val, self.config_vars) + setattr(self, attr, val) + + + def expand_basedirs (self): + self._expand_attrs(['install_base', + 'install_platbase', + 'root']) + + def expand_dirs (self): + self._expand_attrs(['install_purelib', + 'install_platlib', + 'install_lib', + 'install_headers', + 'install_scripts', + 'install_data',]) + + + def convert_paths (self, *names): + for name in names: + attr = "install_" + name + setattr(self, attr, convert_path(getattr(self, attr))) + + + def handle_extra_path (self): + + if self.extra_path is None: + self.extra_path = self.distribution.extra_path + + if self.extra_path is not None: + if type(self.extra_path) is StringType: + self.extra_path = string.split(self.extra_path, ',') + + if len(self.extra_path) == 1: + path_file = extra_dirs = self.extra_path[0] + elif len(self.extra_path) == 2: + (path_file, extra_dirs) = self.extra_path + else: + raise DistutilsOptionError, \ + ("'extra_path' option must be a list, tuple, or " + "comma-separated string with 1 or 2 elements") + + # convert to local form in case Unix notation used (as it + # should be in setup scripts) + extra_dirs = convert_path(extra_dirs) + + else: + path_file = None + extra_dirs = '' + + # XXX should we warn if path_file and not extra_dirs? (in which + # case the path file would be harmless but pointless) + self.path_file = path_file + self.extra_dirs = extra_dirs + + # handle_extra_path () + + + def change_roots (self, *names): + for name in names: + attr = "install_" + name + setattr(self, attr, change_root(self.root, getattr(self, attr))) + + + # -- Command execution methods ------------------------------------- + + def run (self): + + # Obviously have to build before we can install + if not self.skip_build: + self.run_command('build') + + # Run all sub-commands (at least those that need to be run) + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + if self.path_file: + self.create_path_file() + + # write list of installed files, if requested. + if self.record: + outputs = self.get_outputs() + if self.root: # strip any package prefix + root_len = len(self.root) + for counter in xrange(len(outputs)): + outputs[counter] = outputs[counter][root_len:] + self.execute(write_file, + (self.record, outputs), + "writing list of installed files to '%s'" % + self.record) + + sys_path = map(os.path.normpath, sys.path) + sys_path = map(os.path.normcase, sys_path) + install_lib = os.path.normcase(os.path.normpath(self.install_lib)) + if (self.warn_dir and + not (self.path_file and self.install_path_file) and + install_lib not in sys_path): + log.debug(("modules installed to '%s', which is not in " + "Python's module search path (sys.path) -- " + "you'll have to change the search path yourself"), + self.install_lib) + + # run () + + def create_path_file (self): + filename = os.path.join(self.install_libbase, + self.path_file + ".pth") + if self.install_path_file: + self.execute(write_file, + (filename, [self.extra_dirs]), + "creating %s" % filename) + else: + self.warn("path file '%s' not created" % filename) + + + # -- Reporting methods --------------------------------------------- + + def get_outputs (self): + # Assemble the outputs of all the sub-commands. + outputs = [] + for cmd_name in self.get_sub_commands(): + cmd = self.get_finalized_command(cmd_name) + # Add the contents of cmd.get_outputs(), ensuring + # that outputs doesn't contain duplicate entries + for filename in cmd.get_outputs(): + if filename not in outputs: + outputs.append(filename) + + if self.path_file and self.install_path_file: + outputs.append(os.path.join(self.install_libbase, + self.path_file + ".pth")) + + return outputs + + def get_inputs (self): + # XXX gee, this looks familiar ;-( + inputs = [] + for cmd_name in self.get_sub_commands(): + cmd = self.get_finalized_command(cmd_name) + inputs.extend(cmd.get_inputs()) + + return inputs + + + # -- Predicates for sub-command list ------------------------------- + + def has_lib (self): + """Return true if the current distribution has any Python + modules to install.""" + return (self.distribution.has_pure_modules() or + self.distribution.has_ext_modules()) + + def has_headers (self): + return self.distribution.has_headers() + + def has_scripts (self): + return self.distribution.has_scripts() + + def has_data (self): + return self.distribution.has_data_files() + + + # 'sub_commands': a list of commands this command might have to run to + # get its work done. See cmd.py for more info. + sub_commands = [('install_lib', has_lib), + ('install_headers', has_headers), + ('install_scripts', has_scripts), + ('install_data', has_data), + ('install_egg_info', lambda self:True), + ] + +# class install diff --git a/src/main/resources/PythonLibs/distutils/command/install_data.py b/src/main/resources/PythonLibs/distutils/command/install_data.py new file mode 100644 index 0000000000000000000000000000000000000000..ab40797b9866537d9aba9029ed52ecc6cf66bee0 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/install_data.py @@ -0,0 +1,81 @@ +"""distutils.command.install_data + +Implements the Distutils 'install_data' command, for installing +platform-independent data files.""" + +# contributed by Bastian Kleineidam + +__revision__ = "$Id$" + +import os +from distutils.core import Command +from distutils.util import change_root, convert_path + +class install_data(Command): + + description = "install data files" + + user_options = [ + ('install-dir=', 'd', + "base directory for installing data files " + "(default: installation base dir)"), + ('root=', None, + "install everything relative to this alternate root directory"), + ('force', 'f', "force installation (overwrite existing files)"), + ] + + boolean_options = ['force'] + + def initialize_options(self): + self.install_dir = None + self.outfiles = [] + self.root = None + self.force = 0 + self.data_files = self.distribution.data_files + self.warn_dir = 1 + + def finalize_options(self): + self.set_undefined_options('install', + ('install_data', 'install_dir'), + ('root', 'root'), + ('force', 'force'), + ) + + def run(self): + self.mkpath(self.install_dir) + for f in self.data_files: + if isinstance(f, str): + # it's a simple file, so copy it + f = convert_path(f) + if self.warn_dir: + self.warn("setup script did not provide a directory for " + "'%s' -- installing right in '%s'" % + (f, self.install_dir)) + (out, _) = self.copy_file(f, self.install_dir) + self.outfiles.append(out) + else: + # it's a tuple with path to install to and a list of files + dir = convert_path(f[0]) + if not os.path.isabs(dir): + dir = os.path.join(self.install_dir, dir) + elif self.root: + dir = change_root(self.root, dir) + self.mkpath(dir) + + if f[1] == []: + # If there are no files listed, the user must be + # trying to create an empty directory, so add the + # directory to the list of output files. + self.outfiles.append(dir) + else: + # Copy files, adding them to the list of output files. + for data in f[1]: + data = convert_path(data) + (out, _) = self.copy_file(data, dir) + self.outfiles.append(out) + + def get_inputs(self): + return self.data_files or [] + + def get_outputs(self): + return self.outfiles diff --git a/src/main/resources/PythonLibs/distutils/command/install_egg_info.py b/src/main/resources/PythonLibs/distutils/command/install_egg_info.py new file mode 100644 index 0000000000000000000000000000000000000000..c8880310dfcf645fb5728dfb5ad90de79d24c17a --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/install_egg_info.py @@ -0,0 +1,78 @@ +"""distutils.command.install_egg_info + +Implements the Distutils 'install_egg_info' command, for installing +a package's PKG-INFO metadata.""" + + +from distutils.cmd import Command +from distutils import log, dir_util +import os, sys, re + +class install_egg_info(Command): + """Install an .egg-info file for the package""" + + description = "Install package's PKG-INFO metadata as an .egg-info file" + user_options = [ + ('install-dir=', 'd', "directory to install to"), + ] + + def initialize_options(self): + self.install_dir = None + + def finalize_options(self): + self.set_undefined_options('install_lib',('install_dir','install_dir')) + basename = "%s-%s-py%s.egg-info" % ( + to_filename(safe_name(self.distribution.get_name())), + to_filename(safe_version(self.distribution.get_version())), + sys.version[:3] + ) + self.target = os.path.join(self.install_dir, basename) + self.outputs = [self.target] + + def run(self): + target = self.target + if os.path.isdir(target) and not os.path.islink(target): + dir_util.remove_tree(target, dry_run=self.dry_run) + elif os.path.exists(target): + self.execute(os.unlink,(self.target,),"Removing "+target) + elif not os.path.isdir(self.install_dir): + self.execute(os.makedirs, (self.install_dir,), + "Creating "+self.install_dir) + log.info("Writing %s", target) + if not self.dry_run: + f = open(target, 'w') + self.distribution.metadata.write_pkg_file(f) + f.close() + + def get_outputs(self): + return self.outputs + + +# The following routines are taken from setuptools' pkg_resources module and +# can be replaced by importing them from pkg_resources once it is included +# in the stdlib. + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """Convert an arbitrary string to a standard version string + + Spaces become dots, and all other non-alphanumeric characters become + dashes, with runs of multiple dashes condensed to a single dash. + """ + version = version.replace(' ','.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-','_') diff --git a/src/main/resources/PythonLibs/distutils/command/install_headers.py b/src/main/resources/PythonLibs/distutils/command/install_headers.py new file mode 100644 index 0000000000000000000000000000000000000000..d892416a8ccd9c6374eaaef3cc373698a972a22e --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/install_headers.py @@ -0,0 +1,51 @@ +"""distutils.command.install_headers + +Implements the Distutils 'install_headers' command, to install C/C++ header +files to the Python include directory.""" + +__revision__ = "$Id$" + +from distutils.core import Command + + +# XXX force is never used +class install_headers(Command): + + description = "install C/C++ header files" + + user_options = [('install-dir=', 'd', + "directory to install header files to"), + ('force', 'f', + "force installation (overwrite existing files)"), + ] + + boolean_options = ['force'] + + def initialize_options(self): + self.install_dir = None + self.force = 0 + self.outfiles = [] + + def finalize_options(self): + self.set_undefined_options('install', + ('install_headers', 'install_dir'), + ('force', 'force')) + + + def run(self): + headers = self.distribution.headers + if not headers: + return + + self.mkpath(self.install_dir) + for header in headers: + (out, _) = self.copy_file(header, self.install_dir) + self.outfiles.append(out) + + def get_inputs(self): + return self.distribution.headers or [] + + def get_outputs(self): + return self.outfiles + +# class install_headers diff --git a/src/main/resources/PythonLibs/distutils/command/install_lib.py b/src/main/resources/PythonLibs/distutils/command/install_lib.py new file mode 100644 index 0000000000000000000000000000000000000000..043e8b6e27151e959d123938720a6d4978ca5701 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/install_lib.py @@ -0,0 +1,219 @@ +"""distutils.command.install_lib + +Implements the Distutils 'install_lib' command +(install all Python modules).""" + +__revision__ = "$Id$" + +import os +import sys + +from distutils.core import Command +from distutils.errors import DistutilsOptionError + + +# Extension for Python source files. +if hasattr(os, 'extsep'): + PYTHON_SOURCE_EXTENSION = os.extsep + "py" +else: + PYTHON_SOURCE_EXTENSION = ".py" + +class install_lib(Command): + + description = "install all Python modules (extensions and pure Python)" + + # The byte-compilation options are a tad confusing. Here are the + # possible scenarios: + # 1) no compilation at all (--no-compile --no-optimize) + # 2) compile .pyc only (--compile --no-optimize; default) + # 3) compile .pyc and "level 1" .pyo (--compile --optimize) + # 4) compile "level 1" .pyo only (--no-compile --optimize) + # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more) + # 6) compile "level 2" .pyo only (--no-compile --optimize-more) + # + # The UI for this is two option, 'compile' and 'optimize'. + # 'compile' is strictly boolean, and only decides whether to + # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and + # decides both whether to generate .pyo files and what level of + # optimization to use. + + user_options = [ + ('install-dir=', 'd', "directory to install to"), + ('build-dir=','b', "build directory (where to install from)"), + ('force', 'f', "force installation (overwrite existing files)"), + ('compile', 'c', "compile .py to .pyc [default]"), + ('no-compile', None, "don't compile .py files"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + ('skip-build', None, "skip the build steps"), + ] + + boolean_options = ['force', 'compile', 'skip-build'] + negative_opt = {'no-compile' : 'compile'} + + def initialize_options(self): + # let the 'install' command dictate our installation directory + self.install_dir = None + self.build_dir = None + self.force = 0 + self.compile = None + self.optimize = None + self.skip_build = None + + def finalize_options(self): + # Get all the information we need to install pure Python modules + # from the umbrella 'install' command -- build (source) directory, + # install (target) directory, and whether to compile .py files. + self.set_undefined_options('install', + ('build_lib', 'build_dir'), + ('install_lib', 'install_dir'), + ('force', 'force'), + ('compile', 'compile'), + ('optimize', 'optimize'), + ('skip_build', 'skip_build'), + ) + + if self.compile is None: + self.compile = 1 + if self.optimize is None: + self.optimize = 0 + + if not isinstance(self.optimize, int): + try: + self.optimize = int(self.optimize) + if self.optimize not in (0, 1, 2): + raise AssertionError + except (ValueError, AssertionError): + raise DistutilsOptionError, "optimize must be 0, 1, or 2" + + def run(self): + # Make sure we have built everything we need first + self.build() + + # Install everything: simply dump the entire contents of the build + # directory to the installation directory (that's the beauty of + # having a build directory!) + outfiles = self.install() + + # (Optionally) compile .py to .pyc + if outfiles is not None and self.distribution.has_pure_modules(): + self.byte_compile(outfiles) + + # -- Top-level worker functions ------------------------------------ + # (called from 'run()') + + def build(self): + if not self.skip_build: + if self.distribution.has_pure_modules(): + self.run_command('build_py') + if self.distribution.has_ext_modules(): + self.run_command('build_ext') + + def install(self): + if os.path.isdir(self.build_dir): + outfiles = self.copy_tree(self.build_dir, self.install_dir) + else: + self.warn("'%s' does not exist -- no Python modules to install" % + self.build_dir) + return + return outfiles + + def byte_compile(self, files): + if sys.dont_write_bytecode: + self.warn('byte-compiling is disabled, skipping.') + return + + from distutils.util import byte_compile + + # Get the "--root" directory supplied to the "install" command, + # and use it as a prefix to strip off the purported filename + # encoded in bytecode files. This is far from complete, but it + # should at least generate usable bytecode in RPM distributions. + install_root = self.get_finalized_command('install').root + + if self.compile: + byte_compile(files, optimize=0, + force=self.force, prefix=install_root, + dry_run=self.dry_run) + if self.optimize > 0: + byte_compile(files, optimize=self.optimize, + force=self.force, prefix=install_root, + verbose=self.verbose, dry_run=self.dry_run) + + + # -- Utility methods ----------------------------------------------- + + def _mutate_outputs(self, has_any, build_cmd, cmd_option, output_dir): + if not has_any: + return [] + + build_cmd = self.get_finalized_command(build_cmd) + build_files = build_cmd.get_outputs() + build_dir = getattr(build_cmd, cmd_option) + + prefix_len = len(build_dir) + len(os.sep) + outputs = [] + for file in build_files: + outputs.append(os.path.join(output_dir, file[prefix_len:])) + + return outputs + + def _bytecode_filenames(self, py_filenames): + bytecode_files = [] + for py_file in py_filenames: + # Since build_py handles package data installation, the + # list of outputs can contain more than just .py files. + # Make sure we only report bytecode for the .py files. + ext = os.path.splitext(os.path.normcase(py_file))[1] + if ext != PYTHON_SOURCE_EXTENSION: + continue + if self.compile: + bytecode_files.append(py_file + "c") + if self.optimize > 0: + bytecode_files.append(py_file + "o") + + return bytecode_files + + + # -- External interface -------------------------------------------- + # (called by outsiders) + + def get_outputs(self): + """Return the list of files that would be installed if this command + were actually run. Not affected by the "dry-run" flag or whether + modules have actually been built yet. + """ + pure_outputs = \ + self._mutate_outputs(self.distribution.has_pure_modules(), + 'build_py', 'build_lib', + self.install_dir) + if self.compile: + bytecode_outputs = self._bytecode_filenames(pure_outputs) + else: + bytecode_outputs = [] + + ext_outputs = \ + self._mutate_outputs(self.distribution.has_ext_modules(), + 'build_ext', 'build_lib', + self.install_dir) + + return pure_outputs + bytecode_outputs + ext_outputs + + def get_inputs(self): + """Get the list of files that are input to this command, ie. the + files that get installed as they are named in the build tree. + The files in this list correspond one-to-one to the output + filenames returned by 'get_outputs()'. + """ + inputs = [] + + if self.distribution.has_pure_modules(): + build_py = self.get_finalized_command('build_py') + inputs.extend(build_py.get_outputs()) + + if self.distribution.has_ext_modules(): + build_ext = self.get_finalized_command('build_ext') + inputs.extend(build_ext.get_outputs()) + + return inputs diff --git a/src/main/resources/PythonLibs/distutils/command/install_scripts.py b/src/main/resources/PythonLibs/distutils/command/install_scripts.py new file mode 100644 index 0000000000000000000000000000000000000000..d0f4a2ea456e81a68ce51b2c2133e204e219ad6d --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/install_scripts.py @@ -0,0 +1,64 @@ +"""distutils.command.install_scripts + +Implements the Distutils 'install_scripts' command, for installing +Python scripts.""" + +# contributed by Bastian Kleineidam + +__revision__ = "$Id: install_scripts.py 68943 2009-01-25 22:09:10Z tarek.ziade $" + +import os +from distutils.core import Command +from distutils import log +from stat import ST_MODE + +class install_scripts (Command): + + description = "install scripts (Python or otherwise)" + + user_options = [ + ('install-dir=', 'd', "directory to install scripts to"), + ('build-dir=','b', "build directory (where to install from)"), + ('force', 'f', "force installation (overwrite existing files)"), + ('skip-build', None, "skip the build steps"), + ] + + boolean_options = ['force', 'skip-build'] + + + def initialize_options (self): + self.install_dir = None + self.force = 0 + self.build_dir = None + self.skip_build = None + + def finalize_options (self): + self.set_undefined_options('build', ('build_scripts', 'build_dir')) + self.set_undefined_options('install', + ('install_scripts', 'install_dir'), + ('force', 'force'), + ('skip_build', 'skip_build'), + ) + + def run (self): + if not self.skip_build: + self.run_command('build_scripts') + self.outfiles = self.copy_tree(self.build_dir, self.install_dir) + if hasattr(os, 'chmod'): + # Set the executable bits (owner, group, and world) on + # all the scripts we just installed. + for file in self.get_outputs(): + if self.dry_run: + log.info("changing mode of %s", file) + else: + mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777 + log.info("changing mode of %s to %o", file, mode) + os.chmod(file, mode) + + def get_inputs (self): + return self.distribution.scripts or [] + + def get_outputs(self): + return self.outfiles or [] + +# class install_scripts diff --git a/src/main/resources/PythonLibs/distutils/command/register.py b/src/main/resources/PythonLibs/distutils/command/register.py new file mode 100644 index 0000000000000000000000000000000000000000..edb42b955d6ab59276db6dc7da5188f61c84782d --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/register.py @@ -0,0 +1,315 @@ +"""distutils.command.register + +Implements the Distutils 'register' command (register with the repository). +""" + +# created 2002/10/21, Richard Jones + +__revision__ = "$Id$" + +import urllib2 +import getpass +import urlparse +from warnings import warn + +from distutils.core import PyPIRCCommand +from distutils import log + +class register(PyPIRCCommand): + + description = ("register the distribution with the Python package index") + user_options = PyPIRCCommand.user_options + [ + ('list-classifiers', None, + 'list the valid Trove classifiers'), + ('strict', None , + 'Will stop the registering if the meta-data are not fully compliant') + ] + boolean_options = PyPIRCCommand.boolean_options + [ + 'verify', 'list-classifiers', 'strict'] + + sub_commands = [('check', lambda self: True)] + + def initialize_options(self): + PyPIRCCommand.initialize_options(self) + self.list_classifiers = 0 + self.strict = 0 + + def finalize_options(self): + PyPIRCCommand.finalize_options(self) + # setting options for the `check` subcommand + check_options = {'strict': ('register', self.strict), + 'restructuredtext': ('register', 1)} + self.distribution.command_options['check'] = check_options + + def run(self): + self.finalize_options() + self._set_config() + + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + if self.dry_run: + self.verify_metadata() + elif self.list_classifiers: + self.classifiers() + else: + self.send_metadata() + + def check_metadata(self): + """Deprecated API.""" + warn("distutils.command.register.check_metadata is deprecated, \ + use the check command instead", PendingDeprecationWarning) + check = self.distribution.get_command_obj('check') + check.ensure_finalized() + check.strict = self.strict + check.restructuredtext = 1 + check.run() + + def _set_config(self): + ''' Reads the configuration file and set attributes. + ''' + config = self._read_pypirc() + if config != {}: + self.username = config['username'] + self.password = config['password'] + self.repository = config['repository'] + self.realm = config['realm'] + self.has_config = True + else: + if self.repository not in ('pypi', self.DEFAULT_REPOSITORY): + raise ValueError('%s not found in .pypirc' % self.repository) + if self.repository == 'pypi': + self.repository = self.DEFAULT_REPOSITORY + self.has_config = False + + def classifiers(self): + ''' Fetch the list of classifiers from the server. + ''' + response = urllib2.urlopen(self.repository+'?:action=list_classifiers') + log.info(response.read()) + + def verify_metadata(self): + ''' Send the metadata to the package index server to be checked. + ''' + # send the info to the server and report the result + (code, result) = self.post_to_server(self.build_post_data('verify')) + log.info('Server response (%s): %s' % (code, result)) + + + def send_metadata(self): + ''' Send the metadata to the package index server. + + Well, do the following: + 1. figure who the user is, and then + 2. send the data as a Basic auth'ed POST. + + First we try to read the username/password from $HOME/.pypirc, + which is a ConfigParser-formatted file with a section + [distutils] containing username and password entries (both + in clear text). Eg: + + [distutils] + index-servers = + pypi + + [pypi] + username: fred + password: sekrit + + Otherwise, to figure who the user is, we offer the user three + choices: + + 1. use existing login, + 2. register as a new user, or + 3. set the password to a random string and email the user. + + ''' + # see if we can short-cut and get the username/password from the + # config + if self.has_config: + choice = '1' + username = self.username + password = self.password + else: + choice = 'x' + username = password = '' + + # get the user's login info + choices = '1 2 3 4'.split() + while choice not in choices: + self.announce('''\ +We need to know who you are, so please choose either: + 1. use your existing login, + 2. register as a new user, + 3. have the server generate a new password for you (and email it to you), or + 4. quit +Your selection [default 1]: ''', log.INFO) + + choice = raw_input() + if not choice: + choice = '1' + elif choice not in choices: + print 'Please choose one of the four options!' + + if choice == '1': + # get the username and password + while not username: + username = raw_input('Username: ') + while not password: + password = getpass.getpass('Password: ') + + # set up the authentication + auth = urllib2.HTTPPasswordMgr() + host = urlparse.urlparse(self.repository)[1] + auth.add_password(self.realm, host, username, password) + # send the info to the server and report the result + code, result = self.post_to_server(self.build_post_data('submit'), + auth) + self.announce('Server response (%s): %s' % (code, result), + log.INFO) + + # possibly save the login + if code == 200: + if self.has_config: + # sharing the password in the distribution instance + # so the upload command can reuse it + self.distribution.password = password + else: + self.announce(('I can store your PyPI login so future ' + 'submissions will be faster.'), log.INFO) + self.announce('(the login will be stored in %s)' % \ + self._get_rc_file(), log.INFO) + choice = 'X' + while choice.lower() not in 'yn': + choice = raw_input('Save your login (y/N)?') + if not choice: + choice = 'n' + if choice.lower() == 'y': + self._store_pypirc(username, password) + + elif choice == '2': + data = {':action': 'user'} + data['name'] = data['password'] = data['email'] = '' + data['confirm'] = None + while not data['name']: + data['name'] = raw_input('Username: ') + while data['password'] != data['confirm']: + while not data['password']: + data['password'] = getpass.getpass('Password: ') + while not data['confirm']: + data['confirm'] = getpass.getpass(' Confirm: ') + if data['password'] != data['confirm']: + data['password'] = '' + data['confirm'] = None + print "Password and confirm don't match!" + while not data['email']: + data['email'] = raw_input(' EMail: ') + code, result = self.post_to_server(data) + if code != 200: + log.info('Server response (%s): %s' % (code, result)) + else: + log.info('You will receive an email shortly.') + log.info(('Follow the instructions in it to ' + 'complete registration.')) + elif choice == '3': + data = {':action': 'password_reset'} + data['email'] = '' + while not data['email']: + data['email'] = raw_input('Your email address: ') + code, result = self.post_to_server(data) + log.info('Server response (%s): %s' % (code, result)) + + def build_post_data(self, action): + # figure the data to send - the metadata plus some additional + # information used by the package server + meta = self.distribution.metadata + data = { + ':action': action, + 'metadata_version' : '1.0', + 'name': meta.get_name(), + 'version': meta.get_version(), + 'summary': meta.get_description(), + 'home_page': meta.get_url(), + 'author': meta.get_contact(), + 'author_email': meta.get_contact_email(), + 'license': meta.get_licence(), + 'description': meta.get_long_description(), + 'keywords': meta.get_keywords(), + 'platform': meta.get_platforms(), + 'classifiers': meta.get_classifiers(), + 'download_url': meta.get_download_url(), + # PEP 314 + 'provides': meta.get_provides(), + 'requires': meta.get_requires(), + 'obsoletes': meta.get_obsoletes(), + } + if data['provides'] or data['requires'] or data['obsoletes']: + data['metadata_version'] = '1.1' + return data + + def post_to_server(self, data, auth=None): + ''' Post a query to the server, and return a string response. + ''' + if 'name' in data: + self.announce('Registering %s to %s' % (data['name'], + self.repository), + log.INFO) + # Build up the MIME payload for the urllib2 POST data + boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = '\n--' + boundary + end_boundary = sep_boundary + '--' + chunks = [] + for key, value in data.items(): + # handle multiple entries for the same name + if type(value) not in (type([]), type( () )): + value = [value] + for value in value: + chunks.append(sep_boundary) + chunks.append('\nContent-Disposition: form-data; name="%s"'%key) + chunks.append("\n\n") + chunks.append(value) + if value and value[-1] == '\r': + chunks.append('\n') # write an extra newline (lurve Macs) + chunks.append(end_boundary) + chunks.append("\n") + + # chunks may be bytes (str) or unicode objects that we need to encode + body = [] + for chunk in chunks: + if isinstance(chunk, unicode): + body.append(chunk.encode('utf-8')) + else: + body.append(chunk) + + body = ''.join(body) + + # build the Request + headers = { + 'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary, + 'Content-length': str(len(body)) + } + req = urllib2.Request(self.repository, body, headers) + + # handle HTTP and include the Basic Auth handler + opener = urllib2.build_opener( + urllib2.HTTPBasicAuthHandler(password_mgr=auth) + ) + data = '' + try: + result = opener.open(req) + except urllib2.HTTPError, e: + if self.show_response: + data = e.fp.read() + result = e.code, e.msg + except urllib2.URLError, e: + result = 500, str(e) + else: + if self.show_response: + data = result.read() + result = 200, 'OK' + if self.show_response: + dashes = '-' * 75 + self.announce('%s%s%s' % (dashes, data, dashes)) + + return result diff --git a/src/main/resources/PythonLibs/distutils/command/sdist.py b/src/main/resources/PythonLibs/distutils/command/sdist.py new file mode 100644 index 0000000000000000000000000000000000000000..ca3e0b5cc6feab48bd5a039301f81bb94e5ff66b --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/sdist.py @@ -0,0 +1,469 @@ +"""distutils.command.sdist + +Implements the Distutils 'sdist' command (create a source distribution).""" + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id: sdist.py 61268 2008-03-06 07:14:26Z martin.v.loewis $" + +import sys, os, string +from types import * +from glob import glob +from distutils.core import Command +from distutils import dir_util, dep_util, file_util, archive_util +from distutils.text_file import TextFile +from distutils.errors import * +from distutils.filelist import FileList +from distutils import log + + +def show_formats (): + """Print all possible values for the 'formats' option (used by + the "--help-formats" command-line option). + """ + from distutils.fancy_getopt import FancyGetopt + from distutils.archive_util import ARCHIVE_FORMATS + formats=[] + for format in ARCHIVE_FORMATS.keys(): + formats.append(("formats=" + format, None, + ARCHIVE_FORMATS[format][2])) + formats.sort() + pretty_printer = FancyGetopt(formats) + pretty_printer.print_help( + "List of available source distribution formats:") + +class sdist (Command): + + description = "create a source distribution (tarball, zip file, etc.)" + + user_options = [ + ('template=', 't', + "name of manifest template file [default: MANIFEST.in]"), + ('manifest=', 'm', + "name of manifest file [default: MANIFEST]"), + ('use-defaults', None, + "include the default file set in the manifest " + "[default; disable with --no-defaults]"), + ('no-defaults', None, + "don't include the default file set"), + ('prune', None, + "specifically exclude files/directories that should not be " + "distributed (build tree, RCS/CVS dirs, etc.) " + "[default; disable with --no-prune]"), + ('no-prune', None, + "don't automatically exclude anything"), + ('manifest-only', 'o', + "just regenerate the manifest and then stop " + "(implies --force-manifest)"), + ('force-manifest', 'f', + "forcibly regenerate the manifest and carry on as usual"), + ('formats=', None, + "formats for source distribution (comma-separated list)"), + ('keep-temp', 'k', + "keep the distribution tree around after creating " + + "archive file(s)"), + ('dist-dir=', 'd', + "directory to put the source distribution archive(s) in " + "[default: dist]"), + ] + + boolean_options = ['use-defaults', 'prune', + 'manifest-only', 'force-manifest', + 'keep-temp'] + + help_options = [ + ('help-formats', None, + "list available distribution formats", show_formats), + ] + + negative_opt = {'no-defaults': 'use-defaults', + 'no-prune': 'prune' } + + default_format = { 'posix': 'gztar', + 'java': 'gztar', + 'nt': 'zip' } + + def initialize_options (self): + # 'template' and 'manifest' are, respectively, the names of + # the manifest template and manifest file. + self.template = None + self.manifest = None + + # 'use_defaults': if true, we will include the default file set + # in the manifest + self.use_defaults = 1 + self.prune = 1 + + self.manifest_only = 0 + self.force_manifest = 0 + + self.formats = None + self.keep_temp = 0 + self.dist_dir = None + + self.archive_files = None + + + def finalize_options (self): + if self.manifest is None: + self.manifest = "MANIFEST" + if self.template is None: + self.template = "MANIFEST.in" + + self.ensure_string_list('formats') + if self.formats is None: + try: + self.formats = [self.default_format[os.name]] + except KeyError: + raise DistutilsPlatformError, \ + "don't know how to create source distributions " + \ + "on platform %s" % os.name + + bad_format = archive_util.check_archive_formats(self.formats) + if bad_format: + raise DistutilsOptionError, \ + "unknown archive format '%s'" % bad_format + + if self.dist_dir is None: + self.dist_dir = "dist" + + + def run (self): + + # 'filelist' contains the list of files that will make up the + # manifest + self.filelist = FileList() + + # Ensure that all required meta-data is given; warn if not (but + # don't die, it's not *that* serious!) + self.check_metadata() + + # Do whatever it takes to get the list of files to process + # (process the manifest template, read an existing manifest, + # whatever). File list is accumulated in 'self.filelist'. + self.get_file_list() + + # If user just wanted us to regenerate the manifest, stop now. + if self.manifest_only: + return + + # Otherwise, go ahead and create the source distribution tarball, + # or zipfile, or whatever. + self.make_distribution() + + + def check_metadata (self): + """Ensure that all required elements of meta-data (name, version, + URL, (author and author_email) or (maintainer and + maintainer_email)) are supplied by the Distribution object; warn if + any are missing. + """ + metadata = self.distribution.metadata + + missing = [] + for attr in ('name', 'version', 'url'): + if not (hasattr(metadata, attr) and getattr(metadata, attr)): + missing.append(attr) + + if missing: + self.warn("missing required meta-data: " + + string.join(missing, ", ")) + + if metadata.author: + if not metadata.author_email: + self.warn("missing meta-data: if 'author' supplied, " + + "'author_email' must be supplied too") + elif metadata.maintainer: + if not metadata.maintainer_email: + self.warn("missing meta-data: if 'maintainer' supplied, " + + "'maintainer_email' must be supplied too") + else: + self.warn("missing meta-data: either (author and author_email) " + + "or (maintainer and maintainer_email) " + + "must be supplied") + + # check_metadata () + + + def get_file_list (self): + """Figure out the list of files to include in the source + distribution, and put it in 'self.filelist'. This might involve + reading the manifest template (and writing the manifest), or just + reading the manifest, or just using the default file set -- it all + depends on the user's options and the state of the filesystem. + """ + + # If we have a manifest template, see if it's newer than the + # manifest; if so, we'll regenerate the manifest. + template_exists = os.path.isfile(self.template) + if template_exists: + template_newer = dep_util.newer(self.template, self.manifest) + + # The contents of the manifest file almost certainly depend on the + # setup script as well as the manifest template -- so if the setup + # script is newer than the manifest, we'll regenerate the manifest + # from the template. (Well, not quite: if we already have a + # manifest, but there's no template -- which will happen if the + # developer elects to generate a manifest some other way -- then we + # can't regenerate the manifest, so we don't.) + self.debug_print("checking if %s newer than %s" % + (self.distribution.script_name, self.manifest)) + setup_newer = dep_util.newer(self.distribution.script_name, + self.manifest) + + # cases: + # 1) no manifest, template exists: generate manifest + # (covered by 2a: no manifest == template newer) + # 2) manifest & template exist: + # 2a) template or setup script newer than manifest: + # regenerate manifest + # 2b) manifest newer than both: + # do nothing (unless --force or --manifest-only) + # 3) manifest exists, no template: + # do nothing (unless --force or --manifest-only) + # 4) no manifest, no template: generate w/ warning ("defaults only") + + manifest_outofdate = (template_exists and + (template_newer or setup_newer)) + force_regen = self.force_manifest or self.manifest_only + manifest_exists = os.path.isfile(self.manifest) + neither_exists = (not template_exists and not manifest_exists) + + # Regenerate the manifest if necessary (or if explicitly told to) + if manifest_outofdate or neither_exists or force_regen: + if not template_exists: + self.warn(("manifest template '%s' does not exist " + + "(using default file list)") % + self.template) + self.filelist.findall() + + if self.use_defaults: + self.add_defaults() + if template_exists: + self.read_template() + if self.prune: + self.prune_file_list() + + self.filelist.sort() + self.filelist.remove_duplicates() + self.write_manifest() + + # Don't regenerate the manifest, just read it in. + else: + self.read_manifest() + + # get_file_list () + + + def add_defaults (self): + """Add all the default files to self.filelist: + - README or README.txt + - setup.py + - test/test*.py + - all pure Python modules mentioned in setup script + - all C sources listed as part of extensions or C libraries + in the setup script (doesn't catch C headers!) + Warns if (README or README.txt) or setup.py are missing; everything + else is optional. + """ + + standards = [('README', 'README.txt'), self.distribution.script_name] + for fn in standards: + if type(fn) is TupleType: + alts = fn + got_it = 0 + for fn in alts: + if os.path.exists(fn): + got_it = 1 + self.filelist.append(fn) + break + + if not got_it: + self.warn("standard file not found: should have one of " + + string.join(alts, ', ')) + else: + if os.path.exists(fn): + self.filelist.append(fn) + else: + self.warn("standard file '%s' not found" % fn) + + optional = ['test/test*.py', 'setup.cfg'] + for pattern in optional: + files = filter(os.path.isfile, glob(pattern)) + if files: + self.filelist.extend(files) + + if self.distribution.has_pure_modules(): + build_py = self.get_finalized_command('build_py') + self.filelist.extend(build_py.get_source_files()) + + if self.distribution.has_ext_modules(): + build_ext = self.get_finalized_command('build_ext') + self.filelist.extend(build_ext.get_source_files()) + + if self.distribution.has_c_libraries(): + build_clib = self.get_finalized_command('build_clib') + self.filelist.extend(build_clib.get_source_files()) + + if self.distribution.has_scripts(): + build_scripts = self.get_finalized_command('build_scripts') + self.filelist.extend(build_scripts.get_source_files()) + + # add_defaults () + + + def read_template (self): + """Read and parse manifest template file named by self.template. + + (usually "MANIFEST.in") The parsing and processing is done by + 'self.filelist', which updates itself accordingly. + """ + log.info("reading manifest template '%s'", self.template) + template = TextFile(self.template, + strip_comments=1, + skip_blanks=1, + join_lines=1, + lstrip_ws=1, + rstrip_ws=1, + collapse_join=1) + + while 1: + line = template.readline() + if line is None: # end of file + break + + try: + self.filelist.process_template_line(line) + except DistutilsTemplateError, msg: + self.warn("%s, line %d: %s" % (template.filename, + template.current_line, + msg)) + + # read_template () + + + def prune_file_list (self): + """Prune off branches that might slip into the file list as created + by 'read_template()', but really don't belong there: + * the build tree (typically "build") + * the release tree itself (only an issue if we ran "sdist" + previously with --keep-temp, or it aborted) + * any RCS, CVS, .svn, .hg, .git, .bzr, _darcs directories + """ + build = self.get_finalized_command('build') + base_dir = self.distribution.get_fullname() + + self.filelist.exclude_pattern(None, prefix=build.build_base) + self.filelist.exclude_pattern(None, prefix=base_dir) + self.filelist.exclude_pattern(r'(^|/)(RCS|CVS|\.svn|\.hg|\.git|\.bzr|_darcs)/.*', is_regex=1) + + + def write_manifest (self): + """Write the file list in 'self.filelist' (presumably as filled in + by 'add_defaults()' and 'read_template()') to the manifest file + named by 'self.manifest'. + """ + self.execute(file_util.write_file, + (self.manifest, self.filelist.files), + "writing manifest file '%s'" % self.manifest) + + # write_manifest () + + + def read_manifest (self): + """Read the manifest file (named by 'self.manifest') and use it to + fill in 'self.filelist', the list of files to include in the source + distribution. + """ + log.info("reading manifest file '%s'", self.manifest) + manifest = open(self.manifest) + try: + while 1: + line = manifest.readline() + if line == '': # end of file + break + if line[-1] == '\n': + line = line[0:-1] + self.filelist.append(line) + finally: + manifest.close() + + # read_manifest () + + + def make_release_tree (self, base_dir, files): + """Create the directory tree that will become the source + distribution archive. All directories implied by the filenames in + 'files' are created under 'base_dir', and then we hard link or copy + (if hard linking is unavailable) those files into place. + Essentially, this duplicates the developer's source tree, but in a + directory named after the distribution, containing only the files + to be distributed. + """ + # Create all the directories under 'base_dir' necessary to + # put 'files' there; the 'mkpath()' is just so we don't die + # if the manifest happens to be empty. + self.mkpath(base_dir) + dir_util.create_tree(base_dir, files, dry_run=self.dry_run) + + # And walk over the list of files, either making a hard link (if + # os.link exists) to each one that doesn't already exist in its + # corresponding location under 'base_dir', or copying each file + # that's out-of-date in 'base_dir'. (Usually, all files will be + # out-of-date, because by default we blow away 'base_dir' when + # we're done making the distribution archives.) + + if hasattr(os, 'link'): # can make hard links on this system + link = 'hard' + msg = "making hard links in %s..." % base_dir + else: # nope, have to copy + link = None + msg = "copying files to %s..." % base_dir + + if not files: + log.warn("no files to distribute -- empty manifest?") + else: + log.info(msg) + for file in files: + if not os.path.isfile(file): + log.warn("'%s' not a regular file -- skipping" % file) + else: + dest = os.path.join(base_dir, file) + self.copy_file(file, dest, link=link) + + self.distribution.metadata.write_pkg_info(base_dir) + + # make_release_tree () + + def make_distribution (self): + """Create the source distribution(s). First, we create the release + tree with 'make_release_tree()'; then, we create all required + archive files (according to 'self.formats') from the release tree. + Finally, we clean up by blowing away the release tree (unless + 'self.keep_temp' is true). The list of archive files created is + stored so it can be retrieved later by 'get_archive_files()'. + """ + # Don't warn about missing meta-data here -- should be (and is!) + # done elsewhere. + base_dir = self.distribution.get_fullname() + base_name = os.path.join(self.dist_dir, base_dir) + + self.make_release_tree(base_dir, self.filelist.files) + archive_files = [] # remember names of files we create + for fmt in self.formats: + file = self.make_archive(base_name, fmt, base_dir=base_dir) + archive_files.append(file) + self.distribution.dist_files.append(('sdist', '', file)) + + self.archive_files = archive_files + + if not self.keep_temp: + dir_util.remove_tree(base_dir, dry_run=self.dry_run) + + def get_archive_files (self): + """Return the list of archive files created when the command + was run, or None if the command hasn't run yet. + """ + return self.archive_files + +# class sdist diff --git a/src/main/resources/PythonLibs/distutils/command/upload.py b/src/main/resources/PythonLibs/distutils/command/upload.py new file mode 100644 index 0000000000000000000000000000000000000000..d0133353a63a6c4aed923cf16db3a2fa2b96afac --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/command/upload.py @@ -0,0 +1,194 @@ +"""distutils.command.upload + +Implements the Distutils 'upload' subcommand (upload package to PyPI).""" +import os +import socket +import platform +from urllib2 import urlopen, Request, HTTPError +from base64 import standard_b64encode +import urlparse +import cStringIO as StringIO +from hashlib import md5 + +from distutils.errors import DistutilsOptionError +from distutils.core import PyPIRCCommand +from distutils.spawn import spawn +from distutils import log + +class upload(PyPIRCCommand): + + description = "upload binary package to PyPI" + + user_options = PyPIRCCommand.user_options + [ + ('sign', 's', + 'sign files to upload using gpg'), + ('identity=', 'i', 'GPG identity used to sign files'), + ] + + boolean_options = PyPIRCCommand.boolean_options + ['sign'] + + def initialize_options(self): + PyPIRCCommand.initialize_options(self) + self.username = '' + self.password = '' + self.show_response = 0 + self.sign = False + self.identity = None + + def finalize_options(self): + PyPIRCCommand.finalize_options(self) + if self.identity and not self.sign: + raise DistutilsOptionError( + "Must use --sign for --identity to have meaning" + ) + config = self._read_pypirc() + if config != {}: + self.username = config['username'] + self.password = config['password'] + self.repository = config['repository'] + self.realm = config['realm'] + + # getting the password from the distribution + # if previously set by the register command + if not self.password and self.distribution.password: + self.password = self.distribution.password + + def run(self): + if not self.distribution.dist_files: + raise DistutilsOptionError("No dist file created in earlier command") + for command, pyversion, filename in self.distribution.dist_files: + self.upload_file(command, pyversion, filename) + + def upload_file(self, command, pyversion, filename): + # Makes sure the repository URL is compliant + schema, netloc, url, params, query, fragments = \ + urlparse.urlparse(self.repository) + if params or query or fragments: + raise AssertionError("Incompatible url %s" % self.repository) + + if schema not in ('http', 'https'): + raise AssertionError("unsupported schema " + schema) + + # Sign if requested + if self.sign: + gpg_args = ["gpg", "--detach-sign", "-a", filename] + if self.identity: + gpg_args[2:2] = ["--local-user", self.identity] + spawn(gpg_args, + dry_run=self.dry_run) + + # Fill in the data - send all the meta-data in case we need to + # register a new release + f = open(filename,'rb') + try: + content = f.read() + finally: + f.close() + meta = self.distribution.metadata + data = { + # action + ':action': 'file_upload', + 'protcol_version': '1', + + # identify release + 'name': meta.get_name(), + 'version': meta.get_version(), + + # file content + 'content': (os.path.basename(filename),content), + 'filetype': command, + 'pyversion': pyversion, + 'md5_digest': md5(content).hexdigest(), + + # additional meta-data + 'metadata_version' : '1.0', + 'summary': meta.get_description(), + 'home_page': meta.get_url(), + 'author': meta.get_contact(), + 'author_email': meta.get_contact_email(), + 'license': meta.get_licence(), + 'description': meta.get_long_description(), + 'keywords': meta.get_keywords(), + 'platform': meta.get_platforms(), + 'classifiers': meta.get_classifiers(), + 'download_url': meta.get_download_url(), + # PEP 314 + 'provides': meta.get_provides(), + 'requires': meta.get_requires(), + 'obsoletes': meta.get_obsoletes(), + } + comment = '' + if command == 'bdist_rpm': + dist, version, id = platform.dist() + if dist: + comment = 'built for %s %s' % (dist, version) + elif command == 'bdist_dumb': + comment = 'built for %s' % platform.platform(terse=1) + data['comment'] = comment + + if self.sign: + data['gpg_signature'] = (os.path.basename(filename) + ".asc", + open(filename+".asc").read()) + + # set up the authentication + auth = "Basic " + standard_b64encode(self.username + ":" + + self.password) + + # Build up the MIME payload for the POST data + boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = '\n--' + boundary + end_boundary = sep_boundary + '--' + body = StringIO.StringIO() + for key, value in data.items(): + # handle multiple entries for the same name + if not isinstance(value, list): + value = [value] + for value in value: + if isinstance(value, tuple): + fn = ';filename="%s"' % value[0] + value = value[1] + else: + fn = "" + + body.write(sep_boundary) + body.write('\nContent-Disposition: form-data; name="%s"'%key) + body.write(fn) + body.write("\n\n") + body.write(value) + if value and value[-1] == '\r': + body.write('\n') # write an extra newline (lurve Macs) + body.write(end_boundary) + body.write("\n") + body = body.getvalue() + + self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO) + + # build the Request + headers = {'Content-type': + 'multipart/form-data; boundary=%s' % boundary, + 'Content-length': str(len(body)), + 'Authorization': auth} + + request = Request(self.repository, data=body, + headers=headers) + # send the data + try: + result = urlopen(request) + status = result.getcode() + reason = result.msg + if self.show_response: + msg = '\n'.join(('-' * 75, r.read(), '-' * 75)) + self.announce(msg, log.INFO) + except socket.error, e: + self.announce(str(e), log.ERROR) + return + except HTTPError, e: + status = e.code + reason = e.msg + + if status == 200: + self.announce('Server response (%s): %s' % (status, reason), + log.INFO) + else: + self.announce('Upload failed (%s): %s' % (status, reason), + log.ERROR) diff --git a/src/main/resources/PythonLibs/distutils/command/wininst-6.0.exe b/src/main/resources/PythonLibs/distutils/command/wininst-6.0.exe new file mode 100644 index 0000000000000000000000000000000000000000..f57c855a613e2de2b00fff1df431b8d08d171077 Binary files /dev/null and b/src/main/resources/PythonLibs/distutils/command/wininst-6.0.exe differ diff --git a/src/main/resources/PythonLibs/distutils/command/wininst-7.1.exe b/src/main/resources/PythonLibs/distutils/command/wininst-7.1.exe new file mode 100644 index 0000000000000000000000000000000000000000..1433bc1ad3775ec9277e13ca8bdca3a5dbc23643 Binary files /dev/null and b/src/main/resources/PythonLibs/distutils/command/wininst-7.1.exe differ diff --git a/src/main/resources/PythonLibs/distutils/command/wininst-8.0.exe b/src/main/resources/PythonLibs/distutils/command/wininst-8.0.exe new file mode 100644 index 0000000000000000000000000000000000000000..7403bfabf5cc10c13ef2b6a2ea276b4f6d26ff37 Binary files /dev/null and b/src/main/resources/PythonLibs/distutils/command/wininst-8.0.exe differ diff --git a/src/main/resources/PythonLibs/distutils/command/wininst-9.0-amd64.exe b/src/main/resources/PythonLibs/distutils/command/wininst-9.0-amd64.exe new file mode 100644 index 0000000000000000000000000000000000000000..11d8011c717c3a1c54afbe00e002fab6d37766c6 Binary files /dev/null and b/src/main/resources/PythonLibs/distutils/command/wininst-9.0-amd64.exe differ diff --git a/src/main/resources/PythonLibs/distutils/command/wininst-9.0.exe b/src/main/resources/PythonLibs/distutils/command/wininst-9.0.exe new file mode 100644 index 0000000000000000000000000000000000000000..dadb31d8938b9b147830382495eee2453c171648 Binary files /dev/null and b/src/main/resources/PythonLibs/distutils/command/wininst-9.0.exe differ diff --git a/src/main/resources/PythonLibs/distutils/config.py b/src/main/resources/PythonLibs/distutils/config.py new file mode 100644 index 0000000000000000000000000000000000000000..1d327143bea711c3e6e765d3a6dab8f80da89da7 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/config.py @@ -0,0 +1,116 @@ +"""distutils.pypirc + +Provides the PyPIRCCommand class, the base class for the command classes +that uses .pypirc in the distutils.command package. +""" +import os +from ConfigParser import ConfigParser + +from distutils.cmd import Command + +DEFAULT_PYPIRC = """\ +[distutils] +index-servers = + pypi + +[pypi] +username:%s +password:%s +""" + +class PyPIRCCommand(Command): + """Base command that knows how to handle the .pypirc file + """ + DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi' + DEFAULT_REALM = 'pypi' + repository = None + realm = None + + user_options = [ + ('repository=', 'r', + "url of repository [default: %s]" % \ + DEFAULT_REPOSITORY), + ('show-response', None, + 'display full response text from server')] + + boolean_options = ['show-response'] + + def _get_rc_file(self): + """Returns rc file path.""" + return os.path.join(os.path.expanduser('~'), '.pypirc') + + def _store_pypirc(self, username, password): + """Creates a default .pypirc file.""" + rc = self._get_rc_file() + f = os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0600), 'w') + try: + f.write(DEFAULT_PYPIRC % (username, password)) + finally: + f.close() + + def _read_pypirc(self): + """Reads the .pypirc file.""" + rc = self._get_rc_file() + if os.path.exists(rc): + self.announce('Using PyPI login from %s' % rc) + repository = self.repository or self.DEFAULT_REPOSITORY + config = ConfigParser() + config.read(rc) + sections = config.sections() + if 'distutils' in sections: + # let's get the list of servers + index_servers = config.get('distutils', 'index-servers') + _servers = [server.strip() for server in + index_servers.split('\n') + if server.strip() != ''] + if _servers == []: + # nothing set, let's try to get the default pypi + if 'pypi' in sections: + _servers = ['pypi'] + else: + # the file is not properly defined, returning + # an empty dict + return {} + for server in _servers: + current = {'server': server} + current['username'] = config.get(server, 'username') + + # optional params + for key, default in (('repository', + self.DEFAULT_REPOSITORY), + ('realm', self.DEFAULT_REALM), + ('password', None)): + if config.has_option(server, key): + current[key] = config.get(server, key) + else: + current[key] = default + if (current['server'] == repository or + current['repository'] == repository): + return current + elif 'server-login' in sections: + # old format + server = 'server-login' + if config.has_option(server, 'repository'): + repository = config.get(server, 'repository') + else: + repository = self.DEFAULT_REPOSITORY + return {'username': config.get(server, 'username'), + 'password': config.get(server, 'password'), + 'repository': repository, + 'server': server, + 'realm': self.DEFAULT_REALM} + + return {} + + def initialize_options(self): + """Initialize options.""" + self.repository = None + self.realm = None + self.show_response = 0 + + def finalize_options(self): + """Finalizes options.""" + if self.repository is None: + self.repository = self.DEFAULT_REPOSITORY + if self.realm is None: + self.realm = self.DEFAULT_REALM diff --git a/src/main/resources/PythonLibs/distutils/core.py b/src/main/resources/PythonLibs/distutils/core.py new file mode 100644 index 0000000000000000000000000000000000000000..b89557d7679ce9e7f8ce8df8957e5d7175332695 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/core.py @@ -0,0 +1,242 @@ +"""distutils.core + +The only module that needs to be imported to use the Distutils; provides +the 'setup' function (which is to be called from the setup script). Also +indirectly provides the Distribution and Command classes, although they are +really defined in distutils.dist and distutils.cmd. +""" + +__revision__ = "$Id$" + +import sys +import os + +from distutils.debug import DEBUG +from distutils.errors import (DistutilsSetupError, DistutilsArgError, + DistutilsError, CCompilerError) +from distutils.util import grok_environment_error + +# Mainly import these so setup scripts can "from distutils.core import" them. +from distutils.dist import Distribution +from distutils.cmd import Command +from distutils.config import PyPIRCCommand +from distutils.extension import Extension + +# This is a barebones help message generated displayed when the user +# runs the setup script with no arguments at all. More useful help +# is generated with various --help options: global help, list commands, +# and per-command help. +USAGE = """\ +usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] + or: %(script)s --help [cmd1 cmd2 ...] + or: %(script)s --help-commands + or: %(script)s cmd --help +""" + +def gen_usage(script_name): + script = os.path.basename(script_name) + return USAGE % {'script': script} + + +# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'. +_setup_stop_after = None +_setup_distribution = None + +# Legal keyword arguments for the setup() function +setup_keywords = ('distclass', 'script_name', 'script_args', 'options', + 'name', 'version', 'author', 'author_email', + 'maintainer', 'maintainer_email', 'url', 'license', + 'description', 'long_description', 'keywords', + 'platforms', 'classifiers', 'download_url', + 'requires', 'provides', 'obsoletes', + ) + +# Legal keyword arguments for the Extension constructor +extension_keywords = ('name', 'sources', 'include_dirs', + 'define_macros', 'undef_macros', + 'library_dirs', 'libraries', 'runtime_library_dirs', + 'extra_objects', 'extra_compile_args', 'extra_link_args', + 'swig_opts', 'export_symbols', 'depends', 'language') + +def setup(**attrs): + """The gateway to the Distutils: do everything your setup script needs + to do, in a highly flexible and user-driven way. Briefly: create a + Distribution instance; find and parse config files; parse the command + line; run each Distutils command found there, customized by the options + supplied to 'setup()' (as keyword arguments), in config files, and on + the command line. + + The Distribution instance might be an instance of a class supplied via + the 'distclass' keyword argument to 'setup'; if no such class is + supplied, then the Distribution class (in dist.py) is instantiated. + All other arguments to 'setup' (except for 'cmdclass') are used to set + attributes of the Distribution instance. + + The 'cmdclass' argument, if supplied, is a dictionary mapping command + names to command classes. Each command encountered on the command line + will be turned into a command class, which is in turn instantiated; any + class found in 'cmdclass' is used in place of the default, which is + (for command 'foo_bar') class 'foo_bar' in module + 'distutils.command.foo_bar'. The command class must provide a + 'user_options' attribute which is a list of option specifiers for + 'distutils.fancy_getopt'. Any command-line options between the current + and the next command are used to set attributes of the current command + object. + + When the entire command-line has been successfully parsed, calls the + 'run()' method on each command object in turn. This method will be + driven entirely by the Distribution object (which each command object + has a reference to, thanks to its constructor), and the + command-specific options that became attributes of each command + object. + """ + + global _setup_stop_after, _setup_distribution + + # Determine the distribution class -- either caller-supplied or + # our Distribution (see below). + klass = attrs.get('distclass') + if klass: + del attrs['distclass'] + else: + klass = Distribution + + if 'script_name' not in attrs: + attrs['script_name'] = os.path.basename(sys.argv[0]) + if 'script_args' not in attrs: + attrs['script_args'] = sys.argv[1:] + + # Create the Distribution instance, using the remaining arguments + # (ie. everything except distclass) to initialize it + try: + _setup_distribution = dist = klass(attrs) + except DistutilsSetupError, msg: + if 'name' in attrs: + raise SystemExit, "error in %s setup command: %s" % \ + (attrs['name'], msg) + else: + raise SystemExit, "error in setup command: %s" % msg + + if _setup_stop_after == "init": + return dist + + # Find and parse the config file(s): they will override options from + # the setup script, but be overridden by the command line. + dist.parse_config_files() + + if DEBUG: + print "options (after parsing config files):" + dist.dump_option_dicts() + + if _setup_stop_after == "config": + return dist + + # Parse the command line and override config files; any + # command-line errors are the end user's fault, so turn them into + # SystemExit to suppress tracebacks. + try: + ok = dist.parse_command_line() + except DistutilsArgError, msg: + raise SystemExit, gen_usage(dist.script_name) + "\nerror: %s" % msg + + if DEBUG: + print "options (after parsing command line):" + dist.dump_option_dicts() + + if _setup_stop_after == "commandline": + return dist + + # And finally, run all the commands found on the command line. + if ok: + try: + dist.run_commands() + except KeyboardInterrupt: + raise SystemExit, "interrupted" + except (IOError, os.error), exc: + error = grok_environment_error(exc) + + if DEBUG: + sys.stderr.write(error + "\n") + raise + else: + raise SystemExit, error + + except (DistutilsError, + CCompilerError), msg: + if DEBUG: + raise + else: + raise SystemExit, "error: " + str(msg) + + return dist + + +def run_setup(script_name, script_args=None, stop_after="run"): + """Run a setup script in a somewhat controlled environment, and + return the Distribution instance that drives things. This is useful + if you need to find out the distribution meta-data (passed as + keyword args from 'script' to 'setup()', or the contents of the + config files or command-line. + + 'script_name' is a file that will be run with 'execfile()'; + 'sys.argv[0]' will be replaced with 'script' for the duration of the + call. 'script_args' is a list of strings; if supplied, + 'sys.argv[1:]' will be replaced by 'script_args' for the duration of + the call. + + 'stop_after' tells 'setup()' when to stop processing; possible + values: + init + stop after the Distribution instance has been created and + populated with the keyword arguments to 'setup()' + config + stop after config files have been parsed (and their data + stored in the Distribution instance) + commandline + stop after the command-line ('sys.argv[1:]' or 'script_args') + have been parsed (and the data stored in the Distribution) + run [default] + stop after all commands have been run (the same as if 'setup()' + had been called in the usual way + + Returns the Distribution instance, which provides all information + used to drive the Distutils. + """ + if stop_after not in ('init', 'config', 'commandline', 'run'): + raise ValueError, "invalid value for 'stop_after': %r" % (stop_after,) + + global _setup_stop_after, _setup_distribution + _setup_stop_after = stop_after + + save_argv = sys.argv + g = {'__file__': script_name} + l = {} + try: + try: + sys.argv[0] = script_name + if script_args is not None: + sys.argv[1:] = script_args + f = open(script_name) + try: + exec f.read() in g, l + finally: + f.close() + finally: + sys.argv = save_argv + _setup_stop_after = None + except SystemExit: + # Hmm, should we do something if exiting with a non-zero code + # (ie. error)? + pass + except: + raise + + if _setup_distribution is None: + raise RuntimeError, \ + ("'distutils.core.setup()' was never called -- " + "perhaps '%s' is not a Distutils setup script?") % \ + script_name + + # I wonder if the setup script's namespace -- g and l -- would be of + # any interest to callers? + return _setup_distribution diff --git a/src/main/resources/PythonLibs/distutils/cygwinccompiler.py b/src/main/resources/PythonLibs/distutils/cygwinccompiler.py new file mode 100644 index 0000000000000000000000000000000000000000..a1ee815c6cc782354a1ee1735a88d31679e1e4db --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/cygwinccompiler.py @@ -0,0 +1,449 @@ +"""distutils.cygwinccompiler + +Provides the CygwinCCompiler class, a subclass of UnixCCompiler that +handles the Cygwin port of the GNU C compiler to Windows. It also contains +the Mingw32CCompiler class which handles the mingw32 port of GCC (same as +cygwin in no-cygwin mode). +""" + +# problems: +# +# * if you use a msvc compiled python version (1.5.2) +# 1. you have to insert a __GNUC__ section in its config.h +# 2. you have to generate a import library for its dll +# - create a def-file for python??.dll +# - create a import library using +# dlltool --dllname python15.dll --def python15.def \ +# --output-lib libpython15.a +# +# see also http://starship.python.net/crew/kernr/mingw32/Notes.html +# +# * We put export_symbols in a def-file, and don't use +# --export-all-symbols because it doesn't worked reliable in some +# tested configurations. And because other windows compilers also +# need their symbols specified this no serious problem. +# +# tested configurations: +# +# * cygwin gcc 2.91.57/ld 2.9.4/dllwrap 0.2.4 works +# (after patching python's config.h and for C++ some other include files) +# see also http://starship.python.net/crew/kernr/mingw32/Notes.html +# * mingw32 gcc 2.95.2/ld 2.9.4/dllwrap 0.2.4 works +# (ld doesn't support -shared, so we use dllwrap) +# * cygwin gcc 2.95.2/ld 2.10.90/dllwrap 2.10.90 works now +# - its dllwrap doesn't work, there is a bug in binutils 2.10.90 +# see also http://sources.redhat.com/ml/cygwin/2000-06/msg01274.html +# - using gcc -mdll instead dllwrap doesn't work without -static because +# it tries to link against dlls instead their import libraries. (If +# it finds the dll first.) +# By specifying -static we force ld to link against the import libraries, +# this is windows standard and there are normally not the necessary symbols +# in the dlls. +# *** only the version of June 2000 shows these problems +# * cygwin gcc 3.2/ld 2.13.90 works +# (ld supports -shared) +# * mingw gcc 3.2/ld 2.13 works +# (ld supports -shared) + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id$" + +import os,sys,copy +from distutils.ccompiler import gen_preprocess_options, gen_lib_options +from distutils.unixccompiler import UnixCCompiler +from distutils.file_util import write_file +from distutils.errors import DistutilsExecError, CompileError, UnknownFileError +from distutils import log + +def get_msvcr(): + """Include the appropriate MSVC runtime library if Python was built + with MSVC 7.0 or later. + """ + msc_pos = sys.version.find('MSC v.') + if msc_pos != -1: + msc_ver = sys.version[msc_pos+6:msc_pos+10] + if msc_ver == '1300': + # MSVC 7.0 + return ['msvcr70'] + elif msc_ver == '1310': + # MSVC 7.1 + return ['msvcr71'] + elif msc_ver == '1400': + # VS2005 / MSVC 8.0 + return ['msvcr80'] + elif msc_ver == '1500': + # VS2008 / MSVC 9.0 + return ['msvcr90'] + else: + raise ValueError("Unknown MS Compiler version %s " % msc_ver) + + +class CygwinCCompiler (UnixCCompiler): + + compiler_type = 'cygwin' + obj_extension = ".o" + static_lib_extension = ".a" + shared_lib_extension = ".dll" + static_lib_format = "lib%s%s" + shared_lib_format = "%s%s" + exe_extension = ".exe" + + def __init__ (self, verbose=0, dry_run=0, force=0): + + UnixCCompiler.__init__ (self, verbose, dry_run, force) + + (status, details) = check_config_h() + self.debug_print("Python's GCC status: %s (details: %s)" % + (status, details)) + if status is not CONFIG_H_OK: + self.warn( + "Python's pyconfig.h doesn't seem to support your compiler. " + "Reason: %s. " + "Compiling may fail because of undefined preprocessor macros." + % details) + + self.gcc_version, self.ld_version, self.dllwrap_version = \ + get_versions() + self.debug_print(self.compiler_type + ": gcc %s, ld %s, dllwrap %s\n" % + (self.gcc_version, + self.ld_version, + self.dllwrap_version) ) + + # ld_version >= "2.10.90" and < "2.13" should also be able to use + # gcc -mdll instead of dllwrap + # Older dllwraps had own version numbers, newer ones use the + # same as the rest of binutils ( also ld ) + # dllwrap 2.10.90 is buggy + if self.ld_version >= "2.10.90": + self.linker_dll = "gcc" + else: + self.linker_dll = "dllwrap" + + # ld_version >= "2.13" support -shared so use it instead of + # -mdll -static + if self.ld_version >= "2.13": + shared_option = "-shared" + else: + shared_option = "-mdll -static" + + # Hard-code GCC because that's what this is all about. + # XXX optimization, warnings etc. should be customizable. + self.set_executables(compiler='gcc -mcygwin -O -Wall', + compiler_so='gcc -mcygwin -mdll -O -Wall', + compiler_cxx='g++ -mcygwin -O -Wall', + linker_exe='gcc -mcygwin', + linker_so=('%s -mcygwin %s' % + (self.linker_dll, shared_option))) + + # cygwin and mingw32 need different sets of libraries + if self.gcc_version == "2.91.57": + # cygwin shouldn't need msvcrt, but without the dlls will crash + # (gcc version 2.91.57) -- perhaps something about initialization + self.dll_libraries=["msvcrt"] + self.warn( + "Consider upgrading to a newer version of gcc") + else: + # Include the appropriate MSVC runtime library if Python was built + # with MSVC 7.0 or later. + self.dll_libraries = get_msvcr() + + # __init__ () + + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + if ext == '.rc' or ext == '.res': + # gcc needs '.res' and '.rc' compiled to object files !!! + try: + self.spawn(["windres", "-i", src, "-o", obj]) + except DistutilsExecError, msg: + raise CompileError, msg + else: # for other files use the C-compiler + try: + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + # use separate copies, so we can modify the lists + extra_preargs = copy.copy(extra_preargs or []) + libraries = copy.copy(libraries or []) + objects = copy.copy(objects or []) + + # Additional libraries + libraries.extend(self.dll_libraries) + + # handle export symbols by creating a def-file + # with executables this only works with gcc/ld as linker + if ((export_symbols is not None) and + (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): + # (The linker doesn't do anything if output is up-to-date. + # So it would probably better to check if we really need this, + # but for this we had to insert some unchanged parts of + # UnixCCompiler, and this is not what we want.) + + # we want to put some files in the same directory as the + # object files are, build_temp doesn't help much + # where are the object files + temp_dir = os.path.dirname(objects[0]) + # name of dll to give the helper files the same base name + (dll_name, dll_extension) = os.path.splitext( + os.path.basename(output_filename)) + + # generate the filenames for these files + def_file = os.path.join(temp_dir, dll_name + ".def") + lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a") + + # Generate .def file + contents = [ + "LIBRARY %s" % os.path.basename(output_filename), + "EXPORTS"] + for sym in export_symbols: + contents.append(sym) + self.execute(write_file, (def_file, contents), + "writing %s" % def_file) + + # next add options for def-file and to creating import libraries + + # dllwrap uses different options than gcc/ld + if self.linker_dll == "dllwrap": + extra_preargs.extend(["--output-lib", lib_file]) + # for dllwrap we have to use a special option + extra_preargs.extend(["--def", def_file]) + # we use gcc/ld here and can be sure ld is >= 2.9.10 + else: + # doesn't work: bfd_close build\...\libfoo.a: Invalid operation + #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) + # for gcc/ld the def-file is specified as any object files + objects.append(def_file) + + #end: if ((export_symbols is not None) and + # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): + + # who wants symbols and a many times larger output file + # should explicitly switch the debug mode on + # otherwise we let dllwrap/ld strip the output file + # (On my machine: 10KB < stripped_file < ??100KB + # unstripped_file = stripped_file + XXX KB + # ( XXX=254 for a typical python extension)) + if not debug: + extra_preargs.append("-s") + + UnixCCompiler.link(self, + target_desc, + objects, + output_filename, + output_dir, + libraries, + library_dirs, + runtime_library_dirs, + None, # export_symbols, we do this in our def-file + debug, + extra_preargs, + extra_postargs, + build_temp, + target_lang) + + # link () + + # -- Miscellaneous methods ----------------------------------------- + + # overwrite the one from CCompiler to support rc and res-files + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + # use normcase to make sure '.rc' is really '.rc' and not '.RC' + (base, ext) = os.path.splitext (os.path.normcase(src_name)) + if ext not in (self.src_extensions + ['.rc','.res']): + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % \ + (ext, src_name) + if strip_dir: + base = os.path.basename (base) + if ext == '.res' or ext == '.rc': + # these need to be compiled to object files + obj_names.append (os.path.join (output_dir, + base + ext + self.obj_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + +# class CygwinCCompiler + + +# the same as cygwin plus some additional parameters +class Mingw32CCompiler (CygwinCCompiler): + + compiler_type = 'mingw32' + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + CygwinCCompiler.__init__ (self, verbose, dry_run, force) + + # ld_version >= "2.13" support -shared so use it instead of + # -mdll -static + if self.ld_version >= "2.13": + shared_option = "-shared" + else: + shared_option = "-mdll -static" + + # A real mingw32 doesn't need to specify a different entry point, + # but cygwin 2.91.57 in no-cygwin-mode needs it. + if self.gcc_version <= "2.91.57": + entry_point = '--entry _DllMain@12' + else: + entry_point = '' + + self.set_executables(compiler='gcc -mno-cygwin -O -Wall', + compiler_so='gcc -mno-cygwin -mdll -O -Wall', + compiler_cxx='g++ -mno-cygwin -O -Wall', + linker_exe='gcc -mno-cygwin', + linker_so='%s -mno-cygwin %s %s' + % (self.linker_dll, shared_option, + entry_point)) + # Maybe we should also append -mthreads, but then the finished + # dlls need another dll (mingwm10.dll see Mingw32 docs) + # (-mthreads: Support thread-safe exception handling on `Mingw32') + + # no additional libraries needed + self.dll_libraries=[] + + # Include the appropriate MSVC runtime library if Python was built + # with MSVC 7.0 or later. + self.dll_libraries = get_msvcr() + + # __init__ () + +# class Mingw32CCompiler + +# Because these compilers aren't configured in Python's pyconfig.h file by +# default, we should at least warn the user if he is using a unmodified +# version. + +CONFIG_H_OK = "ok" +CONFIG_H_NOTOK = "not ok" +CONFIG_H_UNCERTAIN = "uncertain" + +def check_config_h(): + + """Check if the current Python installation (specifically, pyconfig.h) + appears amenable to building extensions with GCC. Returns a tuple + (status, details), where 'status' is one of the following constants: + CONFIG_H_OK + all is well, go ahead and compile + CONFIG_H_NOTOK + doesn't look good + CONFIG_H_UNCERTAIN + not sure -- unable to read pyconfig.h + 'details' is a human-readable string explaining the situation. + + Note there are two ways to conclude "OK": either 'sys.version' contains + the string "GCC" (implying that this Python was built with GCC), or the + installed "pyconfig.h" contains the string "__GNUC__". + """ + + # XXX since this function also checks sys.version, it's not strictly a + # "pyconfig.h" check -- should probably be renamed... + + from distutils import sysconfig + import string + # if sys.version contains GCC then python was compiled with + # GCC, and the pyconfig.h file should be OK + if string.find(sys.version,"GCC") >= 0: + return (CONFIG_H_OK, "sys.version mentions 'GCC'") + + fn = sysconfig.get_config_h_filename() + try: + # It would probably better to read single lines to search. + # But we do this only once, and it is fast enough + f = open(fn) + try: + s = f.read() + finally: + f.close() + + except IOError, exc: + # if we can't read this file, we cannot say it is wrong + # the compiler will complain later about this file as missing + return (CONFIG_H_UNCERTAIN, + "couldn't read '%s': %s" % (fn, exc.strerror)) + + else: + # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar + if string.find(s,"__GNUC__") >= 0: + return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn) + else: + return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn) + + + +def get_versions(): + """ Try to find out the versions of gcc, ld and dllwrap. + If not possible it returns None for it. + """ + from distutils.version import LooseVersion + from distutils.spawn import find_executable + import re + + gcc_exe = find_executable('gcc') + if gcc_exe: + out = os.popen(gcc_exe + ' -dumpversion','r') + out_string = out.read() + out.close() + result = re.search('(\d+\.\d+(\.\d+)*)',out_string) + if result: + gcc_version = LooseVersion(result.group(1)) + else: + gcc_version = None + else: + gcc_version = None + ld_exe = find_executable('ld') + if ld_exe: + out = os.popen(ld_exe + ' -v','r') + out_string = out.read() + out.close() + result = re.search('(\d+\.\d+(\.\d+)*)',out_string) + if result: + ld_version = LooseVersion(result.group(1)) + else: + ld_version = None + else: + ld_version = None + dllwrap_exe = find_executable('dllwrap') + if dllwrap_exe: + out = os.popen(dllwrap_exe + ' --version','r') + out_string = out.read() + out.close() + result = re.search(' (\d+\.\d+(\.\d+)*)',out_string) + if result: + dllwrap_version = LooseVersion(result.group(1)) + else: + dllwrap_version = None + else: + dllwrap_version = None + return (gcc_version, ld_version, dllwrap_version) diff --git a/src/main/resources/PythonLibs/distutils/debug.py b/src/main/resources/PythonLibs/distutils/debug.py new file mode 100644 index 0000000000000000000000000000000000000000..2886744402e1b5c219f5bbfcc5aab32418632e86 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/debug.py @@ -0,0 +1,7 @@ +import os + +__revision__ = "$Id$" + +# If DISTUTILS_DEBUG is anything other than the empty string, we run in +# debug mode. +DEBUG = os.environ.get('DISTUTILS_DEBUG') diff --git a/src/main/resources/PythonLibs/distutils/dep_util.py b/src/main/resources/PythonLibs/distutils/dep_util.py new file mode 100644 index 0000000000000000000000000000000000000000..2b759056ea8b2a0042355d715d984c496dae54a6 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/dep_util.py @@ -0,0 +1,89 @@ +"""distutils.dep_util + +Utility functions for simple, timestamp-based dependency of files +and groups of files; also, function based entirely on such +timestamp dependency analysis.""" + +__revision__ = "$Id$" + +import os +from stat import ST_MTIME +from distutils.errors import DistutilsFileError + +def newer(source, target): + """Tells if the target is newer than the source. + + Return true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Return false if both exist and 'target' is the same age or younger + than 'source'. Raise DistutilsFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same second + will have the same "age". + """ + if not os.path.exists(source): + raise DistutilsFileError("file '%s' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return True + + return os.stat(source)[ST_MTIME] > os.stat(target)[ST_MTIME] + +def newer_pairwise(sources, targets): + """Walk two filename lists in parallel, testing if each source is newer + than its corresponding target. Return a pair of lists (sources, + targets) where source is newer than target, according to the semantics + of 'newer()'. + """ + if len(sources) != len(targets): + raise ValueError, "'sources' and 'targets' must be same length" + + # build a pair of lists (sources, targets) where source is newer + n_sources = [] + n_targets = [] + for source, target in zip(sources, targets): + if newer(source, target): + n_sources.append(source) + n_targets.append(target) + + return n_sources, n_targets + +def newer_group(sources, target, missing='error'): + """Return true if 'target' is out-of-date with respect to any file + listed in 'sources'. + + In other words, if 'target' exists and is newer + than every file in 'sources', return false; otherwise return true. + 'missing' controls what we do when a source file is missing; the + default ("error") is to blow up with an OSError from inside 'stat()'; + if it is "ignore", we silently drop any missing source files; if it is + "newer", any missing source files make us assume that 'target' is + out-of-date (this is handy in "dry-run" mode: it'll make you pretend to + carry out commands that wouldn't work because inputs are missing, but + that doesn't matter because you're not actually going to run the + commands). + """ + # If the target doesn't even exist, then it's definitely out-of-date. + if not os.path.exists(target): + return True + + # Otherwise we have to find out the hard way: if *any* source file + # is more recent than 'target', then 'target' is out-of-date and + # we can immediately return true. If we fall through to the end + # of the loop, then 'target' is up-to-date and we return false. + target_mtime = os.stat(target)[ST_MTIME] + + for source in sources: + if not os.path.exists(source): + if missing == 'error': # blow up when we stat() the file + pass + elif missing == 'ignore': # missing source dropped from + continue # target's dependency list + elif missing == 'newer': # missing source means target is + return True # out-of-date + + if os.stat(source)[ST_MTIME] > target_mtime: + return True + + return False diff --git a/src/main/resources/PythonLibs/distutils/dir_util.py b/src/main/resources/PythonLibs/distutils/dir_util.py new file mode 100644 index 0000000000000000000000000000000000000000..5026e246685eacf3575db56b944924b2d0e84042 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/dir_util.py @@ -0,0 +1,216 @@ +"""distutils.dir_util + +Utility functions for manipulating directories and directory trees.""" + +__revision__ = "$Id$" + +import os +import errno +from distutils.errors import DistutilsFileError, DistutilsInternalError +from distutils import log + +# cache for by mkpath() -- in addition to cheapening redundant calls, +# eliminates redundant "creating /foo/bar/baz" messages in dry-run mode +_path_created = {} + +# I don't use os.makedirs because a) it's new to Python 1.5.2, and +# b) it blows up if the directory already exists (I want to silently +# succeed in that case). +def mkpath(name, mode=0777, verbose=1, dry_run=0): + """Create a directory and any missing ancestor directories. + + If the directory already exists (or if 'name' is the empty string, which + means the current directory, which of course exists), then do nothing. + Raise DistutilsFileError if unable to create some directory along the way + (eg. some sub-path exists, but is a file rather than a directory). + If 'verbose' is true, print a one-line summary of each mkdir to stdout. + Return the list of directories actually created. + """ + + global _path_created + + # Detect a common bug -- name is None + if not isinstance(name, basestring): + raise DistutilsInternalError, \ + "mkpath: 'name' must be a string (got %r)" % (name,) + + # XXX what's the better way to handle verbosity? print as we create + # each directory in the path (the current behaviour), or only announce + # the creation of the whole path? (quite easy to do the latter since + # we're not using a recursive algorithm) + + name = os.path.normpath(name) + created_dirs = [] + if os.path.isdir(name) or name == '': + return created_dirs + if _path_created.get(os.path.abspath(name)): + return created_dirs + + (head, tail) = os.path.split(name) + tails = [tail] # stack of lone dirs to create + + while head and tail and not os.path.isdir(head): + (head, tail) = os.path.split(head) + tails.insert(0, tail) # push next higher dir onto stack + + # now 'head' contains the deepest directory that already exists + # (that is, the child of 'head' in 'name' is the highest directory + # that does *not* exist) + for d in tails: + #print "head = %s, d = %s: " % (head, d), + head = os.path.join(head, d) + abs_head = os.path.abspath(head) + + if _path_created.get(abs_head): + continue + + if verbose >= 1: + log.info("creating %s", head) + + if not dry_run: + try: + os.mkdir(head, mode) + except OSError, exc: + if not (exc.errno == errno.EEXIST and os.path.isdir(head)): + raise DistutilsFileError( + "could not create '%s': %s" % (head, exc.args[-1])) + created_dirs.append(head) + + _path_created[abs_head] = 1 + return created_dirs + +def create_tree(base_dir, files, mode=0777, verbose=1, dry_run=0): + """Create all the empty directories under 'base_dir' needed to put 'files' + there. + + 'base_dir' is just the a name of a directory which doesn't necessarily + exist yet; 'files' is a list of filenames to be interpreted relative to + 'base_dir'. 'base_dir' + the directory portion of every file in 'files' + will be created if it doesn't already exist. 'mode', 'verbose' and + 'dry_run' flags are as for 'mkpath()'. + """ + # First get the list of directories to create + need_dir = {} + for file in files: + need_dir[os.path.join(base_dir, os.path.dirname(file))] = 1 + need_dirs = need_dir.keys() + need_dirs.sort() + + # Now create them + for dir in need_dirs: + mkpath(dir, mode, verbose=verbose, dry_run=dry_run) + +def copy_tree(src, dst, preserve_mode=1, preserve_times=1, + preserve_symlinks=0, update=0, verbose=1, dry_run=0): + """Copy an entire directory tree 'src' to a new location 'dst'. + + Both 'src' and 'dst' must be directory names. If 'src' is not a + directory, raise DistutilsFileError. If 'dst' does not exist, it is + created with 'mkpath()'. The end result of the copy is that every + file in 'src' is copied to 'dst', and directories under 'src' are + recursively copied to 'dst'. Return the list of files that were + copied or might have been copied, using their output name. The + return value is unaffected by 'update' or 'dry_run': it is simply + the list of all files under 'src', with the names changed to be + under 'dst'. + + 'preserve_mode' and 'preserve_times' are the same as for + 'copy_file'; note that they only apply to regular files, not to + directories. If 'preserve_symlinks' is true, symlinks will be + copied as symlinks (on platforms that support them!); otherwise + (the default), the destination of the symlink will be copied. + 'update' and 'verbose' are the same as for 'copy_file'. + """ + from distutils.file_util import copy_file + + if not dry_run and not os.path.isdir(src): + raise DistutilsFileError, \ + "cannot copy tree '%s': not a directory" % src + try: + names = os.listdir(src) + except os.error, (errno, errstr): + if dry_run: + names = [] + else: + raise DistutilsFileError, \ + "error listing files in '%s': %s" % (src, errstr) + + if not dry_run: + mkpath(dst, verbose=verbose) + + outputs = [] + + for n in names: + src_name = os.path.join(src, n) + dst_name = os.path.join(dst, n) + + if n.startswith('.nfs'): + # skip NFS rename files + continue + + if preserve_symlinks and os.path.islink(src_name): + link_dest = os.readlink(src_name) + if verbose >= 1: + log.info("linking %s -> %s", dst_name, link_dest) + if not dry_run: + os.symlink(link_dest, dst_name) + outputs.append(dst_name) + + elif os.path.isdir(src_name): + outputs.extend( + copy_tree(src_name, dst_name, preserve_mode, + preserve_times, preserve_symlinks, update, + verbose=verbose, dry_run=dry_run)) + else: + copy_file(src_name, dst_name, preserve_mode, + preserve_times, update, verbose=verbose, + dry_run=dry_run) + outputs.append(dst_name) + + return outputs + +def _build_cmdtuple(path, cmdtuples): + """Helper for remove_tree().""" + for f in os.listdir(path): + real_f = os.path.join(path,f) + if os.path.isdir(real_f) and not os.path.islink(real_f): + _build_cmdtuple(real_f, cmdtuples) + else: + cmdtuples.append((os.remove, real_f)) + cmdtuples.append((os.rmdir, path)) + +def remove_tree(directory, verbose=1, dry_run=0): + """Recursively remove an entire directory tree. + + Any errors are ignored (apart from being reported to stdout if 'verbose' + is true). + """ + from distutils.util import grok_environment_error + global _path_created + + if verbose >= 1: + log.info("removing '%s' (and everything under it)", directory) + if dry_run: + return + cmdtuples = [] + _build_cmdtuple(directory, cmdtuples) + for cmd in cmdtuples: + try: + cmd[0](cmd[1]) + # remove dir from cache if it's already there + abspath = os.path.abspath(cmd[1]) + if abspath in _path_created: + del _path_created[abspath] + except (IOError, OSError), exc: + log.warn(grok_environment_error( + exc, "error removing %s: " % directory)) + +def ensure_relative(path): + """Take the full path 'path', and make it a relative path. + + This is useful to make 'path' the second argument to os.path.join(). + """ + drive, path = os.path.splitdrive(path) + if path[0:1] == os.sep: + path = drive + path[1:] + return path diff --git a/src/main/resources/PythonLibs/distutils/dist.py b/src/main/resources/PythonLibs/distutils/dist.py new file mode 100644 index 0000000000000000000000000000000000000000..e025313dbd94e762fc0a9eb93f48dd5dce7cff4f --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/dist.py @@ -0,0 +1,1249 @@ +"""distutils.dist + +Provides the Distribution class, which represents the module distribution +being built/installed/distributed. +""" + +__revision__ = "$Id$" + +import sys, os, re +from email import message_from_file + +try: + import warnings +except ImportError: + warnings = None + +from distutils.errors import (DistutilsOptionError, DistutilsArgError, + DistutilsModuleError, DistutilsClassError) +from distutils.fancy_getopt import FancyGetopt, translate_longopt +from distutils.util import check_environ, strtobool, rfc822_escape +from distutils import log +from distutils.debug import DEBUG + +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + +# Regex to define acceptable Distutils command names. This is not *quite* +# the same as a Python NAME -- I don't allow leading underscores. The fact +# that they're very similar is no coincidence; the default naming scheme is +# to look for a Python module named after the command. +command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$') + + +class Distribution: + """The core of the Distutils. Most of the work hiding behind 'setup' + is really done within a Distribution instance, which farms the work out + to the Distutils commands specified on the command line. + + Setup scripts will almost never instantiate Distribution directly, + unless the 'setup()' function is totally inadequate to their needs. + However, it is conceivable that a setup script might wish to subclass + Distribution for some specialized purpose, and then pass the subclass + to 'setup()' as the 'distclass' keyword argument. If so, it is + necessary to respect the expectations that 'setup' has of Distribution. + See the code for 'setup()', in core.py, for details. + """ + + + # 'global_options' describes the command-line options that may be + # supplied to the setup script prior to any actual commands. + # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of + # these global options. This list should be kept to a bare minimum, + # since every global option is also valid as a command option -- and we + # don't want to pollute the commands with too many options that they + # have minimal control over. + # The fourth entry for verbose means that it can be repeated. + global_options = [('verbose', 'v', "run verbosely (default)", 1), + ('quiet', 'q', "run quietly (turns verbosity off)"), + ('dry-run', 'n', "don't actually do anything"), + ('help', 'h', "show detailed help message"), + ('no-user-cfg', None, + 'ignore pydistutils.cfg in your home directory'), + ] + + # 'common_usage' is a short (2-3 line) string describing the common + # usage of the setup script. + common_usage = """\ +Common commands: (see '--help-commands' for more) + + setup.py build will build the package underneath 'build/' + setup.py install will install the package +""" + + # options that are not propagated to the commands + display_options = [ + ('help-commands', None, + "list all available commands"), + ('name', None, + "print package name"), + ('version', 'V', + "print package version"), + ('fullname', None, + "print <package name>-<version>"), + ('author', None, + "print the author's name"), + ('author-email', None, + "print the author's email address"), + ('maintainer', None, + "print the maintainer's name"), + ('maintainer-email', None, + "print the maintainer's email address"), + ('contact', None, + "print the maintainer's name if known, else the author's"), + ('contact-email', None, + "print the maintainer's email address if known, else the author's"), + ('url', None, + "print the URL for this package"), + ('license', None, + "print the license of the package"), + ('licence', None, + "alias for --license"), + ('description', None, + "print the package description"), + ('long-description', None, + "print the long package description"), + ('platforms', None, + "print the list of platforms"), + ('classifiers', None, + "print the list of classifiers"), + ('keywords', None, + "print the list of keywords"), + ('provides', None, + "print the list of packages/modules provided"), + ('requires', None, + "print the list of packages/modules required"), + ('obsoletes', None, + "print the list of packages/modules made obsolete") + ] + display_option_names = map(lambda x: translate_longopt(x[0]), + display_options) + + # negative options are options that exclude other options + negative_opt = {'quiet': 'verbose'} + + + # -- Creation/initialization methods ------------------------------- + + def __init__ (self, attrs=None): + """Construct a new Distribution instance: initialize all the + attributes of a Distribution, and then use 'attrs' (a dictionary + mapping attribute names to values) to assign some of those + attributes their "real" values. (Any attributes not mentioned in + 'attrs' will be assigned to some null value: 0, None, an empty list + or dictionary, etc.) Most importantly, initialize the + 'command_obj' attribute to the empty dictionary; this will be + filled in with real command objects by 'parse_command_line()'. + """ + + # Default values for our command-line options + self.verbose = 1 + self.dry_run = 0 + self.help = 0 + for attr in self.display_option_names: + setattr(self, attr, 0) + + # Store the distribution meta-data (name, version, author, and so + # forth) in a separate object -- we're getting to have enough + # information here (and enough command-line options) that it's + # worth it. Also delegate 'get_XXX()' methods to the 'metadata' + # object in a sneaky and underhanded (but efficient!) way. + self.metadata = DistributionMetadata() + for basename in self.metadata._METHOD_BASENAMES: + method_name = "get_" + basename + setattr(self, method_name, getattr(self.metadata, method_name)) + + # 'cmdclass' maps command names to class objects, so we + # can 1) quickly figure out which class to instantiate when + # we need to create a new command object, and 2) have a way + # for the setup script to override command classes + self.cmdclass = {} + + # 'command_packages' is a list of packages in which commands + # are searched for. The factory for command 'foo' is expected + # to be named 'foo' in the module 'foo' in one of the packages + # named here. This list is searched from the left; an error + # is raised if no named package provides the command being + # searched for. (Always access using get_command_packages().) + self.command_packages = None + + # 'script_name' and 'script_args' are usually set to sys.argv[0] + # and sys.argv[1:], but they can be overridden when the caller is + # not necessarily a setup script run from the command-line. + self.script_name = None + self.script_args = None + + # 'command_options' is where we store command options between + # parsing them (from config files, the command-line, etc.) and when + # they are actually needed -- ie. when the command in question is + # instantiated. It is a dictionary of dictionaries of 2-tuples: + # command_options = { command_name : { option : (source, value) } } + self.command_options = {} + + # 'dist_files' is the list of (command, pyversion, file) that + # have been created by any dist commands run so far. This is + # filled regardless of whether the run is dry or not. pyversion + # gives sysconfig.get_python_version() if the dist file is + # specific to a Python version, 'any' if it is good for all + # Python versions on the target platform, and '' for a source + # file. pyversion should not be used to specify minimum or + # maximum required Python versions; use the metainfo for that + # instead. + self.dist_files = [] + + # These options are really the business of various commands, rather + # than of the Distribution itself. We provide aliases for them in + # Distribution as a convenience to the developer. + self.packages = None + self.package_data = {} + self.package_dir = None + self.py_modules = None + self.libraries = None + self.headers = None + self.ext_modules = None + self.ext_package = None + self.include_dirs = None + self.extra_path = None + self.scripts = None + self.data_files = None + self.password = '' + + # And now initialize bookkeeping stuff that can't be supplied by + # the caller at all. 'command_obj' maps command names to + # Command instances -- that's how we enforce that every command + # class is a singleton. + self.command_obj = {} + + # 'have_run' maps command names to boolean values; it keeps track + # of whether we have actually run a particular command, to make it + # cheap to "run" a command whenever we think we might need to -- if + # it's already been done, no need for expensive filesystem + # operations, we just check the 'have_run' dictionary and carry on. + # It's only safe to query 'have_run' for a command class that has + # been instantiated -- a false value will be inserted when the + # command object is created, and replaced with a true value when + # the command is successfully run. Thus it's probably best to use + # '.get()' rather than a straight lookup. + self.have_run = {} + + # Now we'll use the attrs dictionary (ultimately, keyword args from + # the setup script) to possibly override any or all of these + # distribution options. + + if attrs: + # Pull out the set of command options and work on them + # specifically. Note that this order guarantees that aliased + # command options will override any supplied redundantly + # through the general options dictionary. + options = attrs.get('options') + if options is not None: + del attrs['options'] + for (command, cmd_options) in options.items(): + opt_dict = self.get_option_dict(command) + for (opt, val) in cmd_options.items(): + opt_dict[opt] = ("setup script", val) + + if 'licence' in attrs: + attrs['license'] = attrs['licence'] + del attrs['licence'] + msg = "'licence' distribution option is deprecated; use 'license'" + if warnings is not None: + warnings.warn(msg) + else: + sys.stderr.write(msg + "\n") + + # Now work on the rest of the attributes. Any attribute that's + # not already defined is invalid! + for (key, val) in attrs.items(): + if hasattr(self.metadata, "set_" + key): + getattr(self.metadata, "set_" + key)(val) + elif hasattr(self.metadata, key): + setattr(self.metadata, key, val) + elif hasattr(self, key): + setattr(self, key, val) + else: + msg = "Unknown distribution option: %s" % repr(key) + if warnings is not None: + warnings.warn(msg) + else: + sys.stderr.write(msg + "\n") + + # no-user-cfg is handled before other command line args + # because other args override the config files, and this + # one is needed before we can load the config files. + # If attrs['script_args'] wasn't passed, assume false. + # + # This also make sure we just look at the global options + self.want_user_cfg = True + + if self.script_args is not None: + for arg in self.script_args: + if not arg.startswith('-'): + break + if arg == '--no-user-cfg': + self.want_user_cfg = False + break + + self.finalize_options() + + def get_option_dict(self, command): + """Get the option dictionary for a given command. If that + command's option dictionary hasn't been created yet, then create it + and return the new dictionary; otherwise, return the existing + option dictionary. + """ + dict = self.command_options.get(command) + if dict is None: + dict = self.command_options[command] = {} + return dict + + def dump_option_dicts(self, header=None, commands=None, indent=""): + from pprint import pformat + + if commands is None: # dump all command option dicts + commands = self.command_options.keys() + commands.sort() + + if header is not None: + self.announce(indent + header) + indent = indent + " " + + if not commands: + self.announce(indent + "no commands known yet") + return + + for cmd_name in commands: + opt_dict = self.command_options.get(cmd_name) + if opt_dict is None: + self.announce(indent + + "no option dict for '%s' command" % cmd_name) + else: + self.announce(indent + + "option dict for '%s' command:" % cmd_name) + out = pformat(opt_dict) + for line in out.split('\n'): + self.announce(indent + " " + line) + + # -- Config file finding/parsing methods --------------------------- + + def find_config_files(self): + """Find as many configuration files as should be processed for this + platform, and return a list of filenames in the order in which they + should be parsed. The filenames returned are guaranteed to exist + (modulo nasty race conditions). + + There are three possible config files: distutils.cfg in the + Distutils installation directory (ie. where the top-level + Distutils __inst__.py file lives), a file in the user's home + directory named .pydistutils.cfg on Unix and pydistutils.cfg + on Windows/Mac; and setup.cfg in the current directory. + + The file in the user's home directory can be disabled with the + --no-user-cfg option. + """ + files = [] + check_environ() + + # Where to look for the system-wide Distutils config file + sys_dir = os.path.dirname(sys.modules['distutils'].__file__) + + # Look for the system config file + sys_file = os.path.join(sys_dir, "distutils.cfg") + if os.path.isfile(sys_file): + files.append(sys_file) + + # What to call the per-user config file + if os.name == 'posix': + user_filename = ".pydistutils.cfg" + else: + user_filename = "pydistutils.cfg" + + # And look for the user config file + if self.want_user_cfg: + user_file = os.path.join(os.path.expanduser('~'), user_filename) + if os.path.isfile(user_file): + files.append(user_file) + + # All platforms support local setup.cfg + local_file = "setup.cfg" + if os.path.isfile(local_file): + files.append(local_file) + + if DEBUG: + self.announce("using config files: %s" % ', '.join(files)) + + return files + + def parse_config_files(self, filenames=None): + from ConfigParser import ConfigParser + + if filenames is None: + filenames = self.find_config_files() + + if DEBUG: + self.announce("Distribution.parse_config_files():") + + parser = ConfigParser() + for filename in filenames: + if DEBUG: + self.announce(" reading %s" % filename) + parser.read(filename) + for section in parser.sections(): + options = parser.options(section) + opt_dict = self.get_option_dict(section) + + for opt in options: + if opt != '__name__': + val = parser.get(section,opt) + opt = opt.replace('-', '_') + opt_dict[opt] = (filename, val) + + # Make the ConfigParser forget everything (so we retain + # the original filenames that options come from) + parser.__init__() + + # If there was a "global" section in the config file, use it + # to set Distribution options. + + if 'global' in self.command_options: + for (opt, (src, val)) in self.command_options['global'].items(): + alias = self.negative_opt.get(opt) + try: + if alias: + setattr(self, alias, not strtobool(val)) + elif opt in ('verbose', 'dry_run'): # ugh! + setattr(self, opt, strtobool(val)) + else: + setattr(self, opt, val) + except ValueError, msg: + raise DistutilsOptionError, msg + + # -- Command-line parsing methods ---------------------------------- + + def parse_command_line(self): + """Parse the setup script's command line, taken from the + 'script_args' instance attribute (which defaults to 'sys.argv[1:]' + -- see 'setup()' in core.py). This list is first processed for + "global options" -- options that set attributes of the Distribution + instance. Then, it is alternately scanned for Distutils commands + and options for that command. Each new command terminates the + options for the previous command. The allowed options for a + command are determined by the 'user_options' attribute of the + command class -- thus, we have to be able to load command classes + in order to parse the command line. Any error in that 'options' + attribute raises DistutilsGetoptError; any error on the + command-line raises DistutilsArgError. If no Distutils commands + were found on the command line, raises DistutilsArgError. Return + true if command-line was successfully parsed and we should carry + on with executing commands; false if no errors but we shouldn't + execute commands (currently, this only happens if user asks for + help). + """ + # + # We now have enough information to show the Macintosh dialog + # that allows the user to interactively specify the "command line". + # + toplevel_options = self._get_toplevel_options() + + # We have to parse the command line a bit at a time -- global + # options, then the first command, then its options, and so on -- + # because each command will be handled by a different class, and + # the options that are valid for a particular class aren't known + # until we have loaded the command class, which doesn't happen + # until we know what the command is. + + self.commands = [] + parser = FancyGetopt(toplevel_options + self.display_options) + parser.set_negative_aliases(self.negative_opt) + parser.set_aliases({'licence': 'license'}) + args = parser.getopt(args=self.script_args, object=self) + option_order = parser.get_option_order() + log.set_verbosity(self.verbose) + + # for display options we return immediately + if self.handle_display_options(option_order): + return + while args: + args = self._parse_command_opts(parser, args) + if args is None: # user asked for help (and got it) + return + + # Handle the cases of --help as a "global" option, ie. + # "setup.py --help" and "setup.py --help command ...". For the + # former, we show global options (--verbose, --dry-run, etc.) + # and display-only options (--name, --version, etc.); for the + # latter, we omit the display-only options and show help for + # each command listed on the command line. + if self.help: + self._show_help(parser, + display_options=len(self.commands) == 0, + commands=self.commands) + return + + # Oops, no commands found -- an end-user error + if not self.commands: + raise DistutilsArgError, "no commands supplied" + + # All is well: return true + return 1 + + def _get_toplevel_options(self): + """Return the non-display options recognized at the top level. + + This includes options that are recognized *only* at the top + level as well as options recognized for commands. + """ + return self.global_options + [ + ("command-packages=", None, + "list of packages that provide distutils commands"), + ] + + def _parse_command_opts(self, parser, args): + """Parse the command-line options for a single command. + 'parser' must be a FancyGetopt instance; 'args' must be the list + of arguments, starting with the current command (whose options + we are about to parse). Returns a new version of 'args' with + the next command at the front of the list; will be the empty + list if there are no more commands on the command line. Returns + None if the user asked for help on this command. + """ + # late import because of mutual dependence between these modules + from distutils.cmd import Command + + # Pull the current command from the head of the command line + command = args[0] + if not command_re.match(command): + raise SystemExit, "invalid command name '%s'" % command + self.commands.append(command) + + # Dig up the command class that implements this command, so we + # 1) know that it's a valid command, and 2) know which options + # it takes. + try: + cmd_class = self.get_command_class(command) + except DistutilsModuleError, msg: + raise DistutilsArgError, msg + + # Require that the command class be derived from Command -- want + # to be sure that the basic "command" interface is implemented. + if not issubclass(cmd_class, Command): + raise DistutilsClassError, \ + "command class %s must subclass Command" % cmd_class + + # Also make sure that the command object provides a list of its + # known options. + if not (hasattr(cmd_class, 'user_options') and + isinstance(cmd_class.user_options, list)): + raise DistutilsClassError, \ + ("command class %s must provide " + + "'user_options' attribute (a list of tuples)") % \ + cmd_class + + # If the command class has a list of negative alias options, + # merge it in with the global negative aliases. + negative_opt = self.negative_opt + if hasattr(cmd_class, 'negative_opt'): + negative_opt = negative_opt.copy() + negative_opt.update(cmd_class.negative_opt) + + # Check for help_options in command class. They have a different + # format (tuple of four) so we need to preprocess them here. + if (hasattr(cmd_class, 'help_options') and + isinstance(cmd_class.help_options, list)): + help_options = fix_help_options(cmd_class.help_options) + else: + help_options = [] + + + # All commands support the global options too, just by adding + # in 'global_options'. + parser.set_option_table(self.global_options + + cmd_class.user_options + + help_options) + parser.set_negative_aliases(negative_opt) + (args, opts) = parser.getopt(args[1:]) + if hasattr(opts, 'help') and opts.help: + self._show_help(parser, display_options=0, commands=[cmd_class]) + return + + if (hasattr(cmd_class, 'help_options') and + isinstance(cmd_class.help_options, list)): + help_option_found=0 + for (help_option, short, desc, func) in cmd_class.help_options: + if hasattr(opts, parser.get_attr_name(help_option)): + help_option_found=1 + if hasattr(func, '__call__'): + func() + else: + raise DistutilsClassError( + "invalid help function %r for help option '%s': " + "must be a callable object (function, etc.)" + % (func, help_option)) + + if help_option_found: + return + + # Put the options from the command-line into their official + # holding pen, the 'command_options' dictionary. + opt_dict = self.get_option_dict(command) + for (name, value) in vars(opts).items(): + opt_dict[name] = ("command line", value) + + return args + + def finalize_options(self): + """Set final values for all the options on the Distribution + instance, analogous to the .finalize_options() method of Command + objects. + """ + for attr in ('keywords', 'platforms'): + value = getattr(self.metadata, attr) + if value is None: + continue + if isinstance(value, str): + value = [elm.strip() for elm in value.split(',')] + setattr(self.metadata, attr, value) + + def _show_help(self, parser, global_options=1, display_options=1, + commands=[]): + """Show help for the setup script command-line in the form of + several lists of command-line options. 'parser' should be a + FancyGetopt instance; do not expect it to be returned in the + same state, as its option table will be reset to make it + generate the correct help text. + + If 'global_options' is true, lists the global options: + --verbose, --dry-run, etc. If 'display_options' is true, lists + the "display-only" options: --name, --version, etc. Finally, + lists per-command help for every command name or command class + in 'commands'. + """ + # late import because of mutual dependence between these modules + from distutils.core import gen_usage + from distutils.cmd import Command + + if global_options: + if display_options: + options = self._get_toplevel_options() + else: + options = self.global_options + parser.set_option_table(options) + parser.print_help(self.common_usage + "\nGlobal options:") + print('') + + if display_options: + parser.set_option_table(self.display_options) + parser.print_help( + "Information display options (just display " + + "information, ignore any commands)") + print('') + + for command in self.commands: + if isinstance(command, type) and issubclass(command, Command): + klass = command + else: + klass = self.get_command_class(command) + if (hasattr(klass, 'help_options') and + isinstance(klass.help_options, list)): + parser.set_option_table(klass.user_options + + fix_help_options(klass.help_options)) + else: + parser.set_option_table(klass.user_options) + parser.print_help("Options for '%s' command:" % klass.__name__) + print('') + + print(gen_usage(self.script_name)) + + def handle_display_options(self, option_order): + """If there were any non-global "display-only" options + (--help-commands or the metadata display options) on the command + line, display the requested info and return true; else return + false. + """ + from distutils.core import gen_usage + + # User just wants a list of commands -- we'll print it out and stop + # processing now (ie. if they ran "setup --help-commands foo bar", + # we ignore "foo bar"). + if self.help_commands: + self.print_commands() + print('') + print(gen_usage(self.script_name)) + return 1 + + # If user supplied any of the "display metadata" options, then + # display that metadata in the order in which the user supplied the + # metadata options. + any_display_options = 0 + is_display_option = {} + for option in self.display_options: + is_display_option[option[0]] = 1 + + for (opt, val) in option_order: + if val and is_display_option.get(opt): + opt = translate_longopt(opt) + value = getattr(self.metadata, "get_"+opt)() + if opt in ['keywords', 'platforms']: + print(','.join(value)) + elif opt in ('classifiers', 'provides', 'requires', + 'obsoletes'): + print('\n'.join(value)) + else: + print(value) + any_display_options = 1 + + return any_display_options + + def print_command_list(self, commands, header, max_length): + """Print a subset of the list of all commands -- used by + 'print_commands()'. + """ + print(header + ":") + + for cmd in commands: + klass = self.cmdclass.get(cmd) + if not klass: + klass = self.get_command_class(cmd) + try: + description = klass.description + except AttributeError: + description = "(no description available)" + + print(" %-*s %s" % (max_length, cmd, description)) + + def print_commands(self): + """Print out a help message listing all available commands with a + description of each. The list is divided into "standard commands" + (listed in distutils.command.__all__) and "extra commands" + (mentioned in self.cmdclass, but not a standard command). The + descriptions come from the command class attribute + 'description'. + """ + import distutils.command + std_commands = distutils.command.__all__ + is_std = {} + for cmd in std_commands: + is_std[cmd] = 1 + + extra_commands = [] + for cmd in self.cmdclass.keys(): + if not is_std.get(cmd): + extra_commands.append(cmd) + + max_length = 0 + for cmd in (std_commands + extra_commands): + if len(cmd) > max_length: + max_length = len(cmd) + + self.print_command_list(std_commands, + "Standard commands", + max_length) + if extra_commands: + print + self.print_command_list(extra_commands, + "Extra commands", + max_length) + + def get_command_list(self): + """Get a list of (command, description) tuples. + The list is divided into "standard commands" (listed in + distutils.command.__all__) and "extra commands" (mentioned in + self.cmdclass, but not a standard command). The descriptions come + from the command class attribute 'description'. + """ + # Currently this is only used on Mac OS, for the Mac-only GUI + # Distutils interface (by Jack Jansen) + + import distutils.command + std_commands = distutils.command.__all__ + is_std = {} + for cmd in std_commands: + is_std[cmd] = 1 + + extra_commands = [] + for cmd in self.cmdclass.keys(): + if not is_std.get(cmd): + extra_commands.append(cmd) + + rv = [] + for cmd in (std_commands + extra_commands): + klass = self.cmdclass.get(cmd) + if not klass: + klass = self.get_command_class(cmd) + try: + description = klass.description + except AttributeError: + description = "(no description available)" + rv.append((cmd, description)) + return rv + + # -- Command class/object methods ---------------------------------- + + def get_command_packages(self): + """Return a list of packages from which commands are loaded.""" + pkgs = self.command_packages + if not isinstance(pkgs, list): + if pkgs is None: + pkgs = '' + pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != ''] + if "distutils.command" not in pkgs: + pkgs.insert(0, "distutils.command") + self.command_packages = pkgs + return pkgs + + def get_command_class(self, command): + """Return the class that implements the Distutils command named by + 'command'. First we check the 'cmdclass' dictionary; if the + command is mentioned there, we fetch the class object from the + dictionary and return it. Otherwise we load the command module + ("distutils.command." + command) and fetch the command class from + the module. The loaded class is also stored in 'cmdclass' + to speed future calls to 'get_command_class()'. + + Raises DistutilsModuleError if the expected module could not be + found, or if that module does not define the expected class. + """ + klass = self.cmdclass.get(command) + if klass: + return klass + + for pkgname in self.get_command_packages(): + module_name = "%s.%s" % (pkgname, command) + klass_name = command + + try: + __import__ (module_name) + module = sys.modules[module_name] + except ImportError: + continue + + try: + klass = getattr(module, klass_name) + except AttributeError: + raise DistutilsModuleError, \ + "invalid command '%s' (no class '%s' in module '%s')" \ + % (command, klass_name, module_name) + + self.cmdclass[command] = klass + return klass + + raise DistutilsModuleError("invalid command '%s'" % command) + + + def get_command_obj(self, command, create=1): + """Return the command object for 'command'. Normally this object + is cached on a previous call to 'get_command_obj()'; if no command + object for 'command' is in the cache, then we either create and + return it (if 'create' is true) or return None. + """ + cmd_obj = self.command_obj.get(command) + if not cmd_obj and create: + if DEBUG: + self.announce("Distribution.get_command_obj(): " \ + "creating '%s' command object" % command) + + klass = self.get_command_class(command) + cmd_obj = self.command_obj[command] = klass(self) + self.have_run[command] = 0 + + # Set any options that were supplied in config files + # or on the command line. (NB. support for error + # reporting is lame here: any errors aren't reported + # until 'finalize_options()' is called, which means + # we won't report the source of the error.) + options = self.command_options.get(command) + if options: + self._set_command_options(cmd_obj, options) + + return cmd_obj + + def _set_command_options(self, command_obj, option_dict=None): + """Set the options for 'command_obj' from 'option_dict'. Basically + this means copying elements of a dictionary ('option_dict') to + attributes of an instance ('command'). + + 'command_obj' must be a Command instance. If 'option_dict' is not + supplied, uses the standard option dictionary for this command + (from 'self.command_options'). + """ + command_name = command_obj.get_command_name() + if option_dict is None: + option_dict = self.get_option_dict(command_name) + + if DEBUG: + self.announce(" setting options for '%s' command:" % command_name) + for (option, (source, value)) in option_dict.items(): + if DEBUG: + self.announce(" %s = %s (from %s)" % (option, value, + source)) + try: + bool_opts = map(translate_longopt, command_obj.boolean_options) + except AttributeError: + bool_opts = [] + try: + neg_opt = command_obj.negative_opt + except AttributeError: + neg_opt = {} + + try: + is_string = isinstance(value, str) + if option in neg_opt and is_string: + setattr(command_obj, neg_opt[option], not strtobool(value)) + elif option in bool_opts and is_string: + setattr(command_obj, option, strtobool(value)) + elif hasattr(command_obj, option): + setattr(command_obj, option, value) + else: + raise DistutilsOptionError, \ + ("error in %s: command '%s' has no such option '%s'" + % (source, command_name, option)) + except ValueError, msg: + raise DistutilsOptionError, msg + + def reinitialize_command(self, command, reinit_subcommands=0): + """Reinitializes a command to the state it was in when first + returned by 'get_command_obj()': ie., initialized but not yet + finalized. This provides the opportunity to sneak option + values in programmatically, overriding or supplementing + user-supplied values from the config files and command line. + You'll have to re-finalize the command object (by calling + 'finalize_options()' or 'ensure_finalized()') before using it for + real. + + 'command' should be a command name (string) or command object. If + 'reinit_subcommands' is true, also reinitializes the command's + sub-commands, as declared by the 'sub_commands' class attribute (if + it has one). See the "install" command for an example. Only + reinitializes the sub-commands that actually matter, ie. those + whose test predicates return true. + + Returns the reinitialized command object. + """ + from distutils.cmd import Command + if not isinstance(command, Command): + command_name = command + command = self.get_command_obj(command_name) + else: + command_name = command.get_command_name() + + if not command.finalized: + return command + command.initialize_options() + command.finalized = 0 + self.have_run[command_name] = 0 + self._set_command_options(command) + + if reinit_subcommands: + for sub in command.get_sub_commands(): + self.reinitialize_command(sub, reinit_subcommands) + + return command + + # -- Methods that operate on the Distribution ---------------------- + + def announce(self, msg, level=log.INFO): + log.log(level, msg) + + def run_commands(self): + """Run each command that was seen on the setup script command line. + Uses the list of commands found and cache of command objects + created by 'get_command_obj()'. + """ + for cmd in self.commands: + self.run_command(cmd) + + # -- Methods that operate on its Commands -------------------------- + + def run_command(self, command): + """Do whatever it takes to run a command (including nothing at all, + if the command has already been run). Specifically: if we have + already created and run the command named by 'command', return + silently without doing anything. If the command named by 'command' + doesn't even have a command object yet, create one. Then invoke + 'run()' on that command object (or an existing one). + """ + # Already been here, done that? then return silently. + if self.have_run.get(command): + return + + log.info("running %s", command) + cmd_obj = self.get_command_obj(command) + cmd_obj.ensure_finalized() + cmd_obj.run() + self.have_run[command] = 1 + + + # -- Distribution query methods ------------------------------------ + + def has_pure_modules(self): + return len(self.packages or self.py_modules or []) > 0 + + def has_ext_modules(self): + return self.ext_modules and len(self.ext_modules) > 0 + + def has_c_libraries(self): + return self.libraries and len(self.libraries) > 0 + + def has_modules(self): + return self.has_pure_modules() or self.has_ext_modules() + + def has_headers(self): + return self.headers and len(self.headers) > 0 + + def has_scripts(self): + return self.scripts and len(self.scripts) > 0 + + def has_data_files(self): + return self.data_files and len(self.data_files) > 0 + + def is_pure(self): + return (self.has_pure_modules() and + not self.has_ext_modules() and + not self.has_c_libraries()) + + # -- Metadata query methods ---------------------------------------- + + # If you're looking for 'get_name()', 'get_version()', and so forth, + # they are defined in a sneaky way: the constructor binds self.get_XXX + # to self.metadata.get_XXX. The actual code is in the + # DistributionMetadata class, below. + +class DistributionMetadata: + """Dummy class to hold the distribution meta-data: name, version, + author, and so forth. + """ + + _METHOD_BASENAMES = ("name", "version", "author", "author_email", + "maintainer", "maintainer_email", "url", + "license", "description", "long_description", + "keywords", "platforms", "fullname", "contact", + "contact_email", "license", "classifiers", + "download_url", + # PEP 314 + "provides", "requires", "obsoletes", + ) + + def __init__(self, path=None): + if path is not None: + self.read_pkg_file(open(path)) + else: + self.name = None + self.version = None + self.author = None + self.author_email = None + self.maintainer = None + self.maintainer_email = None + self.url = None + self.license = None + self.description = None + self.long_description = None + self.keywords = None + self.platforms = None + self.classifiers = None + self.download_url = None + # PEP 314 + self.provides = None + self.requires = None + self.obsoletes = None + + def read_pkg_file(self, file): + """Reads the metadata values from a file object.""" + msg = message_from_file(file) + + def _read_field(name): + value = msg[name] + if value == 'UNKNOWN': + return None + return value + + def _read_list(name): + values = msg.get_all(name, None) + if values == []: + return None + return values + + metadata_version = msg['metadata-version'] + self.name = _read_field('name') + self.version = _read_field('version') + self.description = _read_field('summary') + # we are filling author only. + self.author = _read_field('author') + self.maintainer = None + self.author_email = _read_field('author-email') + self.maintainer_email = None + self.url = _read_field('home-page') + self.license = _read_field('license') + + if 'download-url' in msg: + self.download_url = _read_field('download-url') + else: + self.download_url = None + + self.long_description = _read_field('description') + self.description = _read_field('summary') + + if 'keywords' in msg: + self.keywords = _read_field('keywords').split(',') + + self.platforms = _read_list('platform') + self.classifiers = _read_list('classifier') + + # PEP 314 - these fields only exist in 1.1 + if metadata_version == '1.1': + self.requires = _read_list('requires') + self.provides = _read_list('provides') + self.obsoletes = _read_list('obsoletes') + else: + self.requires = None + self.provides = None + self.obsoletes = None + + def write_pkg_info(self, base_dir): + """Write the PKG-INFO file into the release tree. + """ + pkg_info = open(os.path.join(base_dir, 'PKG-INFO'), 'w') + try: + self.write_pkg_file(pkg_info) + finally: + pkg_info.close() + + def write_pkg_file(self, file): + """Write the PKG-INFO format data to a file object. + """ + version = '1.0' + if (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): + version = '1.1' + + self._write_field(file, 'Metadata-Version', version) + self._write_field(file, 'Name', self.get_name()) + self._write_field(file, 'Version', self.get_version()) + self._write_field(file, 'Summary', self.get_description()) + self._write_field(file, 'Home-page', self.get_url()) + self._write_field(file, 'Author', self.get_contact()) + self._write_field(file, 'Author-email', self.get_contact_email()) + self._write_field(file, 'License', self.get_license()) + if self.download_url: + self._write_field(file, 'Download-URL', self.download_url) + + long_desc = rfc822_escape(self.get_long_description()) + self._write_field(file, 'Description', long_desc) + + keywords = ','.join(self.get_keywords()) + if keywords: + self._write_field(file, 'Keywords', keywords) + + self._write_list(file, 'Platform', self.get_platforms()) + self._write_list(file, 'Classifier', self.get_classifiers()) + + # PEP 314 + self._write_list(file, 'Requires', self.get_requires()) + self._write_list(file, 'Provides', self.get_provides()) + self._write_list(file, 'Obsoletes', self.get_obsoletes()) + + def _write_field(self, file, name, value): + file.write('%s: %s\n' % (name, self._encode_field(value))) + + def _write_list (self, file, name, values): + for value in values: + self._write_field(file, name, value) + + def _encode_field(self, value): + if value is None: + return None + if isinstance(value, unicode): + return value.encode(PKG_INFO_ENCODING) + return str(value) + + # -- Metadata query methods ---------------------------------------- + + def get_name(self): + return self.name or "UNKNOWN" + + def get_version(self): + return self.version or "0.0.0" + + def get_fullname(self): + return "%s-%s" % (self.get_name(), self.get_version()) + + def get_author(self): + return self._encode_field(self.author) or "UNKNOWN" + + def get_author_email(self): + return self.author_email or "UNKNOWN" + + def get_maintainer(self): + return self._encode_field(self.maintainer) or "UNKNOWN" + + def get_maintainer_email(self): + return self.maintainer_email or "UNKNOWN" + + def get_contact(self): + return (self._encode_field(self.maintainer) or + self._encode_field(self.author) or "UNKNOWN") + + def get_contact_email(self): + return self.maintainer_email or self.author_email or "UNKNOWN" + + def get_url(self): + return self.url or "UNKNOWN" + + def get_license(self): + return self.license or "UNKNOWN" + get_licence = get_license + + def get_description(self): + return self._encode_field(self.description) or "UNKNOWN" + + def get_long_description(self): + return self._encode_field(self.long_description) or "UNKNOWN" + + def get_keywords(self): + return self.keywords or [] + + def get_platforms(self): + return self.platforms or ["UNKNOWN"] + + def get_classifiers(self): + return self.classifiers or [] + + def get_download_url(self): + return self.download_url or "UNKNOWN" + + # PEP 314 + def get_requires(self): + return self.requires or [] + + def set_requires(self, value): + import distutils.versionpredicate + for v in value: + distutils.versionpredicate.VersionPredicate(v) + self.requires = value + + def get_provides(self): + return self.provides or [] + + def set_provides(self, value): + value = [v.strip() for v in value] + for v in value: + import distutils.versionpredicate + distutils.versionpredicate.split_provision(v) + self.provides = value + + def get_obsoletes(self): + return self.obsoletes or [] + + def set_obsoletes(self, value): + import distutils.versionpredicate + for v in value: + distutils.versionpredicate.VersionPredicate(v) + self.obsoletes = value + +def fix_help_options(options): + """Convert a 4-tuple 'help_options' list as found in various command + classes to the 3-tuple form required by FancyGetopt. + """ + new_options = [] + for help_tuple in options: + new_options.append(help_tuple[0:3]) + return new_options diff --git a/src/main/resources/PythonLibs/distutils/emxccompiler.py b/src/main/resources/PythonLibs/distutils/emxccompiler.py new file mode 100644 index 0000000000000000000000000000000000000000..a0172058a38175d00bc2da288447c2336be6c15c --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/emxccompiler.py @@ -0,0 +1,319 @@ +"""distutils.emxccompiler + +Provides the EMXCCompiler class, a subclass of UnixCCompiler that +handles the EMX port of the GNU C compiler to OS/2. +""" + +# issues: +# +# * OS/2 insists that DLLs can have names no longer than 8 characters +# We put export_symbols in a def-file, as though the DLL can have +# an arbitrary length name, but truncate the output filename. +# +# * only use OMF objects and use LINK386 as the linker (-Zomf) +# +# * always build for multithreading (-Zmt) as the accompanying OS/2 port +# of Python is only distributed with threads enabled. +# +# tested configurations: +# +# * EMX gcc 2.81/EMX 0.9d fix03 + +__revision__ = "$Id$" + +import os,sys,copy +from distutils.ccompiler import gen_preprocess_options, gen_lib_options +from distutils.unixccompiler import UnixCCompiler +from distutils.file_util import write_file +from distutils.errors import DistutilsExecError, CompileError, UnknownFileError +from distutils import log + +class EMXCCompiler (UnixCCompiler): + + compiler_type = 'emx' + obj_extension = ".obj" + static_lib_extension = ".lib" + shared_lib_extension = ".dll" + static_lib_format = "%s%s" + shared_lib_format = "%s%s" + res_extension = ".res" # compiled resource file + exe_extension = ".exe" + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + UnixCCompiler.__init__ (self, verbose, dry_run, force) + + (status, details) = check_config_h() + self.debug_print("Python's GCC status: %s (details: %s)" % + (status, details)) + if status is not CONFIG_H_OK: + self.warn( + "Python's pyconfig.h doesn't seem to support your compiler. " + + ("Reason: %s." % details) + + "Compiling may fail because of undefined preprocessor macros.") + + (self.gcc_version, self.ld_version) = \ + get_versions() + self.debug_print(self.compiler_type + ": gcc %s, ld %s\n" % + (self.gcc_version, + self.ld_version) ) + + # Hard-code GCC because that's what this is all about. + # XXX optimization, warnings etc. should be customizable. + self.set_executables(compiler='gcc -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall', + compiler_so='gcc -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall', + linker_exe='gcc -Zomf -Zmt -Zcrtdll', + linker_so='gcc -Zomf -Zmt -Zcrtdll -Zdll') + + # want the gcc library statically linked (so that we don't have + # to distribute a version dependent on the compiler we have) + self.dll_libraries=["gcc"] + + # __init__ () + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + if ext == '.rc': + # gcc requires '.rc' compiled to binary ('.res') files !!! + try: + self.spawn(["rc", "-r", src]) + except DistutilsExecError, msg: + raise CompileError, msg + else: # for other files use the C-compiler + try: + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + # use separate copies, so we can modify the lists + extra_preargs = copy.copy(extra_preargs or []) + libraries = copy.copy(libraries or []) + objects = copy.copy(objects or []) + + # Additional libraries + libraries.extend(self.dll_libraries) + + # handle export symbols by creating a def-file + # with executables this only works with gcc/ld as linker + if ((export_symbols is not None) and + (target_desc != self.EXECUTABLE)): + # (The linker doesn't do anything if output is up-to-date. + # So it would probably better to check if we really need this, + # but for this we had to insert some unchanged parts of + # UnixCCompiler, and this is not what we want.) + + # we want to put some files in the same directory as the + # object files are, build_temp doesn't help much + # where are the object files + temp_dir = os.path.dirname(objects[0]) + # name of dll to give the helper files the same base name + (dll_name, dll_extension) = os.path.splitext( + os.path.basename(output_filename)) + + # generate the filenames for these files + def_file = os.path.join(temp_dir, dll_name + ".def") + + # Generate .def file + contents = [ + "LIBRARY %s INITINSTANCE TERMINSTANCE" % \ + os.path.splitext(os.path.basename(output_filename))[0], + "DATA MULTIPLE NONSHARED", + "EXPORTS"] + for sym in export_symbols: + contents.append(' "%s"' % sym) + self.execute(write_file, (def_file, contents), + "writing %s" % def_file) + + # next add options for def-file and to creating import libraries + # for gcc/ld the def-file is specified as any other object files + objects.append(def_file) + + #end: if ((export_symbols is not None) and + # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): + + # who wants symbols and a many times larger output file + # should explicitly switch the debug mode on + # otherwise we let dllwrap/ld strip the output file + # (On my machine: 10KB < stripped_file < ??100KB + # unstripped_file = stripped_file + XXX KB + # ( XXX=254 for a typical python extension)) + if not debug: + extra_preargs.append("-s") + + UnixCCompiler.link(self, + target_desc, + objects, + output_filename, + output_dir, + libraries, + library_dirs, + runtime_library_dirs, + None, # export_symbols, we do this in our def-file + debug, + extra_preargs, + extra_postargs, + build_temp, + target_lang) + + # link () + + # -- Miscellaneous methods ----------------------------------------- + + # override the object_filenames method from CCompiler to + # support rc and res-files + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + # use normcase to make sure '.rc' is really '.rc' and not '.RC' + (base, ext) = os.path.splitext (os.path.normcase(src_name)) + if ext not in (self.src_extensions + ['.rc']): + raise UnknownFileError, \ + "unknown file type '%s' (from '%s')" % \ + (ext, src_name) + if strip_dir: + base = os.path.basename (base) + if ext == '.rc': + # these need to be compiled to object files + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + # override the find_library_file method from UnixCCompiler + # to deal with file naming/searching differences + def find_library_file(self, dirs, lib, debug=0): + shortlib = '%s.lib' % lib + longlib = 'lib%s.lib' % lib # this form very rare + + # get EMX's default library directory search path + try: + emx_dirs = os.environ['LIBRARY_PATH'].split(';') + except KeyError: + emx_dirs = [] + + for dir in dirs + emx_dirs: + shortlibp = os.path.join(dir, shortlib) + longlibp = os.path.join(dir, longlib) + if os.path.exists(shortlibp): + return shortlibp + elif os.path.exists(longlibp): + return longlibp + + # Oops, didn't find it in *any* of 'dirs' + return None + +# class EMXCCompiler + + +# Because these compilers aren't configured in Python's pyconfig.h file by +# default, we should at least warn the user if he is using a unmodified +# version. + +CONFIG_H_OK = "ok" +CONFIG_H_NOTOK = "not ok" +CONFIG_H_UNCERTAIN = "uncertain" + +def check_config_h(): + + """Check if the current Python installation (specifically, pyconfig.h) + appears amenable to building extensions with GCC. Returns a tuple + (status, details), where 'status' is one of the following constants: + CONFIG_H_OK + all is well, go ahead and compile + CONFIG_H_NOTOK + doesn't look good + CONFIG_H_UNCERTAIN + not sure -- unable to read pyconfig.h + 'details' is a human-readable string explaining the situation. + + Note there are two ways to conclude "OK": either 'sys.version' contains + the string "GCC" (implying that this Python was built with GCC), or the + installed "pyconfig.h" contains the string "__GNUC__". + """ + + # XXX since this function also checks sys.version, it's not strictly a + # "pyconfig.h" check -- should probably be renamed... + + from distutils import sysconfig + import string + # if sys.version contains GCC then python was compiled with + # GCC, and the pyconfig.h file should be OK + if string.find(sys.version,"GCC") >= 0: + return (CONFIG_H_OK, "sys.version mentions 'GCC'") + + fn = sysconfig.get_config_h_filename() + try: + # It would probably better to read single lines to search. + # But we do this only once, and it is fast enough + f = open(fn) + try: + s = f.read() + finally: + f.close() + + except IOError, exc: + # if we can't read this file, we cannot say it is wrong + # the compiler will complain later about this file as missing + return (CONFIG_H_UNCERTAIN, + "couldn't read '%s': %s" % (fn, exc.strerror)) + + else: + # "pyconfig.h" contains an "#ifdef __GNUC__" or something similar + if string.find(s,"__GNUC__") >= 0: + return (CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn) + else: + return (CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn) + + +def get_versions(): + """ Try to find out the versions of gcc and ld. + If not possible it returns None for it. + """ + from distutils.version import StrictVersion + from distutils.spawn import find_executable + import re + + gcc_exe = find_executable('gcc') + if gcc_exe: + out = os.popen(gcc_exe + ' -dumpversion','r') + try: + out_string = out.read() + finally: + out.close() + result = re.search('(\d+\.\d+\.\d+)',out_string) + if result: + gcc_version = StrictVersion(result.group(1)) + else: + gcc_version = None + else: + gcc_version = None + # EMX ld has no way of reporting version number, and we use GCC + # anyway - so we can link OMF DLLs + ld_version = None + return (gcc_version, ld_version) diff --git a/src/main/resources/PythonLibs/distutils/errors.py b/src/main/resources/PythonLibs/distutils/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..d9c47c761cb4428cacef0efbe010f78a9d1f930d --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/errors.py @@ -0,0 +1,88 @@ +"""distutils.errors + +Provides exceptions used by the Distutils modules. Note that Distutils +modules may raise standard exceptions; in particular, SystemExit is +usually raised for errors that are obviously the end-user's fault +(eg. bad command-line arguments). + +This module is safe to use in "from ... import *" mode; it only exports +symbols whose names start with "Distutils" and end with "Error".""" + +__revision__ = "$Id$" + +class DistutilsError(Exception): + """The root of all Distutils evil.""" + +class DistutilsModuleError(DistutilsError): + """Unable to load an expected module, or to find an expected class + within some module (in particular, command modules and classes).""" + +class DistutilsClassError(DistutilsError): + """Some command class (or possibly distribution class, if anyone + feels a need to subclass Distribution) is found not to be holding + up its end of the bargain, ie. implementing some part of the + "command "interface.""" + +class DistutilsGetoptError(DistutilsError): + """The option table provided to 'fancy_getopt()' is bogus.""" + +class DistutilsArgError(DistutilsError): + """Raised by fancy_getopt in response to getopt.error -- ie. an + error in the command line usage.""" + +class DistutilsFileError(DistutilsError): + """Any problems in the filesystem: expected file not found, etc. + Typically this is for problems that we detect before IOError or + OSError could be raised.""" + +class DistutilsOptionError(DistutilsError): + """Syntactic/semantic errors in command options, such as use of + mutually conflicting options, or inconsistent options, + badly-spelled values, etc. No distinction is made between option + values originating in the setup script, the command line, config + files, or what-have-you -- but if we *know* something originated in + the setup script, we'll raise DistutilsSetupError instead.""" + +class DistutilsSetupError(DistutilsError): + """For errors that can be definitely blamed on the setup script, + such as invalid keyword arguments to 'setup()'.""" + +class DistutilsPlatformError(DistutilsError): + """We don't know how to do something on the current platform (but + we do know how to do it on some platform) -- eg. trying to compile + C files on a platform not supported by a CCompiler subclass.""" + +class DistutilsExecError(DistutilsError): + """Any problems executing an external program (such as the C + compiler, when compiling C files).""" + +class DistutilsInternalError(DistutilsError): + """Internal inconsistencies or impossibilities (obviously, this + should never be seen if the code is working!).""" + +class DistutilsTemplateError(DistutilsError): + """Syntax error in a file list template.""" + +class DistutilsByteCompileError(DistutilsError): + """Byte compile error.""" + +# Exception classes used by the CCompiler implementation classes +class CCompilerError(Exception): + """Some compile/link operation failed.""" + +class PreprocessError(CCompilerError): + """Failure to preprocess one or more C/C++ files.""" + +class CompileError(CCompilerError): + """Failure to compile one or more C/C++ source files.""" + +class LibError(CCompilerError): + """Failure to create a static library from one or more C/C++ object + files.""" + +class LinkError(CCompilerError): + """Failure to link one or more C/C++ object files into an executable + or shared library file.""" + +class UnknownFileError(CCompilerError): + """Attempt to process an unknown file type.""" diff --git a/src/main/resources/PythonLibs/distutils/extension.py b/src/main/resources/PythonLibs/distutils/extension.py new file mode 100644 index 0000000000000000000000000000000000000000..9a67ca8b3ea9b4690e69a6e47a01794b01106d39 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/extension.py @@ -0,0 +1,255 @@ +"""distutils.extension + +Provides the Extension class, used to describe C/C++ extension +modules in setup scripts.""" + +__revision__ = "$Id$" + +import os, string, sys +from types import * + +try: + import warnings +except ImportError: + warnings = None + +# This class is really only used by the "build_ext" command, so it might +# make sense to put it in distutils.command.build_ext. However, that +# module is already big enough, and I want to make this class a bit more +# complex to simplify some common cases ("foo" module in "foo.c") and do +# better error-checking ("foo.c" actually exists). +# +# Also, putting this in build_ext.py means every setup script would have to +# import that large-ish module (indirectly, through distutils.core) in +# order to do anything. + +class Extension: + """Just a collection of attributes that describes an extension + module and everything needed to build it (hopefully in a portable + way, but there are hooks that let you be as unportable as you need). + + Instance attributes: + name : string + the full name of the extension, including any packages -- ie. + *not* a filename or pathname, but Python dotted name + sources : [string] + list of source filenames, relative to the distribution root + (where the setup script lives), in Unix form (slash-separated) + for portability. Source files may be C, C++, SWIG (.i), + platform-specific resource files, or whatever else is recognized + by the "build_ext" command as source for a Python extension. + include_dirs : [string] + list of directories to search for C/C++ header files (in Unix + form for portability) + define_macros : [(name : string, value : string|None)] + list of macros to define; each macro is defined using a 2-tuple, + where 'value' is either the string to define it to or None to + define it without a particular value (equivalent of "#define + FOO" in source or -DFOO on Unix C compiler command line) + undef_macros : [string] + list of macros to undefine explicitly + library_dirs : [string] + list of directories to search for C/C++ libraries at link time + libraries : [string] + list of library names (not filenames or paths) to link against + runtime_library_dirs : [string] + list of directories to search for C/C++ libraries at run time + (for shared extensions, this is when the extension is loaded) + extra_objects : [string] + list of extra files to link with (eg. object files not implied + by 'sources', static library that must be explicitly specified, + binary resource files, etc.) + extra_compile_args : [string] + any extra platform- and compiler-specific information to use + when compiling the source files in 'sources'. For platforms and + compilers where "command line" makes sense, this is typically a + list of command-line arguments, but for other platforms it could + be anything. + extra_link_args : [string] + any extra platform- and compiler-specific information to use + when linking object files together to create the extension (or + to create a new static Python interpreter). Similar + interpretation as for 'extra_compile_args'. + export_symbols : [string] + list of symbols to be exported from a shared extension. Not + used on all platforms, and not generally necessary for Python + extensions, which typically export exactly one symbol: "init" + + extension_name. + swig_opts : [string] + any extra options to pass to SWIG if a source file has the .i + extension. + depends : [string] + list of files that the extension depends on + language : string + extension language (i.e. "c", "c++", "objc"). Will be detected + from the source extensions if not provided. + """ + + # When adding arguments to this constructor, be sure to update + # setup_keywords in core.py. + def __init__ (self, name, sources, + include_dirs=None, + define_macros=None, + undef_macros=None, + library_dirs=None, + libraries=None, + runtime_library_dirs=None, + extra_objects=None, + extra_compile_args=None, + extra_link_args=None, + export_symbols=None, + swig_opts = None, + depends=None, + language=None, + **kw # To catch unknown keywords + ): + assert type(name) is StringType, "'name' must be a string" + assert (type(sources) is ListType and + map(type, sources) == [StringType]*len(sources)), \ + "'sources' must be a list of strings" + + self.name = name + self.sources = sources + self.include_dirs = include_dirs or [] + self.define_macros = define_macros or [] + self.undef_macros = undef_macros or [] + self.library_dirs = library_dirs or [] + self.libraries = libraries or [] + self.runtime_library_dirs = runtime_library_dirs or [] + self.extra_objects = extra_objects or [] + self.extra_compile_args = extra_compile_args or [] + self.extra_link_args = extra_link_args or [] + self.export_symbols = export_symbols or [] + self.swig_opts = swig_opts or [] + self.depends = depends or [] + self.language = language + + # If there are unknown keyword options, warn about them + if len(kw): + L = kw.keys() ; L.sort() + L = map(repr, L) + msg = "Unknown Extension options: " + string.join(L, ', ') + if warnings is not None: + warnings.warn(msg) + else: + sys.stderr.write(msg + '\n') +# class Extension + + +def read_setup_file (filename): + from distutils.sysconfig import \ + parse_makefile, expand_makefile_vars, _variable_rx + from distutils.text_file import TextFile + from distutils.util import split_quoted + + # First pass over the file to gather "VAR = VALUE" assignments. + vars = parse_makefile(filename) + + # Second pass to gobble up the real content: lines of the form + # <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...] + file = TextFile(filename, + strip_comments=1, skip_blanks=1, join_lines=1, + lstrip_ws=1, rstrip_ws=1) + try: + extensions = [] + + while 1: + line = file.readline() + if line is None: # eof + break + if _variable_rx.match(line): # VAR=VALUE, handled in first pass + continue + + if line[0] == line[-1] == "*": + file.warn("'%s' lines not handled yet" % line) + continue + + #print "original line: " + line + line = expand_makefile_vars(line, vars) + words = split_quoted(line) + #print "expanded line: " + line + + # NB. this parses a slightly different syntax than the old + # makesetup script: here, there must be exactly one extension per + # line, and it must be the first word of the line. I have no idea + # why the old syntax supported multiple extensions per line, as + # they all wind up being the same. + + module = words[0] + ext = Extension(module, []) + append_next_word = None + + for word in words[1:]: + if append_next_word is not None: + append_next_word.append(word) + append_next_word = None + continue + + suffix = os.path.splitext(word)[1] + switch = word[0:2] ; value = word[2:] + + if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"): + # hmm, should we do something about C vs. C++ sources? + # or leave it up to the CCompiler implementation to + # worry about? + ext.sources.append(word) + elif switch == "-I": + ext.include_dirs.append(value) + elif switch == "-D": + equals = string.find(value, "=") + if equals == -1: # bare "-DFOO" -- no value + ext.define_macros.append((value, None)) + else: # "-DFOO=blah" + ext.define_macros.append((value[0:equals], + value[equals+2:])) + elif switch == "-U": + ext.undef_macros.append(value) + elif switch == "-C": # only here 'cause makesetup has it! + ext.extra_compile_args.append(word) + elif switch == "-l": + ext.libraries.append(value) + elif switch == "-L": + ext.library_dirs.append(value) + elif switch == "-R": + ext.runtime_library_dirs.append(value) + elif word == "-rpath": + append_next_word = ext.runtime_library_dirs + elif word == "-Xlinker": + append_next_word = ext.extra_link_args + elif word == "-Xcompiler": + append_next_word = ext.extra_compile_args + elif switch == "-u": + ext.extra_link_args.append(word) + if not value: + append_next_word = ext.extra_link_args + elif word == "-Xcompiler": + append_next_word = ext.extra_compile_args + elif switch == "-u": + ext.extra_link_args.append(word) + if not value: + append_next_word = ext.extra_link_args + elif suffix in (".a", ".so", ".sl", ".o", ".dylib"): + # NB. a really faithful emulation of makesetup would + # append a .o file to extra_objects only if it + # had a slash in it; otherwise, it would s/.o/.c/ + # and append it to sources. Hmmmm. + ext.extra_objects.append(word) + else: + file.warn("unrecognized argument '%s'" % word) + + extensions.append(ext) + finally: + file.close() + + #print "module:", module + #print "source files:", source_files + #print "cpp args:", cpp_args + #print "lib args:", library_args + + #extensions[module] = { 'sources': source_files, + # 'cpp_args': cpp_args, + # 'lib_args': library_args } + + return extensions + +# read_setup_file () diff --git a/src/main/resources/PythonLibs/distutils/fancy_getopt.py b/src/main/resources/PythonLibs/distutils/fancy_getopt.py new file mode 100644 index 0000000000000000000000000000000000000000..2dea948025936bf842acbfb26385b8f965a571e8 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/fancy_getopt.py @@ -0,0 +1,484 @@ +"""distutils.fancy_getopt + +Wrapper around the standard getopt module that provides the following +additional features: + * short and long options are tied together + * options have help strings, so fancy_getopt could potentially + create a complete usage summary + * options set attributes of a passed-in object +""" + +__revision__ = "$Id$" + +import sys +import string +import re +import getopt +from distutils.errors import DistutilsGetoptError, DistutilsArgError + +# Much like command_re in distutils.core, this is close to but not quite +# the same as a Python NAME -- except, in the spirit of most GNU +# utilities, we use '-' in place of '_'. (The spirit of LISP lives on!) +# The similarities to NAME are again not a coincidence... +longopt_pat = r'[a-zA-Z](?:[a-zA-Z0-9-]*)' +longopt_re = re.compile(r'^%s$' % longopt_pat) + +# For recognizing "negative alias" options, eg. "quiet=!verbose" +neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat)) + +# This is used to translate long options to legitimate Python identifiers +# (for use as attributes of some object). +longopt_xlate = string.maketrans('-', '_') + +class FancyGetopt: + """Wrapper around the standard 'getopt()' module that provides some + handy extra functionality: + * short and long options are tied together + * options have help strings, and help text can be assembled + from them + * options set attributes of a passed-in object + * boolean options can have "negative aliases" -- eg. if + --quiet is the "negative alias" of --verbose, then "--quiet" + on the command line sets 'verbose' to false + """ + + def __init__ (self, option_table=None): + + # The option table is (currently) a list of tuples. The + # tuples may have 3 or four values: + # (long_option, short_option, help_string [, repeatable]) + # if an option takes an argument, its long_option should have '=' + # appended; short_option should just be a single character, no ':' + # in any case. If a long_option doesn't have a corresponding + # short_option, short_option should be None. All option tuples + # must have long options. + self.option_table = option_table + + # 'option_index' maps long option names to entries in the option + # table (ie. those 3-tuples). + self.option_index = {} + if self.option_table: + self._build_index() + + # 'alias' records (duh) alias options; {'foo': 'bar'} means + # --foo is an alias for --bar + self.alias = {} + + # 'negative_alias' keeps track of options that are the boolean + # opposite of some other option + self.negative_alias = {} + + # These keep track of the information in the option table. We + # don't actually populate these structures until we're ready to + # parse the command-line, since the 'option_table' passed in here + # isn't necessarily the final word. + self.short_opts = [] + self.long_opts = [] + self.short2long = {} + self.attr_name = {} + self.takes_arg = {} + + # And 'option_order' is filled up in 'getopt()'; it records the + # original order of options (and their values) on the command-line, + # but expands short options, converts aliases, etc. + self.option_order = [] + + # __init__ () + + + def _build_index (self): + self.option_index.clear() + for option in self.option_table: + self.option_index[option[0]] = option + + def set_option_table (self, option_table): + self.option_table = option_table + self._build_index() + + def add_option (self, long_option, short_option=None, help_string=None): + if long_option in self.option_index: + raise DistutilsGetoptError, \ + "option conflict: already an option '%s'" % long_option + else: + option = (long_option, short_option, help_string) + self.option_table.append(option) + self.option_index[long_option] = option + + + def has_option (self, long_option): + """Return true if the option table for this parser has an + option with long name 'long_option'.""" + return long_option in self.option_index + + def get_attr_name (self, long_option): + """Translate long option name 'long_option' to the form it + has as an attribute of some object: ie., translate hyphens + to underscores.""" + return string.translate(long_option, longopt_xlate) + + + def _check_alias_dict (self, aliases, what): + assert isinstance(aliases, dict) + for (alias, opt) in aliases.items(): + if alias not in self.option_index: + raise DistutilsGetoptError, \ + ("invalid %s '%s': " + "option '%s' not defined") % (what, alias, alias) + if opt not in self.option_index: + raise DistutilsGetoptError, \ + ("invalid %s '%s': " + "aliased option '%s' not defined") % (what, alias, opt) + + def set_aliases (self, alias): + """Set the aliases for this option parser.""" + self._check_alias_dict(alias, "alias") + self.alias = alias + + def set_negative_aliases (self, negative_alias): + """Set the negative aliases for this option parser. + 'negative_alias' should be a dictionary mapping option names to + option names, both the key and value must already be defined + in the option table.""" + self._check_alias_dict(negative_alias, "negative alias") + self.negative_alias = negative_alias + + + def _grok_option_table (self): + """Populate the various data structures that keep tabs on the + option table. Called by 'getopt()' before it can do anything + worthwhile. + """ + self.long_opts = [] + self.short_opts = [] + self.short2long.clear() + self.repeat = {} + + for option in self.option_table: + if len(option) == 3: + long, short, help = option + repeat = 0 + elif len(option) == 4: + long, short, help, repeat = option + else: + # the option table is part of the code, so simply + # assert that it is correct + raise ValueError, "invalid option tuple: %r" % (option,) + + # Type- and value-check the option names + if not isinstance(long, str) or len(long) < 2: + raise DistutilsGetoptError, \ + ("invalid long option '%s': " + "must be a string of length >= 2") % long + + if (not ((short is None) or + (isinstance(short, str) and len(short) == 1))): + raise DistutilsGetoptError, \ + ("invalid short option '%s': " + "must a single character or None") % short + + self.repeat[long] = repeat + self.long_opts.append(long) + + if long[-1] == '=': # option takes an argument? + if short: short = short + ':' + long = long[0:-1] + self.takes_arg[long] = 1 + else: + + # Is option is a "negative alias" for some other option (eg. + # "quiet" == "!verbose")? + alias_to = self.negative_alias.get(long) + if alias_to is not None: + if self.takes_arg[alias_to]: + raise DistutilsGetoptError, \ + ("invalid negative alias '%s': " + "aliased option '%s' takes a value") % \ + (long, alias_to) + + self.long_opts[-1] = long # XXX redundant?! + self.takes_arg[long] = 0 + + else: + self.takes_arg[long] = 0 + + # If this is an alias option, make sure its "takes arg" flag is + # the same as the option it's aliased to. + alias_to = self.alias.get(long) + if alias_to is not None: + if self.takes_arg[long] != self.takes_arg[alias_to]: + raise DistutilsGetoptError, \ + ("invalid alias '%s': inconsistent with " + "aliased option '%s' (one of them takes a value, " + "the other doesn't") % (long, alias_to) + + + # Now enforce some bondage on the long option name, so we can + # later translate it to an attribute name on some object. Have + # to do this a bit late to make sure we've removed any trailing + # '='. + if not longopt_re.match(long): + raise DistutilsGetoptError, \ + ("invalid long option name '%s' " + + "(must be letters, numbers, hyphens only") % long + + self.attr_name[long] = self.get_attr_name(long) + if short: + self.short_opts.append(short) + self.short2long[short[0]] = long + + # for option_table + + # _grok_option_table() + + + def getopt (self, args=None, object=None): + """Parse command-line options in args. Store as attributes on object. + + If 'args' is None or not supplied, uses 'sys.argv[1:]'. If + 'object' is None or not supplied, creates a new OptionDummy + object, stores option values there, and returns a tuple (args, + object). If 'object' is supplied, it is modified in place and + 'getopt()' just returns 'args'; in both cases, the returned + 'args' is a modified copy of the passed-in 'args' list, which + is left untouched. + """ + if args is None: + args = sys.argv[1:] + if object is None: + object = OptionDummy() + created_object = 1 + else: + created_object = 0 + + self._grok_option_table() + + short_opts = string.join(self.short_opts) + try: + opts, args = getopt.getopt(args, short_opts, self.long_opts) + except getopt.error, msg: + raise DistutilsArgError, msg + + for opt, val in opts: + if len(opt) == 2 and opt[0] == '-': # it's a short option + opt = self.short2long[opt[1]] + else: + assert len(opt) > 2 and opt[:2] == '--' + opt = opt[2:] + + alias = self.alias.get(opt) + if alias: + opt = alias + + if not self.takes_arg[opt]: # boolean option? + assert val == '', "boolean option can't have value" + alias = self.negative_alias.get(opt) + if alias: + opt = alias + val = 0 + else: + val = 1 + + attr = self.attr_name[opt] + # The only repeating option at the moment is 'verbose'. + # It has a negative option -q quiet, which should set verbose = 0. + if val and self.repeat.get(attr) is not None: + val = getattr(object, attr, 0) + 1 + setattr(object, attr, val) + self.option_order.append((opt, val)) + + # for opts + if created_object: + return args, object + else: + return args + + # getopt() + + + def get_option_order (self): + """Returns the list of (option, value) tuples processed by the + previous run of 'getopt()'. Raises RuntimeError if + 'getopt()' hasn't been called yet. + """ + if self.option_order is None: + raise RuntimeError, "'getopt()' hasn't been called yet" + else: + return self.option_order + + + def generate_help (self, header=None): + """Generate help text (a list of strings, one per suggested line of + output) from the option table for this FancyGetopt object. + """ + # Blithely assume the option table is good: probably wouldn't call + # 'generate_help()' unless you've already called 'getopt()'. + + # First pass: determine maximum length of long option names + max_opt = 0 + for option in self.option_table: + long = option[0] + short = option[1] + l = len(long) + if long[-1] == '=': + l = l - 1 + if short is not None: + l = l + 5 # " (-x)" where short == 'x' + if l > max_opt: + max_opt = l + + opt_width = max_opt + 2 + 2 + 2 # room for indent + dashes + gutter + + # Typical help block looks like this: + # --foo controls foonabulation + # Help block for longest option looks like this: + # --flimflam set the flim-flam level + # and with wrapped text: + # --flimflam set the flim-flam level (must be between + # 0 and 100, except on Tuesdays) + # Options with short names will have the short name shown (but + # it doesn't contribute to max_opt): + # --foo (-f) controls foonabulation + # If adding the short option would make the left column too wide, + # we push the explanation off to the next line + # --flimflam (-l) + # set the flim-flam level + # Important parameters: + # - 2 spaces before option block start lines + # - 2 dashes for each long option name + # - min. 2 spaces between option and explanation (gutter) + # - 5 characters (incl. space) for short option name + + # Now generate lines of help text. (If 80 columns were good enough + # for Jesus, then 78 columns are good enough for me!) + line_width = 78 + text_width = line_width - opt_width + big_indent = ' ' * opt_width + if header: + lines = [header] + else: + lines = ['Option summary:'] + + for option in self.option_table: + long, short, help = option[:3] + text = wrap_text(help, text_width) + if long[-1] == '=': + long = long[0:-1] + + # Case 1: no short option at all (makes life easy) + if short is None: + if text: + lines.append(" --%-*s %s" % (max_opt, long, text[0])) + else: + lines.append(" --%-*s " % (max_opt, long)) + + # Case 2: we have a short option, so we have to include it + # just after the long option + else: + opt_names = "%s (-%s)" % (long, short) + if text: + lines.append(" --%-*s %s" % + (max_opt, opt_names, text[0])) + else: + lines.append(" --%-*s" % opt_names) + + for l in text[1:]: + lines.append(big_indent + l) + + # for self.option_table + + return lines + + # generate_help () + + def print_help (self, header=None, file=None): + if file is None: + file = sys.stdout + for line in self.generate_help(header): + file.write(line + "\n") + +# class FancyGetopt + + +def fancy_getopt (options, negative_opt, object, args): + parser = FancyGetopt(options) + parser.set_negative_aliases(negative_opt) + return parser.getopt(args, object) + + +WS_TRANS = string.maketrans(string.whitespace, ' ' * len(string.whitespace)) + +def wrap_text (text, width): + """wrap_text(text : string, width : int) -> [string] + + Split 'text' into multiple lines of no more than 'width' characters + each, and return the list of strings that results. + """ + + if text is None: + return [] + if len(text) <= width: + return [text] + + text = string.expandtabs(text) + text = string.translate(text, WS_TRANS) + chunks = re.split(r'( +|-+)', text) + chunks = filter(None, chunks) # ' - ' results in empty strings + lines = [] + + while chunks: + + cur_line = [] # list of chunks (to-be-joined) + cur_len = 0 # length of current line + + while chunks: + l = len(chunks[0]) + if cur_len + l <= width: # can squeeze (at least) this chunk in + cur_line.append(chunks[0]) + del chunks[0] + cur_len = cur_len + l + else: # this line is full + # drop last chunk if all space + if cur_line and cur_line[-1][0] == ' ': + del cur_line[-1] + break + + if chunks: # any chunks left to process? + + # if the current line is still empty, then we had a single + # chunk that's too big too fit on a line -- so we break + # down and break it up at the line width + if cur_len == 0: + cur_line.append(chunks[0][0:width]) + chunks[0] = chunks[0][width:] + + # all-whitespace chunks at the end of a line can be discarded + # (and we know from the re.split above that if a chunk has + # *any* whitespace, it is *all* whitespace) + if chunks[0][0] == ' ': + del chunks[0] + + # and store this line in the list-of-all-lines -- as a single + # string, of course! + lines.append(string.join(cur_line, '')) + + # while chunks + + return lines + + +def translate_longopt(opt): + """Convert a long option name to a valid Python identifier by + changing "-" to "_". + """ + return string.translate(opt, longopt_xlate) + + +class OptionDummy: + """Dummy class just used as a place to hold command-line option + values as instance attributes.""" + + def __init__ (self, options=[]): + """Create a new OptionDummy instance. The attributes listed in + 'options' will be initialized to None.""" + for opt in options: + setattr(self, opt, None) diff --git a/src/main/resources/PythonLibs/distutils/file_util.py b/src/main/resources/PythonLibs/distutils/file_util.py new file mode 100644 index 0000000000000000000000000000000000000000..e62ec27fd4f04b3319ecf0d7814443114fe766cb --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/file_util.py @@ -0,0 +1,231 @@ +"""distutils.file_util + +Utility functions for operating on single files. +""" + +__revision__ = "$Id: file_util.py 86238 2010-11-06 04:06:18Z eric.araujo $" + +import os +from distutils.errors import DistutilsFileError +from distutils import log + +# for generating verbose output in 'copy_file()' +_copy_action = {None: 'copying', + 'hard': 'hard linking', + 'sym': 'symbolically linking'} + + +def _copy_file_contents(src, dst, buffer_size=16*1024): + """Copy the file 'src' to 'dst'. + + Both must be filenames. Any error opening either file, reading from + 'src', or writing to 'dst', raises DistutilsFileError. Data is + read/written in chunks of 'buffer_size' bytes (default 16k). No attempt + is made to handle anything apart from regular files. + """ + # Stolen from shutil module in the standard library, but with + # custom error-handling added. + fsrc = None + fdst = None + try: + try: + fsrc = open(src, 'rb') + except os.error, (errno, errstr): + raise DistutilsFileError("could not open '%s': %s" % (src, errstr)) + + if os.path.exists(dst): + try: + os.unlink(dst) + except os.error, (errno, errstr): + raise DistutilsFileError( + "could not delete '%s': %s" % (dst, errstr)) + + try: + fdst = open(dst, 'wb') + except os.error, (errno, errstr): + raise DistutilsFileError( + "could not create '%s': %s" % (dst, errstr)) + + while 1: + try: + buf = fsrc.read(buffer_size) + except os.error, (errno, errstr): + raise DistutilsFileError( + "could not read from '%s': %s" % (src, errstr)) + + if not buf: + break + + try: + fdst.write(buf) + except os.error, (errno, errstr): + raise DistutilsFileError( + "could not write to '%s': %s" % (dst, errstr)) + + finally: + if fdst: + fdst.close() + if fsrc: + fsrc.close() + +def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, + link=None, verbose=1, dry_run=0): + """Copy a file 'src' to 'dst'. + + If 'dst' is a directory, then 'src' is copied there with the same name; + otherwise, it must be a filename. (If the file exists, it will be + ruthlessly clobbered.) If 'preserve_mode' is true (the default), + the file's mode (type and permission bits, or whatever is analogous on + the current platform) is copied. If 'preserve_times' is true (the + default), the last-modified and last-access times are copied as well. + If 'update' is true, 'src' will only be copied if 'dst' does not exist, + or if 'dst' does exist but is older than 'src'. + + 'link' allows you to make hard links (os.link) or symbolic links + (os.symlink) instead of copying: set it to "hard" or "sym"; if it is + None (the default), files are copied. Don't set 'link' on systems that + don't support it: 'copy_file()' doesn't check if hard or symbolic + linking is available. + + Under Mac OS, uses the native file copy function in macostools; on + other systems, uses '_copy_file_contents()' to copy file contents. + + Return a tuple (dest_name, copied): 'dest_name' is the actual name of + the output file, and 'copied' is true if the file was copied (or would + have been copied, if 'dry_run' true). + """ + # XXX if the destination file already exists, we clobber it if + # copying, but blow up if linking. Hmmm. And I don't know what + # macostools.copyfile() does. Should definitely be consistent, and + # should probably blow up if destination exists and we would be + # changing it (ie. it's not already a hard/soft link to src OR + # (not update) and (src newer than dst). + + from distutils.dep_util import newer + from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE + + if not os.path.isfile(src): + raise DistutilsFileError( + "can't copy '%s': doesn't exist or not a regular file" % src) + + if os.path.isdir(dst): + dir = dst + dst = os.path.join(dst, os.path.basename(src)) + else: + dir = os.path.dirname(dst) + + if update and not newer(src, dst): + if verbose >= 1: + log.debug("not copying %s (output up-to-date)", src) + return dst, 0 + + try: + action = _copy_action[link] + except KeyError: + raise ValueError("invalid value '%s' for 'link' argument" % link) + + if verbose >= 1: + if os.path.basename(dst) == os.path.basename(src): + log.info("%s %s -> %s", action, src, dir) + else: + log.info("%s %s -> %s", action, src, dst) + + if dry_run: + return (dst, 1) + + # If linking (hard or symbolic), use the appropriate system call + # (Unix only, of course, but that's the caller's responsibility) + if link == 'hard': + if not (os.path.exists(dst) and os.path.samefile(src, dst)): + os.link(src, dst) + elif link == 'sym': + if not (os.path.exists(dst) and os.path.samefile(src, dst)): + os.symlink(src, dst) + + # Otherwise (non-Mac, not linking), copy the file contents and + # (optionally) copy the times and mode. + else: + _copy_file_contents(src, dst) + if preserve_mode or preserve_times: + st = os.stat(src) + + # According to David Ascher <da@ski.org>, utime() should be done + # before chmod() (at least under NT). + if preserve_times: + os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) + if preserve_mode and hasattr(os, 'chmod'): + os.chmod(dst, S_IMODE(st[ST_MODE])) + + return (dst, 1) + +# XXX I suspect this is Unix-specific -- need porting help! +def move_file (src, dst, verbose=1, dry_run=0): + """Move a file 'src' to 'dst'. + + If 'dst' is a directory, the file will be moved into it with the same + name; otherwise, 'src' is just renamed to 'dst'. Return the new + full name of the file. + + Handles cross-device moves on Unix using 'copy_file()'. What about + other systems??? + """ + from os.path import exists, isfile, isdir, basename, dirname + import errno + + if verbose >= 1: + log.info("moving %s -> %s", src, dst) + + if dry_run: + return dst + + if not isfile(src): + raise DistutilsFileError("can't move '%s': not a regular file" % src) + + if isdir(dst): + dst = os.path.join(dst, basename(src)) + elif exists(dst): + raise DistutilsFileError( + "can't move '%s': destination '%s' already exists" % + (src, dst)) + + if not isdir(dirname(dst)): + raise DistutilsFileError( + "can't move '%s': destination '%s' not a valid path" % \ + (src, dst)) + + copy_it = 0 + try: + os.rename(src, dst) + except os.error, (num, msg): + if num == errno.EXDEV: + copy_it = 1 + else: + raise DistutilsFileError( + "couldn't move '%s' to '%s': %s" % (src, dst, msg)) + + if copy_it: + copy_file(src, dst, verbose=verbose) + try: + os.unlink(src) + except os.error, (num, msg): + try: + os.unlink(dst) + except os.error: + pass + raise DistutilsFileError( + ("couldn't move '%s' to '%s' by copy/delete: " + + "delete '%s' failed: %s") % + (src, dst, src, msg)) + return dst + + +def write_file (filename, contents): + """Create a file with the specified name and write 'contents' (a + sequence of strings without line terminators) to it. + """ + f = open(filename, "w") + try: + for line in contents: + f.write(line + "\n") + finally: + f.close() diff --git a/src/main/resources/PythonLibs/distutils/filelist.py b/src/main/resources/PythonLibs/distutils/filelist.py new file mode 100644 index 0000000000000000000000000000000000000000..2f1c457ea0bec53348c5e3c88b4fb407339c4b3e --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/filelist.py @@ -0,0 +1,343 @@ +"""distutils.filelist + +Provides the FileList class, used for poking about the filesystem +and building lists of files. +""" + +__revision__ = "$Id$" + +import os, re +import fnmatch +from distutils.util import convert_path +from distutils.errors import DistutilsTemplateError, DistutilsInternalError +from distutils import log + +class FileList: + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + + Instance attributes: + dir + directory from which files will be taken -- only used if + 'allfiles' not supplied to constructor + files + list of filenames currently being built/filtered/manipulated + allfiles + complete list of files under consideration (ie. without any + filtering applied) + """ + + def __init__(self, warn=None, debug_print=None): + # ignore argument to FileList, but keep them for backwards + # compatibility + self.allfiles = None + self.files = [] + + def set_allfiles(self, allfiles): + self.allfiles = allfiles + + def findall(self, dir=os.curdir): + self.allfiles = findall(dir) + + def debug_print(self, msg): + """Print 'msg' to stdout if the global DEBUG (taken from the + DISTUTILS_DEBUG environment variable) flag is true. + """ + from distutils.debug import DEBUG + if DEBUG: + print msg + + # -- List-like methods --------------------------------------------- + + def append(self, item): + self.files.append(item) + + def extend(self, items): + self.files.extend(items) + + def sort(self): + # Not a strict lexical sort! + sortable_files = map(os.path.split, self.files) + sortable_files.sort() + self.files = [] + for sort_tuple in sortable_files: + self.files.append(os.path.join(*sort_tuple)) + + + # -- Other miscellaneous utility methods --------------------------- + + def remove_duplicates(self): + # Assumes list has been sorted! + for i in range(len(self.files) - 1, 0, -1): + if self.files[i] == self.files[i - 1]: + del self.files[i] + + + # -- "File template" methods --------------------------------------- + + def _parse_template_line(self, line): + words = line.split() + action = words[0] + + patterns = dir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistutilsTemplateError, \ + "'%s' expects <pattern1> <pattern2> ..." % action + + patterns = map(convert_path, words[1:]) + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistutilsTemplateError, \ + "'%s' expects <dir> <pattern1> <pattern2> ..." % action + + dir = convert_path(words[1]) + patterns = map(convert_path, words[2:]) + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistutilsTemplateError, \ + "'%s' expects a single <dir_pattern>" % action + + dir_pattern = convert_path(words[1]) + + else: + raise DistutilsTemplateError, "unknown action '%s'" % action + + return (action, patterns, dir, dir_pattern) + + def process_template_line(self, line): + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dir_pattern). + action, patterns, dir, dir_pattern = self._parse_template_line(line) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + self.debug_print("include " + ' '.join(patterns)) + for pattern in patterns: + if not self.include_pattern(pattern, anchor=1): + log.warn("warning: no files found matching '%s'", + pattern) + + elif action == 'exclude': + self.debug_print("exclude " + ' '.join(patterns)) + for pattern in patterns: + if not self.exclude_pattern(pattern, anchor=1): + log.warn(("warning: no previously-included files " + "found matching '%s'"), pattern) + + elif action == 'global-include': + self.debug_print("global-include " + ' '.join(patterns)) + for pattern in patterns: + if not self.include_pattern(pattern, anchor=0): + log.warn(("warning: no files found matching '%s' " + + "anywhere in distribution"), pattern) + + elif action == 'global-exclude': + self.debug_print("global-exclude " + ' '.join(patterns)) + for pattern in patterns: + if not self.exclude_pattern(pattern, anchor=0): + log.warn(("warning: no previously-included files matching " + "'%s' found anywhere in distribution"), + pattern) + + elif action == 'recursive-include': + self.debug_print("recursive-include %s %s" % + (dir, ' '.join(patterns))) + for pattern in patterns: + if not self.include_pattern(pattern, prefix=dir): + log.warn(("warning: no files found matching '%s' " + + "under directory '%s'"), + pattern, dir) + + elif action == 'recursive-exclude': + self.debug_print("recursive-exclude %s %s" % + (dir, ' '.join(patterns))) + for pattern in patterns: + if not self.exclude_pattern(pattern, prefix=dir): + log.warn(("warning: no previously-included files matching " + "'%s' found under directory '%s'"), + pattern, dir) + + elif action == 'graft': + self.debug_print("graft " + dir_pattern) + if not self.include_pattern(None, prefix=dir_pattern): + log.warn("warning: no directories found matching '%s'", + dir_pattern) + + elif action == 'prune': + self.debug_print("prune " + dir_pattern) + if not self.exclude_pattern(None, prefix=dir_pattern): + log.warn(("no previously-included directories found " + + "matching '%s'"), dir_pattern) + else: + raise DistutilsInternalError, \ + "this cannot happen: invalid action '%s'" % action + + # -- Filtering/selection methods ----------------------------------- + + def include_pattern(self, pattern, anchor=1, prefix=None, is_regex=0): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. + + Patterns are not quite the same as implemented by the 'fnmatch' + module: '*' and '?' match non-special characters, where "special" + is platform-dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return 1 if files are found. + """ + # XXX docstring lying about what the special chars are? + files_found = 0 + pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) + self.debug_print("include_pattern: applying regex r'%s'" % + pattern_re.pattern) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.debug_print(" adding " + name) + self.files.append(name) + files_found = 1 + + return files_found + + + def exclude_pattern(self, pattern, anchor=1, prefix=None, is_regex=0): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. + + Other parameters are the same as for 'include_pattern()', above. + The list 'self.files' is modified in place. Return 1 if files are + found. + """ + files_found = 0 + pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) + self.debug_print("exclude_pattern: applying regex r'%s'" % + pattern_re.pattern) + for i in range(len(self.files)-1, -1, -1): + if pattern_re.search(self.files[i]): + self.debug_print(" removing " + self.files[i]) + del self.files[i] + files_found = 1 + + return files_found + + +# ---------------------------------------------------------------------- +# Utility functions + +def findall(dir = os.curdir): + """Find all files under 'dir' and return the list of full filenames + (relative to 'dir'). + """ + from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK + + list = [] + stack = [dir] + pop = stack.pop + push = stack.append + + while stack: + dir = pop() + names = os.listdir(dir) + + for name in names: + if dir != os.curdir: # avoid the dreaded "./" syndrome + fullname = os.path.join(dir, name) + else: + fullname = name + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat[ST_MODE] + if S_ISREG(mode): + list.append(fullname) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + return list + + +def glob_to_re(pattern): + """Translate a shell-like glob pattern to a regular expression. + + Return a string containing the regex. Differs from + 'fnmatch.translate()' in that '*' does not match "special characters" + (which are platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters (currently: just os.sep). + sep = os.sep + if os.sep == '\\': + # we're using a regex to manipulate a regex, so we need + # to escape the backslash twice + sep = r'\\\\' + escaped = r'\1[^%s]' % sep + pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) + return pattern_re + + +def translate_pattern(pattern, anchor=1, prefix=None, is_regex=0): + """Translate a shell-like wildcard pattern to a compiled regular + expression. + + Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if isinstance(pattern, str): + return re.compile(pattern) + else: + return pattern + + if pattern: + pattern_re = glob_to_re(pattern) + else: + pattern_re = '' + + if prefix is not None: + # ditch end of pattern character + empty_pattern = glob_to_re('') + prefix_re = glob_to_re(prefix)[:-len(empty_pattern)] + sep = os.sep + if os.sep == '\\': + sep = r'\\' + pattern_re = "^" + sep.join((prefix_re, ".*" + pattern_re)) + else: # no prefix -- respect anchor flag + if anchor: + pattern_re = "^" + pattern_re + + return re.compile(pattern_re) diff --git a/src/main/resources/PythonLibs/distutils/jythoncompiler.py b/src/main/resources/PythonLibs/distutils/jythoncompiler.py new file mode 100644 index 0000000000000000000000000000000000000000..91d106a4bdcb1596b365566c5d11e86a353225b2 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/jythoncompiler.py @@ -0,0 +1,21 @@ +"""distutils.jythoncompiler + +Jython does not support extension libraries. This CCompiler simply +raises CCompiler exceptions. +""" + +from distutils.ccompiler import CCompiler +from distutils.errors import CCompilerError + +class JythonCompiler(CCompiler): + + """Refuses to compile C extensions on Jython""" + + compiler_type = 'jython' + executables = {} + + def refuse_compilation(self, *args, **kwargs): + """Refuse compilation""" + raise CCompilerError('Compiling extensions is not supported on Jython') + + preprocess = compile = create_static_lib = link = refuse_compilation diff --git a/src/main/resources/PythonLibs/distutils/log.py b/src/main/resources/PythonLibs/distutils/log.py new file mode 100644 index 0000000000000000000000000000000000000000..758857081c80e13ec772aea668323961478a752b --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/log.py @@ -0,0 +1,71 @@ +"""A simple log mechanism styled after PEP 282.""" + +# The class here is styled after PEP 282 so that it could later be +# replaced with a standard Python logging implementation. + +DEBUG = 1 +INFO = 2 +WARN = 3 +ERROR = 4 +FATAL = 5 + +import sys + +class Log: + + def __init__(self, threshold=WARN): + self.threshold = threshold + + def _log(self, level, msg, args): + if level not in (DEBUG, INFO, WARN, ERROR, FATAL): + raise ValueError('%s wrong log level' % str(level)) + + if level >= self.threshold: + if args: + msg = msg % args + if level in (WARN, ERROR, FATAL): + stream = sys.stderr + else: + stream = sys.stdout + stream.write('%s\n' % msg) + stream.flush() + + def log(self, level, msg, *args): + self._log(level, msg, args) + + def debug(self, msg, *args): + self._log(DEBUG, msg, args) + + def info(self, msg, *args): + self._log(INFO, msg, args) + + def warn(self, msg, *args): + self._log(WARN, msg, args) + + def error(self, msg, *args): + self._log(ERROR, msg, args) + + def fatal(self, msg, *args): + self._log(FATAL, msg, args) + +_global_log = Log() +log = _global_log.log +debug = _global_log.debug +info = _global_log.info +warn = _global_log.warn +error = _global_log.error +fatal = _global_log.fatal + +def set_threshold(level): + # return the old threshold for use from tests + old = _global_log.threshold + _global_log.threshold = level + return old + +def set_verbosity(v): + if v <= 0: + set_threshold(WARN) + elif v == 1: + set_threshold(INFO) + elif v >= 2: + set_threshold(DEBUG) diff --git a/src/main/resources/PythonLibs/distutils/msvc9compiler.py b/src/main/resources/PythonLibs/distutils/msvc9compiler.py new file mode 100644 index 0000000000000000000000000000000000000000..7ec9b92a5dcbd0656c3bc4ecf32269d3a9e82202 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/msvc9compiler.py @@ -0,0 +1,801 @@ +"""distutils.msvc9compiler + +Contains MSVCCompiler, an implementation of the abstract CCompiler class +for the Microsoft Visual Studio 2008. + +The module is compatible with VS 2005 and VS 2008. You can find legacy support +for older versions of VS in distutils.msvccompiler. +""" + +# Written by Perry Stoll +# hacked by Robin Becker and Thomas Heller to do a better job of +# finding DevStudio (through the registry) +# ported to VS2005 and VS 2008 by Christian Heimes + +__revision__ = "$Id$" + +import os +import subprocess +import sys +import re + +from distutils.errors import (DistutilsExecError, DistutilsPlatformError, + CompileError, LibError, LinkError) +from distutils.ccompiler import CCompiler, gen_lib_options +from distutils import log +from distutils.util import get_platform + +import _winreg + +RegOpenKeyEx = _winreg.OpenKeyEx +RegEnumKey = _winreg.EnumKey +RegEnumValue = _winreg.EnumValue +RegError = _winreg.error + +HKEYS = (_winreg.HKEY_USERS, + _winreg.HKEY_CURRENT_USER, + _winreg.HKEY_LOCAL_MACHINE, + _winreg.HKEY_CLASSES_ROOT) + +NATIVE_WIN64 = (sys.platform == 'win32' and sys.maxsize > 2**32) +if NATIVE_WIN64: + # Visual C++ is a 32-bit application, so we need to look in + # the corresponding registry branch, if we're running a + # 64-bit Python on Win64 + VS_BASE = r"Software\Wow6432Node\Microsoft\VisualStudio\%0.1f" + VSEXPRESS_BASE = r"Software\Wow6432Node\Microsoft\VCExpress\%0.1f" + WINSDK_BASE = r"Software\Wow6432Node\Microsoft\Microsoft SDKs\Windows" + NET_BASE = r"Software\Wow6432Node\Microsoft\.NETFramework" +else: + VS_BASE = r"Software\Microsoft\VisualStudio\%0.1f" + VSEXPRESS_BASE = r"Software\Microsoft\VCExpress\%0.1f" + WINSDK_BASE = r"Software\Microsoft\Microsoft SDKs\Windows" + NET_BASE = r"Software\Microsoft\.NETFramework" + +# A map keyed by get_platform() return values to values accepted by +# 'vcvarsall.bat'. Note a cross-compile may combine these (eg, 'x86_amd64' is +# the param to cross-compile on x86 targetting amd64.) +PLAT_TO_VCVARS = { + 'win32' : 'x86', + 'win-amd64' : 'amd64', + 'win-ia64' : 'ia64', +} + +class Reg: + """Helper class to read values from the registry + """ + + def get_value(cls, path, key): + for base in HKEYS: + d = cls.read_values(base, path) + if d and key in d: + return d[key] + raise KeyError(key) + get_value = classmethod(get_value) + + def read_keys(cls, base, key): + """Return list of registry keys.""" + try: + handle = RegOpenKeyEx(base, key) + except RegError: + return None + L = [] + i = 0 + while True: + try: + k = RegEnumKey(handle, i) + except RegError: + break + L.append(k) + i += 1 + return L + read_keys = classmethod(read_keys) + + def read_values(cls, base, key): + """Return dict of registry keys and values. + + All names are converted to lowercase. + """ + try: + handle = RegOpenKeyEx(base, key) + except RegError: + return None + d = {} + i = 0 + while True: + try: + name, value, type = RegEnumValue(handle, i) + except RegError: + break + name = name.lower() + d[cls.convert_mbcs(name)] = cls.convert_mbcs(value) + i += 1 + return d + read_values = classmethod(read_values) + + def convert_mbcs(s): + dec = getattr(s, "decode", None) + if dec is not None: + try: + s = dec("mbcs") + except UnicodeError: + pass + return s + convert_mbcs = staticmethod(convert_mbcs) + +class MacroExpander: + + def __init__(self, version): + self.macros = {} + self.vsbase = VS_BASE % version + self.load_macros(version) + + def set_macro(self, macro, path, key): + self.macros["$(%s)" % macro] = Reg.get_value(path, key) + + def load_macros(self, version): + self.set_macro("VCInstallDir", self.vsbase + r"\Setup\VC", "productdir") + self.set_macro("VSInstallDir", self.vsbase + r"\Setup\VS", "productdir") + self.set_macro("FrameworkDir", NET_BASE, "installroot") + try: + if version >= 8.0: + self.set_macro("FrameworkSDKDir", NET_BASE, + "sdkinstallrootv2.0") + else: + raise KeyError("sdkinstallrootv2.0") + except KeyError: + raise DistutilsPlatformError( + """Python was built with Visual Studio 2008; +extensions must be built with a compiler than can generate compatible binaries. +Visual Studio 2008 was not found on this system. If you have Cygwin installed, +you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") + + if version >= 9.0: + self.set_macro("FrameworkVersion", self.vsbase, "clr version") + self.set_macro("WindowsSdkDir", WINSDK_BASE, "currentinstallfolder") + else: + p = r"Software\Microsoft\NET Framework Setup\Product" + for base in HKEYS: + try: + h = RegOpenKeyEx(base, p) + except RegError: + continue + key = RegEnumKey(h, 0) + d = Reg.get_value(base, r"%s\%s" % (p, key)) + self.macros["$(FrameworkVersion)"] = d["version"] + + def sub(self, s): + for k, v in self.macros.items(): + s = s.replace(k, v) + return s + +def get_build_version(): + """Return the version of MSVC that was used to build Python. + + For Python 2.3 and up, the version number is included in + sys.version. For earlier versions, assume the compiler is MSVC 6. + """ + prefix = "MSC v." + i = sys.version.find(prefix) + if i == -1: + return 6 + i = i + len(prefix) + s, rest = sys.version[i:].split(" ", 1) + majorVersion = int(s[:-2]) - 6 + minorVersion = int(s[2:3]) / 10.0 + # I don't think paths are affected by minor version in version 6 + if majorVersion == 6: + minorVersion = 0 + if majorVersion >= 6: + return majorVersion + minorVersion + # else we don't know what version of the compiler this is + return None + +def normalize_and_reduce_paths(paths): + """Return a list of normalized paths with duplicates removed. + + The current order of paths is maintained. + """ + # Paths are normalized so things like: /a and /a/ aren't both preserved. + reduced_paths = [] + for p in paths: + np = os.path.normpath(p) + # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. + if np not in reduced_paths: + reduced_paths.append(np) + return reduced_paths + +def removeDuplicates(variable): + """Remove duplicate values of an environment variable. + """ + oldList = variable.split(os.pathsep) + newList = [] + for i in oldList: + if i not in newList: + newList.append(i) + newVariable = os.pathsep.join(newList) + return newVariable + +def find_vcvarsall(version): + """Find the vcvarsall.bat file + + At first it tries to find the productdir of VS 2008 in the registry. If + that fails it falls back to the VS90COMNTOOLS env var. + """ + vsbase = VS_BASE % version + try: + productdir = Reg.get_value(r"%s\Setup\VC" % vsbase, + "productdir") + except KeyError: + productdir = None + + # trying Express edition + if productdir is None: + vsbase = VSEXPRESS_BASE % version + try: + productdir = Reg.get_value(r"%s\Setup\VC" % vsbase, + "productdir") + except KeyError: + productdir = None + log.debug("Unable to find productdir in registry") + + if not productdir or not os.path.isdir(productdir): + toolskey = "VS%0.f0COMNTOOLS" % version + toolsdir = os.environ.get(toolskey, None) + + if toolsdir and os.path.isdir(toolsdir): + productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC") + productdir = os.path.abspath(productdir) + if not os.path.isdir(productdir): + log.debug("%s is not a valid directory" % productdir) + return None + else: + log.debug("Env var %s is not set or invalid" % toolskey) + if not productdir: + log.debug("No productdir found") + return None + vcvarsall = os.path.join(productdir, "vcvarsall.bat") + if os.path.isfile(vcvarsall): + return vcvarsall + log.debug("Unable to find vcvarsall.bat") + return None + +def query_vcvarsall(version, arch="x86"): + """Launch vcvarsall.bat and read the settings from its environment + """ + vcvarsall = find_vcvarsall(version) + interesting = set(("include", "lib", "libpath", "path")) + result = {} + + if vcvarsall is None: + raise DistutilsPlatformError("Unable to find vcvarsall.bat") + log.debug("Calling 'vcvarsall.bat %s' (version=%s)", arch, version) + popen = subprocess.Popen('"%s" %s & set' % (vcvarsall, arch), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + try: + stdout, stderr = popen.communicate() + if popen.wait() != 0: + raise DistutilsPlatformError(stderr.decode("mbcs")) + + stdout = stdout.decode("mbcs") + for line in stdout.split("\n"): + line = Reg.convert_mbcs(line) + if '=' not in line: + continue + line = line.strip() + key, value = line.split('=', 1) + key = key.lower() + if key in interesting: + if value.endswith(os.pathsep): + value = value[:-1] + result[key] = removeDuplicates(value) + + finally: + popen.stdout.close() + popen.stderr.close() + + if len(result) != len(interesting): + raise ValueError(str(list(result.keys()))) + + return result + +# More globals +VERSION = get_build_version() +if VERSION < 8.0: + raise DistutilsPlatformError("VC %0.1f is not supported by this module" % VERSION) +# MACROS = MacroExpander(VERSION) + +class MSVCCompiler(CCompiler) : + """Concrete class that implements an interface to Microsoft Visual C++, + as defined by the CCompiler abstract class.""" + + compiler_type = 'msvc' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + _rc_extensions = ['.rc'] + _mc_extensions = ['.mc'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = (_c_extensions + _cpp_extensions + + _rc_extensions + _mc_extensions) + res_extension = '.res' + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + def __init__(self, verbose=0, dry_run=0, force=0): + CCompiler.__init__ (self, verbose, dry_run, force) + self.__version = VERSION + self.__root = r"Software\Microsoft\VisualStudio" + # self.__macros = MACROS + self.__paths = [] + # target platform (.plat_name is consistent with 'bdist') + self.plat_name = None + self.__arch = None # deprecated name + self.initialized = False + + def initialize(self, plat_name=None): + # multi-init means we would need to check platform same each time... + assert not self.initialized, "don't init multiple times" + if plat_name is None: + plat_name = get_platform() + # sanity check for platforms to prevent obscure errors later. + ok_plats = 'win32', 'win-amd64', 'win-ia64' + if plat_name not in ok_plats: + raise DistutilsPlatformError("--plat-name must be one of %s" % + (ok_plats,)) + + if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): + # Assume that the SDK set up everything alright; don't try to be + # smarter + self.cc = "cl.exe" + self.linker = "link.exe" + self.lib = "lib.exe" + self.rc = "rc.exe" + self.mc = "mc.exe" + else: + # On x86, 'vcvars32.bat amd64' creates an env that doesn't work; + # to cross compile, you use 'x86_amd64'. + # On AMD64, 'vcvars32.bat amd64' is a native build env; to cross + # compile use 'x86' (ie, it runs the x86 compiler directly) + # No idea how itanium handles this, if at all. + if plat_name == get_platform() or plat_name == 'win32': + # native build or cross-compile to win32 + plat_spec = PLAT_TO_VCVARS[plat_name] + else: + # cross compile from win32 -> some 64bit + plat_spec = PLAT_TO_VCVARS[get_platform()] + '_' + \ + PLAT_TO_VCVARS[plat_name] + + vc_env = query_vcvarsall(VERSION, plat_spec) + + # take care to only use strings in the environment. + self.__paths = vc_env['path'].encode('mbcs').split(os.pathsep) + os.environ['lib'] = vc_env['lib'].encode('mbcs') + os.environ['include'] = vc_env['include'].encode('mbcs') + + if len(self.__paths) == 0: + raise DistutilsPlatformError("Python was built with %s, " + "and extensions need to be built with the same " + "version of the compiler, but it isn't installed." + % self.__product) + + self.cc = self.find_exe("cl.exe") + self.linker = self.find_exe("link.exe") + self.lib = self.find_exe("lib.exe") + self.rc = self.find_exe("rc.exe") # resource compiler + self.mc = self.find_exe("mc.exe") # message compiler + #self.set_path_env_var('lib') + #self.set_path_env_var('include') + + # extend the MSVC path with the current path + try: + for p in os.environ['path'].split(';'): + self.__paths.append(p) + except KeyError: + pass + self.__paths = normalize_and_reduce_paths(self.__paths) + os.environ['path'] = ";".join(self.__paths) + + self.preprocess_options = None + if self.__arch == "x86": + self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', + '/DNDEBUG'] + self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', + '/Z7', '/D_DEBUG'] + else: + # Win64 + self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' , + '/DNDEBUG'] + self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', + '/Z7', '/D_DEBUG'] + + self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] + if self.__version >= 7: + self.ldflags_shared_debug = [ + '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG', '/pdb:None' + ] + self.ldflags_static = [ '/nologo'] + + self.initialized = True + + # -- Worker methods ------------------------------------------------ + + def object_filenames(self, + source_filenames, + strip_dir=0, + output_dir=''): + # Copied from ccompiler.py, extended to return .res as 'object'-file + # for .rc input file + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + (base, ext) = os.path.splitext (src_name) + base = os.path.splitdrive(base)[1] # Chop off the drive + base = base[os.path.isabs(base):] # If abs, chop off leading / + if ext not in self.src_extensions: + # Better to raise an exception instead of silently continuing + # and later complain about sources and targets having + # different lengths + raise CompileError ("Don't know how to compile %s" % src_name) + if strip_dir: + base = os.path.basename (base) + if ext in self._rc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + elif ext in self._mc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + + def compile(self, sources, + output_dir=None, macros=None, include_dirs=None, debug=0, + extra_preargs=None, extra_postargs=None, depends=None): + + if not self.initialized: + self.initialize() + compile_info = self._setup_compile(output_dir, macros, include_dirs, + sources, depends, extra_postargs) + macros, objects, extra_postargs, pp_opts, build = compile_info + + compile_opts = extra_preargs or [] + compile_opts.append ('/c') + if debug: + compile_opts.extend(self.compile_options_debug) + else: + compile_opts.extend(self.compile_options) + + for obj in objects: + try: + src, ext = build[obj] + except KeyError: + continue + if debug: + # pass the full pathname to MSVC in debug mode, + # this allows the debugger to find the source file + # without asking the user to browse for it + src = os.path.abspath(src) + + if ext in self._c_extensions: + input_opt = "/Tc" + src + elif ext in self._cpp_extensions: + input_opt = "/Tp" + src + elif ext in self._rc_extensions: + # compile .RC to .RES file + input_opt = src + output_opt = "/fo" + obj + try: + self.spawn([self.rc] + pp_opts + + [output_opt] + [input_opt]) + except DistutilsExecError, msg: + raise CompileError(msg) + continue + elif ext in self._mc_extensions: + # Compile .MC to .RC file to .RES file. + # * '-h dir' specifies the directory for the + # generated include file + # * '-r dir' specifies the target directory of the + # generated RC file and the binary message resource + # it includes + # + # For now (since there are no options to change this), + # we use the source-directory for the include file and + # the build directory for the RC file and message + # resources. This works at least for win32all. + h_dir = os.path.dirname(src) + rc_dir = os.path.dirname(obj) + try: + # first compile .MC to .RC and .H file + self.spawn([self.mc] + + ['-h', h_dir, '-r', rc_dir] + [src]) + base, _ = os.path.splitext (os.path.basename (src)) + rc_file = os.path.join (rc_dir, base + '.rc') + # then compile .RC to .RES file + self.spawn([self.rc] + + ["/fo" + obj] + [rc_file]) + + except DistutilsExecError, msg: + raise CompileError(msg) + continue + else: + # how to handle this file? + raise CompileError("Don't know how to compile %s to %s" + % (src, obj)) + + output_opt = "/Fo" + obj + try: + self.spawn([self.cc] + compile_opts + pp_opts + + [input_opt, output_opt] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError(msg) + + return objects + + + def create_static_lib(self, + objects, + output_libname, + output_dir=None, + debug=0, + target_lang=None): + + if not self.initialized: + self.initialize() + (objects, output_dir) = self._fix_object_args(objects, output_dir) + output_filename = self.library_filename(output_libname, + output_dir=output_dir) + + if self._need_link(objects, output_filename): + lib_args = objects + ['/OUT:' + output_filename] + if debug: + pass # XXX what goes here? + try: + self.spawn([self.lib] + lib_args) + except DistutilsExecError, msg: + raise LibError(msg) + else: + log.debug("skipping %s (up-to-date)", output_filename) + + + def link(self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + if not self.initialized: + self.initialize() + (objects, output_dir) = self._fix_object_args(objects, output_dir) + fixed_args = self._fix_lib_args(libraries, library_dirs, + runtime_library_dirs) + (libraries, library_dirs, runtime_library_dirs) = fixed_args + + if runtime_library_dirs: + self.warn ("I don't know what to do with 'runtime_library_dirs': " + + str (runtime_library_dirs)) + + lib_opts = gen_lib_options(self, + library_dirs, runtime_library_dirs, + libraries) + if output_dir is not None: + output_filename = os.path.join(output_dir, output_filename) + + if self._need_link(objects, output_filename): + if target_desc == CCompiler.EXECUTABLE: + if debug: + ldflags = self.ldflags_shared_debug[1:] + else: + ldflags = self.ldflags_shared[1:] + else: + if debug: + ldflags = self.ldflags_shared_debug + else: + ldflags = self.ldflags_shared + + export_opts = [] + for sym in (export_symbols or []): + export_opts.append("/EXPORT:" + sym) + + ld_args = (ldflags + lib_opts + export_opts + + objects + ['/OUT:' + output_filename]) + + # The MSVC linker generates .lib and .exp files, which cannot be + # suppressed by any linker switches. The .lib files may even be + # needed! Make sure they are generated in the temporary build + # directory. Since they have different names for debug and release + # builds, they can go into the same directory. + build_temp = os.path.dirname(objects[0]) + if export_symbols is not None: + (dll_name, dll_ext) = os.path.splitext( + os.path.basename(output_filename)) + implib_file = os.path.join( + build_temp, + self.library_filename(dll_name)) + ld_args.append ('/IMPLIB:' + implib_file) + + self.manifest_setup_ldargs(output_filename, build_temp, ld_args) + + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + + self.mkpath(os.path.dirname(output_filename)) + try: + self.spawn([self.linker] + ld_args) + except DistutilsExecError, msg: + raise LinkError(msg) + + # embed the manifest + # XXX - this is somewhat fragile - if mt.exe fails, distutils + # will still consider the DLL up-to-date, but it will not have a + # manifest. Maybe we should link to a temp file? OTOH, that + # implies a build environment error that shouldn't go undetected. + mfinfo = self.manifest_get_embed_info(target_desc, ld_args) + if mfinfo is not None: + mffilename, mfid = mfinfo + out_arg = '-outputresource:%s;%s' % (output_filename, mfid) + try: + self.spawn(['mt.exe', '-nologo', '-manifest', + mffilename, out_arg]) + except DistutilsExecError, msg: + raise LinkError(msg) + else: + log.debug("skipping %s (up-to-date)", output_filename) + + def manifest_setup_ldargs(self, output_filename, build_temp, ld_args): + # If we need a manifest at all, an embedded manifest is recommended. + # See MSDN article titled + # "How to: Embed a Manifest Inside a C/C++ Application" + # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx) + # Ask the linker to generate the manifest in the temp dir, so + # we can check it, and possibly embed it, later. + temp_manifest = os.path.join( + build_temp, + os.path.basename(output_filename) + ".manifest") + ld_args.append('/MANIFESTFILE:' + temp_manifest) + + def manifest_get_embed_info(self, target_desc, ld_args): + # If a manifest should be embedded, return a tuple of + # (manifest_filename, resource_id). Returns None if no manifest + # should be embedded. See http://bugs.python.org/issue7833 for why + # we want to avoid any manifest for extension modules if we can) + for arg in ld_args: + if arg.startswith("/MANIFESTFILE:"): + temp_manifest = arg.split(":", 1)[1] + break + else: + # no /MANIFESTFILE so nothing to do. + return None + if target_desc == CCompiler.EXECUTABLE: + # by default, executables always get the manifest with the + # CRT referenced. + mfid = 1 + else: + # Extension modules try and avoid any manifest if possible. + mfid = 2 + temp_manifest = self._remove_visual_c_ref(temp_manifest) + if temp_manifest is None: + return None + return temp_manifest, mfid + + def _remove_visual_c_ref(self, manifest_file): + try: + # Remove references to the Visual C runtime, so they will + # fall through to the Visual C dependency of Python.exe. + # This way, when installed for a restricted user (e.g. + # runtimes are not in WinSxS folder, but in Python's own + # folder), the runtimes do not need to be in every folder + # with .pyd's. + # Returns either the filename of the modified manifest or + # None if no manifest should be embedded. + manifest_f = open(manifest_file) + try: + manifest_buf = manifest_f.read() + finally: + manifest_f.close() + pattern = re.compile( + r"""<assemblyIdentity.*?name=("|')Microsoft\."""\ + r"""VC\d{2}\.CRT("|').*?(/>|</assemblyIdentity>)""", + re.DOTALL) + manifest_buf = re.sub(pattern, "", manifest_buf) + pattern = "<dependentAssembly>\s*</dependentAssembly>" + manifest_buf = re.sub(pattern, "", manifest_buf) + # Now see if any other assemblies are referenced - if not, we + # don't want a manifest embedded. + pattern = re.compile( + r"""<assemblyIdentity.*?name=(?:"|')(.+?)(?:"|')""" + r""".*?(?:/>|</assemblyIdentity>)""", re.DOTALL) + if re.search(pattern, manifest_buf) is None: + return None + + manifest_f = open(manifest_file, 'w') + try: + manifest_f.write(manifest_buf) + return manifest_file + finally: + manifest_f.close() + except IOError: + pass + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function, in + # ccompiler.py. + + def library_dir_option(self, dir): + return "/LIBPATH:" + dir + + def runtime_library_dir_option(self, dir): + raise DistutilsPlatformError( + "don't know how to set runtime library search path for MSVC++") + + def library_option(self, lib): + return self.library_filename(lib) + + + def find_library_file(self, dirs, lib, debug=0): + # Prefer a debugging library if found (and requested), but deal + # with it if we don't have one. + if debug: + try_names = [lib + "_d", lib] + else: + try_names = [lib] + for dir in dirs: + for name in try_names: + libfile = os.path.join(dir, self.library_filename (name)) + if os.path.exists(libfile): + return libfile + else: + # Oops, didn't find it in *any* of 'dirs' + return None + + # Helper methods for using the MSVC registry settings + + def find_exe(self, exe): + """Return path to an MSVC executable program. + + Tries to find the program in several places: first, one of the + MSVC program search paths from the registry; next, the directories + in the PATH environment variable. If any of those work, return an + absolute path that is known to exist. If none of them work, just + return the original program name, 'exe'. + """ + for p in self.__paths: + fn = os.path.join(os.path.abspath(p), exe) + if os.path.isfile(fn): + return fn + + # didn't find it; try existing path + for p in os.environ['Path'].split(';'): + fn = os.path.join(os.path.abspath(p),exe) + if os.path.isfile(fn): + return fn + + return exe diff --git a/src/main/resources/PythonLibs/distutils/msvccompiler.py b/src/main/resources/PythonLibs/distutils/msvccompiler.py new file mode 100644 index 0000000000000000000000000000000000000000..0e69fd368cac78f3967f16336731c7bd6dc87151 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/msvccompiler.py @@ -0,0 +1,659 @@ +"""distutils.msvccompiler + +Contains MSVCCompiler, an implementation of the abstract CCompiler class +for the Microsoft Visual Studio. +""" + +# Written by Perry Stoll +# hacked by Robin Becker and Thomas Heller to do a better job of +# finding DevStudio (through the registry) + +__revision__ = "$Id$" + +import sys +import os +import string + +from distutils.errors import (DistutilsExecError, DistutilsPlatformError, + CompileError, LibError, LinkError) +from distutils.ccompiler import CCompiler, gen_lib_options +from distutils import log + +_can_read_reg = 0 +try: + import _winreg + + _can_read_reg = 1 + hkey_mod = _winreg + + RegOpenKeyEx = _winreg.OpenKeyEx + RegEnumKey = _winreg.EnumKey + RegEnumValue = _winreg.EnumValue + RegError = _winreg.error + +except ImportError: + try: + import win32api + import win32con + _can_read_reg = 1 + hkey_mod = win32con + + RegOpenKeyEx = win32api.RegOpenKeyEx + RegEnumKey = win32api.RegEnumKey + RegEnumValue = win32api.RegEnumValue + RegError = win32api.error + + except ImportError: + log.info("Warning: Can't read registry to find the " + "necessary compiler setting\n" + "Make sure that Python modules _winreg, " + "win32api or win32con are installed.") + pass + +if _can_read_reg: + HKEYS = (hkey_mod.HKEY_USERS, + hkey_mod.HKEY_CURRENT_USER, + hkey_mod.HKEY_LOCAL_MACHINE, + hkey_mod.HKEY_CLASSES_ROOT) + +def read_keys(base, key): + """Return list of registry keys.""" + + try: + handle = RegOpenKeyEx(base, key) + except RegError: + return None + L = [] + i = 0 + while 1: + try: + k = RegEnumKey(handle, i) + except RegError: + break + L.append(k) + i = i + 1 + return L + +def read_values(base, key): + """Return dict of registry keys and values. + + All names are converted to lowercase. + """ + try: + handle = RegOpenKeyEx(base, key) + except RegError: + return None + d = {} + i = 0 + while 1: + try: + name, value, type = RegEnumValue(handle, i) + except RegError: + break + name = name.lower() + d[convert_mbcs(name)] = convert_mbcs(value) + i = i + 1 + return d + +def convert_mbcs(s): + enc = getattr(s, "encode", None) + if enc is not None: + try: + s = enc("mbcs") + except UnicodeError: + pass + return s + +class MacroExpander: + + def __init__(self, version): + self.macros = {} + self.load_macros(version) + + def set_macro(self, macro, path, key): + for base in HKEYS: + d = read_values(base, path) + if d: + self.macros["$(%s)" % macro] = d[key] + break + + def load_macros(self, version): + vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version + self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir") + self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir") + net = r"Software\Microsoft\.NETFramework" + self.set_macro("FrameworkDir", net, "installroot") + try: + if version > 7.0: + self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") + else: + self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") + except KeyError: + raise DistutilsPlatformError, \ + ("""Python was built with Visual Studio 2003; +extensions must be built with a compiler than can generate compatible binaries. +Visual Studio 2003 was not found on this system. If you have Cygwin installed, +you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") + + p = r"Software\Microsoft\NET Framework Setup\Product" + for base in HKEYS: + try: + h = RegOpenKeyEx(base, p) + except RegError: + continue + key = RegEnumKey(h, 0) + d = read_values(base, r"%s\%s" % (p, key)) + self.macros["$(FrameworkVersion)"] = d["version"] + + def sub(self, s): + for k, v in self.macros.items(): + s = string.replace(s, k, v) + return s + +def get_build_version(): + """Return the version of MSVC that was used to build Python. + + For Python 2.3 and up, the version number is included in + sys.version. For earlier versions, assume the compiler is MSVC 6. + """ + + prefix = "MSC v." + i = string.find(sys.version, prefix) + if i == -1: + return 6 + i = i + len(prefix) + s, rest = sys.version[i:].split(" ", 1) + majorVersion = int(s[:-2]) - 6 + minorVersion = int(s[2:3]) / 10.0 + # I don't think paths are affected by minor version in version 6 + if majorVersion == 6: + minorVersion = 0 + if majorVersion >= 6: + return majorVersion + minorVersion + # else we don't know what version of the compiler this is + return None + +def get_build_architecture(): + """Return the processor architecture. + + Possible results are "Intel", "Itanium", or "AMD64". + """ + + prefix = " bit (" + i = string.find(sys.version, prefix) + if i == -1: + return "Intel" + j = string.find(sys.version, ")", i) + return sys.version[i+len(prefix):j] + +def normalize_and_reduce_paths(paths): + """Return a list of normalized paths with duplicates removed. + + The current order of paths is maintained. + """ + # Paths are normalized so things like: /a and /a/ aren't both preserved. + reduced_paths = [] + for p in paths: + np = os.path.normpath(p) + # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. + if np not in reduced_paths: + reduced_paths.append(np) + return reduced_paths + + +class MSVCCompiler (CCompiler) : + """Concrete class that implements an interface to Microsoft Visual C++, + as defined by the CCompiler abstract class.""" + + compiler_type = 'msvc' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + _rc_extensions = ['.rc'] + _mc_extensions = ['.mc'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = (_c_extensions + _cpp_extensions + + _rc_extensions + _mc_extensions) + res_extension = '.res' + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + def __init__ (self, verbose=0, dry_run=0, force=0): + CCompiler.__init__ (self, verbose, dry_run, force) + self.__version = get_build_version() + self.__arch = get_build_architecture() + if self.__arch == "Intel": + # x86 + if self.__version >= 7: + self.__root = r"Software\Microsoft\VisualStudio" + self.__macros = MacroExpander(self.__version) + else: + self.__root = r"Software\Microsoft\Devstudio" + self.__product = "Visual Studio version %s" % self.__version + else: + # Win64. Assume this was built with the platform SDK + self.__product = "Microsoft SDK compiler %s" % (self.__version + 6) + + self.initialized = False + + def initialize(self): + self.__paths = [] + if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): + # Assume that the SDK set up everything alright; don't try to be + # smarter + self.cc = "cl.exe" + self.linker = "link.exe" + self.lib = "lib.exe" + self.rc = "rc.exe" + self.mc = "mc.exe" + else: + self.__paths = self.get_msvc_paths("path") + + if len (self.__paths) == 0: + raise DistutilsPlatformError, \ + ("Python was built with %s, " + "and extensions need to be built with the same " + "version of the compiler, but it isn't installed." % self.__product) + + self.cc = self.find_exe("cl.exe") + self.linker = self.find_exe("link.exe") + self.lib = self.find_exe("lib.exe") + self.rc = self.find_exe("rc.exe") # resource compiler + self.mc = self.find_exe("mc.exe") # message compiler + self.set_path_env_var('lib') + self.set_path_env_var('include') + + # extend the MSVC path with the current path + try: + for p in string.split(os.environ['path'], ';'): + self.__paths.append(p) + except KeyError: + pass + self.__paths = normalize_and_reduce_paths(self.__paths) + os.environ['path'] = string.join(self.__paths, ';') + + self.preprocess_options = None + if self.__arch == "Intel": + self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' , + '/DNDEBUG'] + self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX', + '/Z7', '/D_DEBUG'] + else: + # Win64 + self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' , + '/DNDEBUG'] + self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', + '/Z7', '/D_DEBUG'] + + self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] + if self.__version >= 7: + self.ldflags_shared_debug = [ + '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' + ] + else: + self.ldflags_shared_debug = [ + '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG' + ] + self.ldflags_static = [ '/nologo'] + + self.initialized = True + + # -- Worker methods ------------------------------------------------ + + def object_filenames (self, + source_filenames, + strip_dir=0, + output_dir=''): + # Copied from ccompiler.py, extended to return .res as 'object'-file + # for .rc input file + if output_dir is None: output_dir = '' + obj_names = [] + for src_name in source_filenames: + (base, ext) = os.path.splitext (src_name) + base = os.path.splitdrive(base)[1] # Chop off the drive + base = base[os.path.isabs(base):] # If abs, chop off leading / + if ext not in self.src_extensions: + # Better to raise an exception instead of silently continuing + # and later complain about sources and targets having + # different lengths + raise CompileError ("Don't know how to compile %s" % src_name) + if strip_dir: + base = os.path.basename (base) + if ext in self._rc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + elif ext in self._mc_extensions: + obj_names.append (os.path.join (output_dir, + base + self.res_extension)) + else: + obj_names.append (os.path.join (output_dir, + base + self.obj_extension)) + return obj_names + + # object_filenames () + + + def compile(self, sources, + output_dir=None, macros=None, include_dirs=None, debug=0, + extra_preargs=None, extra_postargs=None, depends=None): + + if not self.initialized: self.initialize() + macros, objects, extra_postargs, pp_opts, build = \ + self._setup_compile(output_dir, macros, include_dirs, sources, + depends, extra_postargs) + + compile_opts = extra_preargs or [] + compile_opts.append ('/c') + if debug: + compile_opts.extend(self.compile_options_debug) + else: + compile_opts.extend(self.compile_options) + + for obj in objects: + try: + src, ext = build[obj] + except KeyError: + continue + if debug: + # pass the full pathname to MSVC in debug mode, + # this allows the debugger to find the source file + # without asking the user to browse for it + src = os.path.abspath(src) + + if ext in self._c_extensions: + input_opt = "/Tc" + src + elif ext in self._cpp_extensions: + input_opt = "/Tp" + src + elif ext in self._rc_extensions: + # compile .RC to .RES file + input_opt = src + output_opt = "/fo" + obj + try: + self.spawn ([self.rc] + pp_opts + + [output_opt] + [input_opt]) + except DistutilsExecError, msg: + raise CompileError, msg + continue + elif ext in self._mc_extensions: + + # Compile .MC to .RC file to .RES file. + # * '-h dir' specifies the directory for the + # generated include file + # * '-r dir' specifies the target directory of the + # generated RC file and the binary message resource + # it includes + # + # For now (since there are no options to change this), + # we use the source-directory for the include file and + # the build directory for the RC file and message + # resources. This works at least for win32all. + + h_dir = os.path.dirname (src) + rc_dir = os.path.dirname (obj) + try: + # first compile .MC to .RC and .H file + self.spawn ([self.mc] + + ['-h', h_dir, '-r', rc_dir] + [src]) + base, _ = os.path.splitext (os.path.basename (src)) + rc_file = os.path.join (rc_dir, base + '.rc') + # then compile .RC to .RES file + self.spawn ([self.rc] + + ["/fo" + obj] + [rc_file]) + + except DistutilsExecError, msg: + raise CompileError, msg + continue + else: + # how to handle this file? + raise CompileError ( + "Don't know how to compile %s to %s" % \ + (src, obj)) + + output_opt = "/Fo" + obj + try: + self.spawn ([self.cc] + compile_opts + pp_opts + + [input_opt, output_opt] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + return objects + + # compile () + + + def create_static_lib (self, + objects, + output_libname, + output_dir=None, + debug=0, + target_lang=None): + + if not self.initialized: self.initialize() + (objects, output_dir) = self._fix_object_args (objects, output_dir) + output_filename = \ + self.library_filename (output_libname, output_dir=output_dir) + + if self._need_link (objects, output_filename): + lib_args = objects + ['/OUT:' + output_filename] + if debug: + pass # XXX what goes here? + try: + self.spawn ([self.lib] + lib_args) + except DistutilsExecError, msg: + raise LibError, msg + + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # create_static_lib () + + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + if not self.initialized: self.initialize() + (objects, output_dir) = self._fix_object_args (objects, output_dir) + (libraries, library_dirs, runtime_library_dirs) = \ + self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) + + if runtime_library_dirs: + self.warn ("I don't know what to do with 'runtime_library_dirs': " + + str (runtime_library_dirs)) + + lib_opts = gen_lib_options (self, + library_dirs, runtime_library_dirs, + libraries) + if output_dir is not None: + output_filename = os.path.join (output_dir, output_filename) + + if self._need_link (objects, output_filename): + + if target_desc == CCompiler.EXECUTABLE: + if debug: + ldflags = self.ldflags_shared_debug[1:] + else: + ldflags = self.ldflags_shared[1:] + else: + if debug: + ldflags = self.ldflags_shared_debug + else: + ldflags = self.ldflags_shared + + export_opts = [] + for sym in (export_symbols or []): + export_opts.append("/EXPORT:" + sym) + + ld_args = (ldflags + lib_opts + export_opts + + objects + ['/OUT:' + output_filename]) + + # The MSVC linker generates .lib and .exp files, which cannot be + # suppressed by any linker switches. The .lib files may even be + # needed! Make sure they are generated in the temporary build + # directory. Since they have different names for debug and release + # builds, they can go into the same directory. + if export_symbols is not None: + (dll_name, dll_ext) = os.path.splitext( + os.path.basename(output_filename)) + implib_file = os.path.join( + os.path.dirname(objects[0]), + self.library_filename(dll_name)) + ld_args.append ('/IMPLIB:' + implib_file) + + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + + self.mkpath (os.path.dirname (output_filename)) + try: + self.spawn ([self.linker] + ld_args) + except DistutilsExecError, msg: + raise LinkError, msg + + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # link () + + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function, in + # ccompiler.py. + + def library_dir_option (self, dir): + return "/LIBPATH:" + dir + + def runtime_library_dir_option (self, dir): + raise DistutilsPlatformError, \ + "don't know how to set runtime library search path for MSVC++" + + def library_option (self, lib): + return self.library_filename (lib) + + + def find_library_file (self, dirs, lib, debug=0): + # Prefer a debugging library if found (and requested), but deal + # with it if we don't have one. + if debug: + try_names = [lib + "_d", lib] + else: + try_names = [lib] + for dir in dirs: + for name in try_names: + libfile = os.path.join(dir, self.library_filename (name)) + if os.path.exists(libfile): + return libfile + else: + # Oops, didn't find it in *any* of 'dirs' + return None + + # find_library_file () + + # Helper methods for using the MSVC registry settings + + def find_exe(self, exe): + """Return path to an MSVC executable program. + + Tries to find the program in several places: first, one of the + MSVC program search paths from the registry; next, the directories + in the PATH environment variable. If any of those work, return an + absolute path that is known to exist. If none of them work, just + return the original program name, 'exe'. + """ + + for p in self.__paths: + fn = os.path.join(os.path.abspath(p), exe) + if os.path.isfile(fn): + return fn + + # didn't find it; try existing path + for p in string.split(os.environ['Path'],';'): + fn = os.path.join(os.path.abspath(p),exe) + if os.path.isfile(fn): + return fn + + return exe + + def get_msvc_paths(self, path, platform='x86'): + """Get a list of devstudio directories (include, lib or path). + + Return a list of strings. The list will be empty if unable to + access the registry or appropriate registry keys not found. + """ + + if not _can_read_reg: + return [] + + path = path + " dirs" + if self.__version >= 7: + key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories" + % (self.__root, self.__version)) + else: + key = (r"%s\6.0\Build System\Components\Platforms" + r"\Win32 (%s)\Directories" % (self.__root, platform)) + + for base in HKEYS: + d = read_values(base, key) + if d: + if self.__version >= 7: + return string.split(self.__macros.sub(d[path]), ";") + else: + return string.split(d[path], ";") + # MSVC 6 seems to create the registry entries we need only when + # the GUI is run. + if self.__version == 6: + for base in HKEYS: + if read_values(base, r"%s\6.0" % self.__root) is not None: + self.warn("It seems you have Visual Studio 6 installed, " + "but the expected registry settings are not present.\n" + "You must at least run the Visual Studio GUI once " + "so that these entries are created.") + break + return [] + + def set_path_env_var(self, name): + """Set environment variable 'name' to an MSVC path type value. + + This is equivalent to a SET command prior to execution of spawned + commands. + """ + + if name == "lib": + p = self.get_msvc_paths("library") + else: + p = self.get_msvc_paths(name) + if p: + os.environ[name] = string.join(p, ';') + + +if get_build_version() >= 8.0: + log.debug("Importing new compiler from distutils.msvc9compiler") + OldMSVCCompiler = MSVCCompiler + from distutils.msvc9compiler import MSVCCompiler + # get_build_architecture not really relevant now we support cross-compile + from distutils.msvc9compiler import MacroExpander diff --git a/src/main/resources/PythonLibs/distutils/spawn.py b/src/main/resources/PythonLibs/distutils/spawn.py new file mode 100644 index 0000000000000000000000000000000000000000..5bc6e5ec9f420e8d61bfe7a2dd8b0b8a70c1a7ee --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/spawn.py @@ -0,0 +1,196 @@ +"""distutils.spawn + +Provides the 'spawn()' function, a front-end to various platform- +specific functions for launching another program in a sub-process. +Also provides the 'find_executable()' to search the path for a given +executable name. +""" + +__revision__ = "$Id: spawn.py 73147 2009-06-02 15:58:43Z tarek.ziade $" + +import sys +import os + +from distutils.errors import DistutilsPlatformError, DistutilsExecError +from distutils import log + +def spawn(cmd, search_path=1, verbose=0, dry_run=0): + """Run another program, specified as a command list 'cmd', in a new process. + + 'cmd' is just the argument list for the new process, ie. + cmd[0] is the program to run and cmd[1:] are the rest of its arguments. + There is no way to run a program with a name different from that of its + executable. + + If 'search_path' is true (the default), the system's executable + search path will be used to find the program; otherwise, cmd[0] + must be the exact path to the executable. If 'dry_run' is true, + the command will not actually be run. + + Raise DistutilsExecError if running the program fails in any way; just + return on success. + """ + if os.name == 'posix': + _spawn_posix(cmd, search_path, dry_run=dry_run) + elif os.name == 'nt': + _spawn_nt(cmd, search_path, dry_run=dry_run) + elif os.name == 'os2': + _spawn_os2(cmd, search_path, dry_run=dry_run) + elif os.name == 'java': + _spawn_java(cmd, search_path, dry_run=dry_run) + else: + raise DistutilsPlatformError, \ + "don't know how to spawn programs on platform '%s'" % os.name + +def _nt_quote_args(args): + """Quote command-line arguments for DOS/Windows conventions. + + Just wraps every argument which contains blanks in double quotes, and + returns a new argument list. + """ + # XXX this doesn't seem very robust to me -- but if the Windows guys + # say it'll work, I guess I'll have to accept it. (What if an arg + # contains quotes? What other magic characters, other than spaces, + # have to be escaped? Is there an escaping mechanism other than + # quoting?) + for i, arg in enumerate(args): + if ' ' in arg: + args[i] = '"%s"' % arg + return args + +def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0): + executable = cmd[0] + cmd = _nt_quote_args(cmd) + if search_path: + # either we find one or it stays the same + executable = find_executable(executable) or executable + log.info(' '.join([executable] + cmd[1:])) + if not dry_run: + # spawn for NT requires a full path to the .exe + try: + rc = os.spawnv(os.P_WAIT, executable, cmd) + except OSError, exc: + # this seems to happen when the command isn't found + raise DistutilsExecError, \ + "command '%s' failed: %s" % (cmd[0], exc[-1]) + if rc != 0: + # and this reflects the command running but failing + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % (cmd[0], rc) + +def _spawn_os2(cmd, search_path=1, verbose=0, dry_run=0): + executable = cmd[0] + if search_path: + # either we find one or it stays the same + executable = find_executable(executable) or executable + log.info(' '.join([executable] + cmd[1:])) + if not dry_run: + # spawnv for OS/2 EMX requires a full path to the .exe + try: + rc = os.spawnv(os.P_WAIT, executable, cmd) + except OSError, exc: + # this seems to happen when the command isn't found + raise DistutilsExecError, \ + "command '%s' failed: %s" % (cmd[0], exc[-1]) + if rc != 0: + # and this reflects the command running but failing + log.debug("command '%s' failed with exit status %d" % (cmd[0], rc)) + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % (cmd[0], rc) + + +def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): + log.info(' '.join(cmd)) + if dry_run: + return + exec_fn = search_path and os.execvp or os.execv + pid = os.fork() + + if pid == 0: # in the child + try: + exec_fn(cmd[0], cmd) + except OSError, e: + sys.stderr.write("unable to execute %s: %s\n" % + (cmd[0], e.strerror)) + os._exit(1) + + sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0]) + os._exit(1) + else: # in the parent + # Loop until the child either exits or is terminated by a signal + # (ie. keep waiting if it's merely stopped) + while 1: + try: + pid, status = os.waitpid(pid, 0) + except OSError, exc: + import errno + if exc.errno == errno.EINTR: + continue + raise DistutilsExecError, \ + "command '%s' failed: %s" % (cmd[0], exc[-1]) + if os.WIFSIGNALED(status): + raise DistutilsExecError, \ + "command '%s' terminated by signal %d" % \ + (cmd[0], os.WTERMSIG(status)) + + elif os.WIFEXITED(status): + exit_status = os.WEXITSTATUS(status) + if exit_status == 0: + return # hey, it succeeded! + else: + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % \ + (cmd[0], exit_status) + + elif os.WIFSTOPPED(status): + continue + + else: + raise DistutilsExecError, \ + "unknown error executing '%s': termination status %d" % \ + (cmd[0], status) + +def _spawn_java(cmd, + search_path=1, + verbose=0, + dry_run=0): + executable = cmd[0] + cmd = ' '.join(_nt_quote_args(cmd)) + log.info(cmd) + if not dry_run: + try: + rc = os.system(cmd) >> 8 + except OSError, exc: + # this seems to happen when the command isn't found + raise DistutilsExecError, \ + "command '%s' failed: %s" % (executable, exc[-1]) + if rc != 0: + # and this reflects the command running but failing + print "command '%s' failed with exit status %d" % (executable, rc) + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % (executable, rc) + + +def find_executable(executable, path=None): + """Tries to find 'executable' in the directories listed in 'path'. + + A string listing directories separated by 'os.pathsep'; defaults to + os.environ['PATH']. Returns the complete filename or None if not found. + """ + if path is None: + path = os.environ['PATH'] + paths = path.split(os.pathsep) + base, ext = os.path.splitext(executable) + + if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'): + executable = executable + '.exe' + + if not os.path.isfile(executable): + for p in paths: + f = os.path.join(p, executable) + if os.path.isfile(f): + # the file exists, we have a shot at spawn working + return f + return None + else: + return executable diff --git a/src/main/resources/PythonLibs/distutils/sysconfig.py b/src/main/resources/PythonLibs/distutils/sysconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..c22b50802ff0636cffeebd29dbd7de447122f3a2 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/sysconfig.py @@ -0,0 +1,622 @@ +"""Provide access to Python's configuration information. The specific +configuration variables available depend heavily on the platform and +configuration. The values may be retrieved using +get_config_var(name), and the list of variables is available via +get_config_vars().keys(). Additional convenience functions are also +available. + +Written by: Fred L. Drake, Jr. +Email: <fdrake@acm.org> +""" + +__revision__ = "$Id: sysconfig.py 83688 2010-08-03 21:18:06Z mark.dickinson $" + +import os +import re +import string +import sys + +from distutils.errors import DistutilsPlatformError + +# These are needed in a couple of spots, so just compute them once. +PREFIX = os.path.normpath(sys.prefix) +EXEC_PREFIX = os.path.normpath(sys.exec_prefix) + +# Path to the base directory of the project. On Windows the binary may +# live in project/PCBuild9. If we're dealing with an x64 Windows build, +# it'll live in project/PCbuild/amd64. +project_base = os.path.dirname(os.path.realpath(sys.executable)) +if os.name == "nt" and "pcbuild" in project_base[-8:].lower(): + project_base = os.path.abspath(os.path.join(project_base, os.path.pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower(): + project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, + os.path.pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in project_base[-14:].lower(): + project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, + os.path.pardir)) + +# python_build: (Boolean) if true, we're either building Python or +# building an extension with an un-installed Python, so we use +# different (hard-wired) directories. +# Setup.local is available for Makefile builds including VPATH builds, +# Setup.dist is available on Windows +def _python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(project_base, "Modules", fn)): + return True + return False +python_build = _python_build() + + +def get_python_version(): + """Return a string containing the major and minor Python version, + leaving off the patchlevel. Sample return values could be '1.5' + or '2.2'. + """ + return sys.version[:3] + + +def get_python_inc(plat_specific=0, prefix=None): + """Return the directory containing installed Python header files. + + If 'plat_specific' is false (the default), this is the path to the + non-platform-specific header files, i.e. Python.h and so on; + otherwise, this is the path to platform-specific header files + (namely pyconfig.h). + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + if prefix is None: + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": + if python_build: + buildir = os.path.dirname(os.path.realpath(sys.executable)) + if plat_specific: + # python.h is located in the buildir + inc_dir = buildir + else: + # the source dir is relative to the buildir + srcdir = os.path.abspath(os.path.join(buildir, + get_config_var('srcdir'))) + # Include is located in the srcdir + inc_dir = os.path.join(srcdir, "Include") + return inc_dir + return os.path.join(prefix, "include", "python" + get_python_version()) + elif os.name == "nt": + return os.path.join(prefix, "include") + elif os.name == "mac": + if plat_specific: + return os.path.join(prefix, "Mac", "Include") + else: + return os.path.join(prefix, "Include") + elif os.name == "os2" or os.name == "java": + return os.path.join(prefix, "Include") + else: + raise DistutilsPlatformError( + "I don't know where Python installs its C header files " + "on platform '%s'" % os.name) + + +def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + """Return the directory containing the Python library (standard or + site additions). + + If 'plat_specific' is true, return the directory containing + platform-specific modules, i.e. any module from a non-pure-Python + module distribution; otherwise, return the platform-shared library + directory. If 'standard_lib' is true, return the directory + containing standard Python library modules; otherwise, return the + directory for site-specific modules. + + If 'prefix' is supplied, use it instead of sys.prefix or + sys.exec_prefix -- i.e., ignore 'plat_specific'. + """ + if prefix is None: + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": + libpython = os.path.join(prefix, + "lib", "python" + get_python_version()) + if standard_lib: + return libpython + else: + return os.path.join(libpython, "site-packages") + + elif os.name == "nt": + if standard_lib: + return os.path.join(prefix, "Lib") + else: + if get_python_version() < "2.2": + return prefix + else: + return os.path.join(prefix, "Lib", "site-packages") + + elif os.name == "mac": + if plat_specific: + if standard_lib: + return os.path.join(prefix, "Lib", "lib-dynload") + else: + return os.path.join(prefix, "Lib", "site-packages") + else: + if standard_lib: + return os.path.join(prefix, "Lib") + else: + return os.path.join(prefix, "Lib", "site-packages") + + elif os.name == "os2" or os.name == "java": + if standard_lib: + return os.path.join(prefix, "Lib") + else: + return os.path.join(prefix, "Lib", "site-packages") + + else: + raise DistutilsPlatformError( + "I don't know where Python installs its library " + "on platform '%s'" % os.name) + + +def customize_compiler(compiler): + """Do any platform-specific customization of a CCompiler instance. + + Mainly needed on Unix, so we can plug in the information that + varies across Unices and is stored in Python's Makefile. + """ + if compiler.compiler_type == "unix": + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \ + get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', + 'CCSHARED', 'LDSHARED', 'SO') + + if 'CC' in os.environ: + cc = os.environ['CC'] + if 'CXX' in os.environ: + cxx = os.environ['CXX'] + if 'LDSHARED' in os.environ: + ldshared = os.environ['LDSHARED'] + if 'CPP' in os.environ: + cpp = os.environ['CPP'] + else: + cpp = cc + " -E" # not always + if 'LDFLAGS' in os.environ: + ldshared = ldshared + ' ' + os.environ['LDFLAGS'] + if 'CFLAGS' in os.environ: + cflags = opt + ' ' + os.environ['CFLAGS'] + ldshared = ldshared + ' ' + os.environ['CFLAGS'] + if 'CPPFLAGS' in os.environ: + cpp = cpp + ' ' + os.environ['CPPFLAGS'] + cflags = cflags + ' ' + os.environ['CPPFLAGS'] + ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] + + cc_cmd = cc + ' ' + cflags + compiler.set_executables( + preprocessor=cpp, + compiler=cc_cmd, + compiler_so=cc_cmd + ' ' + ccshared, + compiler_cxx=cxx, + linker_so=ldshared, + linker_exe=cc) + + compiler.shared_lib_extension = so_ext + + +def get_config_h_filename(): + """Return full pathname of installed pyconfig.h file.""" + if python_build: + if os.name == "nt": + inc_dir = os.path.join(project_base, "PC") + else: + inc_dir = project_base + else: + inc_dir = get_python_inc(plat_specific=1) + if get_python_version() < '2.2': + config_h = 'config.h' + else: + # The name of the config.h file changed in 2.2 + config_h = 'pyconfig.h' + return os.path.join(inc_dir, config_h) + + +def get_makefile_filename(): + """Return full pathname of installed Makefile from the Python build.""" + if python_build: + return os.path.join(os.path.dirname(os.path.realpath(sys.executable)), + "Makefile") + lib_dir = get_python_lib(plat_specific=1, standard_lib=1) + return os.path.join(lib_dir, "config", "Makefile") + + +def parse_config_h(fp, g=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if g is None: + g = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + # + while 1: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: v = int(v) + except ValueError: pass + g[n] = v + else: + m = undef_rx.match(line) + if m: + g[m.group(1)] = 0 + return g + + +# Regexes needed for parsing Makefile (and similar syntaxes, +# like old-style Setup files). +_variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") +_findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") +_findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + +def parse_makefile(fn, g=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + from distutils.text_file import TextFile + fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1) + + if g is None: + g = {} + done = {} + notdone = {} + + while 1: + line = fp.readline() + if line is None: # eof + break + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + while notdone: + for name in notdone.keys(): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + else: + done[n] = item = "" + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + del notdone[name] + else: + # bogus variable reference; just drop it since we can't deal + del notdone[name] + + fp.close() + + # save the results in the global dictionary + g.update(done) + return g + + +def expand_makefile_vars(s, vars): + """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in + 'string' according to 'vars' (a dictionary mapping variable names to + values). Variables not present in 'vars' are silently expanded to the + empty string. The variable values in 'vars' should not contain further + variable expansions; if 'vars' is the output of 'parse_makefile()', + you're fine. Returns a variable-expanded version of 's'. + """ + + # This algorithm does multiple expansion, so if vars['foo'] contains + # "${bar}", it will expand ${foo} to ${bar}, and then expand + # ${bar}... and so forth. This is fine as long as 'vars' comes from + # 'parse_makefile()', which takes care of such expansions eagerly, + # according to make's variable expansion semantics. + + while 1: + m = _findvar1_rx.search(s) or _findvar2_rx.search(s) + if m: + (beg, end) = m.span() + s = s[0:beg] + vars.get(m.group(1)) + s[end:] + else: + break + return s + + +_config_vars = None + +def _init_posix(): + """Initialize the module as appropriate for POSIX systems.""" + g = {} + # load the installed Makefile: + try: + filename = get_makefile_filename() + parse_makefile(filename, g) + except IOError, msg: + my_msg = "invalid Python installation: unable to open %s" % filename + if hasattr(msg, "strerror"): + my_msg = my_msg + " (%s)" % msg.strerror + + raise DistutilsPlatformError(my_msg) + + # load the installed pyconfig.h: + try: + filename = get_config_h_filename() + parse_config_h(file(filename), g) + except IOError, msg: + my_msg = "invalid Python installation: unable to open %s" % filename + if hasattr(msg, "strerror"): + my_msg = my_msg + " (%s)" % msg.strerror + + raise DistutilsPlatformError(my_msg) + + # On MacOSX we need to check the setting of the environment variable + # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so + # it needs to be compatible. + # If it isn't set we set it to the configure-time value + if sys.platform == 'darwin' and 'MACOSX_DEPLOYMENT_TARGET' in g: + cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] + cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') + if cur_target == '': + cur_target = cfg_target + os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target) + elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): + my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' + % (cur_target, cfg_target)) + raise DistutilsPlatformError(my_msg) + + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if python_build: + g['LDSHARED'] = g['BLDSHARED'] + + elif get_python_version() < '2.1': + # The following two branches are for 1.5.2 compatibility. + if sys.platform == 'aix4': # what about AIX 3.x ? + # Linker script is in the config directory, not in Modules as the + # Makefile says. + python_lib = get_python_lib(standard_lib=1) + ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') + python_exp = os.path.join(python_lib, 'config', 'python.exp') + + g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp) + + elif sys.platform == 'beos': + # Linker script is in the config directory. In the Makefile it is + # relative to the srcdir, which after installation no longer makes + # sense. + python_lib = get_python_lib(standard_lib=1) + linkerscript_path = string.split(g['LDSHARED'])[0] + linkerscript_name = os.path.basename(linkerscript_path) + linkerscript = os.path.join(python_lib, 'config', + linkerscript_name) + + # XXX this isn't the right place to do this: adding the Python + # library to the link, if needed, should be in the "build_ext" + # command. (It's also needed for non-MS compilers on Windows, and + # it's taken care of for them by the 'build_ext.get_libraries()' + # method.) + g['LDSHARED'] = ("%s -L%s/lib -lpython%s" % + (linkerscript, PREFIX, get_python_version())) + + global _config_vars + _config_vars = g + + +def _init_nt(): + """Initialize the module as appropriate for NT""" + g = {} + # set basic install directories + g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) + g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) + + # XXX hmmm.. a normal install puts include files here + g['INCLUDEPY'] = get_python_inc(plat_specific=0) + + g['SO'] = '.pyd' + g['EXE'] = ".exe" + g['VERSION'] = get_python_version().replace(".", "") + g['BINDIR'] = os.path.dirname(os.path.realpath(sys.executable)) + + global _config_vars + _config_vars = g + + +def _init_mac(): + """Initialize the module as appropriate for Macintosh systems""" + g = {} + # set basic install directories + g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) + g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) + + # XXX hmmm.. a normal install puts include files here + g['INCLUDEPY'] = get_python_inc(plat_specific=0) + + import MacOS + if not hasattr(MacOS, 'runtimemodel'): + g['SO'] = '.ppc.slb' + else: + g['SO'] = '.%s.slb' % MacOS.runtimemodel + + # XXX are these used anywhere? + g['install_lib'] = os.path.join(EXEC_PREFIX, "Lib") + g['install_platlib'] = os.path.join(EXEC_PREFIX, "Mac", "Lib") + + # These are used by the extension module build + g['srcdir'] = ':' + global _config_vars + _config_vars = g + + +def _init_os2(): + """Initialize the module as appropriate for OS/2""" + g = {} + # set basic install directories + g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1) + g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1) + + # XXX hmmm.. a normal install puts include files here + g['INCLUDEPY'] = get_python_inc(plat_specific=0) + + g['SO'] = '.pyd' + g['EXE'] = ".exe" + + global _config_vars + _config_vars = g + + +def _init_jython(): + """Initialize the module as appropriate for Jython""" + # Stub out some values that build_ext expects; they don't matter + # anyway + _init_os2() + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. Generally this includes + everything needed to build extensions and install both pure modules and + extensions. On Unix, this means every variable defined in Python's + installed Makefile; on Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _config_vars + if _config_vars is None: + if sys.platform.startswith('java'): + # Jython might pose as a different os.name, but we always + # want _init_jython regardless + func = _init_jython + else: + func = globals().get("_init_" + os.name) + if func: + func() + else: + _config_vars = {} + + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # Distutils. + _config_vars['prefix'] = PREFIX + _config_vars['exec_prefix'] = EXEC_PREFIX + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _config_vars[key] + flags = re.sub('-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _config_vars[key] = flags + + else: + + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _config_vars[key] + flags = re.sub('-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _config_vars[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + m = re.search('-isysroot\s+(\S+)', _config_vars['CFLAGS']) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', 'LDSHARED', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _config_vars[key] + flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags) + _config_vars[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_config_vars.get(name)) + return vals + else: + return _config_vars + +def get_config_var(name): + """Return the value of a single variable using the dictionary + returned by 'get_config_vars()'. Equivalent to + get_config_vars().get(name) + """ + return get_config_vars().get(name) diff --git a/src/main/resources/PythonLibs/distutils/text_file.py b/src/main/resources/PythonLibs/distutils/text_file.py new file mode 100644 index 0000000000000000000000000000000000000000..09a798b1902d773ea98765f3dd58dba3ca64b878 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/text_file.py @@ -0,0 +1,304 @@ +"""text_file + +provides the TextFile class, which gives an interface to text files +that (optionally) takes care of stripping comments, ignoring blank +lines, and joining lines with backslashes.""" + +__revision__ = "$Id$" + +import sys + + +class TextFile: + + """Provides a file-like object that takes care of all the things you + commonly want to do when processing a text file that has some + line-by-line syntax: strip comments (as long as "#" is your + comment character), skip blank lines, join adjacent lines by + escaping the newline (ie. backslash at end of line), strip + leading and/or trailing whitespace. All of these are optional + and independently controllable. + + Provides a 'warn()' method so you can generate warning messages that + report physical line number, even if the logical line in question + spans multiple physical lines. Also provides 'unreadline()' for + implementing line-at-a-time lookahead. + + Constructor is called as: + + TextFile (filename=None, file=None, **options) + + It bombs (RuntimeError) if both 'filename' and 'file' are None; + 'filename' should be a string, and 'file' a file object (or + something that provides 'readline()' and 'close()' methods). It is + recommended that you supply at least 'filename', so that TextFile + can include it in warning messages. If 'file' is not supplied, + TextFile creates its own using the 'open()' builtin. + + The options are all boolean, and affect the value returned by + 'readline()': + strip_comments [default: true] + strip from "#" to end-of-line, as well as any whitespace + leading up to the "#" -- unless it is escaped by a backslash + lstrip_ws [default: false] + strip leading whitespace from each line before returning it + rstrip_ws [default: true] + strip trailing whitespace (including line terminator!) from + each line before returning it + skip_blanks [default: true} + skip lines that are empty *after* stripping comments and + whitespace. (If both lstrip_ws and rstrip_ws are false, + then some lines may consist of solely whitespace: these will + *not* be skipped, even if 'skip_blanks' is true.) + join_lines [default: false] + if a backslash is the last non-newline character on a line + after stripping comments and whitespace, join the following line + to it to form one "logical line"; if N consecutive lines end + with a backslash, then N+1 physical lines will be joined to + form one logical line. + collapse_join [default: false] + strip leading whitespace from lines that are joined to their + predecessor; only matters if (join_lines and not lstrip_ws) + + Note that since 'rstrip_ws' can strip the trailing newline, the + semantics of 'readline()' must differ from those of the builtin file + object's 'readline()' method! In particular, 'readline()' returns + None for end-of-file: an empty string might just be a blank line (or + an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is + not.""" + + default_options = { 'strip_comments': 1, + 'skip_blanks': 1, + 'lstrip_ws': 0, + 'rstrip_ws': 1, + 'join_lines': 0, + 'collapse_join': 0, + } + + def __init__ (self, filename=None, file=None, **options): + """Construct a new TextFile object. At least one of 'filename' + (a string) and 'file' (a file-like object) must be supplied. + They keyword argument options are described above and affect + the values returned by 'readline()'.""" + + if filename is None and file is None: + raise RuntimeError, \ + "you must supply either or both of 'filename' and 'file'" + + # set values for all options -- either from client option hash + # or fallback to default_options + for opt in self.default_options.keys(): + if opt in options: + setattr (self, opt, options[opt]) + + else: + setattr (self, opt, self.default_options[opt]) + + # sanity check client option hash + for opt in options.keys(): + if opt not in self.default_options: + raise KeyError, "invalid TextFile option '%s'" % opt + + if file is None: + self.open (filename) + else: + self.filename = filename + self.file = file + self.current_line = 0 # assuming that file is at BOF! + + # 'linebuf' is a stack of lines that will be emptied before we + # actually read from the file; it's only populated by an + # 'unreadline()' operation + self.linebuf = [] + + + def open (self, filename): + """Open a new file named 'filename'. This overrides both the + 'filename' and 'file' arguments to the constructor.""" + + self.filename = filename + self.file = open (self.filename, 'r') + self.current_line = 0 + + + def close (self): + """Close the current file and forget everything we know about it + (filename, current line number).""" + + self.file.close () + self.file = None + self.filename = None + self.current_line = None + + + def gen_error (self, msg, line=None): + outmsg = [] + if line is None: + line = self.current_line + outmsg.append(self.filename + ", ") + if isinstance(line, (list, tuple)): + outmsg.append("lines %d-%d: " % tuple (line)) + else: + outmsg.append("line %d: " % line) + outmsg.append(str(msg)) + return ''.join(outmsg) + + + def error (self, msg, line=None): + raise ValueError, "error: " + self.gen_error(msg, line) + + def warn (self, msg, line=None): + """Print (to stderr) a warning message tied to the current logical + line in the current file. If the current logical line in the + file spans multiple physical lines, the warning refers to the + whole range, eg. "lines 3-5". If 'line' supplied, it overrides + the current line number; it may be a list or tuple to indicate a + range of physical lines, or an integer for a single physical + line.""" + sys.stderr.write("warning: " + self.gen_error(msg, line) + "\n") + + + def readline (self): + """Read and return a single logical line from the current file (or + from an internal buffer if lines have previously been "unread" + with 'unreadline()'). If the 'join_lines' option is true, this + may involve reading multiple physical lines concatenated into a + single string. Updates the current line number, so calling + 'warn()' after 'readline()' emits a warning about the physical + line(s) just read. Returns None on end-of-file, since the empty + string can occur if 'rstrip_ws' is true but 'strip_blanks' is + not.""" + + # If any "unread" lines waiting in 'linebuf', return the top + # one. (We don't actually buffer read-ahead data -- lines only + # get put in 'linebuf' if the client explicitly does an + # 'unreadline()'. + if self.linebuf: + line = self.linebuf[-1] + del self.linebuf[-1] + return line + + buildup_line = '' + + while 1: + # read the line, make it None if EOF + line = self.file.readline() + if line == '': line = None + + if self.strip_comments and line: + + # Look for the first "#" in the line. If none, never + # mind. If we find one and it's the first character, or + # is not preceded by "\", then it starts a comment -- + # strip the comment, strip whitespace before it, and + # carry on. Otherwise, it's just an escaped "#", so + # unescape it (and any other escaped "#"'s that might be + # lurking in there) and otherwise leave the line alone. + + pos = line.find("#") + if pos == -1: # no "#" -- no comments + pass + + # It's definitely a comment -- either "#" is the first + # character, or it's elsewhere and unescaped. + elif pos == 0 or line[pos-1] != "\\": + # Have to preserve the trailing newline, because it's + # the job of a later step (rstrip_ws) to remove it -- + # and if rstrip_ws is false, we'd better preserve it! + # (NB. this means that if the final line is all comment + # and has no trailing newline, we will think that it's + # EOF; I think that's OK.) + eol = (line[-1] == '\n') and '\n' or '' + line = line[0:pos] + eol + + # If all that's left is whitespace, then skip line + # *now*, before we try to join it to 'buildup_line' -- + # that way constructs like + # hello \\ + # # comment that should be ignored + # there + # result in "hello there". + if line.strip() == "": + continue + + else: # it's an escaped "#" + line = line.replace("\\#", "#") + + + # did previous line end with a backslash? then accumulate + if self.join_lines and buildup_line: + # oops: end of file + if line is None: + self.warn ("continuation line immediately precedes " + "end-of-file") + return buildup_line + + if self.collapse_join: + line = line.lstrip() + line = buildup_line + line + + # careful: pay attention to line number when incrementing it + if isinstance(self.current_line, list): + self.current_line[1] = self.current_line[1] + 1 + else: + self.current_line = [self.current_line, + self.current_line+1] + # just an ordinary line, read it as usual + else: + if line is None: # eof + return None + + # still have to be careful about incrementing the line number! + if isinstance(self.current_line, list): + self.current_line = self.current_line[1] + 1 + else: + self.current_line = self.current_line + 1 + + + # strip whitespace however the client wants (leading and + # trailing, or one or the other, or neither) + if self.lstrip_ws and self.rstrip_ws: + line = line.strip() + elif self.lstrip_ws: + line = line.lstrip() + elif self.rstrip_ws: + line = line.rstrip() + + # blank line (whether we rstrip'ed or not)? skip to next line + # if appropriate + if (line == '' or line == '\n') and self.skip_blanks: + continue + + if self.join_lines: + if line[-1] == '\\': + buildup_line = line[:-1] + continue + + if line[-2:] == '\\\n': + buildup_line = line[0:-2] + '\n' + continue + + # well, I guess there's some actual content there: return it + return line + + # readline () + + + def readlines (self): + """Read and return the list of all logical lines remaining in the + current file.""" + + lines = [] + while 1: + line = self.readline() + if line is None: + return lines + lines.append (line) + + + def unreadline (self, line): + """Push 'line' (a string) onto an internal buffer that will be + checked by future 'readline()' calls. Handy for implementing + a parser with line-at-a-time lookahead.""" + + self.linebuf.append (line) diff --git a/src/main/resources/PythonLibs/distutils/unixccompiler.py b/src/main/resources/PythonLibs/distutils/unixccompiler.py new file mode 100644 index 0000000000000000000000000000000000000000..2aa1cb1d27795bb8adc16e082556f5bce0bd716f --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/unixccompiler.py @@ -0,0 +1,288 @@ +"""distutils.unixccompiler + +Contains the UnixCCompiler class, a subclass of CCompiler that handles +the "typical" Unix-style command-line C compiler: + * macros defined with -Dname[=value] + * macros undefined with -Uname + * include search directories specified with -Idir + * libraries specified with -lllib + * library search directories specified with -Ldir + * compile handled by 'cc' (or similar) executable with -c option: + compiles .c to .o + * link static library handled by 'ar' command (possibly with 'ranlib') + * link shared library handled by 'cc -shared' +""" + +__revision__ = "$Id$" + +import os, sys, re +from types import StringType, NoneType + +from distutils import sysconfig +from distutils.dep_util import newer +from distutils.ccompiler import \ + CCompiler, gen_preprocess_options, gen_lib_options +from distutils.errors import \ + DistutilsExecError, CompileError, LibError, LinkError +from distutils import log + +if sys.platform == 'darwin': + import _osx_support + +# XXX Things not currently handled: +# * optimization/debug/warning flags; we just use whatever's in Python's +# Makefile and live with it. Is this adequate? If not, we might +# have to have a bunch of subclasses GNUCCompiler, SGICCompiler, +# SunCCompiler, and I suspect down that road lies madness. +# * even if we don't know a warning flag from an optimization flag, +# we need some way for outsiders to feed preprocessor/compiler/linker +# flags in to us -- eg. a sysadmin might want to mandate certain flags +# via a site config file, or a user might want to set something for +# compiling this module distribution only via the setup.py command +# line, whatever. As long as these options come from something on the +# current system, they can be as system-dependent as they like, and we +# should just happily stuff them into the preprocessor/compiler/linker +# options and carry on. + + +class UnixCCompiler(CCompiler): + + compiler_type = 'unix' + + # These are used by CCompiler in two places: the constructor sets + # instance attributes 'preprocessor', 'compiler', etc. from them, and + # 'set_executable()' allows any of these to be set. The defaults here + # are pretty generic; they will probably have to be set by an outsider + # (eg. using information discovered by the sysconfig about building + # Python extensions). + executables = {'preprocessor' : None, + 'compiler' : ["cc"], + 'compiler_so' : ["cc"], + 'compiler_cxx' : ["cc"], + 'linker_so' : ["cc", "-shared"], + 'linker_exe' : ["cc"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : None, + } + + if sys.platform[:6] == "darwin": + executables['ranlib'] = ["ranlib"] + + # Needed for the filename generation methods provided by the base + # class, CCompiler. NB. whoever instantiates/uses a particular + # UnixCCompiler instance should set 'shared_lib_ext' -- we set a + # reasonable common default here, but it's not necessarily used on all + # Unices! + + src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"] + obj_extension = ".o" + static_lib_extension = ".a" + shared_lib_extension = ".so" + dylib_lib_extension = ".dylib" + static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s" + if sys.platform == "cygwin": + exe_extension = ".exe" + + def preprocess(self, source, + output_file=None, macros=None, include_dirs=None, + extra_preargs=None, extra_postargs=None): + ignore, macros, include_dirs = \ + self._fix_compile_args(None, macros, include_dirs) + pp_opts = gen_preprocess_options(macros, include_dirs) + pp_args = self.preprocessor + pp_opts + if output_file: + pp_args.extend(['-o', output_file]) + if extra_preargs: + pp_args[:0] = extra_preargs + if extra_postargs: + pp_args.extend(extra_postargs) + pp_args.append(source) + + # We need to preprocess: either we're being forced to, or we're + # generating output to stdout, or there's a target output file and + # the source file is newer than the target (or the target doesn't + # exist). + if self.force or output_file is None or newer(source, output_file): + if output_file: + self.mkpath(os.path.dirname(output_file)) + try: + self.spawn(pp_args) + except DistutilsExecError, msg: + raise CompileError, msg + + def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): + compiler_so = self.compiler_so + if sys.platform == 'darwin': + compiler_so = _osx_support.compiler_fixup(compiler_so, + cc_args + extra_postargs) + try: + self.spawn(compiler_so + cc_args + [src, '-o', obj] + + extra_postargs) + except DistutilsExecError, msg: + raise CompileError, msg + + def create_static_lib(self, objects, output_libname, + output_dir=None, debug=0, target_lang=None): + objects, output_dir = self._fix_object_args(objects, output_dir) + + output_filename = \ + self.library_filename(output_libname, output_dir=output_dir) + + if self._need_link(objects, output_filename): + self.mkpath(os.path.dirname(output_filename)) + self.spawn(self.archiver + + [output_filename] + + objects + self.objects) + + # Not many Unices required ranlib anymore -- SunOS 4.x is, I + # think the only major Unix that does. Maybe we need some + # platform intelligence here to skip ranlib if it's not + # needed -- or maybe Python's configure script took care of + # it for us, hence the check for leading colon. + if self.ranlib: + try: + self.spawn(self.ranlib + [output_filename]) + except DistutilsExecError, msg: + raise LibError, msg + else: + log.debug("skipping %s (up-to-date)", output_filename) + + def link(self, target_desc, objects, + output_filename, output_dir=None, libraries=None, + library_dirs=None, runtime_library_dirs=None, + export_symbols=None, debug=0, extra_preargs=None, + extra_postargs=None, build_temp=None, target_lang=None): + objects, output_dir = self._fix_object_args(objects, output_dir) + libraries, library_dirs, runtime_library_dirs = \ + self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) + + lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, + libraries) + if type(output_dir) not in (StringType, NoneType): + raise TypeError, "'output_dir' must be a string or None" + if output_dir is not None: + output_filename = os.path.join(output_dir, output_filename) + + if self._need_link(objects, output_filename): + ld_args = (objects + self.objects + + lib_opts + ['-o', output_filename]) + if debug: + ld_args[:0] = ['-g'] + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + self.mkpath(os.path.dirname(output_filename)) + try: + if target_desc == CCompiler.EXECUTABLE: + linker = self.linker_exe[:] + else: + linker = self.linker_so[:] + if target_lang == "c++" and self.compiler_cxx: + # skip over environment variable settings if /usr/bin/env + # is used to set up the linker's environment. + # This is needed on OSX. Note: this assumes that the + # normal and C++ compiler have the same environment + # settings. + i = 0 + if os.path.basename(linker[0]) == "env": + i = 1 + while '=' in linker[i]: + i = i + 1 + + linker[i] = self.compiler_cxx[i] + + if sys.platform == 'darwin': + linker = _osx_support.compiler_fixup(linker, ld_args) + + self.spawn(linker + ld_args) + except DistutilsExecError, msg: + raise LinkError, msg + else: + log.debug("skipping %s (up-to-date)", output_filename) + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function, in + # ccompiler.py. + + def library_dir_option(self, dir): + return "-L" + dir + + def _is_gcc(self, compiler_name): + return "gcc" in compiler_name or "g++" in compiler_name + + def runtime_library_dir_option(self, dir): + # XXX Hackish, at the very least. See Python bug #445902: + # http://sourceforge.net/tracker/index.php + # ?func=detail&aid=445902&group_id=5470&atid=105470 + # Linkers on different platforms need different options to + # specify that directories need to be added to the list of + # directories searched for dependencies when a dynamic library + # is sought. GCC has to be told to pass the -R option through + # to the linker, whereas other compilers just know this. + # Other compilers may need something slightly different. At + # this time, there's no way to determine this information from + # the configuration data stored in the Python installation, so + # we use this hack. + compiler = os.path.basename(sysconfig.get_config_var("CC")) + if sys.platform[:6] == "darwin": + # MacOSX's linker doesn't understand the -R flag at all + return "-L" + dir + elif sys.platform[:5] == "hp-ux": + if self._is_gcc(compiler): + return ["-Wl,+s", "-L" + dir] + return ["+s", "-L" + dir] + elif sys.platform[:7] == "irix646" or sys.platform[:6] == "osf1V5": + return ["-rpath", dir] + elif self._is_gcc(compiler): + return "-Wl,-R" + dir + else: + return "-R" + dir + + def library_option(self, lib): + return "-l" + lib + + def find_library_file(self, dirs, lib, debug=0): + shared_f = self.library_filename(lib, lib_type='shared') + dylib_f = self.library_filename(lib, lib_type='dylib') + static_f = self.library_filename(lib, lib_type='static') + + if sys.platform == 'darwin': + # On OSX users can specify an alternate SDK using + # '-isysroot', calculate the SDK root if it is specified + # (and use it further on) + cflags = sysconfig.get_config_var('CFLAGS') + m = re.search(r'-isysroot\s+(\S+)', cflags) + if m is None: + sysroot = '/' + else: + sysroot = m.group(1) + + + + for dir in dirs: + shared = os.path.join(dir, shared_f) + dylib = os.path.join(dir, dylib_f) + static = os.path.join(dir, static_f) + + if sys.platform == 'darwin' and ( + dir.startswith('/System/') or ( + dir.startswith('/usr/') and not dir.startswith('/usr/local/'))): + + shared = os.path.join(sysroot, dir[1:], shared_f) + dylib = os.path.join(sysroot, dir[1:], dylib_f) + static = os.path.join(sysroot, dir[1:], static_f) + + # We're second-guessing the linker here, with not much hard + # data to go on: GCC seems to prefer the shared library, so I'm + # assuming that *all* Unix C compilers do. And of course I'm + # ignoring even GCC's "-static" option. So sue me. + if os.path.exists(dylib): + return dylib + elif os.path.exists(shared): + return shared + elif os.path.exists(static): + return static + + # Oops, didn't find it in *any* of 'dirs' + return None diff --git a/src/main/resources/PythonLibs/distutils/util.py b/src/main/resources/PythonLibs/distutils/util.py new file mode 100644 index 0000000000000000000000000000000000000000..570da737124bb994fb3d3e3a76d523382f10fa69 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/util.py @@ -0,0 +1,580 @@ +"""distutils.util + +Miscellaneous utility functions -- anything that doesn't fit into +one of the other *util.py modules. +""" + +__revision__ = "$Id: util.py 83588 2010-08-02 21:35:06Z ezio.melotti $" + +import sys, os, string, re +from distutils.errors import DistutilsPlatformError +from distutils.dep_util import newer +from distutils.spawn import spawn +from distutils import log +from distutils.errors import DistutilsByteCompileError + +def get_platform (): + """Return a string that identifies the current platform. This is used + mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = string.find(sys.version, prefix) + if i == -1: + return sys.platform + j = string.find(sys.version, ")", i) + look = sys.version[i+len(prefix):j].lower() + if look=='amd64': + return 'win-amd64' + if look=='itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + + (osname, host, release, version, machine) = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = string.lower(osname) + osname = string.replace(osname, '/', '') + machine = string.replace(machine, ' ', '_') + machine = string.replace(machine, '/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile (r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + from distutils.sysconfig import get_config_vars + cfgvars = get_config_vars() + + macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET') + if not macver: + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if 1: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + m = re.search( + r'<key>ProductUserVisibleVersion</key>\s*' + + r'<string>(.*?)</string>', f.read()) + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + from distutils.sysconfig import get_config_vars + release = macver + osname = "macosx" + + if (macrelease + '.') >= '10.4.' and \ + '-arch' in get_config_vars().get('CFLAGS', '').strip(): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall('-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r"%(archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxint >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + machine = 'ppc' + + # See 'i386' case + if sys.maxint >= 2**32: + machine = 'ppc64' + + return "%s-%s-%s" % (osname, release, machine) + +# get_platform () + + +def convert_path (pathname): + """Return 'pathname' as a name that will work on the native filesystem, + i.e. split it on '/' and put it back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError, "path '%s' cannot be absolute" % pathname + if pathname[-1] == '/': + raise ValueError, "path '%s' cannot end with '/'" % pathname + + paths = string.split(pathname, '/') + while '.' in paths: + paths.remove('.') + if not paths: + return os.curdir + return os.path.join(*paths) + +# convert_path () + + +def change_root (new_root, pathname): + """Return 'pathname' with 'new_root' prepended. If 'pathname' is + relative, this is equivalent to "os.path.join(new_root,pathname)". + Otherwise, it requires making 'pathname' relative and then joining the + two, which is tricky on DOS/Windows and Mac OS. + """ + os_name = os._name if sys.platform.startswith('java') else os.name + if os_name == 'posix': + if not os.path.isabs(pathname): + return os.path.join(new_root, pathname) + else: + return os.path.join(new_root, pathname[1:]) + + elif os_name == 'nt': + (drive, path) = os.path.splitdrive(pathname) + if path[0] == '\\': + path = path[1:] + return os.path.join(new_root, path) + + elif os_name == 'os2': + (drive, path) = os.path.splitdrive(pathname) + if path[0] == os.sep: + path = path[1:] + return os.path.join(new_root, path) + + elif os_name == 'mac': + if not os.path.isabs(pathname): + return os.path.join(new_root, pathname) + else: + # Chop off volume name from start of path + elements = string.split(pathname, ":", 1) + pathname = ":" + elements[1] + return os.path.join(new_root, pathname) + + else: + raise DistutilsPlatformError, \ + "nothing known about platform '%s'" % os_name + + +_environ_checked = 0 +def check_environ (): + """Ensure that 'os.environ' has all the environment variables we + guarantee that users can use in config files, command-line options, + etc. Currently this includes: + HOME - user's home directory (Unix only) + PLAT - description of the current platform, including hardware + and OS (see 'get_platform()') + """ + global _environ_checked + if _environ_checked: + return + + if os.name == 'posix' and 'HOME' not in os.environ: + import pwd + os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] + + if 'PLAT' not in os.environ: + os.environ['PLAT'] = get_platform() + + _environ_checked = 1 + + +def subst_vars (s, local_vars): + """Perform shell/Perl-style variable substitution on 'string'. Every + occurrence of '$' followed by a name is considered a variable, and + variable is substituted by the value found in the 'local_vars' + dictionary, or in 'os.environ' if it's not in 'local_vars'. + 'os.environ' is first checked/augmented to guarantee that it contains + certain values: see 'check_environ()'. Raise ValueError for any + variables not found in either 'local_vars' or 'os.environ'. + """ + check_environ() + def _subst (match, local_vars=local_vars): + var_name = match.group(1) + if var_name in local_vars: + return str(local_vars[var_name]) + else: + return os.environ[var_name] + + try: + return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s) + except KeyError, var: + raise ValueError, "invalid variable '$%s'" % var + +# subst_vars () + + +def grok_environment_error (exc, prefix="error: "): + """Generate a useful error message from an EnvironmentError (IOError or + OSError) exception object. Handles Python 1.5.1 and 1.5.2 styles, and + does what it can to deal with exception objects that don't have a + filename (which happens when the error is due to a two-file operation, + such as 'rename()' or 'link()'. Returns the error message as a string + prefixed with 'prefix'. + """ + # check for Python 1.5.2-style {IO,OS}Error exception objects + if hasattr(exc, 'filename') and hasattr(exc, 'strerror'): + if exc.filename: + error = prefix + "%s: %s" % (exc.filename, exc.strerror) + else: + # two-argument functions in posix module don't + # include the filename in the exception object! + error = prefix + "%s" % exc.strerror + else: + error = prefix + str(exc[-1]) + + return error + + +# Needed by 'split_quoted()' +_wordchars_re = _squote_re = _dquote_re = None +def _init_regex(): + global _wordchars_re, _squote_re, _dquote_re + _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) + _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") + _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') + +def split_quoted (s): + """Split a string up according to Unix shell-like rules for quotes and + backslashes. In short: words are delimited by spaces, as long as those + spaces are not escaped by a backslash, or inside a quoted string. + Single and double quotes are equivalent, and the quote characters can + be backslash-escaped. The backslash is stripped from any two-character + escape sequence, leaving only the escaped character. The quote + characters are stripped from any quoted string. Returns a list of + words. + """ + + # This is a nice algorithm for splitting up a single string, since it + # doesn't require character-by-character examination. It was a little + # bit of a brain-bender to get it working right, though... + if _wordchars_re is None: _init_regex() + + s = string.strip(s) + words = [] + pos = 0 + + while s: + m = _wordchars_re.match(s, pos) + end = m.end() + if end == len(s): + words.append(s[:end]) + break + + if s[end] in string.whitespace: # unescaped, unquoted whitespace: now + words.append(s[:end]) # we definitely have a word delimiter + s = string.lstrip(s[end:]) + pos = 0 + + elif s[end] == '\\': # preserve whatever is being escaped; + # will become part of the current word + s = s[:end] + s[end+1:] + pos = end+1 + + else: + if s[end] == "'": # slurp singly-quoted string + m = _squote_re.match(s, end) + elif s[end] == '"': # slurp doubly-quoted string + m = _dquote_re.match(s, end) + else: + raise RuntimeError, \ + "this can't happen (bad char '%c')" % s[end] + + if m is None: + raise ValueError, \ + "bad string (mismatched %s quotes?)" % s[end] + + (beg, end) = m.span() + s = s[:beg] + s[beg+1:end-1] + s[end:] + pos = m.end() - 2 + + if pos >= len(s): + words.append(s) + break + + return words + +# split_quoted () + + +def execute (func, args, msg=None, verbose=0, dry_run=0): + """Perform some action that affects the outside world (eg. by + writing to the filesystem). Such actions are special because they + are disabled by the 'dry_run' flag. This method takes care of all + that bureaucracy for you; all you have to do is supply the + function to call and an argument tuple for it (to embody the + "external action" being performed), and an optional message to + print. + """ + if msg is None: + msg = "%s%r" % (func.__name__, args) + if msg[-2:] == ',)': # correct for singleton tuple + msg = msg[0:-2] + ')' + + log.info(msg) + if not dry_run: + func(*args) + + +def strtobool (val): + """Convert a string representation of truth to true (1) or false (0). + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values + are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if + 'val' is anything else. + """ + val = string.lower(val) + if val in ('y', 'yes', 't', 'true', 'on', '1'): + return 1 + elif val in ('n', 'no', 'f', 'false', 'off', '0'): + return 0 + else: + raise ValueError, "invalid truth value %r" % (val,) + + +def byte_compile (py_files, + optimize=0, force=0, + prefix=None, base_dir=None, + verbose=1, dry_run=0, + direct=None): + """Byte-compile a collection of Python source files to either .pyc + or .pyo files in the same directory. 'py_files' is a list of files + to compile; any files that don't end in ".py" are silently skipped. + 'optimize' must be one of the following: + 0 - don't optimize (generate .pyc) + 1 - normal optimization (like "python -O") + 2 - extra optimization (like "python -OO") + If 'force' is true, all files are recompiled regardless of + timestamps. + + The source filename encoded in each bytecode file defaults to the + filenames listed in 'py_files'; you can modify these with 'prefix' and + 'basedir'. 'prefix' is a string that will be stripped off of each + source filename, and 'base_dir' is a directory name that will be + prepended (after 'prefix' is stripped). You can supply either or both + (or neither) of 'prefix' and 'base_dir', as you wish. + + If 'dry_run' is true, doesn't actually do anything that would + affect the filesystem. + + Byte-compilation is either done directly in this interpreter process + with the standard py_compile module, or indirectly by writing a + temporary script and executing it. Normally, you should let + 'byte_compile()' figure out to use direct compilation or not (see + the source for details). The 'direct' flag is used by the script + generated in indirect mode; unless you know what you're doing, leave + it set to None. + """ + # nothing is done if sys.dont_write_bytecode is True + if sys.dont_write_bytecode: + raise DistutilsByteCompileError('byte-compiling is disabled.') + + # First, if the caller didn't force us into direct or indirect mode, + # figure out which mode we should be in. We take a conservative + # approach: choose direct mode *only* if the current interpreter is + # in debug mode and optimize is 0. If we're not in debug mode (-O + # or -OO), we don't know which level of optimization this + # interpreter is running with, so we can't do direct + # byte-compilation and be certain that it's the right thing. Thus, + # always compile indirectly if the current interpreter is in either + # optimize mode, or if either optimization level was requested by + # the caller. + if direct is None: + direct = (__debug__ and optimize == 0) + + # "Indirect" byte-compilation: write a temporary script and then + # run it with the appropriate flags. + if not direct: + try: + from tempfile import mkstemp + (script_fd, script_name) = mkstemp(".py") + except ImportError: + from tempfile import mktemp + (script_fd, script_name) = None, mktemp(".py") + log.info("writing byte-compilation script '%s'", script_name) + if not dry_run: + if script_fd is not None: + script = os.fdopen(script_fd, "w") + else: + script = open(script_name, "w") + + script.write("""\ +from distutils.util import byte_compile +files = [ +""") + + # XXX would be nice to write absolute filenames, just for + # safety's sake (script should be more robust in the face of + # chdir'ing before running it). But this requires abspath'ing + # 'prefix' as well, and that breaks the hack in build_lib's + # 'byte_compile()' method that carefully tacks on a trailing + # slash (os.sep really) to make sure the prefix here is "just + # right". This whole prefix business is rather delicate -- the + # problem is that it's really a directory, but I'm treating it + # as a dumb string, so trailing slashes and so forth matter. + + #py_files = map(os.path.abspath, py_files) + #if prefix: + # prefix = os.path.abspath(prefix) + + script.write(string.join(map(repr, py_files), ",\n") + "]\n") + script.write(""" +byte_compile(files, optimize=%r, force=%r, + prefix=%r, base_dir=%r, + verbose=%r, dry_run=0, + direct=1) +""" % (optimize, force, prefix, base_dir, verbose)) + + script.close() + + cmd = [sys.executable, script_name] + if optimize == 1: + cmd.insert(1, "-O") + elif optimize == 2: + cmd.insert(1, "-OO") + spawn(cmd, dry_run=dry_run) + execute(os.remove, (script_name,), "removing %s" % script_name, + dry_run=dry_run) + + # "Direct" byte-compilation: use the py_compile module to compile + # right here, right now. Note that the script generated in indirect + # mode simply calls 'byte_compile()' in direct mode, a weird sort of + # cross-process recursion. Hey, it works! + else: + from py_compile import compile + + for file in py_files: + if file[-3:] != ".py": + # This lets us be lazy and not filter filenames in + # the "install_lib" command. + continue + + # Terminology from the py_compile module: + # cfile - byte-compiled file + # dfile - purported source filename (same as 'file' by default) + if sys.platform.startswith('java'): + cfile = file[:-3] + '$py.class' + else: + cfile = file + (__debug__ and "c" or "o") + dfile = file + if prefix: + if file[:len(prefix)] != prefix: + raise ValueError, \ + ("invalid prefix: filename %r doesn't start with %r" + % (file, prefix)) + dfile = dfile[len(prefix):] + if base_dir: + dfile = os.path.join(base_dir, dfile) + + cfile_base = os.path.basename(cfile) + if direct: + if force or newer(file, cfile): + log.info("byte-compiling %s to %s", file, cfile_base) + if not dry_run: + compile(file, cfile, dfile) + else: + log.debug("skipping byte-compilation of %s to %s", + file, cfile_base) + +# byte_compile () + +def rfc822_escape (header): + """Return a version of the string escaped for inclusion in an + RFC-822 header, by ensuring there are 8 spaces space after each newline. + """ + lines = string.split(header, '\n') + header = string.join(lines, '\n' + 8*' ') + return header diff --git a/src/main/resources/PythonLibs/distutils/version.py b/src/main/resources/PythonLibs/distutils/version.py new file mode 100644 index 0000000000000000000000000000000000000000..0fb5b6e20411b765360a25b69954877af5de44fd --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/version.py @@ -0,0 +1,299 @@ +# +# distutils/version.py +# +# Implements multiple version numbering conventions for the +# Python Module Distribution Utilities. +# +# $Id$ +# + +"""Provides classes to represent module version numbers (one class for +each style of version numbering). There are currently two such classes +implemented: StrictVersion and LooseVersion. + +Every version number class implements the following interface: + * the 'parse' method takes a string and parses it to some internal + representation; if the string is an invalid version number, + 'parse' raises a ValueError exception + * the class constructor takes an optional string argument which, + if supplied, is passed to 'parse' + * __str__ reconstructs the string that was passed to 'parse' (or + an equivalent string -- ie. one that will generate an equivalent + version number instance) + * __repr__ generates Python code to recreate the version number instance + * __cmp__ compares the current instance with either another instance + of the same class or a string (which will be parsed to an instance + of the same class, thus must follow the same rules) +""" + +import string, re +from types import StringType + +class Version: + """Abstract base class for version numbering classes. Just provides + constructor (__init__) and reproducer (__repr__), because those + seem to be the same for all version numbering classes. + """ + + def __init__ (self, vstring=None): + if vstring: + self.parse(vstring) + + def __repr__ (self): + return "%s ('%s')" % (self.__class__.__name__, str(self)) + + +# Interface for version-number classes -- must be implemented +# by the following classes (the concrete ones -- Version should +# be treated as an abstract class). +# __init__ (string) - create and take same action as 'parse' +# (string parameter is optional) +# parse (string) - convert a string representation to whatever +# internal representation is appropriate for +# this style of version numbering +# __str__ (self) - convert back to a string; should be very similar +# (if not identical to) the string supplied to parse +# __repr__ (self) - generate Python code to recreate +# the instance +# __cmp__ (self, other) - compare two version numbers ('other' may +# be an unparsed version string, or another +# instance of your version class) + + +class StrictVersion (Version): + + """Version numbering for anal retentives and software idealists. + Implements the standard interface for version number classes as + described above. A version number consists of two or three + dot-separated numeric components, with an optional "pre-release" tag + on the end. The pre-release tag consists of the letter 'a' or 'b' + followed by a number. If the numeric components of two version + numbers are equal, then one with a pre-release tag will always + be deemed earlier (lesser) than one without. + + The following are valid version numbers (shown in the order that + would be obtained by sorting according to the supplied cmp function): + + 0.4 0.4.0 (these two are equivalent) + 0.4.1 + 0.5a1 + 0.5b3 + 0.5 + 0.9.6 + 1.0 + 1.0.4a3 + 1.0.4b1 + 1.0.4 + + The following are examples of invalid version numbers: + + 1 + 2.7.2.2 + 1.3.a4 + 1.3pl1 + 1.3c4 + + The rationale for this version numbering system will be explained + in the distutils documentation. + """ + + version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$', + re.VERBOSE) + + + def parse (self, vstring): + match = self.version_re.match(vstring) + if not match: + raise ValueError, "invalid version number '%s'" % vstring + + (major, minor, patch, prerelease, prerelease_num) = \ + match.group(1, 2, 4, 5, 6) + + if patch: + self.version = tuple(map(string.atoi, [major, minor, patch])) + else: + self.version = tuple(map(string.atoi, [major, minor]) + [0]) + + if prerelease: + self.prerelease = (prerelease[0], string.atoi(prerelease_num)) + else: + self.prerelease = None + + + def __str__ (self): + + if self.version[2] == 0: + vstring = string.join(map(str, self.version[0:2]), '.') + else: + vstring = string.join(map(str, self.version), '.') + + if self.prerelease: + vstring = vstring + self.prerelease[0] + str(self.prerelease[1]) + + return vstring + + + def __cmp__ (self, other): + if isinstance(other, StringType): + other = StrictVersion(other) + + compare = cmp(self.version, other.version) + if (compare == 0): # have to compare prerelease + + # case 1: neither has prerelease; they're equal + # case 2: self has prerelease, other doesn't; other is greater + # case 3: self doesn't have prerelease, other does: self is greater + # case 4: both have prerelease: must compare them! + + if (not self.prerelease and not other.prerelease): + return 0 + elif (self.prerelease and not other.prerelease): + return -1 + elif (not self.prerelease and other.prerelease): + return 1 + elif (self.prerelease and other.prerelease): + return cmp(self.prerelease, other.prerelease) + + else: # numeric versions don't match -- + return compare # prerelease stuff doesn't matter + + +# end class StrictVersion + + +# The rules according to Greg Stein: +# 1) a version number has 1 or more numbers separated by a period or by +# sequences of letters. If only periods, then these are compared +# left-to-right to determine an ordering. +# 2) sequences of letters are part of the tuple for comparison and are +# compared lexicographically +# 3) recognize the numeric components may have leading zeroes +# +# The LooseVersion class below implements these rules: a version number +# string is split up into a tuple of integer and string components, and +# comparison is a simple tuple comparison. This means that version +# numbers behave in a predictable and obvious way, but a way that might +# not necessarily be how people *want* version numbers to behave. There +# wouldn't be a problem if people could stick to purely numeric version +# numbers: just split on period and compare the numbers as tuples. +# However, people insist on putting letters into their version numbers; +# the most common purpose seems to be: +# - indicating a "pre-release" version +# ('alpha', 'beta', 'a', 'b', 'pre', 'p') +# - indicating a post-release patch ('p', 'pl', 'patch') +# but of course this can't cover all version number schemes, and there's +# no way to know what a programmer means without asking him. +# +# The problem is what to do with letters (and other non-numeric +# characters) in a version number. The current implementation does the +# obvious and predictable thing: keep them as strings and compare +# lexically within a tuple comparison. This has the desired effect if +# an appended letter sequence implies something "post-release": +# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002". +# +# However, if letters in a version number imply a pre-release version, +# the "obvious" thing isn't correct. Eg. you would expect that +# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison +# implemented here, this just isn't so. +# +# Two possible solutions come to mind. The first is to tie the +# comparison algorithm to a particular set of semantic rules, as has +# been done in the StrictVersion class above. This works great as long +# as everyone can go along with bondage and discipline. Hopefully a +# (large) subset of Python module programmers will agree that the +# particular flavour of bondage and discipline provided by StrictVersion +# provides enough benefit to be worth using, and will submit their +# version numbering scheme to its domination. The free-thinking +# anarchists in the lot will never give in, though, and something needs +# to be done to accommodate them. +# +# Perhaps a "moderately strict" version class could be implemented that +# lets almost anything slide (syntactically), and makes some heuristic +# assumptions about non-digits in version number strings. This could +# sink into special-case-hell, though; if I was as talented and +# idiosyncratic as Larry Wall, I'd go ahead and implement a class that +# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is +# just as happy dealing with things like "2g6" and "1.13++". I don't +# think I'm smart enough to do it right though. +# +# In any case, I've coded the test suite for this module (see +# ../test/test_version.py) specifically to fail on things like comparing +# "1.2a2" and "1.2". That's not because the *code* is doing anything +# wrong, it's because the simple, obvious design doesn't match my +# complicated, hairy expectations for real-world version numbers. It +# would be a snap to fix the test suite to say, "Yep, LooseVersion does +# the Right Thing" (ie. the code matches the conception). But I'd rather +# have a conception that matches common notions about version numbers. + +class LooseVersion (Version): + + """Version numbering for anarchists and software realists. + Implements the standard interface for version number classes as + described above. A version number consists of a series of numbers, + separated by either periods or strings of letters. When comparing + version numbers, the numeric components will be compared + numerically, and the alphabetic components lexically. The following + are all valid version numbers, in no particular order: + + 1.5.1 + 1.5.2b2 + 161 + 3.10a + 8.02 + 3.4j + 1996.07.12 + 3.2.pl0 + 3.1.1.6 + 2g6 + 11g + 0.960923 + 2.2beta29 + 1.13++ + 5.5.kw + 2.0b1pl0 + + In fact, there is no such thing as an invalid version number under + this scheme; the rules for comparison are simple and predictable, + but may not always give the results you want (for some definition + of "want"). + """ + + component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE) + + def __init__ (self, vstring=None): + if vstring: + self.parse(vstring) + + + def parse (self, vstring): + # I've given up on thinking I can reconstruct the version string + # from the parsed tuple -- so I just store the string here for + # use by __str__ + self.vstring = vstring + components = filter(lambda x: x and x != '.', + self.component_re.split(vstring)) + for i in range(len(components)): + try: + components[i] = int(components[i]) + except ValueError: + pass + + self.version = components + + + def __str__ (self): + return self.vstring + + + def __repr__ (self): + return "LooseVersion ('%s')" % str(self) + + + def __cmp__ (self, other): + if isinstance(other, StringType): + other = LooseVersion(other) + + return cmp(self.version, other.version) + + +# end class LooseVersion diff --git a/src/main/resources/PythonLibs/distutils/versionpredicate.py b/src/main/resources/PythonLibs/distutils/versionpredicate.py new file mode 100644 index 0000000000000000000000000000000000000000..ba8b6c021b20082b713c8c23ba1ce8526b191e70 --- /dev/null +++ b/src/main/resources/PythonLibs/distutils/versionpredicate.py @@ -0,0 +1,164 @@ +"""Module for parsing and testing package version predicate strings. +""" +import re +import distutils.version +import operator + + +re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)") +# (package) (rest) + +re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses +re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$") +# (comp) (version) + + +def splitUp(pred): + """Parse a single version comparison. + + Return (comparison string, StrictVersion) + """ + res = re_splitComparison.match(pred) + if not res: + raise ValueError("bad package restriction syntax: %r" % pred) + comp, verStr = res.groups() + return (comp, distutils.version.StrictVersion(verStr)) + +compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq, + ">": operator.gt, ">=": operator.ge, "!=": operator.ne} + +class VersionPredicate: + """Parse and test package version predicates. + + >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)') + + The `name` attribute provides the full dotted name that is given:: + + >>> v.name + 'pyepat.abc' + + The str() of a `VersionPredicate` provides a normalized + human-readable version of the expression:: + + >>> print v + pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3) + + The `satisfied_by()` method can be used to determine with a given + version number is included in the set described by the version + restrictions:: + + >>> v.satisfied_by('1.1') + True + >>> v.satisfied_by('1.4') + True + >>> v.satisfied_by('1.0') + False + >>> v.satisfied_by('4444.4') + False + >>> v.satisfied_by('1555.1b3') + False + + `VersionPredicate` is flexible in accepting extra whitespace:: + + >>> v = VersionPredicate(' pat( == 0.1 ) ') + >>> v.name + 'pat' + >>> v.satisfied_by('0.1') + True + >>> v.satisfied_by('0.2') + False + + If any version numbers passed in do not conform to the + restrictions of `StrictVersion`, a `ValueError` is raised:: + + >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)') + Traceback (most recent call last): + ... + ValueError: invalid version number '1.2zb3' + + It the module or package name given does not conform to what's + allowed as a legal module or package name, `ValueError` is + raised:: + + >>> v = VersionPredicate('foo-bar') + Traceback (most recent call last): + ... + ValueError: expected parenthesized list: '-bar' + + >>> v = VersionPredicate('foo bar (12.21)') + Traceback (most recent call last): + ... + ValueError: expected parenthesized list: 'bar (12.21)' + + """ + + def __init__(self, versionPredicateStr): + """Parse a version predicate string. + """ + # Fields: + # name: package name + # pred: list of (comparison string, StrictVersion) + + versionPredicateStr = versionPredicateStr.strip() + if not versionPredicateStr: + raise ValueError("empty package restriction") + match = re_validPackage.match(versionPredicateStr) + if not match: + raise ValueError("bad package name in %r" % versionPredicateStr) + self.name, paren = match.groups() + paren = paren.strip() + if paren: + match = re_paren.match(paren) + if not match: + raise ValueError("expected parenthesized list: %r" % paren) + str = match.groups()[0] + self.pred = [splitUp(aPred) for aPred in str.split(",")] + if not self.pred: + raise ValueError("empty parenthesized list in %r" + % versionPredicateStr) + else: + self.pred = [] + + def __str__(self): + if self.pred: + seq = [cond + " " + str(ver) for cond, ver in self.pred] + return self.name + " (" + ", ".join(seq) + ")" + else: + return self.name + + def satisfied_by(self, version): + """True if version is compatible with all the predicates in self. + The parameter version must be acceptable to the StrictVersion + constructor. It may be either a string or StrictVersion. + """ + for cond, ver in self.pred: + if not compmap[cond](version, ver): + return False + return True + + +_provision_rx = None + +def split_provision(value): + """Return the name and optional version number of a provision. + + The version number, if given, will be returned as a `StrictVersion` + instance, otherwise it will be `None`. + + >>> split_provision('mypkg') + ('mypkg', None) + >>> split_provision(' mypkg( 1.2 ) ') + ('mypkg', StrictVersion ('1.2')) + """ + global _provision_rx + if _provision_rx is None: + _provision_rx = re.compile( + "([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$") + value = value.strip() + m = _provision_rx.match(value) + if not m: + raise ValueError("illegal provides specification: %r" % value) + ver = m.group(2) or None + if ver: + ver = distutils.version.StrictVersion(ver) + return m.group(1), ver diff --git a/src/main/resources/PythonLibs/doctest.py b/src/main/resources/PythonLibs/doctest.py new file mode 100644 index 0000000000000000000000000000000000000000..66765e738da32bbd14e0233f7f2d9b923572360f --- /dev/null +++ b/src/main/resources/PythonLibs/doctest.py @@ -0,0 +1,2798 @@ +# Module doctest. +# Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org). +# Major enhancements and refactoring by: +# Jim Fulton +# Edward Loper + +# Provided as-is; use at your own risk; no warranty; no promises; enjoy! + +r"""Module doctest -- a framework for running examples in docstrings. + +In simplest use, end each module M to be tested with: + +def _test(): + import doctest + doctest.testmod() + +if __name__ == "__main__": + _test() + +Then running the module as a script will cause the examples in the +docstrings to get executed and verified: + +python M.py + +This won't display anything unless an example fails, in which case the +failing example(s) and the cause(s) of the failure(s) are printed to stdout +(why not stderr? because stderr is a lame hack <0.2 wink>), and the final +line of output is "Test failed.". + +Run it with the -v switch instead: + +python M.py -v + +and a detailed report of all examples tried is printed to stdout, along +with assorted summaries at the end. + +You can force verbose mode by passing "verbose=True" to testmod, or prohibit +it by passing "verbose=False". In either of those cases, sys.argv is not +examined by testmod. + +There are a variety of other ways to run doctests, including integration +with the unittest framework, and support for running non-Python text +files containing doctests. There are also many ways to override parts +of doctest's default behaviors. See the Library Reference Manual for +details. +""" + +__docformat__ = 'reStructuredText en' + +__all__ = [ + # 0, Option Flags + 'register_optionflag', + 'DONT_ACCEPT_TRUE_FOR_1', + 'DONT_ACCEPT_BLANKLINE', + 'NORMALIZE_WHITESPACE', + 'ELLIPSIS', + 'SKIP', + 'IGNORE_EXCEPTION_DETAIL', + 'COMPARISON_FLAGS', + 'REPORT_UDIFF', + 'REPORT_CDIFF', + 'REPORT_NDIFF', + 'REPORT_ONLY_FIRST_FAILURE', + 'REPORTING_FLAGS', + # 1. Utility Functions + # 2. Example & DocTest + 'Example', + 'DocTest', + # 3. Doctest Parser + 'DocTestParser', + # 4. Doctest Finder + 'DocTestFinder', + # 5. Doctest Runner + 'DocTestRunner', + 'OutputChecker', + 'DocTestFailure', + 'UnexpectedException', + 'DebugRunner', + # 6. Test Functions + 'testmod', + 'testfile', + 'run_docstring_examples', + # 7. Tester + 'Tester', + # 8. Unittest Support + 'DocTestSuite', + 'DocFileSuite', + 'set_unittest_reportflags', + # 9. Debugging Support + 'script_from_examples', + 'testsource', + 'debug_src', + 'debug', +] + +import __future__ + +import sys, traceback, inspect, linecache, os, re +import unittest, difflib, pdb, tempfile +import warnings +from StringIO import StringIO +from collections import namedtuple + +TestResults = namedtuple('TestResults', 'failed attempted') + +# There are 4 basic classes: +# - Example: a <source, want> pair, plus an intra-docstring line number. +# - DocTest: a collection of examples, parsed from a docstring, plus +# info about where the docstring came from (name, filename, lineno). +# - DocTestFinder: extracts DocTests from a given object's docstring and +# its contained objects' docstrings. +# - DocTestRunner: runs DocTest cases, and accumulates statistics. +# +# So the basic picture is: +# +# list of: +# +------+ +---------+ +-------+ +# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results| +# +------+ +---------+ +-------+ +# | Example | +# | ... | +# | Example | +# +---------+ + +# Option constants. + +OPTIONFLAGS_BY_NAME = {} +def register_optionflag(name): + # Create a new flag unless `name` is already known. + return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME)) + +DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1') +DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE') +NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') +ELLIPSIS = register_optionflag('ELLIPSIS') +SKIP = register_optionflag('SKIP') +IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') + +COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | + DONT_ACCEPT_BLANKLINE | + NORMALIZE_WHITESPACE | + ELLIPSIS | + SKIP | + IGNORE_EXCEPTION_DETAIL) + +REPORT_UDIFF = register_optionflag('REPORT_UDIFF') +REPORT_CDIFF = register_optionflag('REPORT_CDIFF') +REPORT_NDIFF = register_optionflag('REPORT_NDIFF') +REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE') + +REPORTING_FLAGS = (REPORT_UDIFF | + REPORT_CDIFF | + REPORT_NDIFF | + REPORT_ONLY_FIRST_FAILURE) + +# Special string markers for use in `want` strings: +BLANKLINE_MARKER = '<BLANKLINE>' +ELLIPSIS_MARKER = '...' + +###################################################################### +## Table of Contents +###################################################################### +# 1. Utility Functions +# 2. Example & DocTest -- store test cases +# 3. DocTest Parser -- extracts examples from strings +# 4. DocTest Finder -- extracts test cases from objects +# 5. DocTest Runner -- runs test cases +# 6. Test Functions -- convenient wrappers for testing +# 7. Tester Class -- for backwards compatibility +# 8. Unittest Support +# 9. Debugging Support +# 10. Example Usage + +###################################################################### +## 1. Utility Functions +###################################################################### + +def _extract_future_flags(globs): + """ + Return the compiler-flags associated with the future features that + have been imported into the given namespace (globs). + """ + flags = 0 + for fname in __future__.all_feature_names: + feature = globs.get(fname, None) + if feature is getattr(__future__, fname): + flags |= feature.compiler_flag + return flags + +def _normalize_module(module, depth=2): + """ + Return the module specified by `module`. In particular: + - If `module` is a module, then return module. + - If `module` is a string, then import and return the + module with that name. + - If `module` is None, then return the calling module. + The calling module is assumed to be the module of + the stack frame at the given depth in the call stack. + """ + if inspect.ismodule(module): + return module + elif isinstance(module, (str, unicode)): + return __import__(module, globals(), locals(), ["*"]) + elif module is None: + return sys.modules[sys._getframe(depth).f_globals['__name__']] + else: + raise TypeError("Expected a module, string, or None") + +def _load_testfile(filename, package, module_relative): + if module_relative: + package = _normalize_module(package, 3) + filename = _module_relative_path(package, filename) + if hasattr(package, '__loader__'): + if hasattr(package.__loader__, 'get_data'): + file_contents = package.__loader__.get_data(filename) + # get_data() opens files as 'rb', so one must do the equivalent + # conversion as universal newlines would do. + return file_contents.replace(os.linesep, '\n'), filename + with open(filename) as f: + return f.read(), filename + +# Use sys.stdout encoding for ouput. +_encoding = getattr(sys.__stdout__, 'encoding', None) or 'utf-8' + +def _indent(s, indent=4): + """ + Add the given number of space characters to the beginning of + every non-blank line in `s`, and return the result. + If the string `s` is Unicode, it is encoded using the stdout + encoding and the `backslashreplace` error handler. + """ + if isinstance(s, unicode): + s = s.encode(_encoding, 'backslashreplace') + # This regexp matches the start of non-blank lines: + return re.sub('(?m)^(?!$)', indent*' ', s) + +def _exception_traceback(exc_info): + """ + Return a string containing a traceback message for the given + exc_info tuple (as returned by sys.exc_info()). + """ + # Get a traceback message. + excout = StringIO() + exc_type, exc_val, exc_tb = exc_info + traceback.print_exception(exc_type, exc_val, exc_tb, file=excout) + return excout.getvalue() + +# Override some StringIO methods. +class _SpoofOut(StringIO): + def getvalue(self): + result = StringIO.getvalue(self) + # If anything at all was written, make sure there's a trailing + # newline. There's no way for the expected output to indicate + # that a trailing newline is missing. + if result and not result.endswith("\n"): + result += "\n" + # Prevent softspace from screwing up the next test case, in + # case they used print with a trailing comma in an example. + if hasattr(self, "softspace"): + del self.softspace + return result + + def truncate(self, size=None): + StringIO.truncate(self, size) + if hasattr(self, "softspace"): + del self.softspace + if not self.buf: + # Reset it to an empty string, to make sure it's not unicode. + self.buf = '' + +# Worst-case linear-time ellipsis matching. +def _ellipsis_match(want, got): + """ + Essentially the only subtle case: + >>> _ellipsis_match('aa...aa', 'aaa') + False + """ + if ELLIPSIS_MARKER not in want: + return want == got + + # Find "the real" strings. + ws = want.split(ELLIPSIS_MARKER) + assert len(ws) >= 2 + + # Deal with exact matches possibly needed at one or both ends. + startpos, endpos = 0, len(got) + w = ws[0] + if w: # starts with exact match + if got.startswith(w): + startpos = len(w) + del ws[0] + else: + return False + w = ws[-1] + if w: # ends with exact match + if got.endswith(w): + endpos -= len(w) + del ws[-1] + else: + return False + + if startpos > endpos: + # Exact end matches required more characters than we have, as in + # _ellipsis_match('aa...aa', 'aaa') + return False + + # For the rest, we only need to find the leftmost non-overlapping + # match for each piece. If there's no overall match that way alone, + # there's no overall match period. + for w in ws: + # w may be '' at times, if there are consecutive ellipses, or + # due to an ellipsis at the start or end of `want`. That's OK. + # Search for an empty string succeeds, and doesn't change startpos. + startpos = got.find(w, startpos, endpos) + if startpos < 0: + return False + startpos += len(w) + + return True + +def _comment_line(line): + "Return a commented form of the given line" + line = line.rstrip() + if line: + return '# '+line + else: + return '#' + +class _OutputRedirectingPdb(pdb.Pdb): + """ + A specialized version of the python debugger that redirects stdout + to a given stream when interacting with the user. Stdout is *not* + redirected when traced code is executed. + """ + def __init__(self, out): + self.__out = out + self.__debugger_used = False + pdb.Pdb.__init__(self, stdout=out) + # still use input() to get user input + self.use_rawinput = 1 + + def set_trace(self, frame=None): + self.__debugger_used = True + if frame is None: + frame = sys._getframe().f_back + pdb.Pdb.set_trace(self, frame) + + def set_continue(self): + # Calling set_continue unconditionally would break unit test + # coverage reporting, as Bdb.set_continue calls sys.settrace(None). + if self.__debugger_used: + pdb.Pdb.set_continue(self) + + def trace_dispatch(self, *args): + # Redirect stdout to the given stream. + save_stdout = sys.stdout + sys.stdout = self.__out + # Call Pdb's trace dispatch method. + try: + return pdb.Pdb.trace_dispatch(self, *args) + finally: + sys.stdout = save_stdout + +# [XX] Normalize with respect to os.path.pardir? +def _module_relative_path(module, path): + if not inspect.ismodule(module): + raise TypeError, 'Expected a module: %r' % module + if path.startswith('/'): + raise ValueError, 'Module-relative files may not have absolute paths' + + # Find the base directory for the path. + if hasattr(module, '__file__'): + # A normal module/package + basedir = os.path.split(module.__file__)[0] + elif module.__name__ == '__main__': + # An interactive session. + if len(sys.argv)>0 and sys.argv[0] != '': + basedir = os.path.split(sys.argv[0])[0] + else: + basedir = os.curdir + else: + # A module w/o __file__ (this includes builtins) + raise ValueError("Can't resolve paths relative to the module " + + module + " (it has no __file__)") + + # Combine the base directory and the path. + return os.path.join(basedir, *(path.split('/'))) + +###################################################################### +## 2. Example & DocTest +###################################################################### +## - An "example" is a <source, want> pair, where "source" is a +## fragment of source code, and "want" is the expected output for +## "source." The Example class also includes information about +## where the example was extracted from. +## +## - A "doctest" is a collection of examples, typically extracted from +## a string (such as an object's docstring). The DocTest class also +## includes information about where the string was extracted from. + +class Example: + """ + A single doctest example, consisting of source code and expected + output. `Example` defines the following attributes: + + - source: A single Python statement, always ending with a newline. + The constructor adds a newline if needed. + + - want: The expected output from running the source code (either + from stdout, or a traceback in case of exception). `want` ends + with a newline unless it's empty, in which case it's an empty + string. The constructor adds a newline if needed. + + - exc_msg: The exception message generated by the example, if + the example is expected to generate an exception; or `None` if + it is not expected to generate an exception. This exception + message is compared against the return value of + `traceback.format_exception_only()`. `exc_msg` ends with a + newline unless it's `None`. The constructor adds a newline + if needed. + + - lineno: The line number within the DocTest string containing + this Example where the Example begins. This line number is + zero-based, with respect to the beginning of the DocTest. + + - indent: The example's indentation in the DocTest string. + I.e., the number of space characters that preceed the + example's first prompt. + + - options: A dictionary mapping from option flags to True or + False, which is used to override default options for this + example. Any option flags not contained in this dictionary + are left at their default value (as specified by the + DocTestRunner's optionflags). By default, no options are set. + """ + def __init__(self, source, want, exc_msg=None, lineno=0, indent=0, + options=None): + # Normalize inputs. + if not source.endswith('\n'): + source += '\n' + if want and not want.endswith('\n'): + want += '\n' + if exc_msg is not None and not exc_msg.endswith('\n'): + exc_msg += '\n' + # Store properties. + self.source = source + self.want = want + self.lineno = lineno + self.indent = indent + if options is None: options = {} + self.options = options + self.exc_msg = exc_msg + + def __eq__(self, other): + if type(self) is not type(other): + return NotImplemented + + return self.source == other.source and \ + self.want == other.want and \ + self.lineno == other.lineno and \ + self.indent == other.indent and \ + self.options == other.options and \ + self.exc_msg == other.exc_msg + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.source, self.want, self.lineno, self.indent, + self.exc_msg)) + + +class DocTest: + """ + A collection of doctest examples that should be run in a single + namespace. Each `DocTest` defines the following attributes: + + - examples: the list of examples. + + - globs: The namespace (aka globals) that the examples should + be run in. + + - name: A name identifying the DocTest (typically, the name of + the object whose docstring this DocTest was extracted from). + + - filename: The name of the file that this DocTest was extracted + from, or `None` if the filename is unknown. + + - lineno: The line number within filename where this DocTest + begins, or `None` if the line number is unavailable. This + line number is zero-based, with respect to the beginning of + the file. + + - docstring: The string that the examples were extracted from, + or `None` if the string is unavailable. + """ + def __init__(self, examples, globs, name, filename, lineno, docstring): + """ + Create a new DocTest containing the given examples. The + DocTest's globals are initialized with a copy of `globs`. + """ + assert not isinstance(examples, basestring), \ + "DocTest no longer accepts str; use DocTestParser instead" + self.examples = examples + self.docstring = docstring + self.globs = globs.copy() + self.name = name + self.filename = filename + self.lineno = lineno + + def __repr__(self): + if len(self.examples) == 0: + examples = 'no examples' + elif len(self.examples) == 1: + examples = '1 example' + else: + examples = '%d examples' % len(self.examples) + return ('<DocTest %s from %s:%s (%s)>' % + (self.name, self.filename, self.lineno, examples)) + + def __eq__(self, other): + if type(self) is not type(other): + return NotImplemented + + return self.examples == other.examples and \ + self.docstring == other.docstring and \ + self.globs == other.globs and \ + self.name == other.name and \ + self.filename == other.filename and \ + self.lineno == other.lineno + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self.docstring, self.name, self.filename, self.lineno)) + + # This lets us sort tests by name: + def __cmp__(self, other): + if not isinstance(other, DocTest): + return -1 + return cmp((self.name, self.filename, self.lineno, id(self)), + (other.name, other.filename, other.lineno, id(other))) + +###################################################################### +## 3. DocTestParser +###################################################################### + +class DocTestParser: + """ + A class used to parse strings containing doctest examples. + """ + # This regular expression is used to find doctest examples in a + # string. It defines three groups: `source` is the source code + # (including leading indentation and prompts); `indent` is the + # indentation of the first (PS1) line of the source code; and + # `want` is the expected output (including leading indentation). + _EXAMPLE_RE = re.compile(r''' + # Source consists of a PS1 line followed by zero or more PS2 lines. + (?P<source> + (?:^(?P<indent> [ ]*) >>> .*) # PS1 line + (?:\n [ ]* \.\.\. .*)*) # PS2 lines + \n? + # Want consists of any non-blank lines that do not start with PS1. + (?P<want> (?:(?![ ]*$) # Not a blank line + (?![ ]*>>>) # Not a line starting with PS1 + .*$\n? # But any other line + )*) + ''', re.MULTILINE | re.VERBOSE) + + # A regular expression for handling `want` strings that contain + # expected exceptions. It divides `want` into three pieces: + # - the traceback header line (`hdr`) + # - the traceback stack (`stack`) + # - the exception message (`msg`), as generated by + # traceback.format_exception_only() + # `msg` may have multiple lines. We assume/require that the + # exception message is the first non-indented line starting with a word + # character following the traceback header line. + _EXCEPTION_RE = re.compile(r""" + # Grab the traceback header. Different versions of Python have + # said different things on the first traceback line. + ^(?P<hdr> Traceback\ \( + (?: most\ recent\ call\ last + | innermost\ last + ) \) : + ) + \s* $ # toss trailing whitespace on the header. + (?P<stack> .*?) # don't blink: absorb stuff until... + ^ (?P<msg> \w+ .*) # a line *starts* with alphanum. + """, re.VERBOSE | re.MULTILINE | re.DOTALL) + + # A callable returning a true value iff its argument is a blank line + # or contains a single comment. + _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match + + def parse(self, string, name='<string>'): + """ + Divide the given string into examples and intervening text, + and return them as a list of alternating Examples and strings. + Line numbers for the Examples are 0-based. The optional + argument `name` is a name identifying this string, and is only + used for error messages. + """ + string = string.expandtabs() + # If all lines begin with the same indentation, then strip it. + min_indent = self._min_indent(string) + if min_indent > 0: + string = '\n'.join([l[min_indent:] for l in string.split('\n')]) + + output = [] + charno, lineno = 0, 0 + # Find all doctest examples in the string: + for m in self._EXAMPLE_RE.finditer(string): + # Add the pre-example text to `output`. + output.append(string[charno:m.start()]) + # Update lineno (lines before this example) + lineno += string.count('\n', charno, m.start()) + # Extract info from the regexp match. + (source, options, want, exc_msg) = \ + self._parse_example(m, name, lineno) + # Create an Example, and add it to the list. + if not self._IS_BLANK_OR_COMMENT(source): + output.append( Example(source, want, exc_msg, + lineno=lineno, + indent=min_indent+len(m.group('indent')), + options=options) ) + # Update lineno (lines inside this example) + lineno += string.count('\n', m.start(), m.end()) + # Update charno. + charno = m.end() + # Add any remaining post-example text to `output`. + output.append(string[charno:]) + return output + + def get_doctest(self, string, globs, name, filename, lineno): + """ + Extract all doctest examples from the given string, and + collect them into a `DocTest` object. + + `globs`, `name`, `filename`, and `lineno` are attributes for + the new `DocTest` object. See the documentation for `DocTest` + for more information. + """ + return DocTest(self.get_examples(string, name), globs, + name, filename, lineno, string) + + def get_examples(self, string, name='<string>'): + """ + Extract all doctest examples from the given string, and return + them as a list of `Example` objects. Line numbers are + 0-based, because it's most common in doctests that nothing + interesting appears on the same line as opening triple-quote, + and so the first interesting line is called \"line 1\" then. + + The optional argument `name` is a name identifying this + string, and is only used for error messages. + """ + return [x for x in self.parse(string, name) + if isinstance(x, Example)] + + def _parse_example(self, m, name, lineno): + """ + Given a regular expression match from `_EXAMPLE_RE` (`m`), + return a pair `(source, want)`, where `source` is the matched + example's source code (with prompts and indentation stripped); + and `want` is the example's expected output (with indentation + stripped). + + `name` is the string's name, and `lineno` is the line number + where the example starts; both are used for error messages. + """ + # Get the example's indentation level. + indent = len(m.group('indent')) + + # Divide source into lines; check that they're properly + # indented; and then strip their indentation & prompts. + source_lines = m.group('source').split('\n') + self._check_prompt_blank(source_lines, indent, name, lineno) + self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno) + source = '\n'.join([sl[indent+4:] for sl in source_lines]) + + # Divide want into lines; check that it's properly indented; and + # then strip the indentation. Spaces before the last newline should + # be preserved, so plain rstrip() isn't good enough. + want = m.group('want') + want_lines = want.split('\n') + if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]): + del want_lines[-1] # forget final newline & spaces after it + self._check_prefix(want_lines, ' '*indent, name, + lineno + len(source_lines)) + want = '\n'.join([wl[indent:] for wl in want_lines]) + + # If `want` contains a traceback message, then extract it. + m = self._EXCEPTION_RE.match(want) + if m: + exc_msg = m.group('msg') + else: + exc_msg = None + + # Extract options from the source. + options = self._find_options(source, name, lineno) + + return source, options, want, exc_msg + + # This regular expression looks for option directives in the + # source code of an example. Option directives are comments + # starting with "doctest:". Warning: this may give false + # positives for string-literals that contain the string + # "#doctest:". Eliminating these false positives would require + # actually parsing the string; but we limit them by ignoring any + # line containing "#doctest:" that is *followed* by a quote mark. + _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$', + re.MULTILINE) + + def _find_options(self, source, name, lineno): + """ + Return a dictionary containing option overrides extracted from + option directives in the given source string. + + `name` is the string's name, and `lineno` is the line number + where the example starts; both are used for error messages. + """ + options = {} + # (note: with the current regexp, this will match at most once:) + for m in self._OPTION_DIRECTIVE_RE.finditer(source): + option_strings = m.group(1).replace(',', ' ').split() + for option in option_strings: + if (option[0] not in '+-' or + option[1:] not in OPTIONFLAGS_BY_NAME): + raise ValueError('line %r of the doctest for %s ' + 'has an invalid option: %r' % + (lineno+1, name, option)) + flag = OPTIONFLAGS_BY_NAME[option[1:]] + options[flag] = (option[0] == '+') + if options and self._IS_BLANK_OR_COMMENT(source): + raise ValueError('line %r of the doctest for %s has an option ' + 'directive on a line with no example: %r' % + (lineno, name, source)) + return options + + # This regular expression finds the indentation of every non-blank + # line in a string. + _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE) + + def _min_indent(self, s): + "Return the minimum indentation of any non-blank line in `s`" + indents = [len(indent) for indent in self._INDENT_RE.findall(s)] + if len(indents) > 0: + return min(indents) + else: + return 0 + + def _check_prompt_blank(self, lines, indent, name, lineno): + """ + Given the lines of a source string (including prompts and + leading indentation), check to make sure that every prompt is + followed by a space character. If any line is not followed by + a space character, then raise ValueError. + """ + for i, line in enumerate(lines): + if len(line) >= indent+4 and line[indent+3] != ' ': + raise ValueError('line %r of the docstring for %s ' + 'lacks blank after %s: %r' % + (lineno+i+1, name, + line[indent:indent+3], line)) + + def _check_prefix(self, lines, prefix, name, lineno): + """ + Check that every line in the given list starts with the given + prefix; if any line does not, then raise a ValueError. + """ + for i, line in enumerate(lines): + if line and not line.startswith(prefix): + raise ValueError('line %r of the docstring for %s has ' + 'inconsistent leading whitespace: %r' % + (lineno+i+1, name, line)) + + +###################################################################### +## 4. DocTest Finder +###################################################################### + +class DocTestFinder: + """ + A class used to extract the DocTests that are relevant to a given + object, from its docstring and the docstrings of its contained + objects. Doctests can currently be extracted from the following + object types: modules, functions, classes, methods, staticmethods, + classmethods, and properties. + """ + + def __init__(self, verbose=False, parser=DocTestParser(), + recurse=True, exclude_empty=True): + """ + Create a new doctest finder. + + The optional argument `parser` specifies a class or + function that should be used to create new DocTest objects (or + objects that implement the same interface as DocTest). The + signature for this factory function should match the signature + of the DocTest constructor. + + If the optional argument `recurse` is false, then `find` will + only examine the given object, and not any contained objects. + + If the optional argument `exclude_empty` is false, then `find` + will include tests for objects with empty docstrings. + """ + self._parser = parser + self._verbose = verbose + self._recurse = recurse + self._exclude_empty = exclude_empty + + def find(self, obj, name=None, module=None, globs=None, extraglobs=None): + """ + Return a list of the DocTests that are defined by the given + object's docstring, or by any of its contained objects' + docstrings. + + The optional parameter `module` is the module that contains + the given object. If the module is not specified or is None, then + the test finder will attempt to automatically determine the + correct module. The object's module is used: + + - As a default namespace, if `globs` is not specified. + - To prevent the DocTestFinder from extracting DocTests + from objects that are imported from other modules. + - To find the name of the file containing the object. + - To help find the line number of the object within its + file. + + Contained objects whose module does not match `module` are ignored. + + If `module` is False, no attempt to find the module will be made. + This is obscure, of use mostly in tests: if `module` is False, or + is None but cannot be found automatically, then all objects are + considered to belong to the (non-existent) module, so all contained + objects will (recursively) be searched for doctests. + + The globals for each DocTest is formed by combining `globs` + and `extraglobs` (bindings in `extraglobs` override bindings + in `globs`). A new copy of the globals dictionary is created + for each DocTest. If `globs` is not specified, then it + defaults to the module's `__dict__`, if specified, or {} + otherwise. If `extraglobs` is not specified, then it defaults + to {}. + + """ + # If name was not specified, then extract it from the object. + if name is None: + name = getattr(obj, '__name__', None) + if name is None: + raise ValueError("DocTestFinder.find: name must be given " + "when obj.__name__ doesn't exist: %r" % + (type(obj),)) + + # Find the module that contains the given object (if obj is + # a module, then module=obj.). Note: this may fail, in which + # case module will be None. + if module is False: + module = None + elif module is None: + module = inspect.getmodule(obj) + + # Read the module's source code. This is used by + # DocTestFinder._find_lineno to find the line number for a + # given object's docstring. + try: + file = inspect.getsourcefile(obj) or inspect.getfile(obj) + if module is not None: + # Supply the module globals in case the module was + # originally loaded via a PEP 302 loader and + # file is not a valid filesystem path + source_lines = linecache.getlines(file, module.__dict__) + else: + # No access to a loader, so assume it's a normal + # filesystem path + source_lines = linecache.getlines(file) + if not source_lines: + source_lines = None + except TypeError: + source_lines = None + + # Initialize globals, and merge in extraglobs. + if globs is None: + if module is None: + globs = {} + else: + globs = module.__dict__.copy() + else: + globs = globs.copy() + if extraglobs is not None: + globs.update(extraglobs) + if '__name__' not in globs: + globs['__name__'] = '__main__' # provide a default module name + + # Recursively expore `obj`, extracting DocTests. + tests = [] + self._find(tests, obj, name, module, source_lines, globs, {}) + # Sort the tests by alpha order of names, for consistency in + # verbose-mode output. This was a feature of doctest in Pythons + # <= 2.3 that got lost by accident in 2.4. It was repaired in + # 2.4.4 and 2.5. + tests.sort() + return tests + + def _from_module(self, module, object): + """ + Return true if the given object is defined in the given + module. + """ + if module is None: + return True + elif inspect.getmodule(object) is not None: + return module is inspect.getmodule(object) + elif inspect.isfunction(object): + return module.__dict__ is object.func_globals + elif inspect.isclass(object): + return module.__name__ == object.__module__ + elif hasattr(object, '__module__'): + return module.__name__ == object.__module__ + elif isinstance(object, property): + return True # [XX] no way not be sure. + else: + raise ValueError("object must be a class or function") + + def _find(self, tests, obj, name, module, source_lines, globs, seen): + """ + Find tests for the given object and any contained objects, and + add them to `tests`. + """ + if self._verbose: + print 'Finding tests in %s' % name + + # If we've already processed this object, then ignore it. + if id(obj) in seen: + return + seen[id(obj)] = 1 + + # Find a test for this object, and add it to the list of tests. + test = self._get_test(obj, name, module, globs, source_lines) + if test is not None: + tests.append(test) + + # Look for tests in a module's contained objects. + if inspect.ismodule(obj) and self._recurse: + for valname, val in obj.__dict__.items(): + valname = '%s.%s' % (name, valname) + # Recurse to functions & classes. + if ((inspect.isfunction(val) or inspect.isclass(val)) and + self._from_module(module, val)): + self._find(tests, val, valname, module, source_lines, + globs, seen) + + # Look for tests in a module's __test__ dictionary. + if inspect.ismodule(obj) and self._recurse: + for valname, val in getattr(obj, '__test__', {}).items(): + if not isinstance(valname, basestring): + raise ValueError("DocTestFinder.find: __test__ keys " + "must be strings: %r" % + (type(valname),)) + if not (inspect.isfunction(val) or inspect.isclass(val) or + inspect.ismethod(val) or inspect.ismodule(val) or + isinstance(val, basestring)): + raise ValueError("DocTestFinder.find: __test__ values " + "must be strings, functions, methods, " + "classes, or modules: %r" % + (type(val),)) + valname = '%s.__test__.%s' % (name, valname) + self._find(tests, val, valname, module, source_lines, + globs, seen) + + # Look for tests in a class's contained objects. + if inspect.isclass(obj) and self._recurse: + for valname, val in obj.__dict__.items(): + # Special handling for staticmethod/classmethod. + if isinstance(val, staticmethod): + val = getattr(obj, valname) + if isinstance(val, classmethod): + val = getattr(obj, valname).im_func + + # Recurse to methods, properties, and nested classes. + if ((inspect.isfunction(val) or inspect.isclass(val) or + isinstance(val, property)) and + self._from_module(module, val)): + valname = '%s.%s' % (name, valname) + self._find(tests, val, valname, module, source_lines, + globs, seen) + + def _get_test(self, obj, name, module, globs, source_lines): + """ + Return a DocTest for the given object, if it defines a docstring; + otherwise, return None. + """ + # Extract the object's docstring. If it doesn't have one, + # then return None (no test for this object). + if isinstance(obj, basestring): + docstring = obj + else: + try: + if obj.__doc__ is None: + docstring = '' + else: + docstring = obj.__doc__ + if not isinstance(docstring, basestring): + docstring = str(docstring) + except (TypeError, AttributeError): + docstring = '' + + # Find the docstring's location in the file. + lineno = self._find_lineno(obj, source_lines) + + # Don't bother if the docstring is empty. + if self._exclude_empty and not docstring: + return None + + # Return a DocTest for this object. + if module is None: + filename = None + else: + filename = getattr(module, '__file__', module.__name__) + if filename[-4:] in (".pyc", ".pyo"): + filename = filename[:-1] + elif filename.endswith('$py.class'): + filename = '%s.py' % filename[:-9] + return self._parser.get_doctest(docstring, globs, name, + filename, lineno) + + def _find_lineno(self, obj, source_lines): + """ + Return a line number of the given object's docstring. Note: + this method assumes that the object has a docstring. + """ + lineno = None + + # Find the line number for modules. + if inspect.ismodule(obj): + lineno = 0 + + # Find the line number for classes. + # Note: this could be fooled if a class is defined multiple + # times in a single file. + if inspect.isclass(obj): + if source_lines is None: + return None + pat = re.compile(r'^\s*class\s*%s\b' % + getattr(obj, '__name__', '-')) + for i, line in enumerate(source_lines): + if pat.match(line): + lineno = i + break + + # Find the line number for functions & methods. + if inspect.ismethod(obj): obj = obj.im_func + if inspect.isfunction(obj): obj = obj.func_code + if inspect.istraceback(obj): obj = obj.tb_frame + if inspect.isframe(obj): obj = obj.f_code + if inspect.iscode(obj): + lineno = getattr(obj, 'co_firstlineno', None)-1 + + # Find the line number where the docstring starts. Assume + # that it's the first line that begins with a quote mark. + # Note: this could be fooled by a multiline function + # signature, where a continuation line begins with a quote + # mark. + if lineno is not None: + if source_lines is None: + return lineno+1 + pat = re.compile('(^|.*:)\s*\w*("|\')') + for lineno in range(lineno, len(source_lines)): + if pat.match(source_lines[lineno]): + return lineno + + # We couldn't find the line number. + return None + +###################################################################### +## 5. DocTest Runner +###################################################################### + +class DocTestRunner: + """ + A class used to run DocTest test cases, and accumulate statistics. + The `run` method is used to process a single DocTest case. It + returns a tuple `(f, t)`, where `t` is the number of test cases + tried, and `f` is the number of test cases that failed. + + >>> tests = DocTestFinder().find(_TestClass) + >>> runner = DocTestRunner(verbose=False) + >>> tests.sort(key = lambda test: test.name) + >>> for test in tests: + ... print test.name, '->', runner.run(test) + _TestClass -> TestResults(failed=0, attempted=2) + _TestClass.__init__ -> TestResults(failed=0, attempted=2) + _TestClass.get -> TestResults(failed=0, attempted=2) + _TestClass.square -> TestResults(failed=0, attempted=1) + + The `summarize` method prints a summary of all the test cases that + have been run by the runner, and returns an aggregated `(f, t)` + tuple: + + >>> runner.summarize(verbose=1) + 4 items passed all tests: + 2 tests in _TestClass + 2 tests in _TestClass.__init__ + 2 tests in _TestClass.get + 1 tests in _TestClass.square + 7 tests in 4 items. + 7 passed and 0 failed. + Test passed. + TestResults(failed=0, attempted=7) + + The aggregated number of tried examples and failed examples is + also available via the `tries` and `failures` attributes: + + >>> runner.tries + 7 + >>> runner.failures + 0 + + The comparison between expected outputs and actual outputs is done + by an `OutputChecker`. This comparison may be customized with a + number of option flags; see the documentation for `testmod` for + more information. If the option flags are insufficient, then the + comparison may also be customized by passing a subclass of + `OutputChecker` to the constructor. + + The test runner's display output can be controlled in two ways. + First, an output function (`out) can be passed to + `TestRunner.run`; this function will be called with strings that + should be displayed. It defaults to `sys.stdout.write`. If + capturing the output is not sufficient, then the display output + can be also customized by subclassing DocTestRunner, and + overriding the methods `report_start`, `report_success`, + `report_unexpected_exception`, and `report_failure`. + """ + # This divider string is used to separate failure messages, and to + # separate sections of the summary. + DIVIDER = "*" * 70 + + def __init__(self, checker=None, verbose=None, optionflags=0): + """ + Create a new test runner. + + Optional keyword arg `checker` is the `OutputChecker` that + should be used to compare the expected outputs and actual + outputs of doctest examples. + + Optional keyword arg 'verbose' prints lots of stuff if true, + only failures if false; by default, it's true iff '-v' is in + sys.argv. + + Optional argument `optionflags` can be used to control how the + test runner compares expected output to actual output, and how + it displays failures. See the documentation for `testmod` for + more information. + """ + self._checker = checker or OutputChecker() + if verbose is None: + verbose = '-v' in sys.argv + self._verbose = verbose + self.optionflags = optionflags + self.original_optionflags = optionflags + + # Keep track of the examples we've run. + self.tries = 0 + self.failures = 0 + self._name2ft = {} + + # Create a fake output target for capturing doctest output. + self._fakeout = _SpoofOut() + + #///////////////////////////////////////////////////////////////// + # Reporting methods + #///////////////////////////////////////////////////////////////// + + def report_start(self, out, test, example): + """ + Report that the test runner is about to process the given + example. (Only displays a message if verbose=True) + """ + if self._verbose: + if example.want: + out('Trying:\n' + _indent(example.source) + + 'Expecting:\n' + _indent(example.want)) + else: + out('Trying:\n' + _indent(example.source) + + 'Expecting nothing\n') + + def report_success(self, out, test, example, got): + """ + Report that the given example ran successfully. (Only + displays a message if verbose=True) + """ + if self._verbose: + out("ok\n") + + def report_failure(self, out, test, example, got): + """ + Report that the given example failed. + """ + out(self._failure_header(test, example) + + self._checker.output_difference(example, got, self.optionflags)) + + def report_unexpected_exception(self, out, test, example, exc_info): + """ + Report that the given example raised an unexpected exception. + """ + out(self._failure_header(test, example) + + 'Exception raised:\n' + _indent(_exception_traceback(exc_info))) + + def _failure_header(self, test, example): + out = [self.DIVIDER] + if test.filename: + if test.lineno is not None and example.lineno is not None: + lineno = test.lineno + example.lineno + 1 + else: + lineno = '?' + out.append('File "%s", line %s, in %s' % + (test.filename, lineno, test.name)) + else: + out.append('Line %s, in %s' % (example.lineno+1, test.name)) + out.append('Failed example:') + source = example.source + out.append(_indent(source)) + return '\n'.join(out) + + #///////////////////////////////////////////////////////////////// + # DocTest Running + #///////////////////////////////////////////////////////////////// + + def __run(self, test, compileflags, out): + """ + Run the examples in `test`. Write the outcome of each example + with one of the `DocTestRunner.report_*` methods, using the + writer function `out`. `compileflags` is the set of compiler + flags that should be used to execute examples. Return a tuple + `(f, t)`, where `t` is the number of examples tried, and `f` + is the number of examples that failed. The examples are run + in the namespace `test.globs`. + """ + # Keep track of the number of failures and tries. + failures = tries = 0 + + # Save the option flags (since option directives can be used + # to modify them). + original_optionflags = self.optionflags + + SUCCESS, FAILURE, BOOM = range(3) # `outcome` state + + check = self._checker.check_output + + # Process each example. + for examplenum, example in enumerate(test.examples): + + # If REPORT_ONLY_FIRST_FAILURE is set, then suppress + # reporting after the first failure. + quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and + failures > 0) + + # Merge in the example's options. + self.optionflags = original_optionflags + if example.options: + for (optionflag, val) in example.options.items(): + if val: + self.optionflags |= optionflag + else: + self.optionflags &= ~optionflag + + # If 'SKIP' is set, then skip this example. + if self.optionflags & SKIP: + continue + + # Record that we started this example. + tries += 1 + if not quiet: + self.report_start(out, test, example) + + # Use a special filename for compile(), so we can retrieve + # the source code during interactive debugging (see + # __patched_linecache_getlines). + filename = '<doctest %s[%d]>' % (test.name, examplenum) + + # Run the example in the given context (globs), and record + # any exception that gets raised. (But don't intercept + # keyboard interrupts.) + try: + # Don't blink! This is where the user's code gets run. + exec compile(example.source, filename, "single", + compileflags, 1) in test.globs + self.debugger.set_continue() # ==== Example Finished ==== + exception = None + except KeyboardInterrupt: + raise + except: + exception = sys.exc_info() + self.debugger.set_continue() # ==== Example Finished ==== + + got = self._fakeout.getvalue() # the actual output + self._fakeout.truncate(0) + outcome = FAILURE # guilty until proved innocent or insane + + # If the example executed without raising any exceptions, + # verify its output. + if exception is None: + if check(example.want, got, self.optionflags): + outcome = SUCCESS + + # The example raised an exception: check if it was expected. + else: + exc_info = sys.exc_info() + exc_msg = traceback.format_exception_only(*exc_info[:2])[-1] + if not quiet: + got += _exception_traceback(exc_info) + + # If `example.exc_msg` is None, then we weren't expecting + # an exception. + if example.exc_msg is None: + outcome = BOOM + + # We expected an exception: see whether it matches. + elif check(example.exc_msg, exc_msg, self.optionflags): + outcome = SUCCESS + + # Another chance if they didn't care about the detail. + elif self.optionflags & IGNORE_EXCEPTION_DETAIL: + m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg) + m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg) + if m1 and m2 and check(m1.group(1), m2.group(1), + self.optionflags): + outcome = SUCCESS + + # Report the outcome. + if outcome is SUCCESS: + if not quiet: + self.report_success(out, test, example, got) + elif outcome is FAILURE: + if not quiet: + self.report_failure(out, test, example, got) + failures += 1 + elif outcome is BOOM: + if not quiet: + self.report_unexpected_exception(out, test, example, + exc_info) + failures += 1 + else: + assert False, ("unknown outcome", outcome) + + # Restore the option flags (in case they were modified) + self.optionflags = original_optionflags + + # Record and return the number of failures and tries. + self.__record_outcome(test, failures, tries) + return TestResults(failures, tries) + + def __record_outcome(self, test, f, t): + """ + Record the fact that the given DocTest (`test`) generated `f` + failures out of `t` tried examples. + """ + f2, t2 = self._name2ft.get(test.name, (0,0)) + self._name2ft[test.name] = (f+f2, t+t2) + self.failures += f + self.tries += t + + __LINECACHE_FILENAME_RE = re.compile(r'<doctest ' + r'(?P<name>.+)' + r'\[(?P<examplenum>\d+)\]>$') + def __patched_linecache_getlines(self, filename, module_globals=None): + m = self.__LINECACHE_FILENAME_RE.match(filename) + if m and m.group('name') == self.test.name: + example = self.test.examples[int(m.group('examplenum'))] + source = example.source + if isinstance(source, unicode): + source = source.encode('ascii', 'backslashreplace') + return source.splitlines(True) + else: + return self.save_linecache_getlines(filename, module_globals) + + def run(self, test, compileflags=None, out=None, clear_globs=True): + """ + Run the examples in `test`, and display the results using the + writer function `out`. + + The examples are run in the namespace `test.globs`. If + `clear_globs` is true (the default), then this namespace will + be cleared after the test runs, to help with garbage + collection. If you would like to examine the namespace after + the test completes, then use `clear_globs=False`. + + `compileflags` gives the set of flags that should be used by + the Python compiler when running the examples. If not + specified, then it will default to the set of future-import + flags that apply to `globs`. + + The output of each example is checked using + `DocTestRunner.check_output`, and the results are formatted by + the `DocTestRunner.report_*` methods. + """ + self.test = test + + if compileflags is None: + compileflags = _extract_future_flags(test.globs) + + save_stdout = sys.stdout + if out is None: + out = save_stdout.write + sys.stdout = self._fakeout + + # Patch pdb.set_trace to restore sys.stdout during interactive + # debugging (so it's not still redirected to self._fakeout). + # Note that the interactive output will go to *our* + # save_stdout, even if that's not the real sys.stdout; this + # allows us to write test cases for the set_trace behavior. + save_set_trace = pdb.set_trace + self.debugger = _OutputRedirectingPdb(save_stdout) + self.debugger.reset() + pdb.set_trace = self.debugger.set_trace + + # Patch linecache.getlines, so we can see the example's source + # when we're inside the debugger. + self.save_linecache_getlines = linecache.getlines + linecache.getlines = self.__patched_linecache_getlines + + # Make sure sys.displayhook just prints the value to stdout + save_displayhook = sys.displayhook + sys.displayhook = sys.__displayhook__ + + try: + return self.__run(test, compileflags, out) + finally: + sys.stdout = save_stdout + pdb.set_trace = save_set_trace + linecache.getlines = self.save_linecache_getlines + sys.displayhook = save_displayhook + if clear_globs: + test.globs.clear() + + #///////////////////////////////////////////////////////////////// + # Summarization + #///////////////////////////////////////////////////////////////// + def summarize(self, verbose=None): + """ + Print a summary of all the test cases that have been run by + this DocTestRunner, and return a tuple `(f, t)`, where `f` is + the total number of failed examples, and `t` is the total + number of tried examples. + + The optional `verbose` argument controls how detailed the + summary is. If the verbosity is not specified, then the + DocTestRunner's verbosity is used. + """ + if verbose is None: + verbose = self._verbose + notests = [] + passed = [] + failed = [] + totalt = totalf = 0 + for x in self._name2ft.items(): + name, (f, t) = x + assert f <= t + totalt += t + totalf += f + if t == 0: + notests.append(name) + elif f == 0: + passed.append( (name, t) ) + else: + failed.append(x) + if verbose: + if notests: + print len(notests), "items had no tests:" + notests.sort() + for thing in notests: + print " ", thing + if passed: + print len(passed), "items passed all tests:" + passed.sort() + for thing, count in passed: + print " %3d tests in %s" % (count, thing) + if failed: + print self.DIVIDER + print len(failed), "items had failures:" + failed.sort() + for thing, (f, t) in failed: + print " %3d of %3d in %s" % (f, t, thing) + if verbose: + print totalt, "tests in", len(self._name2ft), "items." + print totalt - totalf, "passed and", totalf, "failed." + if totalf: + print "***Test Failed***", totalf, "failures." + elif verbose: + print "Test passed." + return TestResults(totalf, totalt) + + #///////////////////////////////////////////////////////////////// + # Backward compatibility cruft to maintain doctest.master. + #///////////////////////////////////////////////////////////////// + def merge(self, other): + d = self._name2ft + for name, (f, t) in other._name2ft.items(): + if name in d: + # Don't print here by default, since doing + # so breaks some of the buildbots + #print "*** DocTestRunner.merge: '" + name + "' in both" \ + # " testers; summing outcomes." + f2, t2 = d[name] + f = f + f2 + t = t + t2 + d[name] = f, t + +class OutputChecker: + """ + A class used to check the whether the actual output from a doctest + example matches the expected output. `OutputChecker` defines two + methods: `check_output`, which compares a given pair of outputs, + and returns true if they match; and `output_difference`, which + returns a string describing the differences between two outputs. + """ + def check_output(self, want, got, optionflags): + """ + Return True iff the actual output from an example (`got`) + matches the expected output (`want`). These strings are + always considered to match if they are identical; but + depending on what option flags the test runner is using, + several non-exact match types are also possible. See the + documentation for `TestRunner` for more information about + option flags. + """ + # Handle the common case first, for efficiency: + # if they're string-identical, always return true. + if got == want: + return True + + # The values True and False replaced 1 and 0 as the return + # value for boolean comparisons in Python 2.3. + if not (optionflags & DONT_ACCEPT_TRUE_FOR_1): + if (got,want) == ("True\n", "1\n"): + return True + if (got,want) == ("False\n", "0\n"): + return True + + # <BLANKLINE> can be used as a special sequence to signify a + # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used. + if not (optionflags & DONT_ACCEPT_BLANKLINE): + # Replace <BLANKLINE> in want with a blank line. + want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER), + '', want) + # If a line in got contains only spaces, then remove the + # spaces. + got = re.sub('(?m)^\s*?$', '', got) + if got == want: + return True + + # This flag causes doctest to ignore any differences in the + # contents of whitespace strings. Note that this can be used + # in conjunction with the ELLIPSIS flag. + if optionflags & NORMALIZE_WHITESPACE: + got = ' '.join(got.split()) + want = ' '.join(want.split()) + if got == want: + return True + + # The ELLIPSIS flag says to let the sequence "..." in `want` + # match any substring in `got`. + if optionflags & ELLIPSIS: + if _ellipsis_match(want, got): + return True + + # We didn't find any match; return false. + return False + + # Should we do a fancy diff? + def _do_a_fancy_diff(self, want, got, optionflags): + # Not unless they asked for a fancy diff. + if not optionflags & (REPORT_UDIFF | + REPORT_CDIFF | + REPORT_NDIFF): + return False + + # If expected output uses ellipsis, a meaningful fancy diff is + # too hard ... or maybe not. In two real-life failures Tim saw, + # a diff was a major help anyway, so this is commented out. + # [todo] _ellipsis_match() knows which pieces do and don't match, + # and could be the basis for a kick-ass diff in this case. + ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want: + ## return False + + # ndiff does intraline difference marking, so can be useful even + # for 1-line differences. + if optionflags & REPORT_NDIFF: + return True + + # The other diff types need at least a few lines to be helpful. + return want.count('\n') > 2 and got.count('\n') > 2 + + def output_difference(self, example, got, optionflags): + """ + Return a string describing the differences between the + expected output for a given example (`example`) and the actual + output (`got`). `optionflags` is the set of option flags used + to compare `want` and `got`. + """ + want = example.want + # If <BLANKLINE>s are being used, then replace blank lines + # with <BLANKLINE> in the actual output string. + if not (optionflags & DONT_ACCEPT_BLANKLINE): + got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got) + + # Check if we should use diff. + if self._do_a_fancy_diff(want, got, optionflags): + # Split want & got into lines. + want_lines = want.splitlines(True) # True == keep line ends + got_lines = got.splitlines(True) + # Use difflib to find their differences. + if optionflags & REPORT_UDIFF: + diff = difflib.unified_diff(want_lines, got_lines, n=2) + diff = list(diff)[2:] # strip the diff header + kind = 'unified diff with -expected +actual' + elif optionflags & REPORT_CDIFF: + diff = difflib.context_diff(want_lines, got_lines, n=2) + diff = list(diff)[2:] # strip the diff header + kind = 'context diff with expected followed by actual' + elif optionflags & REPORT_NDIFF: + engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) + diff = list(engine.compare(want_lines, got_lines)) + kind = 'ndiff with -expected +actual' + else: + assert 0, 'Bad diff option' + # Remove trailing whitespace on diff output. + diff = [line.rstrip() + '\n' for line in diff] + return 'Differences (%s):\n' % kind + _indent(''.join(diff)) + + # If we're not using diff, then simply list the expected + # output followed by the actual output. + if want and got: + return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got)) + elif want: + return 'Expected:\n%sGot nothing\n' % _indent(want) + elif got: + return 'Expected nothing\nGot:\n%s' % _indent(got) + else: + return 'Expected nothing\nGot nothing\n' + +class DocTestFailure(Exception): + """A DocTest example has failed in debugging mode. + + The exception instance has variables: + + - test: the DocTest object being run + + - example: the Example object that failed + + - got: the actual output + """ + def __init__(self, test, example, got): + self.test = test + self.example = example + self.got = got + + def __str__(self): + return str(self.test) + +class UnexpectedException(Exception): + """A DocTest example has encountered an unexpected exception + + The exception instance has variables: + + - test: the DocTest object being run + + - example: the Example object that failed + + - exc_info: the exception info + """ + def __init__(self, test, example, exc_info): + self.test = test + self.example = example + self.exc_info = exc_info + + def __str__(self): + return str(self.test) + +class DebugRunner(DocTestRunner): + r"""Run doc tests but raise an exception as soon as there is a failure. + + If an unexpected exception occurs, an UnexpectedException is raised. + It contains the test, the example, and the original exception: + + >>> runner = DebugRunner(verbose=False) + >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', + ... {}, 'foo', 'foo.py', 0) + >>> try: + ... runner.run(test) + ... except UnexpectedException, failure: + ... pass + + >>> failure.test is test + True + + >>> failure.example.want + '42\n' + + >>> exc_info = failure.exc_info + >>> raise exc_info[0], exc_info[1], exc_info[2] + Traceback (most recent call last): + ... + KeyError + + We wrap the original exception to give the calling application + access to the test and example information. + + If the output doesn't match, then a DocTestFailure is raised: + + >>> test = DocTestParser().get_doctest(''' + ... >>> x = 1 + ... >>> x + ... 2 + ... ''', {}, 'foo', 'foo.py', 0) + + >>> try: + ... runner.run(test) + ... except DocTestFailure, failure: + ... pass + + DocTestFailure objects provide access to the test: + + >>> failure.test is test + True + + As well as to the example: + + >>> failure.example.want + '2\n' + + and the actual output: + + >>> failure.got + '1\n' + + If a failure or error occurs, the globals are left intact: + + >>> if '__builtins__' in test.globs: + ... del test.globs['__builtins__'] + >>> test.globs + {'x': 1} + + >>> test = DocTestParser().get_doctest(''' + ... >>> x = 2 + ... >>> raise KeyError + ... ''', {}, 'foo', 'foo.py', 0) + + >>> runner.run(test) + Traceback (most recent call last): + ... + UnexpectedException: <DocTest foo from foo.py:0 (2 examples)> + + >>> if '__builtins__' in test.globs: + ... del test.globs['__builtins__'] + >>> test.globs + {'x': 2} + + But the globals are cleared if there is no error: + + >>> test = DocTestParser().get_doctest(''' + ... >>> x = 2 + ... ''', {}, 'foo', 'foo.py', 0) + + >>> runner.run(test) + TestResults(failed=0, attempted=1) + + >>> test.globs + {} + + """ + + def run(self, test, compileflags=None, out=None, clear_globs=True): + r = DocTestRunner.run(self, test, compileflags, out, False) + if clear_globs: + test.globs.clear() + return r + + def report_unexpected_exception(self, out, test, example, exc_info): + raise UnexpectedException(test, example, exc_info) + + def report_failure(self, out, test, example, got): + raise DocTestFailure(test, example, got) + +###################################################################### +## 6. Test Functions +###################################################################### +# These should be backwards compatible. + +# For backward compatibility, a global instance of a DocTestRunner +# class, updated by testmod. +master = None + +def testmod(m=None, name=None, globs=None, verbose=None, + report=True, optionflags=0, extraglobs=None, + raise_on_error=False, exclude_empty=False): + """m=None, name=None, globs=None, verbose=None, report=True, + optionflags=0, extraglobs=None, raise_on_error=False, + exclude_empty=False + + Test examples in docstrings in functions and classes reachable + from module m (or the current module if m is not supplied), starting + with m.__doc__. + + Also test examples reachable from dict m.__test__ if it exists and is + not None. m.__test__ maps names to functions, classes and strings; + function and class docstrings are tested even if the name is private; + strings are tested directly, as if they were docstrings. + + Return (#failures, #tests). + + See help(doctest) for an overview. + + Optional keyword arg "name" gives the name of the module; by default + use m.__name__. + + Optional keyword arg "globs" gives a dict to be used as the globals + when executing examples; by default, use m.__dict__. A copy of this + dict is actually used for each docstring, so that each docstring's + examples start with a clean slate. + + Optional keyword arg "extraglobs" gives a dictionary that should be + merged into the globals that are used to execute examples. By + default, no extra globals are used. This is new in 2.4. + + Optional keyword arg "verbose" prints lots of stuff if true, prints + only failures if false; by default, it's true iff "-v" is in sys.argv. + + Optional keyword arg "report" prints a summary at the end when true, + else prints nothing at the end. In verbose mode, the summary is + detailed, else very brief (in fact, empty if all tests passed). + + Optional keyword arg "optionflags" or's together module constants, + and defaults to 0. This is new in 2.3. Possible values (see the + docs for details): + + DONT_ACCEPT_TRUE_FOR_1 + DONT_ACCEPT_BLANKLINE + NORMALIZE_WHITESPACE + ELLIPSIS + SKIP + IGNORE_EXCEPTION_DETAIL + REPORT_UDIFF + REPORT_CDIFF + REPORT_NDIFF + REPORT_ONLY_FIRST_FAILURE + + Optional keyword arg "raise_on_error" raises an exception on the + first unexpected exception or failure. This allows failures to be + post-mortem debugged. + + Advanced tomfoolery: testmod runs methods of a local instance of + class doctest.Tester, then merges the results into (or creates) + global Tester instance doctest.master. Methods of doctest.master + can be called directly too, if you want to do something unusual. + Passing report=0 to testmod is especially useful then, to delay + displaying a summary. Invoke doctest.master.summarize(verbose) + when you're done fiddling. + """ + global master + + # If no module was given, then use __main__. + if m is None: + # DWA - m will still be None if this wasn't invoked from the command + # line, in which case the following TypeError is about as good an error + # as we should expect + m = sys.modules.get('__main__') + + # Check that we were actually given a module. + if not inspect.ismodule(m): + raise TypeError("testmod: module required; %r" % (m,)) + + # If no name was given, then use the module's name. + if name is None: + name = m.__name__ + + # Find, parse, and run all tests in the given module. + finder = DocTestFinder(exclude_empty=exclude_empty) + + if raise_on_error: + runner = DebugRunner(verbose=verbose, optionflags=optionflags) + else: + runner = DocTestRunner(verbose=verbose, optionflags=optionflags) + + for test in finder.find(m, name, globs=globs, extraglobs=extraglobs): + runner.run(test) + + if report: + runner.summarize() + + if master is None: + master = runner + else: + master.merge(runner) + + return TestResults(runner.failures, runner.tries) + +def testfile(filename, module_relative=True, name=None, package=None, + globs=None, verbose=None, report=True, optionflags=0, + extraglobs=None, raise_on_error=False, parser=DocTestParser(), + encoding=None): + """ + Test examples in the given file. Return (#failures, #tests). + + Optional keyword arg "module_relative" specifies how filenames + should be interpreted: + + - If "module_relative" is True (the default), then "filename" + specifies a module-relative path. By default, this path is + relative to the calling module's directory; but if the + "package" argument is specified, then it is relative to that + package. To ensure os-independence, "filename" should use + "/" characters to separate path segments, and should not + be an absolute path (i.e., it may not begin with "/"). + + - If "module_relative" is False, then "filename" specifies an + os-specific path. The path may be absolute or relative (to + the current working directory). + + Optional keyword arg "name" gives the name of the test; by default + use the file's basename. + + Optional keyword argument "package" is a Python package or the + name of a Python package whose directory should be used as the + base directory for a module relative filename. If no package is + specified, then the calling module's directory is used as the base + directory for module relative filenames. It is an error to + specify "package" if "module_relative" is False. + + Optional keyword arg "globs" gives a dict to be used as the globals + when executing examples; by default, use {}. A copy of this dict + is actually used for each docstring, so that each docstring's + examples start with a clean slate. + + Optional keyword arg "extraglobs" gives a dictionary that should be + merged into the globals that are used to execute examples. By + default, no extra globals are used. + + Optional keyword arg "verbose" prints lots of stuff if true, prints + only failures if false; by default, it's true iff "-v" is in sys.argv. + + Optional keyword arg "report" prints a summary at the end when true, + else prints nothing at the end. In verbose mode, the summary is + detailed, else very brief (in fact, empty if all tests passed). + + Optional keyword arg "optionflags" or's together module constants, + and defaults to 0. Possible values (see the docs for details): + + DONT_ACCEPT_TRUE_FOR_1 + DONT_ACCEPT_BLANKLINE + NORMALIZE_WHITESPACE + ELLIPSIS + SKIP + IGNORE_EXCEPTION_DETAIL + REPORT_UDIFF + REPORT_CDIFF + REPORT_NDIFF + REPORT_ONLY_FIRST_FAILURE + + Optional keyword arg "raise_on_error" raises an exception on the + first unexpected exception or failure. This allows failures to be + post-mortem debugged. + + Optional keyword arg "parser" specifies a DocTestParser (or + subclass) that should be used to extract tests from the files. + + Optional keyword arg "encoding" specifies an encoding that should + be used to convert the file to unicode. + + Advanced tomfoolery: testmod runs methods of a local instance of + class doctest.Tester, then merges the results into (or creates) + global Tester instance doctest.master. Methods of doctest.master + can be called directly too, if you want to do something unusual. + Passing report=0 to testmod is especially useful then, to delay + displaying a summary. Invoke doctest.master.summarize(verbose) + when you're done fiddling. + """ + global master + + if package and not module_relative: + raise ValueError("Package may only be specified for module-" + "relative paths.") + + # Relativize the path + text, filename = _load_testfile(filename, package, module_relative) + + # If no name was given, then use the file's name. + if name is None: + name = os.path.basename(filename) + + # Assemble the globals. + if globs is None: + globs = {} + else: + globs = globs.copy() + if extraglobs is not None: + globs.update(extraglobs) + if '__name__' not in globs: + globs['__name__'] = '__main__' + + if raise_on_error: + runner = DebugRunner(verbose=verbose, optionflags=optionflags) + else: + runner = DocTestRunner(verbose=verbose, optionflags=optionflags) + + if encoding is not None: + text = text.decode(encoding) + + # Read the file, convert it to a test, and run it. + test = parser.get_doctest(text, globs, name, filename, 0) + runner.run(test) + + if report: + runner.summarize() + + if master is None: + master = runner + else: + master.merge(runner) + + return TestResults(runner.failures, runner.tries) + +def run_docstring_examples(f, globs, verbose=False, name="NoName", + compileflags=None, optionflags=0): + """ + Test examples in the given object's docstring (`f`), using `globs` + as globals. Optional argument `name` is used in failure messages. + If the optional argument `verbose` is true, then generate output + even if there are no failures. + + `compileflags` gives the set of flags that should be used by the + Python compiler when running the examples. If not specified, then + it will default to the set of future-import flags that apply to + `globs`. + + Optional keyword arg `optionflags` specifies options for the + testing and output. See the documentation for `testmod` for more + information. + """ + # Find, parse, and run all tests in the given module. + finder = DocTestFinder(verbose=verbose, recurse=False) + runner = DocTestRunner(verbose=verbose, optionflags=optionflags) + for test in finder.find(f, name, globs=globs): + runner.run(test, compileflags=compileflags) + +###################################################################### +## 7. Tester +###################################################################### +# This is provided only for backwards compatibility. It's not +# actually used in any way. + +class Tester: + def __init__(self, mod=None, globs=None, verbose=None, optionflags=0): + + warnings.warn("class Tester is deprecated; " + "use class doctest.DocTestRunner instead", + DeprecationWarning, stacklevel=2) + if mod is None and globs is None: + raise TypeError("Tester.__init__: must specify mod or globs") + if mod is not None and not inspect.ismodule(mod): + raise TypeError("Tester.__init__: mod must be a module; %r" % + (mod,)) + if globs is None: + globs = mod.__dict__ + self.globs = globs + + self.verbose = verbose + self.optionflags = optionflags + self.testfinder = DocTestFinder() + self.testrunner = DocTestRunner(verbose=verbose, + optionflags=optionflags) + + def runstring(self, s, name): + test = DocTestParser().get_doctest(s, self.globs, name, None, None) + if self.verbose: + print "Running string", name + (f,t) = self.testrunner.run(test) + if self.verbose: + print f, "of", t, "examples failed in string", name + return TestResults(f,t) + + def rundoc(self, object, name=None, module=None): + f = t = 0 + tests = self.testfinder.find(object, name, module=module, + globs=self.globs) + for test in tests: + (f2, t2) = self.testrunner.run(test) + (f,t) = (f+f2, t+t2) + return TestResults(f,t) + + def rundict(self, d, name, module=None): + import types + m = types.ModuleType(name) + m.__dict__.update(d) + if module is None: + module = False + return self.rundoc(m, name, module) + + def run__test__(self, d, name): + import types + m = types.ModuleType(name) + m.__test__ = d + return self.rundoc(m, name) + + def summarize(self, verbose=None): + return self.testrunner.summarize(verbose) + + def merge(self, other): + self.testrunner.merge(other.testrunner) + +###################################################################### +## 8. Unittest Support +###################################################################### + +_unittest_reportflags = 0 + +def set_unittest_reportflags(flags): + """Sets the unittest option flags. + + The old flag is returned so that a runner could restore the old + value if it wished to: + + >>> import doctest + >>> old = doctest._unittest_reportflags + >>> doctest.set_unittest_reportflags(REPORT_NDIFF | + ... REPORT_ONLY_FIRST_FAILURE) == old + True + + >>> doctest._unittest_reportflags == (REPORT_NDIFF | + ... REPORT_ONLY_FIRST_FAILURE) + True + + Only reporting flags can be set: + + >>> doctest.set_unittest_reportflags(ELLIPSIS) + Traceback (most recent call last): + ... + ValueError: ('Only reporting flags allowed', 8) + + >>> doctest.set_unittest_reportflags(old) == (REPORT_NDIFF | + ... REPORT_ONLY_FIRST_FAILURE) + True + """ + global _unittest_reportflags + + if (flags & REPORTING_FLAGS) != flags: + raise ValueError("Only reporting flags allowed", flags) + old = _unittest_reportflags + _unittest_reportflags = flags + return old + + +class DocTestCase(unittest.TestCase): + + def __init__(self, test, optionflags=0, setUp=None, tearDown=None, + checker=None): + + unittest.TestCase.__init__(self) + self._dt_optionflags = optionflags + self._dt_checker = checker + self._dt_test = test + self._dt_setUp = setUp + self._dt_tearDown = tearDown + + def setUp(self): + test = self._dt_test + + if self._dt_setUp is not None: + self._dt_setUp(test) + + def tearDown(self): + test = self._dt_test + + if self._dt_tearDown is not None: + self._dt_tearDown(test) + + test.globs.clear() + + def runTest(self): + test = self._dt_test + old = sys.stdout + new = StringIO() + optionflags = self._dt_optionflags + + if not (optionflags & REPORTING_FLAGS): + # The option flags don't include any reporting flags, + # so add the default reporting flags + optionflags |= _unittest_reportflags + + runner = DocTestRunner(optionflags=optionflags, + checker=self._dt_checker, verbose=False) + + try: + runner.DIVIDER = "-"*70 + failures, tries = runner.run( + test, out=new.write, clear_globs=False) + finally: + sys.stdout = old + + if failures: + raise self.failureException(self.format_failure(new.getvalue())) + + def format_failure(self, err): + test = self._dt_test + if test.lineno is None: + lineno = 'unknown line number' + else: + lineno = '%s' % test.lineno + lname = '.'.join(test.name.split('.')[-1:]) + return ('Failed doctest test for %s\n' + ' File "%s", line %s, in %s\n\n%s' + % (test.name, test.filename, lineno, lname, err) + ) + + def debug(self): + r"""Run the test case without results and without catching exceptions + + The unit test framework includes a debug method on test cases + and test suites to support post-mortem debugging. The test code + is run in such a way that errors are not caught. This way a + caller can catch the errors and initiate post-mortem debugging. + + The DocTestCase provides a debug method that raises + UnexpectedException errors if there is an unexpected + exception: + + >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', + ... {}, 'foo', 'foo.py', 0) + >>> case = DocTestCase(test) + >>> try: + ... case.debug() + ... except UnexpectedException, failure: + ... pass + + The UnexpectedException contains the test, the example, and + the original exception: + + >>> failure.test is test + True + + >>> failure.example.want + '42\n' + + >>> exc_info = failure.exc_info + >>> raise exc_info[0], exc_info[1], exc_info[2] + Traceback (most recent call last): + ... + KeyError + + If the output doesn't match, then a DocTestFailure is raised: + + >>> test = DocTestParser().get_doctest(''' + ... >>> x = 1 + ... >>> x + ... 2 + ... ''', {}, 'foo', 'foo.py', 0) + >>> case = DocTestCase(test) + + >>> try: + ... case.debug() + ... except DocTestFailure, failure: + ... pass + + DocTestFailure objects provide access to the test: + + >>> failure.test is test + True + + As well as to the example: + + >>> failure.example.want + '2\n' + + and the actual output: + + >>> failure.got + '1\n' + + """ + + self.setUp() + runner = DebugRunner(optionflags=self._dt_optionflags, + checker=self._dt_checker, verbose=False) + runner.run(self._dt_test, clear_globs=False) + self.tearDown() + + def id(self): + return self._dt_test.name + + def __eq__(self, other): + if type(self) is not type(other): + return NotImplemented + + return self._dt_test == other._dt_test and \ + self._dt_optionflags == other._dt_optionflags and \ + self._dt_setUp == other._dt_setUp and \ + self._dt_tearDown == other._dt_tearDown and \ + self._dt_checker == other._dt_checker + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((self._dt_optionflags, self._dt_setUp, self._dt_tearDown, + self._dt_checker)) + + def __repr__(self): + name = self._dt_test.name.split('.') + return "%s (%s)" % (name[-1], '.'.join(name[:-1])) + + __str__ = __repr__ + + def shortDescription(self): + return "Doctest: " + self._dt_test.name + +class SkipDocTestCase(DocTestCase): + def __init__(self, module): + self.module = module + DocTestCase.__init__(self, None) + + def setUp(self): + self.skipTest("DocTestSuite will not work with -O2 and above") + + def test_skip(self): + pass + + def shortDescription(self): + return "Skipping tests from %s" % self.module.__name__ + + __str__ = shortDescription + + +def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, + **options): + """ + Convert doctest tests for a module to a unittest test suite. + + This converts each documentation string in a module that + contains doctest tests to a unittest test case. If any of the + tests in a doc string fail, then the test case fails. An exception + is raised showing the name of the file containing the test and a + (sometimes approximate) line number. + + The `module` argument provides the module to be tested. The argument + can be either a module or a module name. + + If no argument is given, the calling module is used. + + A number of options may be provided as keyword arguments: + + setUp + A set-up function. This is called before running the + tests in each file. The setUp function will be passed a DocTest + object. The setUp function can access the test globals as the + globs attribute of the test passed. + + tearDown + A tear-down function. This is called after running the + tests in each file. The tearDown function will be passed a DocTest + object. The tearDown function can access the test globals as the + globs attribute of the test passed. + + globs + A dictionary containing initial global variables for the tests. + + optionflags + A set of doctest option flags expressed as an integer. + """ + + if test_finder is None: + test_finder = DocTestFinder() + + module = _normalize_module(module) + tests = test_finder.find(module, globs=globs, extraglobs=extraglobs) + + if not tests and sys.flags.optimize >=2: + # Skip doctests when running with -O2 + suite = unittest.TestSuite() + suite.addTest(SkipDocTestCase(module)) + return suite + elif not tests: + # Why do we want to do this? Because it reveals a bug that might + # otherwise be hidden. + # It is probably a bug that this exception is not also raised if the + # number of doctest examples in tests is zero (i.e. if no doctest + # examples were found). However, we should probably not be raising + # an exception at all here, though it is too late to make this change + # for a maintenance release. See also issue #14649. + raise ValueError(module, "has no docstrings") + + tests.sort() + suite = unittest.TestSuite() + + for test in tests: + if len(test.examples) == 0: + continue + if not test.filename: + filename = module.__file__ + if filename[-4:] in (".pyc", ".pyo"): + filename = filename[:-1] + elif filename.endswith('$py.class'): + filename = '%s.py' % filename[:-9] + test.filename = filename + suite.addTest(DocTestCase(test, **options)) + + return suite + +class DocFileCase(DocTestCase): + + def id(self): + return '_'.join(self._dt_test.name.split('.')) + + def __repr__(self): + return self._dt_test.filename + __str__ = __repr__ + + def format_failure(self, err): + return ('Failed doctest test for %s\n File "%s", line 0\n\n%s' + % (self._dt_test.name, self._dt_test.filename, err) + ) + +def DocFileTest(path, module_relative=True, package=None, + globs=None, parser=DocTestParser(), + encoding=None, **options): + if globs is None: + globs = {} + else: + globs = globs.copy() + + if package and not module_relative: + raise ValueError("Package may only be specified for module-" + "relative paths.") + + # Relativize the path. + doc, path = _load_testfile(path, package, module_relative) + + if "__file__" not in globs: + globs["__file__"] = path + + # Find the file and read it. + name = os.path.basename(path) + + # If an encoding is specified, use it to convert the file to unicode + if encoding is not None: + doc = doc.decode(encoding) + + # Convert it to a test, and wrap it in a DocFileCase. + test = parser.get_doctest(doc, globs, name, path, 0) + return DocFileCase(test, **options) + +def DocFileSuite(*paths, **kw): + """A unittest suite for one or more doctest files. + + The path to each doctest file is given as a string; the + interpretation of that string depends on the keyword argument + "module_relative". + + A number of options may be provided as keyword arguments: + + module_relative + If "module_relative" is True, then the given file paths are + interpreted as os-independent module-relative paths. By + default, these paths are relative to the calling module's + directory; but if the "package" argument is specified, then + they are relative to that package. To ensure os-independence, + "filename" should use "/" characters to separate path + segments, and may not be an absolute path (i.e., it may not + begin with "/"). + + If "module_relative" is False, then the given file paths are + interpreted as os-specific paths. These paths may be absolute + or relative (to the current working directory). + + package + A Python package or the name of a Python package whose directory + should be used as the base directory for module relative paths. + If "package" is not specified, then the calling module's + directory is used as the base directory for module relative + filenames. It is an error to specify "package" if + "module_relative" is False. + + setUp + A set-up function. This is called before running the + tests in each file. The setUp function will be passed a DocTest + object. The setUp function can access the test globals as the + globs attribute of the test passed. + + tearDown + A tear-down function. This is called after running the + tests in each file. The tearDown function will be passed a DocTest + object. The tearDown function can access the test globals as the + globs attribute of the test passed. + + globs + A dictionary containing initial global variables for the tests. + + optionflags + A set of doctest option flags expressed as an integer. + + parser + A DocTestParser (or subclass) that should be used to extract + tests from the files. + + encoding + An encoding that will be used to convert the files to unicode. + """ + suite = unittest.TestSuite() + + # We do this here so that _normalize_module is called at the right + # level. If it were called in DocFileTest, then this function + # would be the caller and we might guess the package incorrectly. + if kw.get('module_relative', True): + kw['package'] = _normalize_module(kw.get('package')) + + for path in paths: + suite.addTest(DocFileTest(path, **kw)) + + return suite + +###################################################################### +## 9. Debugging Support +###################################################################### + +def script_from_examples(s): + r"""Extract script from text with examples. + + Converts text with examples to a Python script. Example input is + converted to regular code. Example output and all other words + are converted to comments: + + >>> text = ''' + ... Here are examples of simple math. + ... + ... Python has super accurate integer addition + ... + ... >>> 2 + 2 + ... 5 + ... + ... And very friendly error messages: + ... + ... >>> 1/0 + ... To Infinity + ... And + ... Beyond + ... + ... You can use logic if you want: + ... + ... >>> if 0: + ... ... blah + ... ... blah + ... ... + ... + ... Ho hum + ... ''' + + >>> print script_from_examples(text) + # Here are examples of simple math. + # + # Python has super accurate integer addition + # + 2 + 2 + # Expected: + ## 5 + # + # And very friendly error messages: + # + 1/0 + # Expected: + ## To Infinity + ## And + ## Beyond + # + # You can use logic if you want: + # + if 0: + blah + blah + # + # Ho hum + <BLANKLINE> + """ + output = [] + for piece in DocTestParser().parse(s): + if isinstance(piece, Example): + # Add the example's source code (strip trailing NL) + output.append(piece.source[:-1]) + # Add the expected output: + want = piece.want + if want: + output.append('# Expected:') + output += ['## '+l for l in want.split('\n')[:-1]] + else: + # Add non-example text. + output += [_comment_line(l) + for l in piece.split('\n')[:-1]] + + # Trim junk on both ends. + while output and output[-1] == '#': + output.pop() + while output and output[0] == '#': + output.pop(0) + # Combine the output, and return it. + # Add a courtesy newline to prevent exec from choking (see bug #1172785) + return '\n'.join(output) + '\n' + +def testsource(module, name): + """Extract the test sources from a doctest docstring as a script. + + Provide the module (or dotted name of the module) containing the + test to be debugged and the name (within the module) of the object + with the doc string with tests to be debugged. + """ + module = _normalize_module(module) + tests = DocTestFinder().find(module) + test = [t for t in tests if t.name == name] + if not test: + raise ValueError(name, "not found in tests") + test = test[0] + testsrc = script_from_examples(test.docstring) + return testsrc + +def debug_src(src, pm=False, globs=None): + """Debug a single doctest docstring, in argument `src`'""" + testsrc = script_from_examples(src) + debug_script(testsrc, pm, globs) + +def debug_script(src, pm=False, globs=None): + "Debug a test script. `src` is the script, as a string." + import pdb + + # Note that tempfile.NameTemporaryFile() cannot be used. As the + # docs say, a file so created cannot be opened by name a second time + # on modern Windows boxes, and execfile() needs to open it. + srcfilename = tempfile.mktemp(".py", "doctestdebug") + f = open(srcfilename, 'w') + f.write(src) + f.close() + + try: + if globs: + globs = globs.copy() + else: + globs = {} + + if pm: + try: + execfile(srcfilename, globs, globs) + except: + print sys.exc_info()[1] + pdb.post_mortem(sys.exc_info()[2]) + else: + # Note that %r is vital here. '%s' instead can, e.g., cause + # backslashes to get treated as metacharacters on Windows. + pdb.run("execfile(%r)" % srcfilename, globs, globs) + + finally: + os.remove(srcfilename) + +def debug(module, name, pm=False): + """Debug a single doctest docstring. + + Provide the module (or dotted name of the module) containing the + test to be debugged and the name (within the module) of the object + with the docstring with tests to be debugged. + """ + module = _normalize_module(module) + testsrc = testsource(module, name) + debug_script(testsrc, pm, module.__dict__) + +###################################################################### +## 10. Example Usage +###################################################################### +class _TestClass: + """ + A pointless class, for sanity-checking of docstring testing. + + Methods: + square() + get() + + >>> _TestClass(13).get() + _TestClass(-12).get() + 1 + >>> hex(_TestClass(13).square().get()) + '0xa9' + """ + + def __init__(self, val): + """val -> _TestClass object with associated value val. + + >>> t = _TestClass(123) + >>> print t.get() + 123 + """ + + self.val = val + + def square(self): + """square() -> square TestClass's associated value + + >>> _TestClass(13).square().get() + 169 + """ + + self.val = self.val ** 2 + return self + + def get(self): + """get() -> return TestClass's associated value. + + >>> x = _TestClass(-42) + >>> print x.get() + -42 + """ + + return self.val + +__test__ = {"_TestClass": _TestClass, + "string": r""" + Example of a string object, searched as-is. + >>> x = 1; y = 2 + >>> x + y, x * y + (3, 2) + """, + + "bool-int equivalence": r""" + In 2.2, boolean expressions displayed + 0 or 1. By default, we still accept + them. This can be disabled by passing + DONT_ACCEPT_TRUE_FOR_1 to the new + optionflags argument. + >>> 4 == 4 + 1 + >>> 4 == 4 + True + >>> 4 > 4 + 0 + >>> 4 > 4 + False + """, + + "blank lines": r""" + Blank lines can be marked with <BLANKLINE>: + >>> print 'foo\n\nbar\n' + foo + <BLANKLINE> + bar + <BLANKLINE> + """, + + "ellipsis": r""" + If the ellipsis flag is used, then '...' can be used to + elide substrings in the desired output: + >>> print range(1000) #doctest: +ELLIPSIS + [0, 1, 2, ..., 999] + """, + + "whitespace normalization": r""" + If the whitespace normalization flag is used, then + differences in whitespace are ignored. + >>> print range(30) #doctest: +NORMALIZE_WHITESPACE + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29] + """, + } + + +def _test(): + testfiles = [arg for arg in sys.argv[1:] if arg and arg[0] != '-'] + if not testfiles: + name = os.path.basename(sys.argv[0]) + if '__loader__' in globals(): # python -m + name, _ = os.path.splitext(name) + print("usage: {0} [-v] file ...".format(name)) + return 2 + for filename in testfiles: + if filename.endswith(".py"): + # It is a module -- insert its dir into sys.path and try to + # import it. If it is part of a package, that possibly + # won't work because of package imports. + dirname, filename = os.path.split(filename) + sys.path.insert(0, dirname) + m = __import__(filename[:-3]) + del sys.path[0] + failures, _ = testmod(m) + else: + failures, _ = testfile(filename, module_relative=False) + if failures: + return 1 + return 0 + + +if __name__ == "__main__": + sys.exit(_test()) diff --git a/src/main/resources/PythonLibs/dumbdbm.py b/src/main/resources/PythonLibs/dumbdbm.py new file mode 100644 index 0000000000000000000000000000000000000000..fb54a93041b4d33c94a10524544a92fe1002266e --- /dev/null +++ b/src/main/resources/PythonLibs/dumbdbm.py @@ -0,0 +1,250 @@ +"""A dumb and slow but simple dbm clone. + +For database spam, spam.dir contains the index (a text file), +spam.bak *may* contain a backup of the index (also a text file), +while spam.dat contains the data (a binary file). + +XXX TO DO: + +- seems to contain a bug when updating... + +- reclaim free space (currently, space once occupied by deleted or expanded +items is never reused) + +- support concurrent access (currently, if two processes take turns making +updates, they can mess up the index) + +- support efficient access to large databases (currently, the whole index +is read when the database is opened, and some updates rewrite the whole index) + +- support opening for read-only (flag = 'm') + +""" + +import os as _os +import __builtin__ +import UserDict + +_open = __builtin__.open + +_BLOCKSIZE = 512 + +error = IOError # For anydbm + +class _Database(UserDict.DictMixin): + + # The on-disk directory and data files can remain in mutually + # inconsistent states for an arbitrarily long time (see comments + # at the end of __setitem__). This is only repaired when _commit() + # gets called. One place _commit() gets called is from __del__(), + # and if that occurs at program shutdown time, module globals may + # already have gotten rebound to None. Since it's crucial that + # _commit() finish successfully, we can't ignore shutdown races + # here, and _commit() must not reference any globals. + _os = _os # for _commit() + _open = _open # for _commit() + + def __init__(self, filebasename, mode): + self._mode = mode + + # The directory file is a text file. Each line looks like + # "%r, (%d, %d)\n" % (key, pos, siz) + # where key is the string key, pos is the offset into the dat + # file of the associated value's first byte, and siz is the number + # of bytes in the associated value. + self._dirfile = filebasename + _os.extsep + 'dir' + + # The data file is a binary file pointed into by the directory + # file, and holds the values associated with keys. Each value + # begins at a _BLOCKSIZE-aligned byte offset, and is a raw + # binary 8-bit string value. + self._datfile = filebasename + _os.extsep + 'dat' + self._bakfile = filebasename + _os.extsep + 'bak' + + # The index is an in-memory dict, mirroring the directory file. + self._index = None # maps keys to (pos, siz) pairs + + # Mod by Jack: create data file if needed + try: + f = _open(self._datfile, 'r') + except IOError: + f = _open(self._datfile, 'w') + self._chmod(self._datfile) + f.close() + self._update() + + # Read directory file into the in-memory index dict. + def _update(self): + self._index = {} + try: + f = _open(self._dirfile) + except IOError: + pass + else: + for line in f: + line = line.rstrip() + key, pos_and_siz_pair = eval(line) + self._index[key] = pos_and_siz_pair + f.close() + + # Write the index dict to the directory file. The original directory + # file (if any) is renamed with a .bak extension first. If a .bak + # file currently exists, it's deleted. + def _commit(self): + # CAUTION: It's vital that _commit() succeed, and _commit() can + # be called from __del__(). Therefore we must never reference a + # global in this routine. + if self._index is None: + return # nothing to do + + try: + self._os.unlink(self._bakfile) + except self._os.error: + pass + + try: + self._os.rename(self._dirfile, self._bakfile) + except self._os.error: + pass + + f = self._open(self._dirfile, 'w') + self._chmod(self._dirfile) + for key, pos_and_siz_pair in self._index.iteritems(): + f.write("%r, %r\n" % (key, pos_and_siz_pair)) + f.close() + + sync = _commit + + def __getitem__(self, key): + pos, siz = self._index[key] # may raise KeyError + f = _open(self._datfile, 'rb') + f.seek(pos) + dat = f.read(siz) + f.close() + return dat + + # Append val to the data file, starting at a _BLOCKSIZE-aligned + # offset. The data file is first padded with NUL bytes (if needed) + # to get to an aligned offset. Return pair + # (starting offset of val, len(val)) + def _addval(self, val): + f = _open(self._datfile, 'rb+') + f.seek(0, 2) + pos = int(f.tell()) + npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE + f.write('\0'*(npos-pos)) + pos = npos + f.write(val) + f.close() + return (pos, len(val)) + + # Write val to the data file, starting at offset pos. The caller + # is responsible for ensuring that there's enough room starting at + # pos to hold val, without overwriting some other value. Return + # pair (pos, len(val)). + def _setval(self, pos, val): + f = _open(self._datfile, 'rb+') + f.seek(pos) + f.write(val) + f.close() + return (pos, len(val)) + + # key is a new key whose associated value starts in the data file + # at offset pos and with length siz. Add an index record to + # the in-memory index dict, and append one to the directory file. + def _addkey(self, key, pos_and_siz_pair): + self._index[key] = pos_and_siz_pair + f = _open(self._dirfile, 'a') + self._chmod(self._dirfile) + f.write("%r, %r\n" % (key, pos_and_siz_pair)) + f.close() + + def __setitem__(self, key, val): + if not type(key) == type('') == type(val): + raise TypeError, "keys and values must be strings" + if key not in self._index: + self._addkey(key, self._addval(val)) + else: + # See whether the new value is small enough to fit in the + # (padded) space currently occupied by the old value. + pos, siz = self._index[key] + oldblocks = (siz + _BLOCKSIZE - 1) // _BLOCKSIZE + newblocks = (len(val) + _BLOCKSIZE - 1) // _BLOCKSIZE + if newblocks <= oldblocks: + self._index[key] = self._setval(pos, val) + else: + # The new value doesn't fit in the (padded) space used + # by the old value. The blocks used by the old value are + # forever lost. + self._index[key] = self._addval(val) + + # Note that _index may be out of synch with the directory + # file now: _setval() and _addval() don't update the directory + # file. This also means that the on-disk directory and data + # files are in a mutually inconsistent state, and they'll + # remain that way until _commit() is called. Note that this + # is a disaster (for the database) if the program crashes + # (so that _commit() never gets called). + + def __delitem__(self, key): + # The blocks used by the associated value are lost. + del self._index[key] + # XXX It's unclear why we do a _commit() here (the code always + # XXX has, so I'm not changing it). _setitem__ doesn't try to + # XXX keep the directory file in synch. Why should we? Or + # XXX why shouldn't __setitem__? + self._commit() + + def keys(self): + return self._index.keys() + + def has_key(self, key): + return key in self._index + + def __contains__(self, key): + return key in self._index + + def iterkeys(self): + return self._index.iterkeys() + __iter__ = iterkeys + + def __len__(self): + return len(self._index) + + def close(self): + self._commit() + self._index = self._datfile = self._dirfile = self._bakfile = None + + __del__ = close + + def _chmod (self, file): + if hasattr(self._os, 'chmod'): + self._os.chmod(file, self._mode) + + +def open(file, flag=None, mode=0666): + """Open the database file, filename, and return corresponding object. + + The flag argument, used to control how the database is opened in the + other DBM implementations, is ignored in the dumbdbm module; the + database is always opened for update, and will be created if it does + not exist. + + The optional mode argument is the UNIX mode of the file, used only when + the database has to be created. It defaults to octal code 0666 (and + will be modified by the prevailing umask). + + """ + # flag argument is currently ignored + + # Modify mode depending on the umask + try: + um = _os.umask(0) + _os.umask(um) + except AttributeError: + pass + else: + # Turn off any bits that are set in the umask + mode = mode & (~um) + + return _Database(file, mode) diff --git a/src/main/resources/PythonLibs/dummy_thread.py b/src/main/resources/PythonLibs/dummy_thread.py new file mode 100644 index 0000000000000000000000000000000000000000..198dc49dba39e6550bc1c1c701009a7a43d2a93d --- /dev/null +++ b/src/main/resources/PythonLibs/dummy_thread.py @@ -0,0 +1,145 @@ +"""Drop-in replacement for the thread module. + +Meant to be used as a brain-dead substitute so that threaded code does +not need to be rewritten for when the thread module is not present. + +Suggested usage is:: + + try: + import thread + except ImportError: + import dummy_thread as thread + +""" +# Exports only things specified by thread documentation; +# skipping obsolete synonyms allocate(), start_new(), exit_thread(). +__all__ = ['error', 'start_new_thread', 'exit', 'get_ident', 'allocate_lock', + 'interrupt_main', 'LockType'] + +import traceback as _traceback + +class error(Exception): + """Dummy implementation of thread.error.""" + + def __init__(self, *args): + self.args = args + +def start_new_thread(function, args, kwargs={}): + """Dummy implementation of thread.start_new_thread(). + + Compatibility is maintained by making sure that ``args`` is a + tuple and ``kwargs`` is a dictionary. If an exception is raised + and it is SystemExit (which can be done by thread.exit()) it is + caught and nothing is done; all other exceptions are printed out + by using traceback.print_exc(). + + If the executed function calls interrupt_main the KeyboardInterrupt will be + raised when the function returns. + + """ + if type(args) != type(tuple()): + raise TypeError("2nd arg must be a tuple") + if type(kwargs) != type(dict()): + raise TypeError("3rd arg must be a dict") + global _main + _main = False + try: + function(*args, **kwargs) + except SystemExit: + pass + except: + _traceback.print_exc() + _main = True + global _interrupt + if _interrupt: + _interrupt = False + raise KeyboardInterrupt + +def exit(): + """Dummy implementation of thread.exit().""" + raise SystemExit + +def get_ident(): + """Dummy implementation of thread.get_ident(). + + Since this module should only be used when threadmodule is not + available, it is safe to assume that the current process is the + only thread. Thus a constant can be safely returned. + """ + return -1 + +def allocate_lock(): + """Dummy implementation of thread.allocate_lock().""" + return LockType() + +def stack_size(size=None): + """Dummy implementation of thread.stack_size().""" + if size is not None: + raise error("setting thread stack size not supported") + return 0 + +class LockType(object): + """Class implementing dummy implementation of thread.LockType. + + Compatibility is maintained by maintaining self.locked_status + which is a boolean that stores the state of the lock. Pickling of + the lock, though, should not be done since if the thread module is + then used with an unpickled ``lock()`` from here problems could + occur from this class not having atomic methods. + + """ + + def __init__(self): + self.locked_status = False + + def acquire(self, waitflag=None): + """Dummy implementation of acquire(). + + For blocking calls, self.locked_status is automatically set to + True and returned appropriately based on value of + ``waitflag``. If it is non-blocking, then the value is + actually checked and not set if it is already acquired. This + is all done so that threading.Condition's assert statements + aren't triggered and throw a little fit. + + """ + if waitflag is None or waitflag: + self.locked_status = True + return True + else: + if not self.locked_status: + self.locked_status = True + return True + else: + return False + + __enter__ = acquire + + def __exit__(self, typ, val, tb): + self.release() + + def release(self): + """Release the dummy lock.""" + # XXX Perhaps shouldn't actually bother to test? Could lead + # to problems for complex, threaded code. + if not self.locked_status: + raise error + self.locked_status = False + return True + + def locked(self): + return self.locked_status + +# Used to signal that interrupt_main was called in a "thread" +_interrupt = False +# True when not executing in a "thread" +_main = True + +def interrupt_main(): + """Set _interrupt flag to True to have start_new_thread raise + KeyboardInterrupt upon exiting.""" + if _main: + raise KeyboardInterrupt + else: + global _interrupt + _interrupt = True diff --git a/src/main/resources/PythonLibs/dummy_threading.py b/src/main/resources/PythonLibs/dummy_threading.py new file mode 100644 index 0000000000000000000000000000000000000000..81028a3d4e8a05aaa6ad3b85757b013e0c829c4d --- /dev/null +++ b/src/main/resources/PythonLibs/dummy_threading.py @@ -0,0 +1,78 @@ +"""Faux ``threading`` version using ``dummy_thread`` instead of ``thread``. + +The module ``_dummy_threading`` is added to ``sys.modules`` in order +to not have ``threading`` considered imported. Had ``threading`` been +directly imported it would have made all subsequent imports succeed +regardless of whether ``thread`` was available which is not desired. + +""" +from sys import modules as sys_modules + +import dummy_thread + +# Declaring now so as to not have to nest ``try``s to get proper clean-up. +holding_thread = False +holding_threading = False +holding__threading_local = False + +try: + # Could have checked if ``thread`` was not in sys.modules and gone + # a different route, but decided to mirror technique used with + # ``threading`` below. + if 'thread' in sys_modules: + held_thread = sys_modules['thread'] + holding_thread = True + # Must have some module named ``thread`` that implements its API + # in order to initially import ``threading``. + sys_modules['thread'] = sys_modules['dummy_thread'] + + if 'threading' in sys_modules: + # If ``threading`` is already imported, might as well prevent + # trying to import it more than needed by saving it if it is + # already imported before deleting it. + held_threading = sys_modules['threading'] + holding_threading = True + del sys_modules['threading'] + + if '_threading_local' in sys_modules: + # If ``_threading_local`` is already imported, might as well prevent + # trying to import it more than needed by saving it if it is + # already imported before deleting it. + held__threading_local = sys_modules['_threading_local'] + holding__threading_local = True + del sys_modules['_threading_local'] + + import threading + # Need a copy of the code kept somewhere... + sys_modules['_dummy_threading'] = sys_modules['threading'] + del sys_modules['threading'] + sys_modules['_dummy__threading_local'] = sys_modules['_threading_local'] + del sys_modules['_threading_local'] + from _dummy_threading import * + from _dummy_threading import __all__ + +finally: + # Put back ``threading`` if we overwrote earlier + + if holding_threading: + sys_modules['threading'] = held_threading + del held_threading + del holding_threading + + # Put back ``_threading_local`` if we overwrote earlier + + if holding__threading_local: + sys_modules['_threading_local'] = held__threading_local + del held__threading_local + del holding__threading_local + + # Put back ``thread`` if we overwrote, else del the entry we made + if holding_thread: + sys_modules['thread'] = held_thread + del held_thread + else: + del sys_modules['thread'] + del holding_thread + + del dummy_thread + del sys_modules diff --git a/src/main/resources/PythonLibs/email/__init__.py b/src/main/resources/PythonLibs/email/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a780ebe339bde909541c72dbf8396c1c04d26c2c --- /dev/null +++ b/src/main/resources/PythonLibs/email/__init__.py @@ -0,0 +1,123 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""A package for parsing, handling, and generating email messages.""" + +__version__ = '4.0.3' + +__all__ = [ + # Old names + 'base64MIME', + 'Charset', + 'Encoders', + 'Errors', + 'Generator', + 'Header', + 'Iterators', + 'Message', + 'MIMEAudio', + 'MIMEBase', + 'MIMEImage', + 'MIMEMessage', + 'MIMEMultipart', + 'MIMENonMultipart', + 'MIMEText', + 'Parser', + 'quopriMIME', + 'Utils', + 'message_from_string', + 'message_from_file', + # new names + 'base64mime', + 'charset', + 'encoders', + 'errors', + 'generator', + 'header', + 'iterators', + 'message', + 'mime', + 'parser', + 'quoprimime', + 'utils', + ] + + + +# Some convenience routines. Don't import Parser and Message as side-effects +# of importing email since those cascadingly import most of the rest of the +# email package. +def message_from_string(s, *args, **kws): + """Parse a string into a Message object model. + + Optional _class and strict are passed to the Parser constructor. + """ + from email.parser import Parser + return Parser(*args, **kws).parsestr(s) + + +def message_from_file(fp, *args, **kws): + """Read a file and parse its contents into a Message object model. + + Optional _class and strict are passed to the Parser constructor. + """ + from email.parser import Parser + return Parser(*args, **kws).parse(fp) + + + +# Lazy loading to provide name mapping from new-style names (PEP 8 compatible +# email 4.0 module names), to old-style names (email 3.0 module names). +import sys + +class LazyImporter(object): + def __init__(self, module_name): + self.__name__ = 'email.' + module_name + + def __getattr__(self, name): + __import__(self.__name__) + mod = sys.modules[self.__name__] + self.__dict__.update(mod.__dict__) + return getattr(mod, name) + + +_LOWERNAMES = [ + # email.<old name> -> email.<new name is lowercased old name> + 'Charset', + 'Encoders', + 'Errors', + 'FeedParser', + 'Generator', + 'Header', + 'Iterators', + 'Message', + 'Parser', + 'Utils', + 'base64MIME', + 'quopriMIME', + ] + +_MIMENAMES = [ + # email.MIME<old name> -> email.mime.<new name is lowercased old name> + 'Audio', + 'Base', + 'Image', + 'Message', + 'Multipart', + 'NonMultipart', + 'Text', + ] + +for _name in _LOWERNAMES: + importer = LazyImporter(_name.lower()) + sys.modules['email.' + _name] = importer + setattr(sys.modules['email'], _name, importer) + + +import email.mime +for _name in _MIMENAMES: + importer = LazyImporter('mime.' + _name.lower()) + sys.modules['email.MIME' + _name] = importer + setattr(sys.modules['email'], 'MIME' + _name, importer) + setattr(sys.modules['email.mime'], _name, importer) diff --git a/src/main/resources/PythonLibs/email/_parseaddr.py b/src/main/resources/PythonLibs/email/_parseaddr.py new file mode 100644 index 0000000000000000000000000000000000000000..690db2c22d34d358b6707d6befa0fcf96e6373bc --- /dev/null +++ b/src/main/resources/PythonLibs/email/_parseaddr.py @@ -0,0 +1,497 @@ +# Copyright (C) 2002-2007 Python Software Foundation +# Contact: email-sig@python.org + +"""Email address parsing code. + +Lifted directly from rfc822.py. This should eventually be rewritten. +""" + +__all__ = [ + 'mktime_tz', + 'parsedate', + 'parsedate_tz', + 'quote', + ] + +import time, calendar + +SPACE = ' ' +EMPTYSTRING = '' +COMMASPACE = ', ' + +# Parse a date field +_monthnames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', + 'aug', 'sep', 'oct', 'nov', 'dec', + 'january', 'february', 'march', 'april', 'may', 'june', 'july', + 'august', 'september', 'october', 'november', 'december'] + +_daynames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] + +# The timezone table does not include the military time zones defined +# in RFC822, other than Z. According to RFC1123, the description in +# RFC822 gets the signs wrong, so we can't rely on any such time +# zones. RFC1123 recommends that numeric timezone indicators be used +# instead of timezone names. + +_timezones = {'UT':0, 'UTC':0, 'GMT':0, 'Z':0, + 'AST': -400, 'ADT': -300, # Atlantic (used in Canada) + 'EST': -500, 'EDT': -400, # Eastern + 'CST': -600, 'CDT': -500, # Central + 'MST': -700, 'MDT': -600, # Mountain + 'PST': -800, 'PDT': -700 # Pacific + } + + +def parsedate_tz(data): + """Convert a date string to a time tuple. + + Accounts for military timezones. + """ + data = data.split() + # The FWS after the comma after the day-of-week is optional, so search and + # adjust for this. + if data[0].endswith(',') or data[0].lower() in _daynames: + # There's a dayname here. Skip it + del data[0] + else: + i = data[0].rfind(',') + if i >= 0: + data[0] = data[0][i+1:] + if len(data) == 3: # RFC 850 date, deprecated + stuff = data[0].split('-') + if len(stuff) == 3: + data = stuff + data[1:] + if len(data) == 4: + s = data[3] + i = s.find('+') + if i > 0: + data[3:] = [s[:i], s[i+1:]] + else: + data.append('') # Dummy tz + if len(data) < 5: + return None + data = data[:5] + [dd, mm, yy, tm, tz] = data + mm = mm.lower() + if mm not in _monthnames: + dd, mm = mm, dd.lower() + if mm not in _monthnames: + return None + mm = _monthnames.index(mm) + 1 + if mm > 12: + mm -= 12 + if dd[-1] == ',': + dd = dd[:-1] + i = yy.find(':') + if i > 0: + yy, tm = tm, yy + if yy[-1] == ',': + yy = yy[:-1] + if not yy[0].isdigit(): + yy, tz = tz, yy + if tm[-1] == ',': + tm = tm[:-1] + tm = tm.split(':') + if len(tm) == 2: + [thh, tmm] = tm + tss = '0' + elif len(tm) == 3: + [thh, tmm, tss] = tm + else: + return None + try: + yy = int(yy) + dd = int(dd) + thh = int(thh) + tmm = int(tmm) + tss = int(tss) + except ValueError: + return None + # Check for a yy specified in two-digit format, then convert it to the + # appropriate four-digit format, according to the POSIX standard. RFC 822 + # calls for a two-digit yy, but RFC 2822 (which obsoletes RFC 822) + # mandates a 4-digit yy. For more information, see the documentation for + # the time module. + if yy < 100: + # The year is between 1969 and 1999 (inclusive). + if yy > 68: + yy += 1900 + # The year is between 2000 and 2068 (inclusive). + else: + yy += 2000 + tzoffset = None + tz = tz.upper() + if tz in _timezones: + tzoffset = _timezones[tz] + else: + try: + tzoffset = int(tz) + except ValueError: + pass + # Convert a timezone offset into seconds ; -0500 -> -18000 + if tzoffset: + if tzoffset < 0: + tzsign = -1 + tzoffset = -tzoffset + else: + tzsign = 1 + tzoffset = tzsign * ( (tzoffset//100)*3600 + (tzoffset % 100)*60) + # Daylight Saving Time flag is set to -1, since DST is unknown. + return yy, mm, dd, thh, tmm, tss, 0, 1, -1, tzoffset + + +def parsedate(data): + """Convert a time string to a time tuple.""" + t = parsedate_tz(data) + if isinstance(t, tuple): + return t[:9] + else: + return t + + +def mktime_tz(data): + """Turn a 10-tuple as returned by parsedate_tz() into a POSIX timestamp.""" + if data[9] is None: + # No zone info, so localtime is better assumption than GMT + return time.mktime(data[:8] + (-1,)) + else: + t = calendar.timegm(data) + return t - data[9] + + +def quote(str): + """Prepare string to be used in a quoted string. + + Turns backslash and double quote characters into quoted pairs. These + are the only characters that need to be quoted inside a quoted string. + Does not add the surrounding double quotes. + """ + return str.replace('\\', '\\\\').replace('"', '\\"') + + +class AddrlistClass: + """Address parser class by Ben Escoto. + + To understand what this class does, it helps to have a copy of RFC 2822 in + front of you. + + Note: this class interface is deprecated and may be removed in the future. + Use rfc822.AddressList instead. + """ + + def __init__(self, field): + """Initialize a new instance. + + `field' is an unparsed address header field, containing + one or more addresses. + """ + self.specials = '()<>@,:;.\"[]' + self.pos = 0 + self.LWS = ' \t' + self.CR = '\r\n' + self.FWS = self.LWS + self.CR + self.atomends = self.specials + self.LWS + self.CR + # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it + # is obsolete syntax. RFC 2822 requires that we recognize obsolete + # syntax, so allow dots in phrases. + self.phraseends = self.atomends.replace('.', '') + self.field = field + self.commentlist = [] + + def gotonext(self): + """Parse up to the start of the next address.""" + while self.pos < len(self.field): + if self.field[self.pos] in self.LWS + '\n\r': + self.pos += 1 + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + else: + break + + def getaddrlist(self): + """Parse all addresses. + + Returns a list containing all of the addresses. + """ + result = [] + while self.pos < len(self.field): + ad = self.getaddress() + if ad: + result += ad + else: + result.append(('', '')) + return result + + def getaddress(self): + """Parse the next address.""" + self.commentlist = [] + self.gotonext() + + oldpos = self.pos + oldcl = self.commentlist + plist = self.getphraselist() + + self.gotonext() + returnlist = [] + + if self.pos >= len(self.field): + # Bad email address technically, no domain. + if plist: + returnlist = [(SPACE.join(self.commentlist), plist[0])] + + elif self.field[self.pos] in '.@': + # email address is just an addrspec + # this isn't very efficient since we start over + self.pos = oldpos + self.commentlist = oldcl + addrspec = self.getaddrspec() + returnlist = [(SPACE.join(self.commentlist), addrspec)] + + elif self.field[self.pos] == ':': + # address is a group + returnlist = [] + + fieldlen = len(self.field) + self.pos += 1 + while self.pos < len(self.field): + self.gotonext() + if self.pos < fieldlen and self.field[self.pos] == ';': + self.pos += 1 + break + returnlist = returnlist + self.getaddress() + + elif self.field[self.pos] == '<': + # Address is a phrase then a route addr + routeaddr = self.getrouteaddr() + + if self.commentlist: + returnlist = [(SPACE.join(plist) + ' (' + + ' '.join(self.commentlist) + ')', routeaddr)] + else: + returnlist = [(SPACE.join(plist), routeaddr)] + + else: + if plist: + returnlist = [(SPACE.join(self.commentlist), plist[0])] + elif self.field[self.pos] in self.specials: + self.pos += 1 + + self.gotonext() + if self.pos < len(self.field) and self.field[self.pos] == ',': + self.pos += 1 + return returnlist + + def getrouteaddr(self): + """Parse a route address (Return-path value). + + This method just skips all the route stuff and returns the addrspec. + """ + if self.field[self.pos] != '<': + return + + expectroute = False + self.pos += 1 + self.gotonext() + adlist = '' + while self.pos < len(self.field): + if expectroute: + self.getdomain() + expectroute = False + elif self.field[self.pos] == '>': + self.pos += 1 + break + elif self.field[self.pos] == '@': + self.pos += 1 + expectroute = True + elif self.field[self.pos] == ':': + self.pos += 1 + else: + adlist = self.getaddrspec() + self.pos += 1 + break + self.gotonext() + + return adlist + + def getaddrspec(self): + """Parse an RFC 2822 addr-spec.""" + aslist = [] + + self.gotonext() + while self.pos < len(self.field): + if self.field[self.pos] == '.': + aslist.append('.') + self.pos += 1 + elif self.field[self.pos] == '"': + aslist.append('"%s"' % quote(self.getquote())) + elif self.field[self.pos] in self.atomends: + break + else: + aslist.append(self.getatom()) + self.gotonext() + + if self.pos >= len(self.field) or self.field[self.pos] != '@': + return EMPTYSTRING.join(aslist) + + aslist.append('@') + self.pos += 1 + self.gotonext() + return EMPTYSTRING.join(aslist) + self.getdomain() + + def getdomain(self): + """Get the complete domain name from an address.""" + sdlist = [] + while self.pos < len(self.field): + if self.field[self.pos] in self.LWS: + self.pos += 1 + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + elif self.field[self.pos] == '[': + sdlist.append(self.getdomainliteral()) + elif self.field[self.pos] == '.': + self.pos += 1 + sdlist.append('.') + elif self.field[self.pos] in self.atomends: + break + else: + sdlist.append(self.getatom()) + return EMPTYSTRING.join(sdlist) + + def getdelimited(self, beginchar, endchars, allowcomments=True): + """Parse a header fragment delimited by special characters. + + `beginchar' is the start character for the fragment. + If self is not looking at an instance of `beginchar' then + getdelimited returns the empty string. + + `endchars' is a sequence of allowable end-delimiting characters. + Parsing stops when one of these is encountered. + + If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed + within the parsed fragment. + """ + if self.field[self.pos] != beginchar: + return '' + + slist = [''] + quote = False + self.pos += 1 + while self.pos < len(self.field): + if quote: + slist.append(self.field[self.pos]) + quote = False + elif self.field[self.pos] in endchars: + self.pos += 1 + break + elif allowcomments and self.field[self.pos] == '(': + slist.append(self.getcomment()) + continue # have already advanced pos from getcomment + elif self.field[self.pos] == '\\': + quote = True + else: + slist.append(self.field[self.pos]) + self.pos += 1 + + return EMPTYSTRING.join(slist) + + def getquote(self): + """Get a quote-delimited fragment from self's field.""" + return self.getdelimited('"', '"\r', False) + + def getcomment(self): + """Get a parenthesis-delimited fragment from self's field.""" + return self.getdelimited('(', ')\r', True) + + def getdomainliteral(self): + """Parse an RFC 2822 domain-literal.""" + return '[%s]' % self.getdelimited('[', ']\r', False) + + def getatom(self, atomends=None): + """Parse an RFC 2822 atom. + + Optional atomends specifies a different set of end token delimiters + (the default is to use self.atomends). This is used e.g. in + getphraselist() since phrase endings must not include the `.' (which + is legal in phrases).""" + atomlist = [''] + if atomends is None: + atomends = self.atomends + + while self.pos < len(self.field): + if self.field[self.pos] in atomends: + break + else: + atomlist.append(self.field[self.pos]) + self.pos += 1 + + return EMPTYSTRING.join(atomlist) + + def getphraselist(self): + """Parse a sequence of RFC 2822 phrases. + + A phrase is a sequence of words, which are in turn either RFC 2822 + atoms or quoted-strings. Phrases are canonicalized by squeezing all + runs of continuous whitespace into one space. + """ + plist = [] + + while self.pos < len(self.field): + if self.field[self.pos] in self.FWS: + self.pos += 1 + elif self.field[self.pos] == '"': + plist.append(self.getquote()) + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + elif self.field[self.pos] in self.phraseends: + break + else: + plist.append(self.getatom(self.phraseends)) + + return plist + +class AddressList(AddrlistClass): + """An AddressList encapsulates a list of parsed RFC 2822 addresses.""" + def __init__(self, field): + AddrlistClass.__init__(self, field) + if field: + self.addresslist = self.getaddrlist() + else: + self.addresslist = [] + + def __len__(self): + return len(self.addresslist) + + def __add__(self, other): + # Set union + newaddr = AddressList(None) + newaddr.addresslist = self.addresslist[:] + for x in other.addresslist: + if not x in self.addresslist: + newaddr.addresslist.append(x) + return newaddr + + def __iadd__(self, other): + # Set union, in-place + for x in other.addresslist: + if not x in self.addresslist: + self.addresslist.append(x) + return self + + def __sub__(self, other): + # Set difference + newaddr = AddressList(None) + for x in self.addresslist: + if not x in other.addresslist: + newaddr.addresslist.append(x) + return newaddr + + def __isub__(self, other): + # Set difference, in-place + for x in other.addresslist: + if x in self.addresslist: + self.addresslist.remove(x) + return self + + def __getitem__(self, index): + # Make indexing, slices, and 'in' work + return self.addresslist[index] diff --git a/src/main/resources/PythonLibs/email/base64mime.py b/src/main/resources/PythonLibs/email/base64mime.py new file mode 100644 index 0000000000000000000000000000000000000000..4aa800026d650f33971729ba67d00bb1931547f9 --- /dev/null +++ b/src/main/resources/PythonLibs/email/base64mime.py @@ -0,0 +1,183 @@ +# Copyright (C) 2002-2006 Python Software Foundation +# Author: Ben Gertzfield +# Contact: email-sig@python.org + +"""Base64 content transfer encoding per RFCs 2045-2047. + +This module handles the content transfer encoding method defined in RFC 2045 +to encode arbitrary 8-bit data using the three 8-bit bytes in four 7-bit +characters encoding known as Base64. + +It is used in the MIME standards for email to attach images, audio, and text +using some 8-bit character sets to messages. + +This module provides an interface to encode and decode both headers and bodies +with Base64 encoding. + +RFC 2045 defines a method for including character set information in an +`encoded-word' in a header. This method is commonly used for 8-bit real names +in To:, From:, Cc:, etc. fields, as well as Subject: lines. + +This module does not do the line wrapping or end-of-line character conversion +necessary for proper internationalized headers; it only does dumb encoding and +decoding. To deal with the various line wrapping issues, use the email.header +module. +""" + +__all__ = [ + 'base64_len', + 'body_decode', + 'body_encode', + 'decode', + 'decodestring', + 'encode', + 'encodestring', + 'header_encode', + ] + + +from binascii import b2a_base64, a2b_base64 +from email.utils import fix_eols + +CRLF = '\r\n' +NL = '\n' +EMPTYSTRING = '' + +# See also Charset.py +MISC_LEN = 7 + + + +# Helpers +def base64_len(s): + """Return the length of s when it is encoded with base64.""" + groups_of_3, leftover = divmod(len(s), 3) + # 4 bytes out for each 3 bytes (or nonzero fraction thereof) in. + # Thanks, Tim! + n = groups_of_3 * 4 + if leftover: + n += 4 + return n + + + +def header_encode(header, charset='iso-8859-1', keep_eols=False, + maxlinelen=76, eol=NL): + """Encode a single header line with Base64 encoding in a given charset. + + Defined in RFC 2045, this Base64 encoding is identical to normal Base64 + encoding, except that each line must be intelligently wrapped (respecting + the Base64 encoding), and subsequent lines must start with a space. + + charset names the character set to use to encode the header. It defaults + to iso-8859-1. + + End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted + to the canonical email line separator \\r\\n unless the keep_eols + parameter is True (the default is False). + + Each line of the header will be terminated in the value of eol, which + defaults to "\\n". Set this to "\\r\\n" if you are using the result of + this function directly in email. + + The resulting string will be in the form: + + "=?charset?b?WW/5ciBtYXp66XLrIHf8eiBhIGhhbXBzdGHuciBBIFlv+XIgbWF6euly?=\\n + =?charset?b?6yB3/HogYSBoYW1wc3Rh7nIgQkMgWW/5ciBtYXp66XLrIHf8eiBhIGhh?=" + + with each line wrapped at, at most, maxlinelen characters (defaults to 76 + characters). + """ + # Return empty headers unchanged + if not header: + return header + + if not keep_eols: + header = fix_eols(header) + + # Base64 encode each line, in encoded chunks no greater than maxlinelen in + # length, after the RFC chrome is added in. + base64ed = [] + max_encoded = maxlinelen - len(charset) - MISC_LEN + max_unencoded = max_encoded * 3 // 4 + + for i in range(0, len(header), max_unencoded): + base64ed.append(b2a_base64(header[i:i+max_unencoded])) + + # Now add the RFC chrome to each encoded chunk + lines = [] + for line in base64ed: + # Ignore the last character of each line if it is a newline + if line.endswith(NL): + line = line[:-1] + # Add the chrome + lines.append('=?%s?b?%s?=' % (charset, line)) + # Glue the lines together and return it. BAW: should we be able to + # specify the leading whitespace in the joiner? + joiner = eol + ' ' + return joiner.join(lines) + + + +def encode(s, binary=True, maxlinelen=76, eol=NL): + """Encode a string with base64. + + Each line will be wrapped at, at most, maxlinelen characters (defaults to + 76 characters). + + If binary is False, end-of-line characters will be converted to the + canonical email end-of-line sequence \\r\\n. Otherwise they will be left + verbatim (this is the default). + + Each line of encoded text will end with eol, which defaults to "\\n". Set + this to "\\r\\n" if you will be using the result of this function directly + in an email. + """ + if not s: + return s + + if not binary: + s = fix_eols(s) + + encvec = [] + max_unencoded = maxlinelen * 3 // 4 + for i in range(0, len(s), max_unencoded): + # BAW: should encode() inherit b2a_base64()'s dubious behavior in + # adding a newline to the encoded string? + enc = b2a_base64(s[i:i + max_unencoded]) + if enc.endswith(NL) and eol != NL: + enc = enc[:-1] + eol + encvec.append(enc) + return EMPTYSTRING.join(encvec) + + +# For convenience and backwards compatibility w/ standard base64 module +body_encode = encode +encodestring = encode + + + +def decode(s, convert_eols=None): + """Decode a raw base64 string. + + If convert_eols is set to a string value, all canonical email linefeeds, + e.g. "\\r\\n", in the decoded text will be converted to the value of + convert_eols. os.linesep is a good choice for convert_eols if you are + decoding a text attachment. + + This function does not parse a full MIME header value encoded with + base64 (like =?iso-8895-1?b?bmloISBuaWgh?=) -- please use the high + level email.header class for that functionality. + """ + if not s: + return s + + dec = a2b_base64(s) + if convert_eols: + return dec.replace(CRLF, convert_eols) + return dec + + +# For convenience and backwards compatibility w/ standard base64 module +body_decode = decode +decodestring = decode diff --git a/src/main/resources/PythonLibs/email/charset.py b/src/main/resources/PythonLibs/email/charset.py new file mode 100644 index 0000000000000000000000000000000000000000..dddaa76c55d760614b52a383b98f0db6dc45dfdb --- /dev/null +++ b/src/main/resources/PythonLibs/email/charset.py @@ -0,0 +1,397 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Ben Gertzfield, Barry Warsaw +# Contact: email-sig@python.org + +__all__ = [ + 'Charset', + 'add_alias', + 'add_charset', + 'add_codec', + ] + +import codecs +import email.base64mime +import email.quoprimime + +from email import errors +from email.encoders import encode_7or8bit + + + +# Flags for types of header encodings +QP = 1 # Quoted-Printable +BASE64 = 2 # Base64 +SHORTEST = 3 # the shorter of QP and base64, but only for headers + +# In "=?charset?q?hello_world?=", the =?, ?q?, and ?= add up to 7 +MISC_LEN = 7 + +DEFAULT_CHARSET = 'us-ascii' + + + +# Defaults +CHARSETS = { + # input header enc body enc output conv + 'iso-8859-1': (QP, QP, None), + 'iso-8859-2': (QP, QP, None), + 'iso-8859-3': (QP, QP, None), + 'iso-8859-4': (QP, QP, None), + # iso-8859-5 is Cyrillic, and not especially used + # iso-8859-6 is Arabic, also not particularly used + # iso-8859-7 is Greek, QP will not make it readable + # iso-8859-8 is Hebrew, QP will not make it readable + 'iso-8859-9': (QP, QP, None), + 'iso-8859-10': (QP, QP, None), + # iso-8859-11 is Thai, QP will not make it readable + 'iso-8859-13': (QP, QP, None), + 'iso-8859-14': (QP, QP, None), + 'iso-8859-15': (QP, QP, None), + 'iso-8859-16': (QP, QP, None), + 'windows-1252':(QP, QP, None), + 'viscii': (QP, QP, None), + 'us-ascii': (None, None, None), + 'big5': (BASE64, BASE64, None), + 'gb2312': (BASE64, BASE64, None), + 'euc-jp': (BASE64, None, 'iso-2022-jp'), + 'shift_jis': (BASE64, None, 'iso-2022-jp'), + 'iso-2022-jp': (BASE64, None, None), + 'koi8-r': (BASE64, BASE64, None), + 'utf-8': (SHORTEST, BASE64, 'utf-8'), + # We're making this one up to represent raw unencoded 8-bit + '8bit': (None, BASE64, 'utf-8'), + } + +# Aliases for other commonly-used names for character sets. Map +# them to the real ones used in email. +ALIASES = { + 'latin_1': 'iso-8859-1', + 'latin-1': 'iso-8859-1', + 'latin_2': 'iso-8859-2', + 'latin-2': 'iso-8859-2', + 'latin_3': 'iso-8859-3', + 'latin-3': 'iso-8859-3', + 'latin_4': 'iso-8859-4', + 'latin-4': 'iso-8859-4', + 'latin_5': 'iso-8859-9', + 'latin-5': 'iso-8859-9', + 'latin_6': 'iso-8859-10', + 'latin-6': 'iso-8859-10', + 'latin_7': 'iso-8859-13', + 'latin-7': 'iso-8859-13', + 'latin_8': 'iso-8859-14', + 'latin-8': 'iso-8859-14', + 'latin_9': 'iso-8859-15', + 'latin-9': 'iso-8859-15', + 'latin_10':'iso-8859-16', + 'latin-10':'iso-8859-16', + 'cp949': 'ks_c_5601-1987', + 'euc_jp': 'euc-jp', + 'euc_kr': 'euc-kr', + 'ascii': 'us-ascii', + } + + +# Map charsets to their Unicode codec strings. +CODEC_MAP = { + 'gb2312': 'eucgb2312_cn', + 'big5': 'big5_tw', + # Hack: We don't want *any* conversion for stuff marked us-ascii, as all + # sorts of garbage might be sent to us in the guise of 7-bit us-ascii. + # Let that stuff pass through without conversion to/from Unicode. + 'us-ascii': None, + } + + + +# Convenience functions for extending the above mappings +def add_charset(charset, header_enc=None, body_enc=None, output_charset=None): + """Add character set properties to the global registry. + + charset is the input character set, and must be the canonical name of a + character set. + + Optional header_enc and body_enc is either Charset.QP for + quoted-printable, Charset.BASE64 for base64 encoding, Charset.SHORTEST for + the shortest of qp or base64 encoding, or None for no encoding. SHORTEST + is only valid for header_enc. It describes how message headers and + message bodies in the input charset are to be encoded. Default is no + encoding. + + Optional output_charset is the character set that the output should be + in. Conversions will proceed from input charset, to Unicode, to the + output charset when the method Charset.convert() is called. The default + is to output in the same character set as the input. + + Both input_charset and output_charset must have Unicode codec entries in + the module's charset-to-codec mapping; use add_codec(charset, codecname) + to add codecs the module does not know about. See the codecs module's + documentation for more information. + """ + if body_enc == SHORTEST: + raise ValueError('SHORTEST not allowed for body_enc') + CHARSETS[charset] = (header_enc, body_enc, output_charset) + + +def add_alias(alias, canonical): + """Add a character set alias. + + alias is the alias name, e.g. latin-1 + canonical is the character set's canonical name, e.g. iso-8859-1 + """ + ALIASES[alias] = canonical + + +def add_codec(charset, codecname): + """Add a codec that map characters in the given charset to/from Unicode. + + charset is the canonical name of a character set. codecname is the name + of a Python codec, as appropriate for the second argument to the unicode() + built-in, or to the encode() method of a Unicode string. + """ + CODEC_MAP[charset] = codecname + + + +class Charset: + """Map character sets to their email properties. + + This class provides information about the requirements imposed on email + for a specific character set. It also provides convenience routines for + converting between character sets, given the availability of the + applicable codecs. Given a character set, it will do its best to provide + information on how to use that character set in an email in an + RFC-compliant way. + + Certain character sets must be encoded with quoted-printable or base64 + when used in email headers or bodies. Certain character sets must be + converted outright, and are not allowed in email. Instances of this + module expose the following information about a character set: + + input_charset: The initial character set specified. Common aliases + are converted to their `official' email names (e.g. latin_1 + is converted to iso-8859-1). Defaults to 7-bit us-ascii. + + header_encoding: If the character set must be encoded before it can be + used in an email header, this attribute will be set to + Charset.QP (for quoted-printable), Charset.BASE64 (for + base64 encoding), or Charset.SHORTEST for the shortest of + QP or BASE64 encoding. Otherwise, it will be None. + + body_encoding: Same as header_encoding, but describes the encoding for the + mail message's body, which indeed may be different than the + header encoding. Charset.SHORTEST is not allowed for + body_encoding. + + output_charset: Some character sets must be converted before the can be + used in email headers or bodies. If the input_charset is + one of them, this attribute will contain the name of the + charset output will be converted to. Otherwise, it will + be None. + + input_codec: The name of the Python codec used to convert the + input_charset to Unicode. If no conversion codec is + necessary, this attribute will be None. + + output_codec: The name of the Python codec used to convert Unicode + to the output_charset. If no conversion codec is necessary, + this attribute will have the same value as the input_codec. + """ + def __init__(self, input_charset=DEFAULT_CHARSET): + # RFC 2046, $4.1.2 says charsets are not case sensitive. We coerce to + # unicode because its .lower() is locale insensitive. If the argument + # is already a unicode, we leave it at that, but ensure that the + # charset is ASCII, as the standard (RFC XXX) requires. + try: + if isinstance(input_charset, unicode): + input_charset.encode('ascii') + else: + input_charset = unicode(input_charset, 'ascii') + except UnicodeError: + raise errors.CharsetError(input_charset) + input_charset = input_charset.lower().encode('ascii') + # Set the input charset after filtering through the aliases and/or codecs + if not (input_charset in ALIASES or input_charset in CHARSETS): + try: + input_charset = codecs.lookup(input_charset).name + except LookupError: + pass + self.input_charset = ALIASES.get(input_charset, input_charset) + # We can try to guess which encoding and conversion to use by the + # charset_map dictionary. Try that first, but let the user override + # it. + henc, benc, conv = CHARSETS.get(self.input_charset, + (SHORTEST, BASE64, None)) + if not conv: + conv = self.input_charset + # Set the attributes, allowing the arguments to override the default. + self.header_encoding = henc + self.body_encoding = benc + self.output_charset = ALIASES.get(conv, conv) + # Now set the codecs. If one isn't defined for input_charset, + # guess and try a Unicode codec with the same name as input_codec. + self.input_codec = CODEC_MAP.get(self.input_charset, + self.input_charset) + self.output_codec = CODEC_MAP.get(self.output_charset, + self.output_charset) + + def __str__(self): + return self.input_charset.lower() + + __repr__ = __str__ + + def __eq__(self, other): + return str(self) == str(other).lower() + + def __ne__(self, other): + return not self.__eq__(other) + + def get_body_encoding(self): + """Return the content-transfer-encoding used for body encoding. + + This is either the string `quoted-printable' or `base64' depending on + the encoding used, or it is a function in which case you should call + the function with a single argument, the Message object being + encoded. The function should then set the Content-Transfer-Encoding + header itself to whatever is appropriate. + + Returns "quoted-printable" if self.body_encoding is QP. + Returns "base64" if self.body_encoding is BASE64. + Returns "7bit" otherwise. + """ + assert self.body_encoding != SHORTEST + if self.body_encoding == QP: + return 'quoted-printable' + elif self.body_encoding == BASE64: + return 'base64' + else: + return encode_7or8bit + + def convert(self, s): + """Convert a string from the input_codec to the output_codec.""" + if self.input_codec != self.output_codec: + return unicode(s, self.input_codec).encode(self.output_codec) + else: + return s + + def to_splittable(self, s): + """Convert a possibly multibyte string to a safely splittable format. + + Uses the input_codec to try and convert the string to Unicode, so it + can be safely split on character boundaries (even for multibyte + characters). + + Returns the string as-is if it isn't known how to convert it to + Unicode with the input_charset. + + Characters that could not be converted to Unicode will be replaced + with the Unicode replacement character U+FFFD. + """ + if isinstance(s, unicode) or self.input_codec is None: + return s + try: + return unicode(s, self.input_codec, 'replace') + except LookupError: + # Input codec not installed on system, so return the original + # string unchanged. + return s + + def from_splittable(self, ustr, to_output=True): + """Convert a splittable string back into an encoded string. + + Uses the proper codec to try and convert the string from Unicode back + into an encoded format. Return the string as-is if it is not Unicode, + or if it could not be converted from Unicode. + + Characters that could not be converted from Unicode will be replaced + with an appropriate character (usually '?'). + + If to_output is True (the default), uses output_codec to convert to an + encoded format. If to_output is False, uses input_codec. + """ + if to_output: + codec = self.output_codec + else: + codec = self.input_codec + if not isinstance(ustr, unicode) or codec is None: + return ustr + try: + return ustr.encode(codec, 'replace') + except LookupError: + # Output codec not installed + return ustr + + def get_output_charset(self): + """Return the output character set. + + This is self.output_charset if that is not None, otherwise it is + self.input_charset. + """ + return self.output_charset or self.input_charset + + def encoded_header_len(self, s): + """Return the length of the encoded header string.""" + cset = self.get_output_charset() + # The len(s) of a 7bit encoding is len(s) + if self.header_encoding == BASE64: + return email.base64mime.base64_len(s) + len(cset) + MISC_LEN + elif self.header_encoding == QP: + return email.quoprimime.header_quopri_len(s) + len(cset) + MISC_LEN + elif self.header_encoding == SHORTEST: + lenb64 = email.base64mime.base64_len(s) + lenqp = email.quoprimime.header_quopri_len(s) + return min(lenb64, lenqp) + len(cset) + MISC_LEN + else: + return len(s) + + def header_encode(self, s, convert=False): + """Header-encode a string, optionally converting it to output_charset. + + If convert is True, the string will be converted from the input + charset to the output charset automatically. This is not useful for + multibyte character sets, which have line length issues (multibyte + characters must be split on a character, not a byte boundary); use the + high-level Header class to deal with these issues. convert defaults + to False. + + The type of encoding (base64 or quoted-printable) will be based on + self.header_encoding. + """ + cset = self.get_output_charset() + if convert: + s = self.convert(s) + # 7bit/8bit encodings return the string unchanged (modulo conversions) + if self.header_encoding == BASE64: + return email.base64mime.header_encode(s, cset) + elif self.header_encoding == QP: + return email.quoprimime.header_encode(s, cset, maxlinelen=None) + elif self.header_encoding == SHORTEST: + lenb64 = email.base64mime.base64_len(s) + lenqp = email.quoprimime.header_quopri_len(s) + if lenb64 < lenqp: + return email.base64mime.header_encode(s, cset) + else: + return email.quoprimime.header_encode(s, cset, maxlinelen=None) + else: + return s + + def body_encode(self, s, convert=True): + """Body-encode a string and convert it to output_charset. + + If convert is True (the default), the string will be converted from + the input charset to output charset automatically. Unlike + header_encode(), there are no issues with byte boundaries and + multibyte charsets in email bodies, so this is usually pretty safe. + + The type of encoding (base64 or quoted-printable) will be based on + self.body_encoding. + """ + if convert: + s = self.convert(s) + # 7bit/8bit encodings return the string unchanged (module conversions) + if self.body_encoding is BASE64: + return email.base64mime.body_encode(s) + elif self.body_encoding is QP: + return email.quoprimime.body_encode(s) + else: + return s diff --git a/src/main/resources/PythonLibs/email/encoders.py b/src/main/resources/PythonLibs/email/encoders.py new file mode 100644 index 0000000000000000000000000000000000000000..af45e62c333100021a7c8f8e51f85769d8eba0ac --- /dev/null +++ b/src/main/resources/PythonLibs/email/encoders.py @@ -0,0 +1,82 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Encodings and related functions.""" + +__all__ = [ + 'encode_7or8bit', + 'encode_base64', + 'encode_noop', + 'encode_quopri', + ] + +import base64 + +from quopri import encodestring as _encodestring + + + +def _qencode(s): + enc = _encodestring(s, quotetabs=True) + # Must encode spaces, which quopri.encodestring() doesn't do + return enc.replace(' ', '=20') + + +def _bencode(s): + # We can't quite use base64.encodestring() since it tacks on a "courtesy + # newline". Blech! + if not s: + return s + hasnewline = (s[-1] == '\n') + value = base64.encodestring(s) + if not hasnewline and value[-1] == '\n': + return value[:-1] + return value + + + +def encode_base64(msg): + """Encode the message's payload in Base64. + + Also, add an appropriate Content-Transfer-Encoding header. + """ + orig = msg.get_payload() + encdata = _bencode(orig) + msg.set_payload(encdata) + msg['Content-Transfer-Encoding'] = 'base64' + + + +def encode_quopri(msg): + """Encode the message's payload in quoted-printable. + + Also, add an appropriate Content-Transfer-Encoding header. + """ + orig = msg.get_payload() + encdata = _qencode(orig) + msg.set_payload(encdata) + msg['Content-Transfer-Encoding'] = 'quoted-printable' + + + +def encode_7or8bit(msg): + """Set the Content-Transfer-Encoding header to 7bit or 8bit.""" + orig = msg.get_payload() + if orig is None: + # There's no payload. For backwards compatibility we use 7bit + msg['Content-Transfer-Encoding'] = '7bit' + return + # We play a trick to make this go fast. If encoding to ASCII succeeds, we + # know the data must be 7bit, otherwise treat it as 8bit. + try: + orig.encode('ascii') + except UnicodeError: + msg['Content-Transfer-Encoding'] = '8bit' + else: + msg['Content-Transfer-Encoding'] = '7bit' + + + +def encode_noop(msg): + """Do nothing.""" diff --git a/src/main/resources/PythonLibs/email/errors.py b/src/main/resources/PythonLibs/email/errors.py new file mode 100644 index 0000000000000000000000000000000000000000..d52a624601f09216ba49f727c6b3fd1853b9ef68 --- /dev/null +++ b/src/main/resources/PythonLibs/email/errors.py @@ -0,0 +1,57 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""email package exception classes.""" + + + +class MessageError(Exception): + """Base class for errors in the email package.""" + + +class MessageParseError(MessageError): + """Base class for message parsing errors.""" + + +class HeaderParseError(MessageParseError): + """Error while parsing headers.""" + + +class BoundaryError(MessageParseError): + """Couldn't find terminating boundary.""" + + +class MultipartConversionError(MessageError, TypeError): + """Conversion to a multipart is prohibited.""" + + +class CharsetError(MessageError): + """An illegal charset was given.""" + + + +# These are parsing defects which the parser was able to work around. +class MessageDefect: + """Base class for a message defect.""" + + def __init__(self, line=None): + self.line = line + +class NoBoundaryInMultipartDefect(MessageDefect): + """A message claimed to be a multipart but had no boundary parameter.""" + +class StartBoundaryNotFoundDefect(MessageDefect): + """The claimed start boundary was never found.""" + +class FirstHeaderLineIsContinuationDefect(MessageDefect): + """A message had a continuation line as its first header line.""" + +class MisplacedEnvelopeHeaderDefect(MessageDefect): + """A 'Unix-from' header was found in the middle of a header block.""" + +class MalformedHeaderDefect(MessageDefect): + """Found a header that was missing a colon, or was otherwise malformed.""" + +class MultipartInvariantViolationDefect(MessageDefect): + """A message claimed to be a multipart but no subparts were found.""" diff --git a/src/main/resources/PythonLibs/email/feedparser.py b/src/main/resources/PythonLibs/email/feedparser.py new file mode 100644 index 0000000000000000000000000000000000000000..15db26d22a275698dcf59fabe4f86c41fee6984d --- /dev/null +++ b/src/main/resources/PythonLibs/email/feedparser.py @@ -0,0 +1,484 @@ +# Copyright (C) 2004-2006 Python Software Foundation +# Authors: Baxter, Wouters and Warsaw +# Contact: email-sig@python.org + +"""FeedParser - An email feed parser. + +The feed parser implements an interface for incrementally parsing an email +message, line by line. This has advantages for certain applications, such as +those reading email messages off a socket. + +FeedParser.feed() is the primary interface for pushing new data into the +parser. It returns when there's nothing more it can do with the available +data. When you have no more data to push into the parser, call .close(). +This completes the parsing and returns the root message object. + +The other advantage of this parser is that it will never raise a parsing +exception. Instead, when it finds something unexpected, it adds a 'defect' to +the current message. Defects are just instances that live on the message +object's .defects attribute. +""" + +__all__ = ['FeedParser'] + +import re + +from email import errors +from email import message + +NLCRE = re.compile('\r\n|\r|\n') +NLCRE_bol = re.compile('(\r\n|\r|\n)') +NLCRE_eol = re.compile('(\r\n|\r|\n)\Z') +NLCRE_crack = re.compile('(\r\n|\r|\n)') +# RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character +# except controls, SP, and ":". +headerRE = re.compile(r'^(From |[\041-\071\073-\176]{1,}:|[\t ])') +EMPTYSTRING = '' +NL = '\n' + +NeedMoreData = object() + + + +class BufferedSubFile(object): + """A file-ish object that can have new data loaded into it. + + You can also push and pop line-matching predicates onto a stack. When the + current predicate matches the current line, a false EOF response + (i.e. empty string) is returned instead. This lets the parser adhere to a + simple abstraction -- it parses until EOF closes the current message. + """ + def __init__(self): + # The last partial line pushed into this object. + self._partial = '' + # The list of full, pushed lines, in reverse order + self._lines = [] + # The stack of false-EOF checking predicates. + self._eofstack = [] + # A flag indicating whether the file has been closed or not. + self._closed = False + + def push_eof_matcher(self, pred): + self._eofstack.append(pred) + + def pop_eof_matcher(self): + return self._eofstack.pop() + + def close(self): + # Don't forget any trailing partial line. + self._lines.append(self._partial) + self._partial = '' + self._closed = True + + def readline(self): + if not self._lines: + if self._closed: + return '' + return NeedMoreData + # Pop the line off the stack and see if it matches the current + # false-EOF predicate. + line = self._lines.pop() + # RFC 2046, section 5.1.2 requires us to recognize outer level + # boundaries at any level of inner nesting. Do this, but be sure it's + # in the order of most to least nested. + for ateof in self._eofstack[::-1]: + if ateof(line): + # We're at the false EOF. But push the last line back first. + self._lines.append(line) + return '' + return line + + def unreadline(self, line): + # Let the consumer push a line back into the buffer. + assert line is not NeedMoreData + self._lines.append(line) + + def push(self, data): + """Push some new data into this object.""" + # Handle any previous leftovers + data, self._partial = self._partial + data, '' + # Crack into lines, but preserve the newlines on the end of each + parts = NLCRE_crack.split(data) + # The *ahem* interesting behaviour of re.split when supplied grouping + # parentheses is that the last element of the resulting list is the + # data after the final RE. In the case of a NL/CR terminated string, + # this is the empty string. + self._partial = parts.pop() + #GAN 29Mar09 bugs 1555570, 1721862 Confusion at 8K boundary ending with \r: + # is there a \n to follow later? + if not self._partial and parts and parts[-1].endswith('\r'): + self._partial = parts.pop(-2)+parts.pop() + # parts is a list of strings, alternating between the line contents + # and the eol character(s). Gather up a list of lines after + # re-attaching the newlines. + lines = [] + for i in range(len(parts) // 2): + lines.append(parts[i*2] + parts[i*2+1]) + self.pushlines(lines) + + def pushlines(self, lines): + # Reverse and insert at the front of the lines. + self._lines[:0] = lines[::-1] + + def is_closed(self): + return self._closed + + def __iter__(self): + return self + + def next(self): + line = self.readline() + if line == '': + raise StopIteration + return line + + + +class FeedParser: + """A feed-style parser of email.""" + + def __init__(self, _factory=message.Message): + """_factory is called with no arguments to create a new message obj""" + self._factory = _factory + self._input = BufferedSubFile() + self._msgstack = [] + self._parse = self._parsegen().next + self._cur = None + self._last = None + self._headersonly = False + + # Non-public interface for supporting Parser's headersonly flag + def _set_headersonly(self): + self._headersonly = True + + def feed(self, data): + """Push more data into the parser.""" + self._input.push(data) + self._call_parse() + + def _call_parse(self): + try: + self._parse() + except StopIteration: + pass + + def close(self): + """Parse all remaining data and return the root message object.""" + self._input.close() + self._call_parse() + root = self._pop_message() + assert not self._msgstack + # Look for final set of defects + if root.get_content_maintype() == 'multipart' \ + and not root.is_multipart(): + root.defects.append(errors.MultipartInvariantViolationDefect()) + return root + + def _new_message(self): + msg = self._factory() + if self._cur and self._cur.get_content_type() == 'multipart/digest': + msg.set_default_type('message/rfc822') + if self._msgstack: + self._msgstack[-1].attach(msg) + self._msgstack.append(msg) + self._cur = msg + self._last = msg + + def _pop_message(self): + retval = self._msgstack.pop() + if self._msgstack: + self._cur = self._msgstack[-1] + else: + self._cur = None + return retval + + def _parsegen(self): + # Create a new message and start by parsing headers. + self._new_message() + headers = [] + # Collect the headers, searching for a line that doesn't match the RFC + # 2822 header or continuation pattern (including an empty line). + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + if not headerRE.match(line): + # If we saw the RFC defined header/body separator + # (i.e. newline), just throw it away. Otherwise the line is + # part of the body so push it back. + if not NLCRE.match(line): + self._input.unreadline(line) + break + headers.append(line) + # Done with the headers, so parse them and figure out what we're + # supposed to see in the body of the message. + self._parse_headers(headers) + # Headers-only parsing is a backwards compatibility hack, which was + # necessary in the older parser, which could raise errors. All + # remaining lines in the input are thrown into the message body. + if self._headersonly: + lines = [] + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + if line == '': + break + lines.append(line) + self._cur.set_payload(EMPTYSTRING.join(lines)) + return + if self._cur.get_content_type() == 'message/delivery-status': + # message/delivery-status contains blocks of headers separated by + # a blank line. We'll represent each header block as a separate + # nested message object, but the processing is a bit different + # than standard message/* types because there is no body for the + # nested messages. A blank line separates the subparts. + while True: + self._input.push_eof_matcher(NLCRE.match) + for retval in self._parsegen(): + if retval is NeedMoreData: + yield NeedMoreData + continue + break + msg = self._pop_message() + # We need to pop the EOF matcher in order to tell if we're at + # the end of the current file, not the end of the last block + # of message headers. + self._input.pop_eof_matcher() + # The input stream must be sitting at the newline or at the + # EOF. We want to see if we're at the end of this subpart, so + # first consume the blank line, then test the next line to see + # if we're at this subpart's EOF. + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + break + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + break + if line == '': + break + # Not at EOF so this is a line we're going to need. + self._input.unreadline(line) + return + if self._cur.get_content_maintype() == 'message': + # The message claims to be a message/* type, then what follows is + # another RFC 2822 message. + for retval in self._parsegen(): + if retval is NeedMoreData: + yield NeedMoreData + continue + break + self._pop_message() + return + if self._cur.get_content_maintype() == 'multipart': + boundary = self._cur.get_boundary() + if boundary is None: + # The message /claims/ to be a multipart but it has not + # defined a boundary. That's a problem which we'll handle by + # reading everything until the EOF and marking the message as + # defective. + self._cur.defects.append(errors.NoBoundaryInMultipartDefect()) + lines = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + lines.append(line) + self._cur.set_payload(EMPTYSTRING.join(lines)) + return + # Create a line match predicate which matches the inter-part + # boundary as well as the end-of-multipart boundary. Don't push + # this onto the input stream until we've scanned past the + # preamble. + separator = '--' + boundary + boundaryre = re.compile( + '(?P<sep>' + re.escape(separator) + + r')(?P<end>--)?(?P<ws>[ \t]*)(?P<linesep>\r\n|\r|\n)?$') + capturing_preamble = True + preamble = [] + linesep = False + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + if line == '': + break + mo = boundaryre.match(line) + if mo: + # If we're looking at the end boundary, we're done with + # this multipart. If there was a newline at the end of + # the closing boundary, then we need to initialize the + # epilogue with the empty string (see below). + if mo.group('end'): + linesep = mo.group('linesep') + break + # We saw an inter-part boundary. Were we in the preamble? + if capturing_preamble: + if preamble: + # According to RFC 2046, the last newline belongs + # to the boundary. + lastline = preamble[-1] + eolmo = NLCRE_eol.search(lastline) + if eolmo: + preamble[-1] = lastline[:-len(eolmo.group(0))] + self._cur.preamble = EMPTYSTRING.join(preamble) + capturing_preamble = False + self._input.unreadline(line) + continue + # We saw a boundary separating two parts. Consume any + # multiple boundary lines that may be following. Our + # interpretation of RFC 2046 BNF grammar does not produce + # body parts within such double boundaries. + while True: + line = self._input.readline() + if line is NeedMoreData: + yield NeedMoreData + continue + mo = boundaryre.match(line) + if not mo: + self._input.unreadline(line) + break + # Recurse to parse this subpart; the input stream points + # at the subpart's first line. + self._input.push_eof_matcher(boundaryre.match) + for retval in self._parsegen(): + if retval is NeedMoreData: + yield NeedMoreData + continue + break + # Because of RFC 2046, the newline preceding the boundary + # separator actually belongs to the boundary, not the + # previous subpart's payload (or epilogue if the previous + # part is a multipart). + if self._last.get_content_maintype() == 'multipart': + epilogue = self._last.epilogue + if epilogue == '': + self._last.epilogue = None + elif epilogue is not None: + mo = NLCRE_eol.search(epilogue) + if mo: + end = len(mo.group(0)) + self._last.epilogue = epilogue[:-end] + else: + payload = self._last.get_payload() + if isinstance(payload, basestring): + mo = NLCRE_eol.search(payload) + if mo: + payload = payload[:-len(mo.group(0))] + self._last.set_payload(payload) + self._input.pop_eof_matcher() + self._pop_message() + # Set the multipart up for newline cleansing, which will + # happen if we're in a nested multipart. + self._last = self._cur + else: + # I think we must be in the preamble + assert capturing_preamble + preamble.append(line) + # We've seen either the EOF or the end boundary. If we're still + # capturing the preamble, we never saw the start boundary. Note + # that as a defect and store the captured text as the payload. + # Everything from here to the EOF is epilogue. + if capturing_preamble: + self._cur.defects.append(errors.StartBoundaryNotFoundDefect()) + self._cur.set_payload(EMPTYSTRING.join(preamble)) + epilogue = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + self._cur.epilogue = EMPTYSTRING.join(epilogue) + return + # If the end boundary ended in a newline, we'll need to make sure + # the epilogue isn't None + if linesep: + epilogue = [''] + else: + epilogue = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + epilogue.append(line) + # Any CRLF at the front of the epilogue is not technically part of + # the epilogue. Also, watch out for an empty string epilogue, + # which means a single newline. + if epilogue: + firstline = epilogue[0] + bolmo = NLCRE_bol.match(firstline) + if bolmo: + epilogue[0] = firstline[len(bolmo.group(0)):] + self._cur.epilogue = EMPTYSTRING.join(epilogue) + return + # Otherwise, it's some non-multipart type, so the entire rest of the + # file contents becomes the payload. + lines = [] + for line in self._input: + if line is NeedMoreData: + yield NeedMoreData + continue + lines.append(line) + self._cur.set_payload(EMPTYSTRING.join(lines)) + + def _parse_headers(self, lines): + # Passed a list of lines that make up the headers for the current msg + lastheader = '' + lastvalue = [] + for lineno, line in enumerate(lines): + # Check for continuation + if line[0] in ' \t': + if not lastheader: + # The first line of the headers was a continuation. This + # is illegal, so let's note the defect, store the illegal + # line, and ignore it for purposes of headers. + defect = errors.FirstHeaderLineIsContinuationDefect(line) + self._cur.defects.append(defect) + continue + lastvalue.append(line) + continue + if lastheader: + # XXX reconsider the joining of folded lines + lhdr = EMPTYSTRING.join(lastvalue)[:-1].rstrip('\r\n') + self._cur[lastheader] = lhdr + lastheader, lastvalue = '', [] + # Check for envelope header, i.e. unix-from + if line.startswith('From '): + if lineno == 0: + # Strip off the trailing newline + mo = NLCRE_eol.search(line) + if mo: + line = line[:-len(mo.group(0))] + self._cur.set_unixfrom(line) + continue + elif lineno == len(lines) - 1: + # Something looking like a unix-from at the end - it's + # probably the first line of the body, so push back the + # line and stop. + self._input.unreadline(line) + return + else: + # Weirdly placed unix-from line. Note this as a defect + # and ignore it. + defect = errors.MisplacedEnvelopeHeaderDefect(line) + self._cur.defects.append(defect) + continue + # Split the line on the colon separating field name from value. + i = line.find(':') + if i < 0: + defect = errors.MalformedHeaderDefect(line) + self._cur.defects.append(defect) + continue + lastheader = line[:i] + lastvalue = [line[i+1:].lstrip()] + # Done with all the lines, so handle the last header. + if lastheader: + # XXX reconsider the joining of folded lines + self._cur[lastheader] = EMPTYSTRING.join(lastvalue).rstrip('\r\n') diff --git a/src/main/resources/PythonLibs/email/generator.py b/src/main/resources/PythonLibs/email/generator.py new file mode 100644 index 0000000000000000000000000000000000000000..5626ab91eb57da6b0fbe54885dd71e6b17b12ec7 --- /dev/null +++ b/src/main/resources/PythonLibs/email/generator.py @@ -0,0 +1,372 @@ +# Copyright (C) 2001-2010 Python Software Foundation +# Contact: email-sig@python.org + +"""Classes to generate plain text from a message object tree.""" + +__all__ = ['Generator', 'DecodedGenerator'] + +import re +import sys +import time +import random +import warnings + +from cStringIO import StringIO +from email.header import Header + +UNDERSCORE = '_' +NL = '\n' + +fcre = re.compile(r'^From ', re.MULTILINE) + +def _is8bitstring(s): + if isinstance(s, str): + try: + unicode(s, 'us-ascii') + except UnicodeError: + return True + return False + + + +class Generator: + """Generates output from a Message object tree. + + This basic generator writes the message to the given file object as plain + text. + """ + # + # Public interface + # + + def __init__(self, outfp, mangle_from_=True, maxheaderlen=78): + """Create the generator for message flattening. + + outfp is the output file-like object for writing the message to. It + must have a write() method. + + Optional mangle_from_ is a flag that, when True (the default), escapes + From_ lines in the body of the message by putting a `>' in front of + them. + + Optional maxheaderlen specifies the longest length for a non-continued + header. When a header line is longer (in characters, with tabs + expanded to 8 spaces) than maxheaderlen, the header will split as + defined in the Header class. Set maxheaderlen to zero to disable + header wrapping. The default is 78, as recommended (but not required) + by RFC 2822. + """ + self._fp = outfp + self._mangle_from_ = mangle_from_ + self._maxheaderlen = maxheaderlen + + def write(self, s): + # Just delegate to the file object + self._fp.write(s) + + def flatten(self, msg, unixfrom=False): + """Print the message object tree rooted at msg to the output file + specified when the Generator instance was created. + + unixfrom is a flag that forces the printing of a Unix From_ delimiter + before the first object in the message tree. If the original message + has no From_ delimiter, a `standard' one is crafted. By default, this + is False to inhibit the printing of any From_ delimiter. + + Note that for subobjects, no From_ line is printed. + """ + if unixfrom: + ufrom = msg.get_unixfrom() + if not ufrom: + ufrom = 'From nobody ' + time.ctime(time.time()) + print >> self._fp, ufrom + self._write(msg) + + def clone(self, fp): + """Clone this generator with the exact same options.""" + return self.__class__(fp, self._mangle_from_, self._maxheaderlen) + + # + # Protected interface - undocumented ;/ + # + + def _write(self, msg): + # We can't write the headers yet because of the following scenario: + # say a multipart message includes the boundary string somewhere in + # its body. We'd have to calculate the new boundary /before/ we write + # the headers so that we can write the correct Content-Type: + # parameter. + # + # The way we do this, so as to make the _handle_*() methods simpler, + # is to cache any subpart writes into a StringIO. The we write the + # headers and the StringIO contents. That way, subpart handlers can + # Do The Right Thing, and can still modify the Content-Type: header if + # necessary. + oldfp = self._fp + try: + self._fp = sfp = StringIO() + self._dispatch(msg) + finally: + self._fp = oldfp + # Write the headers. First we see if the message object wants to + # handle that itself. If not, we'll do it generically. + meth = getattr(msg, '_write_headers', None) + if meth is None: + self._write_headers(msg) + else: + meth(self) + self._fp.write(sfp.getvalue()) + + def _dispatch(self, msg): + # Get the Content-Type: for the message, then try to dispatch to + # self._handle_<maintype>_<subtype>(). If there's no handler for the + # full MIME type, then dispatch to self._handle_<maintype>(). If + # that's missing too, then dispatch to self._writeBody(). + main = msg.get_content_maintype() + sub = msg.get_content_subtype() + specific = UNDERSCORE.join((main, sub)).replace('-', '_') + meth = getattr(self, '_handle_' + specific, None) + if meth is None: + generic = main.replace('-', '_') + meth = getattr(self, '_handle_' + generic, None) + if meth is None: + meth = self._writeBody + meth(msg) + + # + # Default handlers + # + + def _write_headers(self, msg): + for h, v in msg.items(): + print >> self._fp, '%s:' % h, + if self._maxheaderlen == 0: + # Explicit no-wrapping + print >> self._fp, v + elif isinstance(v, Header): + # Header instances know what to do + print >> self._fp, v.encode() + elif _is8bitstring(v): + # If we have raw 8bit data in a byte string, we have no idea + # what the encoding is. There is no safe way to split this + # string. If it's ascii-subset, then we could do a normal + # ascii split, but if it's multibyte then we could break the + # string. There's no way to know so the least harm seems to + # be to not split the string and risk it being too long. + print >> self._fp, v + else: + # Header's got lots of smarts, so use it. Note that this is + # fundamentally broken though because we lose idempotency when + # the header string is continued with tabs. It will now be + # continued with spaces. This was reversedly broken before we + # fixed bug 1974. Either way, we lose. + print >> self._fp, Header( + v, maxlinelen=self._maxheaderlen, header_name=h).encode() + # A blank line always separates headers from body + print >> self._fp + + # + # Handlers for writing types and subtypes + # + + def _handle_text(self, msg): + payload = msg.get_payload() + if payload is None: + return + if not isinstance(payload, basestring): + raise TypeError('string payload expected: %s' % type(payload)) + if self._mangle_from_: + payload = fcre.sub('>From ', payload) + self._fp.write(payload) + + # Default body handler + _writeBody = _handle_text + + def _handle_multipart(self, msg): + # The trick here is to write out each part separately, merge them all + # together, and then make sure that the boundary we've chosen isn't + # present in the payload. + msgtexts = [] + subparts = msg.get_payload() + if subparts is None: + subparts = [] + elif isinstance(subparts, basestring): + # e.g. a non-strict parse of a message with no starting boundary. + self._fp.write(subparts) + return + elif not isinstance(subparts, list): + # Scalar payload + subparts = [subparts] + for part in subparts: + s = StringIO() + g = self.clone(s) + g.flatten(part, unixfrom=False) + msgtexts.append(s.getvalue()) + # BAW: What about boundaries that are wrapped in double-quotes? + boundary = msg.get_boundary() + if not boundary: + # Create a boundary that doesn't appear in any of the + # message texts. + alltext = NL.join(msgtexts) + boundary = _make_boundary(alltext) + msg.set_boundary(boundary) + # If there's a preamble, write it out, with a trailing CRLF + if msg.preamble is not None: + if self._mangle_from_: + preamble = fcre.sub('>From ', msg.preamble) + else: + preamble = msg.preamble + print >> self._fp, preamble + # dash-boundary transport-padding CRLF + print >> self._fp, '--' + boundary + # body-part + if msgtexts: + self._fp.write(msgtexts.pop(0)) + # *encapsulation + # --> delimiter transport-padding + # --> CRLF body-part + for body_part in msgtexts: + # delimiter transport-padding CRLF + print >> self._fp, '\n--' + boundary + # body-part + self._fp.write(body_part) + # close-delimiter transport-padding + self._fp.write('\n--' + boundary + '--') + if msg.epilogue is not None: + print >> self._fp + if self._mangle_from_: + epilogue = fcre.sub('>From ', msg.epilogue) + else: + epilogue = msg.epilogue + self._fp.write(epilogue) + + def _handle_multipart_signed(self, msg): + # The contents of signed parts has to stay unmodified in order to keep + # the signature intact per RFC1847 2.1, so we disable header wrapping. + # RDM: This isn't enough to completely preserve the part, but it helps. + old_maxheaderlen = self._maxheaderlen + try: + self._maxheaderlen = 0 + self._handle_multipart(msg) + finally: + self._maxheaderlen = old_maxheaderlen + + def _handle_message_delivery_status(self, msg): + # We can't just write the headers directly to self's file object + # because this will leave an extra newline between the last header + # block and the boundary. Sigh. + blocks = [] + for part in msg.get_payload(): + s = StringIO() + g = self.clone(s) + g.flatten(part, unixfrom=False) + text = s.getvalue() + lines = text.split('\n') + # Strip off the unnecessary trailing empty line + if lines and lines[-1] == '': + blocks.append(NL.join(lines[:-1])) + else: + blocks.append(text) + # Now join all the blocks with an empty line. This has the lovely + # effect of separating each block with an empty line, but not adding + # an extra one after the last one. + self._fp.write(NL.join(blocks)) + + def _handle_message(self, msg): + s = StringIO() + g = self.clone(s) + # The payload of a message/rfc822 part should be a multipart sequence + # of length 1. The zeroth element of the list should be the Message + # object for the subpart. Extract that object, stringify it, and + # write it out. + # Except, it turns out, when it's a string instead, which happens when + # and only when HeaderParser is used on a message of mime type + # message/rfc822. Such messages are generated by, for example, + # Groupwise when forwarding unadorned messages. (Issue 7970.) So + # in that case we just emit the string body. + payload = msg.get_payload() + if isinstance(payload, list): + g.flatten(msg.get_payload(0), unixfrom=False) + payload = s.getvalue() + self._fp.write(payload) + + + +_FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]' + +class DecodedGenerator(Generator): + """Generates a text representation of a message. + + Like the Generator base class, except that non-text parts are substituted + with a format string representing the part. + """ + def __init__(self, outfp, mangle_from_=True, maxheaderlen=78, fmt=None): + """Like Generator.__init__() except that an additional optional + argument is allowed. + + Walks through all subparts of a message. If the subpart is of main + type `text', then it prints the decoded payload of the subpart. + + Otherwise, fmt is a format string that is used instead of the message + payload. fmt is expanded with the following keywords (in + %(keyword)s format): + + type : Full MIME type of the non-text part + maintype : Main MIME type of the non-text part + subtype : Sub-MIME type of the non-text part + filename : Filename of the non-text part + description: Description associated with the non-text part + encoding : Content transfer encoding of the non-text part + + The default value for fmt is None, meaning + + [Non-text (%(type)s) part of message omitted, filename %(filename)s] + """ + Generator.__init__(self, outfp, mangle_from_, maxheaderlen) + if fmt is None: + self._fmt = _FMT + else: + self._fmt = fmt + + def _dispatch(self, msg): + for part in msg.walk(): + maintype = part.get_content_maintype() + if maintype == 'text': + print >> self, part.get_payload(decode=True) + elif maintype == 'multipart': + # Just skip this + pass + else: + print >> self, self._fmt % { + 'type' : part.get_content_type(), + 'maintype' : part.get_content_maintype(), + 'subtype' : part.get_content_subtype(), + 'filename' : part.get_filename('[no filename]'), + 'description': part.get('Content-Description', + '[no description]'), + 'encoding' : part.get('Content-Transfer-Encoding', + '[no encoding]'), + } + + + +# Helper +_width = len(repr(sys.maxint-1)) +_fmt = '%%0%dd' % _width + +def _make_boundary(text=None): + # Craft a random boundary. If text is given, ensure that the chosen + # boundary doesn't appear in the text. + token = random.randrange(sys.maxint) + boundary = ('=' * 15) + (_fmt % token) + '==' + if text is None: + return boundary + b = boundary + counter = 0 + while True: + cre = re.compile('^--' + re.escape(b) + '(--)?$', re.MULTILINE) + if not cre.search(text): + break + b = boundary + '.' + str(counter) + counter += 1 + return b diff --git a/src/main/resources/PythonLibs/email/header.py b/src/main/resources/PythonLibs/email/header.py new file mode 100644 index 0000000000000000000000000000000000000000..2cf870fd575f9a3d8109d17ac3c30989f2b414db --- /dev/null +++ b/src/main/resources/PythonLibs/email/header.py @@ -0,0 +1,514 @@ +# Copyright (C) 2002-2006 Python Software Foundation +# Author: Ben Gertzfield, Barry Warsaw +# Contact: email-sig@python.org + +"""Header encoding and decoding functionality.""" + +__all__ = [ + 'Header', + 'decode_header', + 'make_header', + ] + +import re +import binascii + +import email.quoprimime +import email.base64mime + +from email.errors import HeaderParseError +from email.charset import Charset + +NL = '\n' +SPACE = ' ' +USPACE = u' ' +SPACE8 = ' ' * 8 +UEMPTYSTRING = u'' + +MAXLINELEN = 76 + +USASCII = Charset('us-ascii') +UTF8 = Charset('utf-8') + +# Match encoded-word strings in the form =?charset?q?Hello_World?= +ecre = re.compile(r''' + =\? # literal =? + (?P<charset>[^?]*?) # non-greedy up to the next ? is the charset + \? # literal ? + (?P<encoding>[qb]) # either a "q" or a "b", case insensitive + \? # literal ? + (?P<encoded>.*?) # non-greedy up to the next ?= is the encoded string + \?= # literal ?= + (?=[ \t]|$) # whitespace or the end of the string + ''', re.VERBOSE | re.IGNORECASE | re.MULTILINE) + +# Field name regexp, including trailing colon, but not separating whitespace, +# according to RFC 2822. Character range is from tilde to exclamation mark. +# For use with .match() +fcre = re.compile(r'[\041-\176]+:$') + +# Find a header embedded in a putative header value. Used to check for +# header injection attack. +_embeded_header = re.compile(r'\n[^ \t]+:') + + + +# Helpers +_max_append = email.quoprimime._max_append + + + +def decode_header(header): + """Decode a message header value without converting charset. + + Returns a list of (decoded_string, charset) pairs containing each of the + decoded parts of the header. Charset is None for non-encoded parts of the + header, otherwise a lower-case string containing the name of the character + set specified in the encoded string. + + An email.errors.HeaderParseError may be raised when certain decoding error + occurs (e.g. a base64 decoding exception). + """ + # If no encoding, just return the header + header = str(header) + if not ecre.search(header): + return [(header, None)] + decoded = [] + dec = '' + for line in header.splitlines(): + # This line might not have an encoding in it + if not ecre.search(line): + decoded.append((line, None)) + continue + parts = ecre.split(line) + while parts: + unenc = parts.pop(0).strip() + if unenc: + # Should we continue a long line? + if decoded and decoded[-1][1] is None: + decoded[-1] = (decoded[-1][0] + SPACE + unenc, None) + else: + decoded.append((unenc, None)) + if parts: + charset, encoding = [s.lower() for s in parts[0:2]] + encoded = parts[2] + dec = None + if encoding == 'q': + dec = email.quoprimime.header_decode(encoded) + elif encoding == 'b': + paderr = len(encoded) % 4 # Postel's law: add missing padding + if paderr: + encoded += '==='[:4 - paderr] + try: + dec = email.base64mime.decode(encoded) + except binascii.Error: + # Turn this into a higher level exception. BAW: Right + # now we throw the lower level exception away but + # when/if we get exception chaining, we'll preserve it. + raise HeaderParseError + if dec is None: + dec = encoded + + if decoded and decoded[-1][1] == charset: + decoded[-1] = (decoded[-1][0] + dec, decoded[-1][1]) + else: + decoded.append((dec, charset)) + del parts[0:3] + return decoded + + + +def make_header(decoded_seq, maxlinelen=None, header_name=None, + continuation_ws=' '): + """Create a Header from a sequence of pairs as returned by decode_header() + + decode_header() takes a header value string and returns a sequence of + pairs of the format (decoded_string, charset) where charset is the string + name of the character set. + + This function takes one of those sequence of pairs and returns a Header + instance. Optional maxlinelen, header_name, and continuation_ws are as in + the Header constructor. + """ + h = Header(maxlinelen=maxlinelen, header_name=header_name, + continuation_ws=continuation_ws) + for s, charset in decoded_seq: + # None means us-ascii but we can simply pass it on to h.append() + if charset is not None and not isinstance(charset, Charset): + charset = Charset(charset) + h.append(s, charset) + return h + + + +class Header: + def __init__(self, s=None, charset=None, + maxlinelen=None, header_name=None, + continuation_ws=' ', errors='strict'): + """Create a MIME-compliant header that can contain many character sets. + + Optional s is the initial header value. If None, the initial header + value is not set. You can later append to the header with .append() + method calls. s may be a byte string or a Unicode string, but see the + .append() documentation for semantics. + + Optional charset serves two purposes: it has the same meaning as the + charset argument to the .append() method. It also sets the default + character set for all subsequent .append() calls that omit the charset + argument. If charset is not provided in the constructor, the us-ascii + charset is used both as s's initial charset and as the default for + subsequent .append() calls. + + The maximum line length can be specified explicit via maxlinelen. For + splitting the first line to a shorter value (to account for the field + header which isn't included in s, e.g. `Subject') pass in the name of + the field in header_name. The default maxlinelen is 76. + + continuation_ws must be RFC 2822 compliant folding whitespace (usually + either a space or a hard tab) which will be prepended to continuation + lines. + + errors is passed through to the .append() call. + """ + if charset is None: + charset = USASCII + if not isinstance(charset, Charset): + charset = Charset(charset) + self._charset = charset + self._continuation_ws = continuation_ws + cws_expanded_len = len(continuation_ws.replace('\t', SPACE8)) + # BAW: I believe `chunks' and `maxlinelen' should be non-public. + self._chunks = [] + if s is not None: + self.append(s, charset, errors) + if maxlinelen is None: + maxlinelen = MAXLINELEN + if header_name is None: + # We don't know anything about the field header so the first line + # is the same length as subsequent lines. + self._firstlinelen = maxlinelen + else: + # The first line should be shorter to take into account the field + # header. Also subtract off 2 extra for the colon and space. + self._firstlinelen = maxlinelen - len(header_name) - 2 + # Second and subsequent lines should subtract off the length in + # columns of the continuation whitespace prefix. + self._maxlinelen = maxlinelen - cws_expanded_len + + def __str__(self): + """A synonym for self.encode().""" + return self.encode() + + def __unicode__(self): + """Helper for the built-in unicode function.""" + uchunks = [] + lastcs = None + for s, charset in self._chunks: + # We must preserve spaces between encoded and non-encoded word + # boundaries, which means for us we need to add a space when we go + # from a charset to None/us-ascii, or from None/us-ascii to a + # charset. Only do this for the second and subsequent chunks. + nextcs = charset + if uchunks: + if lastcs not in (None, 'us-ascii'): + if nextcs in (None, 'us-ascii'): + uchunks.append(USPACE) + nextcs = None + elif nextcs not in (None, 'us-ascii'): + uchunks.append(USPACE) + lastcs = nextcs + uchunks.append(unicode(s, str(charset))) + return UEMPTYSTRING.join(uchunks) + + # Rich comparison operators for equality only. BAW: does it make sense to + # have or explicitly disable <, <=, >, >= operators? + def __eq__(self, other): + # other may be a Header or a string. Both are fine so coerce + # ourselves to a string, swap the args and do another comparison. + return other == self.encode() + + def __ne__(self, other): + return not self == other + + def append(self, s, charset=None, errors='strict'): + """Append a string to the MIME header. + + Optional charset, if given, should be a Charset instance or the name + of a character set (which will be converted to a Charset instance). A + value of None (the default) means that the charset given in the + constructor is used. + + s may be a byte string or a Unicode string. If it is a byte string + (i.e. isinstance(s, str) is true), then charset is the encoding of + that byte string, and a UnicodeError will be raised if the string + cannot be decoded with that charset. If s is a Unicode string, then + charset is a hint specifying the character set of the characters in + the string. In this case, when producing an RFC 2822 compliant header + using RFC 2047 rules, the Unicode string will be encoded using the + following charsets in order: us-ascii, the charset hint, utf-8. The + first character set not to provoke a UnicodeError is used. + + Optional `errors' is passed as the third argument to any unicode() or + ustr.encode() call. + """ + if charset is None: + charset = self._charset + elif not isinstance(charset, Charset): + charset = Charset(charset) + # If the charset is our faux 8bit charset, leave the string unchanged + if charset != '8bit': + # We need to test that the string can be converted to unicode and + # back to a byte string, given the input and output codecs of the + # charset. + if isinstance(s, str): + # Possibly raise UnicodeError if the byte string can't be + # converted to a unicode with the input codec of the charset. + incodec = charset.input_codec or 'us-ascii' + ustr = unicode(s, incodec, errors) + # Now make sure that the unicode could be converted back to a + # byte string with the output codec, which may be different + # than the iput coded. Still, use the original byte string. + outcodec = charset.output_codec or 'us-ascii' + ustr.encode(outcodec, errors) + elif isinstance(s, unicode): + # Now we have to be sure the unicode string can be converted + # to a byte string with a reasonable output codec. We want to + # use the byte string in the chunk. + for charset in USASCII, charset, UTF8: + try: + outcodec = charset.output_codec or 'us-ascii' + s = s.encode(outcodec, errors) + break + except UnicodeError: + pass + else: + assert False, 'utf-8 conversion failed' + self._chunks.append((s, charset)) + + def _split(self, s, charset, maxlinelen, splitchars): + # Split up a header safely for use with encode_chunks. + splittable = charset.to_splittable(s) + encoded = charset.from_splittable(splittable, True) + elen = charset.encoded_header_len(encoded) + # If the line's encoded length first, just return it + if elen <= maxlinelen: + return [(encoded, charset)] + # If we have undetermined raw 8bit characters sitting in a byte + # string, we really don't know what the right thing to do is. We + # can't really split it because it might be multibyte data which we + # could break if we split it between pairs. The least harm seems to + # be to not split the header at all, but that means they could go out + # longer than maxlinelen. + if charset == '8bit': + return [(s, charset)] + # BAW: I'm not sure what the right test here is. What we're trying to + # do is be faithful to RFC 2822's recommendation that ($2.2.3): + # + # "Note: Though structured field bodies are defined in such a way that + # folding can take place between many of the lexical tokens (and even + # within some of the lexical tokens), folding SHOULD be limited to + # placing the CRLF at higher-level syntactic breaks." + # + # For now, I can only imagine doing this when the charset is us-ascii, + # although it's possible that other charsets may also benefit from the + # higher-level syntactic breaks. + elif charset == 'us-ascii': + return self._split_ascii(s, charset, maxlinelen, splitchars) + # BAW: should we use encoded? + elif elen == len(s): + # We can split on _maxlinelen boundaries because we know that the + # encoding won't change the size of the string + splitpnt = maxlinelen + first = charset.from_splittable(splittable[:splitpnt], False) + last = charset.from_splittable(splittable[splitpnt:], False) + else: + # Binary search for split point + first, last = _binsplit(splittable, charset, maxlinelen) + # first is of the proper length so just wrap it in the appropriate + # chrome. last must be recursively split. + fsplittable = charset.to_splittable(first) + fencoded = charset.from_splittable(fsplittable, True) + chunk = [(fencoded, charset)] + return chunk + self._split(last, charset, self._maxlinelen, splitchars) + + def _split_ascii(self, s, charset, firstlen, splitchars): + chunks = _split_ascii(s, firstlen, self._maxlinelen, + self._continuation_ws, splitchars) + return zip(chunks, [charset]*len(chunks)) + + def _encode_chunks(self, newchunks, maxlinelen): + # MIME-encode a header with many different charsets and/or encodings. + # + # Given a list of pairs (string, charset), return a MIME-encoded + # string suitable for use in a header field. Each pair may have + # different charsets and/or encodings, and the resulting header will + # accurately reflect each setting. + # + # Each encoding can be email.utils.QP (quoted-printable, for + # ASCII-like character sets like iso-8859-1), email.utils.BASE64 + # (Base64, for non-ASCII like character sets like KOI8-R and + # iso-2022-jp), or None (no encoding). + # + # Each pair will be represented on a separate line; the resulting + # string will be in the format: + # + # =?charset1?q?Mar=EDa_Gonz=E1lez_Alonso?=\n + # =?charset2?b?SvxyZ2VuIEL2aW5n?=" + chunks = [] + for header, charset in newchunks: + if not header: + continue + if charset is None or charset.header_encoding is None: + s = header + else: + s = charset.header_encode(header) + # Don't add more folding whitespace than necessary + if chunks and chunks[-1].endswith(' '): + extra = '' + else: + extra = ' ' + _max_append(chunks, s, maxlinelen, extra) + joiner = NL + self._continuation_ws + return joiner.join(chunks) + + def encode(self, splitchars=';, '): + """Encode a message header into an RFC-compliant format. + + There are many issues involved in converting a given string for use in + an email header. Only certain character sets are readable in most + email clients, and as header strings can only contain a subset of + 7-bit ASCII, care must be taken to properly convert and encode (with + Base64 or quoted-printable) header strings. In addition, there is a + 75-character length limit on any given encoded header field, so + line-wrapping must be performed, even with double-byte character sets. + + This method will do its best to convert the string to the correct + character set used in email, and encode and line wrap it safely with + the appropriate scheme for that character set. + + If the given charset is not known or an error occurs during + conversion, this function will return the header untouched. + + Optional splitchars is a string containing characters to split long + ASCII lines on, in rough support of RFC 2822's `highest level + syntactic breaks'. This doesn't affect RFC 2047 encoded lines. + """ + newchunks = [] + maxlinelen = self._firstlinelen + lastlen = 0 + for s, charset in self._chunks: + # The first bit of the next chunk should be just long enough to + # fill the next line. Don't forget the space separating the + # encoded words. + targetlen = maxlinelen - lastlen - 1 + if targetlen < charset.encoded_header_len(''): + # Stick it on the next line + targetlen = maxlinelen + newchunks += self._split(s, charset, targetlen, splitchars) + lastchunk, lastcharset = newchunks[-1] + lastlen = lastcharset.encoded_header_len(lastchunk) + value = self._encode_chunks(newchunks, maxlinelen) + if _embeded_header.search(value): + raise HeaderParseError("header value appears to contain " + "an embedded header: {!r}".format(value)) + return value + + + +def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars): + lines = [] + maxlen = firstlen + for line in s.splitlines(): + # Ignore any leading whitespace (i.e. continuation whitespace) already + # on the line, since we'll be adding our own. + line = line.lstrip() + if len(line) < maxlen: + lines.append(line) + maxlen = restlen + continue + # Attempt to split the line at the highest-level syntactic break + # possible. Note that we don't have a lot of smarts about field + # syntax; we just try to break on semi-colons, then commas, then + # whitespace. + for ch in splitchars: + if ch in line: + break + else: + # There's nothing useful to split the line on, not even spaces, so + # just append this line unchanged + lines.append(line) + maxlen = restlen + continue + # Now split the line on the character plus trailing whitespace + cre = re.compile(r'%s\s*' % ch) + if ch in ';,': + eol = ch + else: + eol = '' + joiner = eol + ' ' + joinlen = len(joiner) + wslen = len(continuation_ws.replace('\t', SPACE8)) + this = [] + linelen = 0 + for part in cre.split(line): + curlen = linelen + max(0, len(this)-1) * joinlen + partlen = len(part) + onfirstline = not lines + # We don't want to split after the field name, if we're on the + # first line and the field name is present in the header string. + if ch == ' ' and onfirstline and \ + len(this) == 1 and fcre.match(this[0]): + this.append(part) + linelen += partlen + elif curlen + partlen > maxlen: + if this: + lines.append(joiner.join(this) + eol) + # If this part is longer than maxlen and we aren't already + # splitting on whitespace, try to recursively split this line + # on whitespace. + if partlen > maxlen and ch != ' ': + subl = _split_ascii(part, maxlen, restlen, + continuation_ws, ' ') + lines.extend(subl[:-1]) + this = [subl[-1]] + else: + this = [part] + linelen = wslen + len(this[-1]) + maxlen = restlen + else: + this.append(part) + linelen += partlen + # Put any left over parts on a line by themselves + if this: + lines.append(joiner.join(this)) + return lines + + + +def _binsplit(splittable, charset, maxlinelen): + i = 0 + j = len(splittable) + while i < j: + # Invariants: + # 1. splittable[:k] fits for all k <= i (note that we *assume*, + # at the start, that splittable[:0] fits). + # 2. splittable[:k] does not fit for any k > j (at the start, + # this means we shouldn't look at any k > len(splittable)). + # 3. We don't know about splittable[:k] for k in i+1..j. + # 4. We want to set i to the largest k that fits, with i <= k <= j. + # + m = (i+j+1) >> 1 # ceiling((i+j)/2); i < m <= j + chunk = charset.from_splittable(splittable[:m], True) + chunklen = charset.encoded_header_len(chunk) + if chunklen <= maxlinelen: + # m is acceptable, so is a new lower bound. + i = m + else: + # m is not acceptable, so final i must be < m. + j = m - 1 + # i == j. Invariant #1 implies that splittable[:i] fits, and + # invariant #2 implies that splittable[:i+1] does not fit, so i + # is what we're looking for. + first = charset.from_splittable(splittable[:i], False) + last = charset.from_splittable(splittable[i:], False) + return first, last diff --git a/src/main/resources/PythonLibs/email/iterators.py b/src/main/resources/PythonLibs/email/iterators.py new file mode 100644 index 0000000000000000000000000000000000000000..e99f2280da3814421db67c476902cbeab96280c7 --- /dev/null +++ b/src/main/resources/PythonLibs/email/iterators.py @@ -0,0 +1,73 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Various types of useful iterators and generators.""" + +__all__ = [ + 'body_line_iterator', + 'typed_subpart_iterator', + 'walk', + # Do not include _structure() since it's part of the debugging API. + ] + +import sys +from cStringIO import StringIO + + + +# This function will become a method of the Message class +def walk(self): + """Walk over the message tree, yielding each subpart. + + The walk is performed in depth-first order. This method is a + generator. + """ + yield self + if self.is_multipart(): + for subpart in self.get_payload(): + for subsubpart in subpart.walk(): + yield subsubpart + + + +# These two functions are imported into the Iterators.py interface module. +def body_line_iterator(msg, decode=False): + """Iterate over the parts, returning string payloads line-by-line. + + Optional decode (default False) is passed through to .get_payload(). + """ + for subpart in msg.walk(): + payload = subpart.get_payload(decode=decode) + if isinstance(payload, basestring): + for line in StringIO(payload): + yield line + + +def typed_subpart_iterator(msg, maintype='text', subtype=None): + """Iterate over the subparts with a given MIME type. + + Use `maintype' as the main MIME type to match against; this defaults to + "text". Optional `subtype' is the MIME subtype to match against; if + omitted, only the main type is matched. + """ + for subpart in msg.walk(): + if subpart.get_content_maintype() == maintype: + if subtype is None or subpart.get_content_subtype() == subtype: + yield subpart + + + +def _structure(msg, fp=None, level=0, include_default=False): + """A handy debugging aid""" + if fp is None: + fp = sys.stdout + tab = ' ' * (level * 4) + print >> fp, tab + msg.get_content_type(), + if include_default: + print >> fp, '[%s]' % msg.get_default_type() + else: + print >> fp + if msg.is_multipart(): + for subpart in msg.get_payload(): + _structure(subpart, fp, level+1, include_default) diff --git a/src/main/resources/PythonLibs/email/message.py b/src/main/resources/PythonLibs/email/message.py new file mode 100644 index 0000000000000000000000000000000000000000..7c93370984c0d040dde803bd88101c2bbde0d1ea --- /dev/null +++ b/src/main/resources/PythonLibs/email/message.py @@ -0,0 +1,797 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Basic message object for the email package object model.""" + +__all__ = ['Message'] + +import re +import uu +import binascii +import warnings +from cStringIO import StringIO + +# Intrapackage imports +import email.charset +from email import utils +from email import errors + +SEMISPACE = '; ' + +# Regular expression that matches `special' characters in parameters, the +# existence of which force quoting of the parameter value. +tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]') + + +# Helper functions +def _splitparam(param): + # Split header parameters. BAW: this may be too simple. It isn't + # strictly RFC 2045 (section 5.1) compliant, but it catches most headers + # found in the wild. We may eventually need a full fledged parser + # eventually. + a, sep, b = param.partition(';') + if not sep: + return a.strip(), None + return a.strip(), b.strip() + +def _formatparam(param, value=None, quote=True): + """Convenience function to format and return a key=value pair. + + This will quote the value if needed or if quote is true. If value is a + three tuple (charset, language, value), it will be encoded according + to RFC2231 rules. + """ + if value is not None and len(value) > 0: + # A tuple is used for RFC 2231 encoded parameter values where items + # are (charset, language, value). charset is a string, not a Charset + # instance. + if isinstance(value, tuple): + # Encode as per RFC 2231 + param += '*' + value = utils.encode_rfc2231(value[2], value[0], value[1]) + # BAW: Please check this. I think that if quote is set it should + # force quoting even if not necessary. + if quote or tspecials.search(value): + return '%s="%s"' % (param, utils.quote(value)) + else: + return '%s=%s' % (param, value) + else: + return param + +def _parseparam(s): + plist = [] + while s[:1] == ';': + s = s[1:] + end = s.find(';') + while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: + end = s.find(';', end + 1) + if end < 0: + end = len(s) + f = s[:end] + if '=' in f: + i = f.index('=') + f = f[:i].strip().lower() + '=' + f[i+1:].strip() + plist.append(f.strip()) + s = s[end:] + return plist + + +def _unquotevalue(value): + # This is different than utils.collapse_rfc2231_value() because it doesn't + # try to convert the value to a unicode. Message.get_param() and + # Message.get_params() are both currently defined to return the tuple in + # the face of RFC 2231 parameters. + if isinstance(value, tuple): + return value[0], value[1], utils.unquote(value[2]) + else: + return utils.unquote(value) + + + +class Message: + """Basic message object. + + A message object is defined as something that has a bunch of RFC 2822 + headers and a payload. It may optionally have an envelope header + (a.k.a. Unix-From or From_ header). If the message is a container (i.e. a + multipart or a message/rfc822), then the payload is a list of Message + objects, otherwise it is a string. + + Message objects implement part of the `mapping' interface, which assumes + there is exactly one occurrence of the header per message. Some headers + do in fact appear multiple times (e.g. Received) and for those headers, + you must use the explicit API to set or get all the headers. Not all of + the mapping methods are implemented. + """ + def __init__(self): + self._headers = [] + self._unixfrom = None + self._payload = None + self._charset = None + # Defaults for multipart messages + self.preamble = self.epilogue = None + self.defects = [] + # Default content type + self._default_type = 'text/plain' + + def __str__(self): + """Return the entire formatted message as a string. + This includes the headers, body, and envelope header. + """ + return self.as_string(unixfrom=True) + + def as_string(self, unixfrom=False): + """Return the entire formatted message as a string. + Optional `unixfrom' when True, means include the Unix From_ envelope + header. + + This is a convenience method and may not generate the message exactly + as you intend because by default it mangles lines that begin with + "From ". For more flexibility, use the flatten() method of a + Generator instance. + """ + from email.generator import Generator + fp = StringIO() + g = Generator(fp) + g.flatten(self, unixfrom=unixfrom) + return fp.getvalue() + + def is_multipart(self): + """Return True if the message consists of multiple parts.""" + return isinstance(self._payload, list) + + # + # Unix From_ line + # + def set_unixfrom(self, unixfrom): + self._unixfrom = unixfrom + + def get_unixfrom(self): + return self._unixfrom + + # + # Payload manipulation. + # + def attach(self, payload): + """Add the given payload to the current payload. + + The current payload will always be a list of objects after this method + is called. If you want to set the payload to a scalar object, use + set_payload() instead. + """ + if self._payload is None: + self._payload = [payload] + else: + self._payload.append(payload) + + def get_payload(self, i=None, decode=False): + """Return a reference to the payload. + + The payload will either be a list object or a string. If you mutate + the list object, you modify the message's payload in place. Optional + i returns that index into the payload. + + Optional decode is a flag indicating whether the payload should be + decoded or not, according to the Content-Transfer-Encoding header + (default is False). + + When True and the message is not a multipart, the payload will be + decoded if this header's value is `quoted-printable' or `base64'. If + some other encoding is used, or the header is missing, or if the + payload has bogus data (i.e. bogus base64 or uuencoded data), the + payload is returned as-is. + + If the message is a multipart and the decode flag is True, then None + is returned. + """ + if i is None: + payload = self._payload + elif not isinstance(self._payload, list): + raise TypeError('Expected list, got %s' % type(self._payload)) + else: + payload = self._payload[i] + if decode: + if self.is_multipart(): + return None + cte = self.get('content-transfer-encoding', '').lower() + if cte == 'quoted-printable': + return utils._qdecode(payload) + elif cte == 'base64': + try: + return utils._bdecode(payload) + except binascii.Error: + # Incorrect padding + return payload + elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): + sfp = StringIO() + try: + uu.decode(StringIO(payload+'\n'), sfp, quiet=True) + payload = sfp.getvalue() + except uu.Error: + # Some decoding problem + return payload + # Everything else, including encodings with 8bit or 7bit are returned + # unchanged. + return payload + + def set_payload(self, payload, charset=None): + """Set the payload to the given value. + + Optional charset sets the message's default character set. See + set_charset() for details. + """ + self._payload = payload + if charset is not None: + self.set_charset(charset) + + def set_charset(self, charset): + """Set the charset of the payload to a given character set. + + charset can be a Charset instance, a string naming a character set, or + None. If it is a string it will be converted to a Charset instance. + If charset is None, the charset parameter will be removed from the + Content-Type field. Anything else will generate a TypeError. + + The message will be assumed to be of type text/* encoded with + charset.input_charset. It will be converted to charset.output_charset + and encoded properly, if needed, when generating the plain text + representation of the message. MIME headers (MIME-Version, + Content-Type, Content-Transfer-Encoding) will be added as needed. + + """ + if charset is None: + self.del_param('charset') + self._charset = None + return + if isinstance(charset, basestring): + charset = email.charset.Charset(charset) + if not isinstance(charset, email.charset.Charset): + raise TypeError(charset) + # BAW: should we accept strings that can serve as arguments to the + # Charset constructor? + self._charset = charset + if 'MIME-Version' not in self: + self.add_header('MIME-Version', '1.0') + if 'Content-Type' not in self: + self.add_header('Content-Type', 'text/plain', + charset=charset.get_output_charset()) + else: + self.set_param('charset', charset.get_output_charset()) + if isinstance(self._payload, unicode): + self._payload = self._payload.encode(charset.output_charset) + if str(charset) != charset.get_output_charset(): + self._payload = charset.body_encode(self._payload) + if 'Content-Transfer-Encoding' not in self: + cte = charset.get_body_encoding() + try: + cte(self) + except TypeError: + self._payload = charset.body_encode(self._payload) + self.add_header('Content-Transfer-Encoding', cte) + + def get_charset(self): + """Return the Charset instance associated with the message's payload. + """ + return self._charset + + # + # MAPPING INTERFACE (partial) + # + def __len__(self): + """Return the total number of headers, including duplicates.""" + return len(self._headers) + + def __getitem__(self, name): + """Get a header value. + + Return None if the header is missing instead of raising an exception. + + Note that if the header appeared multiple times, exactly which + occurrence gets returned is undefined. Use get_all() to get all + the values matching a header field name. + """ + return self.get(name) + + def __setitem__(self, name, val): + """Set the value of a header. + + Note: this does not overwrite an existing header with the same field + name. Use __delitem__() first to delete any existing headers. + """ + self._headers.append((name, val)) + + def __delitem__(self, name): + """Delete all occurrences of a header, if present. + + Does not raise an exception if the header is missing. + """ + name = name.lower() + newheaders = [] + for k, v in self._headers: + if k.lower() != name: + newheaders.append((k, v)) + self._headers = newheaders + + def __contains__(self, name): + return name.lower() in [k.lower() for k, v in self._headers] + + def has_key(self, name): + """Return true if the message contains the header.""" + missing = object() + return self.get(name, missing) is not missing + + def keys(self): + """Return a list of all the message's header field names. + + These will be sorted in the order they appeared in the original + message, or were added to the message, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return [k for k, v in self._headers] + + def values(self): + """Return a list of all the message's header values. + + These will be sorted in the order they appeared in the original + message, or were added to the message, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return [v for k, v in self._headers] + + def items(self): + """Get all the message's header fields and values. + + These will be sorted in the order they appeared in the original + message, or were added to the message, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return self._headers[:] + + def get(self, name, failobj=None): + """Get a header value. + + Like __getitem__() but return failobj instead of None when the field + is missing. + """ + name = name.lower() + for k, v in self._headers: + if k.lower() == name: + return v + return failobj + + # + # Additional useful stuff + # + + def get_all(self, name, failobj=None): + """Return a list of all the values for the named field. + + These will be sorted in the order they appeared in the original + message, and may contain duplicates. Any fields deleted and + re-inserted are always appended to the header list. + + If no such fields exist, failobj is returned (defaults to None). + """ + values = [] + name = name.lower() + for k, v in self._headers: + if k.lower() == name: + values.append(v) + if not values: + return failobj + return values + + def add_header(self, _name, _value, **_params): + """Extended header setting. + + name is the header field to add. keyword arguments can be used to set + additional parameters for the header field, with underscores converted + to dashes. Normally the parameter will be added as key="value" unless + value is None, in which case only the key will be added. If a + parameter value contains non-ASCII characters it must be specified as a + three-tuple of (charset, language, value), in which case it will be + encoded according to RFC2231 rules. + + Example: + + msg.add_header('content-disposition', 'attachment', filename='bud.gif') + """ + parts = [] + for k, v in _params.items(): + if v is None: + parts.append(k.replace('_', '-')) + else: + parts.append(_formatparam(k.replace('_', '-'), v)) + if _value is not None: + parts.insert(0, _value) + self._headers.append((_name, SEMISPACE.join(parts))) + + def replace_header(self, _name, _value): + """Replace a header. + + Replace the first matching header found in the message, retaining + header order and case. If no matching header was found, a KeyError is + raised. + """ + _name = _name.lower() + for i, (k, v) in zip(range(len(self._headers)), self._headers): + if k.lower() == _name: + self._headers[i] = (k, _value) + break + else: + raise KeyError(_name) + + # + # Use these three methods instead of the three above. + # + + def get_content_type(self): + """Return the message's content type. + + The returned string is coerced to lower case of the form + `maintype/subtype'. If there was no Content-Type header in the + message, the default type as given by get_default_type() will be + returned. Since according to RFC 2045, messages always have a default + type this will always return a value. + + RFC 2045 defines a message's default type to be text/plain unless it + appears inside a multipart/digest container, in which case it would be + message/rfc822. + """ + missing = object() + value = self.get('content-type', missing) + if value is missing: + # This should have no parameters + return self.get_default_type() + ctype = _splitparam(value)[0].lower() + # RFC 2045, section 5.2 says if its invalid, use text/plain + if ctype.count('/') != 1: + return 'text/plain' + return ctype + + def get_content_maintype(self): + """Return the message's main content type. + + This is the `maintype' part of the string returned by + get_content_type(). + """ + ctype = self.get_content_type() + return ctype.split('/')[0] + + def get_content_subtype(self): + """Returns the message's sub-content type. + + This is the `subtype' part of the string returned by + get_content_type(). + """ + ctype = self.get_content_type() + return ctype.split('/')[1] + + def get_default_type(self): + """Return the `default' content type. + + Most messages have a default content type of text/plain, except for + messages that are subparts of multipart/digest containers. Such + subparts have a default content type of message/rfc822. + """ + return self._default_type + + def set_default_type(self, ctype): + """Set the `default' content type. + + ctype should be either "text/plain" or "message/rfc822", although this + is not enforced. The default content type is not stored in the + Content-Type header. + """ + self._default_type = ctype + + def _get_params_preserve(self, failobj, header): + # Like get_params() but preserves the quoting of values. BAW: + # should this be part of the public interface? + missing = object() + value = self.get(header, missing) + if value is missing: + return failobj + params = [] + for p in _parseparam(';' + value): + try: + name, val = p.split('=', 1) + name = name.strip() + val = val.strip() + except ValueError: + # Must have been a bare attribute + name = p.strip() + val = '' + params.append((name, val)) + params = utils.decode_params(params) + return params + + def get_params(self, failobj=None, header='content-type', unquote=True): + """Return the message's Content-Type parameters, as a list. + + The elements of the returned list are 2-tuples of key/value pairs, as + split on the `=' sign. The left hand side of the `=' is the key, + while the right hand side is the value. If there is no `=' sign in + the parameter the value is the empty string. The value is as + described in the get_param() method. + + Optional failobj is the object to return if there is no Content-Type + header. Optional header is the header to search instead of + Content-Type. If unquote is True, the value is unquoted. + """ + missing = object() + params = self._get_params_preserve(missing, header) + if params is missing: + return failobj + if unquote: + return [(k, _unquotevalue(v)) for k, v in params] + else: + return params + + def get_param(self, param, failobj=None, header='content-type', + unquote=True): + """Return the parameter value if found in the Content-Type header. + + Optional failobj is the object to return if there is no Content-Type + header, or the Content-Type header has no such parameter. Optional + header is the header to search instead of Content-Type. + + Parameter keys are always compared case insensitively. The return + value can either be a string, or a 3-tuple if the parameter was RFC + 2231 encoded. When it's a 3-tuple, the elements of the value are of + the form (CHARSET, LANGUAGE, VALUE). Note that both CHARSET and + LANGUAGE can be None, in which case you should consider VALUE to be + encoded in the us-ascii charset. You can usually ignore LANGUAGE. + + Your application should be prepared to deal with 3-tuple return + values, and can convert the parameter to a Unicode string like so: + + param = msg.get_param('foo') + if isinstance(param, tuple): + param = unicode(param[2], param[0] or 'us-ascii') + + In any case, the parameter value (either the returned string, or the + VALUE item in the 3-tuple) is always unquoted, unless unquote is set + to False. + """ + if header not in self: + return failobj + for k, v in self._get_params_preserve(failobj, header): + if k.lower() == param.lower(): + if unquote: + return _unquotevalue(v) + else: + return v + return failobj + + def set_param(self, param, value, header='Content-Type', requote=True, + charset=None, language=''): + """Set a parameter in the Content-Type header. + + If the parameter already exists in the header, its value will be + replaced with the new value. + + If header is Content-Type and has not yet been defined for this + message, it will be set to "text/plain" and the new parameter and + value will be appended as per RFC 2045. + + An alternate header can specified in the header argument, and all + parameters will be quoted as necessary unless requote is False. + + If charset is specified, the parameter will be encoded according to RFC + 2231. Optional language specifies the RFC 2231 language, defaulting + to the empty string. Both charset and language should be strings. + """ + if not isinstance(value, tuple) and charset: + value = (charset, language, value) + + if header not in self and header.lower() == 'content-type': + ctype = 'text/plain' + else: + ctype = self.get(header) + if not self.get_param(param, header=header): + if not ctype: + ctype = _formatparam(param, value, requote) + else: + ctype = SEMISPACE.join( + [ctype, _formatparam(param, value, requote)]) + else: + ctype = '' + for old_param, old_value in self.get_params(header=header, + unquote=requote): + append_param = '' + if old_param.lower() == param.lower(): + append_param = _formatparam(param, value, requote) + else: + append_param = _formatparam(old_param, old_value, requote) + if not ctype: + ctype = append_param + else: + ctype = SEMISPACE.join([ctype, append_param]) + if ctype != self.get(header): + del self[header] + self[header] = ctype + + def del_param(self, param, header='content-type', requote=True): + """Remove the given parameter completely from the Content-Type header. + + The header will be re-written in place without the parameter or its + value. All values will be quoted as necessary unless requote is + False. Optional header specifies an alternative to the Content-Type + header. + """ + if header not in self: + return + new_ctype = '' + for p, v in self.get_params(header=header, unquote=requote): + if p.lower() != param.lower(): + if not new_ctype: + new_ctype = _formatparam(p, v, requote) + else: + new_ctype = SEMISPACE.join([new_ctype, + _formatparam(p, v, requote)]) + if new_ctype != self.get(header): + del self[header] + self[header] = new_ctype + + def set_type(self, type, header='Content-Type', requote=True): + """Set the main type and subtype for the Content-Type header. + + type must be a string in the form "maintype/subtype", otherwise a + ValueError is raised. + + This method replaces the Content-Type header, keeping all the + parameters in place. If requote is False, this leaves the existing + header's quoting as is. Otherwise, the parameters will be quoted (the + default). + + An alternative header can be specified in the header argument. When + the Content-Type header is set, we'll always also add a MIME-Version + header. + """ + # BAW: should we be strict? + if not type.count('/') == 1: + raise ValueError + # Set the Content-Type, you get a MIME-Version + if header.lower() == 'content-type': + del self['mime-version'] + self['MIME-Version'] = '1.0' + if header not in self: + self[header] = type + return + params = self.get_params(header=header, unquote=requote) + del self[header] + self[header] = type + # Skip the first param; it's the old type. + for p, v in params[1:]: + self.set_param(p, v, header, requote) + + def get_filename(self, failobj=None): + """Return the filename associated with the payload if present. + + The filename is extracted from the Content-Disposition header's + `filename' parameter, and it is unquoted. If that header is missing + the `filename' parameter, this method falls back to looking for the + `name' parameter. + """ + missing = object() + filename = self.get_param('filename', missing, 'content-disposition') + if filename is missing: + filename = self.get_param('name', missing, 'content-type') + if filename is missing: + return failobj + return utils.collapse_rfc2231_value(filename).strip() + + def get_boundary(self, failobj=None): + """Return the boundary associated with the payload if present. + + The boundary is extracted from the Content-Type header's `boundary' + parameter, and it is unquoted. + """ + missing = object() + boundary = self.get_param('boundary', missing) + if boundary is missing: + return failobj + # RFC 2046 says that boundaries may begin but not end in w/s + return utils.collapse_rfc2231_value(boundary).rstrip() + + def set_boundary(self, boundary): + """Set the boundary parameter in Content-Type to 'boundary'. + + This is subtly different than deleting the Content-Type header and + adding a new one with a new boundary parameter via add_header(). The + main difference is that using the set_boundary() method preserves the + order of the Content-Type header in the original message. + + HeaderParseError is raised if the message has no Content-Type header. + """ + missing = object() + params = self._get_params_preserve(missing, 'content-type') + if params is missing: + # There was no Content-Type header, and we don't know what type + # to set it to, so raise an exception. + raise errors.HeaderParseError('No Content-Type header found') + newparams = [] + foundp = False + for pk, pv in params: + if pk.lower() == 'boundary': + newparams.append(('boundary', '"%s"' % boundary)) + foundp = True + else: + newparams.append((pk, pv)) + if not foundp: + # The original Content-Type header had no boundary attribute. + # Tack one on the end. BAW: should we raise an exception + # instead??? + newparams.append(('boundary', '"%s"' % boundary)) + # Replace the existing Content-Type header with the new value + newheaders = [] + for h, v in self._headers: + if h.lower() == 'content-type': + parts = [] + for k, v in newparams: + if v == '': + parts.append(k) + else: + parts.append('%s=%s' % (k, v)) + newheaders.append((h, SEMISPACE.join(parts))) + + else: + newheaders.append((h, v)) + self._headers = newheaders + + def get_content_charset(self, failobj=None): + """Return the charset parameter of the Content-Type header. + + The returned string is always coerced to lower case. If there is no + Content-Type header, or if that header has no charset parameter, + failobj is returned. + """ + missing = object() + charset = self.get_param('charset', missing) + if charset is missing: + return failobj + if isinstance(charset, tuple): + # RFC 2231 encoded, so decode it, and it better end up as ascii. + pcharset = charset[0] or 'us-ascii' + try: + # LookupError will be raised if the charset isn't known to + # Python. UnicodeError will be raised if the encoded text + # contains a character not in the charset. + charset = unicode(charset[2], pcharset).encode('us-ascii') + except (LookupError, UnicodeError): + charset = charset[2] + # charset character must be in us-ascii range + try: + if isinstance(charset, str): + charset = unicode(charset, 'us-ascii') + charset = charset.encode('us-ascii') + except UnicodeError: + return failobj + # RFC 2046, $4.1.2 says charsets are not case sensitive + return charset.lower() + + def get_charsets(self, failobj=None): + """Return a list containing the charset(s) used in this message. + + The returned list of items describes the Content-Type headers' + charset parameter for this message and all the subparts in its + payload. + + Each item will either be a string (the value of the charset parameter + in the Content-Type header of that part) or the value of the + 'failobj' parameter (defaults to None), if the part does not have a + main MIME type of "text", or the charset is not defined. + + The list will contain one string for each part of the message, plus + one for the container message (i.e. self), so that a non-multipart + message will still return a list of length 1. + """ + return [part.get_content_charset(failobj) for part in self.walk()] + + # I.e. def walk(self): ... + from email.iterators import walk diff --git a/src/main/resources/PythonLibs/email/mime/__init__.py b/src/main/resources/PythonLibs/email/mime/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/resources/PythonLibs/email/mime/application.py b/src/main/resources/PythonLibs/email/mime/application.py new file mode 100644 index 0000000000000000000000000000000000000000..f5c5905564f690dc36a5d8afef5958bc0283281f --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/application.py @@ -0,0 +1,36 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Keith Dart +# Contact: email-sig@python.org + +"""Class representing application/* type MIME documents.""" + +__all__ = ["MIMEApplication"] + +from email import encoders +from email.mime.nonmultipart import MIMENonMultipart + + +class MIMEApplication(MIMENonMultipart): + """Class for generating application/* MIME documents.""" + + def __init__(self, _data, _subtype='octet-stream', + _encoder=encoders.encode_base64, **_params): + """Create an application/* type MIME document. + + _data is a string containing the raw application data. + + _subtype is the MIME content type subtype, defaulting to + 'octet-stream'. + + _encoder is a function which will perform the actual encoding for + transport of the application data, defaulting to base64 encoding. + + Any additional keyword arguments are passed to the base class + constructor, which turns them into parameters on the Content-Type + header. + """ + if _subtype is None: + raise TypeError('Invalid application MIME subtype') + MIMENonMultipart.__init__(self, 'application', _subtype, **_params) + self.set_payload(_data) + _encoder(self) diff --git a/src/main/resources/PythonLibs/email/mime/audio.py b/src/main/resources/PythonLibs/email/mime/audio.py new file mode 100644 index 0000000000000000000000000000000000000000..c7290c4b1c27dda6fe4a97f6c3d79ac6924bafd3 --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/audio.py @@ -0,0 +1,73 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Anthony Baxter +# Contact: email-sig@python.org + +"""Class representing audio/* type MIME documents.""" + +__all__ = ['MIMEAudio'] + +import sndhdr + +from cStringIO import StringIO +from email import encoders +from email.mime.nonmultipart import MIMENonMultipart + + + +_sndhdr_MIMEmap = {'au' : 'basic', + 'wav' :'x-wav', + 'aiff':'x-aiff', + 'aifc':'x-aiff', + } + +# There are others in sndhdr that don't have MIME types. :( +# Additional ones to be added to sndhdr? midi, mp3, realaudio, wma?? +def _whatsnd(data): + """Try to identify a sound file type. + + sndhdr.what() has a pretty cruddy interface, unfortunately. This is why + we re-do it here. It would be easier to reverse engineer the Unix 'file' + command and use the standard 'magic' file, as shipped with a modern Unix. + """ + hdr = data[:512] + fakefile = StringIO(hdr) + for testfn in sndhdr.tests: + res = testfn(hdr, fakefile) + if res is not None: + return _sndhdr_MIMEmap.get(res[0]) + return None + + + +class MIMEAudio(MIMENonMultipart): + """Class for generating audio/* MIME documents.""" + + def __init__(self, _audiodata, _subtype=None, + _encoder=encoders.encode_base64, **_params): + """Create an audio/* type MIME document. + + _audiodata is a string containing the raw audio data. If this data + can be decoded by the standard Python `sndhdr' module, then the + subtype will be automatically included in the Content-Type header. + Otherwise, you can specify the specific audio subtype via the + _subtype parameter. If _subtype is not given, and no subtype can be + guessed, a TypeError is raised. + + _encoder is a function which will perform the actual encoding for + transport of the image data. It takes one argument, which is this + Image instance. It should use get_payload() and set_payload() to + change the payload to the encoded form. It should also add any + Content-Transfer-Encoding or other headers to the message as + necessary. The default encoding is Base64. + + Any additional keyword arguments are passed to the base class + constructor, which turns them into parameters on the Content-Type + header. + """ + if _subtype is None: + _subtype = _whatsnd(_audiodata) + if _subtype is None: + raise TypeError('Could not find audio MIME subtype') + MIMENonMultipart.__init__(self, 'audio', _subtype, **_params) + self.set_payload(_audiodata) + _encoder(self) diff --git a/src/main/resources/PythonLibs/email/mime/base.py b/src/main/resources/PythonLibs/email/mime/base.py new file mode 100644 index 0000000000000000000000000000000000000000..ac919258b15ba8e678fde8a979ba2f93828930db --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/base.py @@ -0,0 +1,26 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Base class for MIME specializations.""" + +__all__ = ['MIMEBase'] + +from email import message + + + +class MIMEBase(message.Message): + """Base class for MIME specializations.""" + + def __init__(self, _maintype, _subtype, **_params): + """This constructor adds a Content-Type: and a MIME-Version: header. + + The Content-Type: header is taken from the _maintype and _subtype + arguments. Additional parameters for this header are taken from the + keyword arguments. + """ + message.Message.__init__(self) + ctype = '%s/%s' % (_maintype, _subtype) + self.add_header('Content-Type', ctype, **_params) + self['MIME-Version'] = '1.0' diff --git a/src/main/resources/PythonLibs/email/mime/image.py b/src/main/resources/PythonLibs/email/mime/image.py new file mode 100644 index 0000000000000000000000000000000000000000..5563823239b8be88893d6d03a39fb1a206c65285 --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/image.py @@ -0,0 +1,46 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Class representing image/* type MIME documents.""" + +__all__ = ['MIMEImage'] + +import imghdr + +from email import encoders +from email.mime.nonmultipart import MIMENonMultipart + + + +class MIMEImage(MIMENonMultipart): + """Class for generating image/* type MIME documents.""" + + def __init__(self, _imagedata, _subtype=None, + _encoder=encoders.encode_base64, **_params): + """Create an image/* type MIME document. + + _imagedata is a string containing the raw image data. If this data + can be decoded by the standard Python `imghdr' module, then the + subtype will be automatically included in the Content-Type header. + Otherwise, you can specify the specific image subtype via the _subtype + parameter. + + _encoder is a function which will perform the actual encoding for + transport of the image data. It takes one argument, which is this + Image instance. It should use get_payload() and set_payload() to + change the payload to the encoded form. It should also add any + Content-Transfer-Encoding or other headers to the message as + necessary. The default encoding is Base64. + + Any additional keyword arguments are passed to the base class + constructor, which turns them into parameters on the Content-Type + header. + """ + if _subtype is None: + _subtype = imghdr.what(None, _imagedata) + if _subtype is None: + raise TypeError('Could not guess image MIME subtype') + MIMENonMultipart.__init__(self, 'image', _subtype, **_params) + self.set_payload(_imagedata) + _encoder(self) diff --git a/src/main/resources/PythonLibs/email/mime/message.py b/src/main/resources/PythonLibs/email/mime/message.py new file mode 100644 index 0000000000000000000000000000000000000000..275dbfd088652abedbf062ef99521261510141b4 --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/message.py @@ -0,0 +1,34 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Class representing message/* MIME documents.""" + +__all__ = ['MIMEMessage'] + +from email import message +from email.mime.nonmultipart import MIMENonMultipart + + + +class MIMEMessage(MIMENonMultipart): + """Class representing message/* MIME documents.""" + + def __init__(self, _msg, _subtype='rfc822'): + """Create a message/* type MIME document. + + _msg is a message object and must be an instance of Message, or a + derived class of Message, otherwise a TypeError is raised. + + Optional _subtype defines the subtype of the contained message. The + default is "rfc822" (this is defined by the MIME standard, even though + the term "rfc822" is technically outdated by RFC 2822). + """ + MIMENonMultipart.__init__(self, 'message', _subtype) + if not isinstance(_msg, message.Message): + raise TypeError('Argument is not an instance of Message') + # It's convenient to use this base class method. We need to do it + # this way or we'll get an exception + message.Message.attach(self, _msg) + # And be sure our default type is set correctly + self.set_default_type('message/rfc822') diff --git a/src/main/resources/PythonLibs/email/mime/multipart.py b/src/main/resources/PythonLibs/email/mime/multipart.py new file mode 100644 index 0000000000000000000000000000000000000000..96618650c519c5cdf38cd2dbfe6ddba8d78ec63f --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/multipart.py @@ -0,0 +1,47 @@ +# Copyright (C) 2002-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Base class for MIME multipart/* type messages.""" + +__all__ = ['MIMEMultipart'] + +from email.mime.base import MIMEBase + + + +class MIMEMultipart(MIMEBase): + """Base class for MIME multipart/* type messages.""" + + def __init__(self, _subtype='mixed', boundary=None, _subparts=None, + **_params): + """Creates a multipart/* type message. + + By default, creates a multipart/mixed message, with proper + Content-Type and MIME-Version headers. + + _subtype is the subtype of the multipart content type, defaulting to + `mixed'. + + boundary is the multipart boundary string. By default it is + calculated as needed. + + _subparts is a sequence of initial subparts for the payload. It + must be an iterable object, such as a list. You can always + attach new subparts to the message by using the attach() method. + + Additional parameters for the Content-Type header are taken from the + keyword arguments (or passed into the _params argument). + """ + MIMEBase.__init__(self, 'multipart', _subtype, **_params) + + # Initialise _payload to an empty list as the Message superclass's + # implementation of is_multipart assumes that _payload is a list for + # multipart messages. + self._payload = [] + + if _subparts: + for p in _subparts: + self.attach(p) + if boundary: + self.set_boundary(boundary) diff --git a/src/main/resources/PythonLibs/email/mime/nonmultipart.py b/src/main/resources/PythonLibs/email/mime/nonmultipart.py new file mode 100644 index 0000000000000000000000000000000000000000..fc3b9eb4dcfbf8ef4621ee7e545cc237dcf12e09 --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/nonmultipart.py @@ -0,0 +1,22 @@ +# Copyright (C) 2002-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Base class for MIME type messages that are not multipart.""" + +__all__ = ['MIMENonMultipart'] + +from email import errors +from email.mime.base import MIMEBase + + + +class MIMENonMultipart(MIMEBase): + """Base class for MIME multipart/* type messages.""" + + def attach(self, payload): + # The public API prohibits attaching multiple subparts to MIMEBase + # derived subtypes since none of them are, by definition, of content + # type multipart/* + raise errors.MultipartConversionError( + 'Cannot attach additional subparts to non-multipart/*') diff --git a/src/main/resources/PythonLibs/email/mime/text.py b/src/main/resources/PythonLibs/email/mime/text.py new file mode 100644 index 0000000000000000000000000000000000000000..5747db5d670c8082999cc6f089dcc416db07ddba --- /dev/null +++ b/src/main/resources/PythonLibs/email/mime/text.py @@ -0,0 +1,30 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Class representing text/* type MIME documents.""" + +__all__ = ['MIMEText'] + +from email.encoders import encode_7or8bit +from email.mime.nonmultipart import MIMENonMultipart + + + +class MIMEText(MIMENonMultipart): + """Class for generating text/* type MIME documents.""" + + def __init__(self, _text, _subtype='plain', _charset='us-ascii'): + """Create a text/* type MIME document. + + _text is the string for this message object. + + _subtype is the MIME sub content type, defaulting to "plain". + + _charset is the character set parameter added to the Content-Type + header. This defaults to "us-ascii". Note that as a side-effect, the + Content-Transfer-Encoding header will also be set. + """ + MIMENonMultipart.__init__(self, 'text', _subtype, + **{'charset': _charset}) + self.set_payload(_text, _charset) diff --git a/src/main/resources/PythonLibs/email/parser.py b/src/main/resources/PythonLibs/email/parser.py new file mode 100644 index 0000000000000000000000000000000000000000..2fcaf25456273b94cbde5b7a55bc4ab7613affbf --- /dev/null +++ b/src/main/resources/PythonLibs/email/parser.py @@ -0,0 +1,91 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Barry Warsaw, Thomas Wouters, Anthony Baxter +# Contact: email-sig@python.org + +"""A parser of RFC 2822 and MIME email messages.""" + +__all__ = ['Parser', 'HeaderParser'] + +import warnings +from cStringIO import StringIO + +from email.feedparser import FeedParser +from email.message import Message + + + +class Parser: + def __init__(self, *args, **kws): + """Parser of RFC 2822 and MIME email messages. + + Creates an in-memory object tree representing the email message, which + can then be manipulated and turned over to a Generator to return the + textual representation of the message. + + The string must be formatted as a block of RFC 2822 headers and header + continuation lines, optionally preceeded by a `Unix-from' header. The + header block is terminated either by the end of the string or by a + blank line. + + _class is the class to instantiate for new message objects when they + must be created. This class must have a constructor that can take + zero arguments. Default is Message.Message. + """ + if len(args) >= 1: + if '_class' in kws: + raise TypeError("Multiple values for keyword arg '_class'") + kws['_class'] = args[0] + if len(args) == 2: + if 'strict' in kws: + raise TypeError("Multiple values for keyword arg 'strict'") + kws['strict'] = args[1] + if len(args) > 2: + raise TypeError('Too many arguments') + if '_class' in kws: + self._class = kws['_class'] + del kws['_class'] + else: + self._class = Message + if 'strict' in kws: + warnings.warn("'strict' argument is deprecated (and ignored)", + DeprecationWarning, 2) + del kws['strict'] + if kws: + raise TypeError('Unexpected keyword arguments') + + def parse(self, fp, headersonly=False): + """Create a message structure from the data in a file. + + Reads all the data from the file and returns the root of the message + structure. Optional headersonly is a flag specifying whether to stop + parsing after reading the headers or not. The default is False, + meaning it parses the entire contents of the file. + """ + feedparser = FeedParser(self._class) + if headersonly: + feedparser._set_headersonly() + while True: + data = fp.read(8192) + if not data: + break + feedparser.feed(data) + return feedparser.close() + + def parsestr(self, text, headersonly=False): + """Create a message structure from a string. + + Returns the root of the message structure. Optional headersonly is a + flag specifying whether to stop parsing after reading the headers or + not. The default is False, meaning it parses the entire contents of + the file. + """ + return self.parse(StringIO(text), headersonly=headersonly) + + + +class HeaderParser(Parser): + def parse(self, fp, headersonly=True): + return Parser.parse(self, fp, True) + + def parsestr(self, text, headersonly=True): + return Parser.parsestr(self, text, True) diff --git a/src/main/resources/PythonLibs/email/quoprimime.py b/src/main/resources/PythonLibs/email/quoprimime.py new file mode 100644 index 0000000000000000000000000000000000000000..0c18a9e04efb23beb8d6089d514d0d0a577c6e40 --- /dev/null +++ b/src/main/resources/PythonLibs/email/quoprimime.py @@ -0,0 +1,336 @@ +# Copyright (C) 2001-2006 Python Software Foundation +# Author: Ben Gertzfield +# Contact: email-sig@python.org + +"""Quoted-printable content transfer encoding per RFCs 2045-2047. + +This module handles the content transfer encoding method defined in RFC 2045 +to encode US ASCII-like 8-bit data called `quoted-printable'. It is used to +safely encode text that is in a character set similar to the 7-bit US ASCII +character set, but that includes some 8-bit characters that are normally not +allowed in email bodies or headers. + +Quoted-printable is very space-inefficient for encoding binary files; use the +email.base64mime module for that instead. + +This module provides an interface to encode and decode both headers and bodies +with quoted-printable encoding. + +RFC 2045 defines a method for including character set information in an +`encoded-word' in a header. This method is commonly used for 8-bit real names +in To:/From:/Cc: etc. fields, as well as Subject: lines. + +This module does not do the line wrapping or end-of-line character +conversion necessary for proper internationalized headers; it only +does dumb encoding and decoding. To deal with the various line +wrapping issues, use the email.header module. +""" + +__all__ = [ + 'body_decode', + 'body_encode', + 'body_quopri_check', + 'body_quopri_len', + 'decode', + 'decodestring', + 'encode', + 'encodestring', + 'header_decode', + 'header_encode', + 'header_quopri_check', + 'header_quopri_len', + 'quote', + 'unquote', + ] + +import re + +from string import hexdigits +from email.utils import fix_eols + +CRLF = '\r\n' +NL = '\n' + +# See also Charset.py +MISC_LEN = 7 + +hqre = re.compile(r'[^-a-zA-Z0-9!*+/ ]') +bqre = re.compile(r'[^ !-<>-~\t]') + + + +# Helpers +def header_quopri_check(c): + """Return True if the character should be escaped with header quopri.""" + return bool(hqre.match(c)) + + +def body_quopri_check(c): + """Return True if the character should be escaped with body quopri.""" + return bool(bqre.match(c)) + + +def header_quopri_len(s): + """Return the length of str when it is encoded with header quopri.""" + count = 0 + for c in s: + if hqre.match(c): + count += 3 + else: + count += 1 + return count + + +def body_quopri_len(str): + """Return the length of str when it is encoded with body quopri.""" + count = 0 + for c in str: + if bqre.match(c): + count += 3 + else: + count += 1 + return count + + +def _max_append(L, s, maxlen, extra=''): + if not L: + L.append(s.lstrip()) + elif len(L[-1]) + len(s) <= maxlen: + L[-1] += extra + s + else: + L.append(s.lstrip()) + + +def unquote(s): + """Turn a string in the form =AB to the ASCII character with value 0xab""" + return chr(int(s[1:3], 16)) + + +def quote(c): + return "=%02X" % ord(c) + + + +def header_encode(header, charset="iso-8859-1", keep_eols=False, + maxlinelen=76, eol=NL): + """Encode a single header line with quoted-printable (like) encoding. + + Defined in RFC 2045, this `Q' encoding is similar to quoted-printable, but + used specifically for email header fields to allow charsets with mostly 7 + bit characters (and some 8 bit) to remain more or less readable in non-RFC + 2045 aware mail clients. + + charset names the character set to use to encode the header. It defaults + to iso-8859-1. + + The resulting string will be in the form: + + "=?charset?q?I_f=E2rt_in_your_g=E8n=E8ral_dire=E7tion?\\n + =?charset?q?Silly_=C8nglish_Kn=EEghts?=" + + with each line wrapped safely at, at most, maxlinelen characters (defaults + to 76 characters). If maxlinelen is None, the entire string is encoded in + one chunk with no splitting. + + End-of-line characters (\\r, \\n, \\r\\n) will be automatically converted + to the canonical email line separator \\r\\n unless the keep_eols + parameter is True (the default is False). + + Each line of the header will be terminated in the value of eol, which + defaults to "\\n". Set this to "\\r\\n" if you are using the result of + this function directly in email. + """ + # Return empty headers unchanged + if not header: + return header + + if not keep_eols: + header = fix_eols(header) + + # Quopri encode each line, in encoded chunks no greater than maxlinelen in + # length, after the RFC chrome is added in. + quoted = [] + if maxlinelen is None: + # An obnoxiously large number that's good enough + max_encoded = 100000 + else: + max_encoded = maxlinelen - len(charset) - MISC_LEN - 1 + + for c in header: + # Space may be represented as _ instead of =20 for readability + if c == ' ': + _max_append(quoted, '_', max_encoded) + # These characters can be included verbatim + elif not hqre.match(c): + _max_append(quoted, c, max_encoded) + # Otherwise, replace with hex value like =E2 + else: + _max_append(quoted, "=%02X" % ord(c), max_encoded) + + # Now add the RFC chrome to each encoded chunk and glue the chunks + # together. BAW: should we be able to specify the leading whitespace in + # the joiner? + joiner = eol + ' ' + return joiner.join(['=?%s?q?%s?=' % (charset, line) for line in quoted]) + + + +def encode(body, binary=False, maxlinelen=76, eol=NL): + """Encode with quoted-printable, wrapping at maxlinelen characters. + + If binary is False (the default), end-of-line characters will be converted + to the canonical email end-of-line sequence \\r\\n. Otherwise they will + be left verbatim. + + Each line of encoded text will end with eol, which defaults to "\\n". Set + this to "\\r\\n" if you will be using the result of this function directly + in an email. + + Each line will be wrapped at, at most, maxlinelen characters (defaults to + 76 characters). Long lines will have the `soft linefeed' quoted-printable + character "=" appended to them, so the decoded text will be identical to + the original text. + """ + if not body: + return body + + if not binary: + body = fix_eols(body) + + # BAW: We're accumulating the body text by string concatenation. That + # can't be very efficient, but I don't have time now to rewrite it. It + # just feels like this algorithm could be more efficient. + encoded_body = '' + lineno = -1 + # Preserve line endings here so we can check later to see an eol needs to + # be added to the output later. + lines = body.splitlines(1) + for line in lines: + # But strip off line-endings for processing this line. + if line.endswith(CRLF): + line = line[:-2] + elif line[-1] in CRLF: + line = line[:-1] + + lineno += 1 + encoded_line = '' + prev = None + linelen = len(line) + # Now we need to examine every character to see if it needs to be + # quopri encoded. BAW: again, string concatenation is inefficient. + for j in range(linelen): + c = line[j] + prev = c + if bqre.match(c): + c = quote(c) + elif j+1 == linelen: + # Check for whitespace at end of line; special case + if c not in ' \t': + encoded_line += c + prev = c + continue + # Check to see to see if the line has reached its maximum length + if len(encoded_line) + len(c) >= maxlinelen: + encoded_body += encoded_line + '=' + eol + encoded_line = '' + encoded_line += c + # Now at end of line.. + if prev and prev in ' \t': + # Special case for whitespace at end of file + if lineno + 1 == len(lines): + prev = quote(prev) + if len(encoded_line) + len(prev) > maxlinelen: + encoded_body += encoded_line + '=' + eol + prev + else: + encoded_body += encoded_line + prev + # Just normal whitespace at end of line + else: + encoded_body += encoded_line + prev + '=' + eol + encoded_line = '' + # Now look at the line we just finished and it has a line ending, we + # need to add eol to the end of the line. + if lines[lineno].endswith(CRLF) or lines[lineno][-1] in CRLF: + encoded_body += encoded_line + eol + else: + encoded_body += encoded_line + encoded_line = '' + return encoded_body + + +# For convenience and backwards compatibility w/ standard base64 module +body_encode = encode +encodestring = encode + + + +# BAW: I'm not sure if the intent was for the signature of this function to be +# the same as base64MIME.decode() or not... +def decode(encoded, eol=NL): + """Decode a quoted-printable string. + + Lines are separated with eol, which defaults to \\n. + """ + if not encoded: + return encoded + # BAW: see comment in encode() above. Again, we're building up the + # decoded string with string concatenation, which could be done much more + # efficiently. + decoded = '' + + for line in encoded.splitlines(): + line = line.rstrip() + if not line: + decoded += eol + continue + + i = 0 + n = len(line) + while i < n: + c = line[i] + if c != '=': + decoded += c + i += 1 + # Otherwise, c == "=". Are we at the end of the line? If so, add + # a soft line break. + elif i+1 == n: + i += 1 + continue + # Decode if in form =AB + elif i+2 < n and line[i+1] in hexdigits and line[i+2] in hexdigits: + decoded += unquote(line[i:i+3]) + i += 3 + # Otherwise, not in form =AB, pass literally + else: + decoded += c + i += 1 + + if i == n: + decoded += eol + # Special case if original string did not end with eol + if not encoded.endswith(eol) and decoded.endswith(eol): + decoded = decoded[:-1] + return decoded + + +# For convenience and backwards compatibility w/ standard base64 module +body_decode = decode +decodestring = decode + + + +def _unquote_match(match): + """Turn a match in the form =AB to the ASCII character with value 0xab""" + s = match.group(0) + return unquote(s) + + +# Header decoding is done a bit differently +def header_decode(s): + """Decode a string encoded with RFC 2045 MIME header `Q' encoding. + + This function does not parse a full MIME header value encoded with + quoted-printable (like =?iso-8895-1?q?Hello_World?=) -- please use + the high level email.header class for that functionality. + """ + s = s.replace('_', ' ') + return re.sub(r'=[a-fA-F0-9]{2}', _unquote_match, s) diff --git a/src/main/resources/PythonLibs/email/utils.py b/src/main/resources/PythonLibs/email/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..c976021e0e0584c6ee56d5aa32b0034c531349c5 --- /dev/null +++ b/src/main/resources/PythonLibs/email/utils.py @@ -0,0 +1,324 @@ +# Copyright (C) 2001-2010 Python Software Foundation +# Author: Barry Warsaw +# Contact: email-sig@python.org + +"""Miscellaneous utilities.""" + +__all__ = [ + 'collapse_rfc2231_value', + 'decode_params', + 'decode_rfc2231', + 'encode_rfc2231', + 'formataddr', + 'formatdate', + 'getaddresses', + 'make_msgid', + 'mktime_tz', + 'parseaddr', + 'parsedate', + 'parsedate_tz', + 'unquote', + ] + +import os +import re +import time +import base64 +import random +import socket +import urllib +import warnings + +from email._parseaddr import quote +from email._parseaddr import AddressList as _AddressList +from email._parseaddr import mktime_tz + +# We need wormarounds for bugs in these methods in older Pythons (see below) +from email._parseaddr import parsedate as _parsedate +from email._parseaddr import parsedate_tz as _parsedate_tz + +from quopri import decodestring as _qdecode + +# Intrapackage imports +from email.encoders import _bencode, _qencode + +COMMASPACE = ', ' +EMPTYSTRING = '' +UEMPTYSTRING = u'' +CRLF = '\r\n' +TICK = "'" + +specialsre = re.compile(r'[][\\()<>@,:;".]') +escapesre = re.compile(r'[][\\()"]') + + + +# Helpers + +def _identity(s): + return s + + +def _bdecode(s): + """Decodes a base64 string. + + This function is equivalent to base64.decodestring and it's retained only + for backward compatibility. It used to remove the last \\n of the decoded + string, if it had any (see issue 7143). + """ + if not s: + return s + return base64.decodestring(s) + + + +def fix_eols(s): + """Replace all line-ending characters with \\r\\n.""" + # Fix newlines with no preceding carriage return + s = re.sub(r'(?<!\r)\n', CRLF, s) + # Fix carriage returns with no following newline + s = re.sub(r'\r(?!\n)', CRLF, s) + return s + + + +def formataddr(pair): + """The inverse of parseaddr(), this takes a 2-tuple of the form + (realname, email_address) and returns the string value suitable + for an RFC 2822 From, To or Cc header. + + If the first element of pair is false, then the second element is + returned unmodified. + """ + name, address = pair + if name: + quotes = '' + if specialsre.search(name): + quotes = '"' + name = escapesre.sub(r'\\\g<0>', name) + return '%s%s%s <%s>' % (quotes, name, quotes, address) + return address + + + +def getaddresses(fieldvalues): + """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" + all = COMMASPACE.join(fieldvalues) + a = _AddressList(all) + return a.addresslist + + + +ecre = re.compile(r''' + =\? # literal =? + (?P<charset>[^?]*?) # non-greedy up to the next ? is the charset + \? # literal ? + (?P<encoding>[qb]) # either a "q" or a "b", case insensitive + \? # literal ? + (?P<atom>.*?) # non-greedy up to the next ?= is the atom + \?= # literal ?= + ''', re.VERBOSE | re.IGNORECASE) + + + +def formatdate(timeval=None, localtime=False, usegmt=False): + """Returns a date string as specified by RFC 2822, e.g.: + + Fri, 09 Nov 2001 01:08:47 -0000 + + Optional timeval if given is a floating point time value as accepted by + gmtime() and localtime(), otherwise the current time is used. + + Optional localtime is a flag that when True, interprets timeval, and + returns a date relative to the local timezone instead of UTC, properly + taking daylight savings time into account. + + Optional argument usegmt means that the timezone is written out as + an ascii string, not numeric one (so "GMT" instead of "+0000"). This + is needed for HTTP, and is only used when localtime==False. + """ + # Note: we cannot use strftime() because that honors the locale and RFC + # 2822 requires that day and month names be the English abbreviations. + if timeval is None: + timeval = time.time() + if localtime: + now = time.localtime(timeval) + # Calculate timezone offset, based on whether the local zone has + # daylight savings time, and whether DST is in effect. + if time.daylight and now[-1]: + offset = time.altzone + else: + offset = time.timezone + hours, minutes = divmod(abs(offset), 3600) + # Remember offset is in seconds west of UTC, but the timezone is in + # minutes east of UTC, so the signs differ. + if offset > 0: + sign = '-' + else: + sign = '+' + zone = '%s%02d%02d' % (sign, hours, minutes // 60) + else: + now = time.gmtime(timeval) + # Timezone offset is always -0000 + if usegmt: + zone = 'GMT' + else: + zone = '-0000' + return '%s, %02d %s %04d %02d:%02d:%02d %s' % ( + ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'][now[6]], + now[2], + ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][now[1] - 1], + now[0], now[3], now[4], now[5], + zone) + + + +def make_msgid(idstring=None): + """Returns a string suitable for RFC 2822 compliant Message-ID, e.g: + + <20020201195627.33539.96671@nightshade.la.mastaler.com> + + Optional idstring if given is a string used to strengthen the + uniqueness of the message id. + """ + timeval = time.time() + utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval)) + pid = os.getpid() + randint = random.randrange(100000) + if idstring is None: + idstring = '' + else: + idstring = '.' + idstring + idhost = socket.getfqdn() + msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, idhost) + return msgid + + + +# These functions are in the standalone mimelib version only because they've +# subsequently been fixed in the latest Python versions. We use this to worm +# around broken older Pythons. +def parsedate(data): + if not data: + return None + return _parsedate(data) + + +def parsedate_tz(data): + if not data: + return None + return _parsedate_tz(data) + + +def parseaddr(addr): + addrs = _AddressList(addr).addresslist + if not addrs: + return '', '' + return addrs[0] + + +# rfc822.unquote() doesn't properly de-backslash-ify in Python pre-2.3. +def unquote(str): + """Remove quotes from a string.""" + if len(str) > 1: + if str.startswith('"') and str.endswith('"'): + return str[1:-1].replace('\\\\', '\\').replace('\\"', '"') + if str.startswith('<') and str.endswith('>'): + return str[1:-1] + return str + + + +# RFC2231-related functions - parameter encoding and decoding +def decode_rfc2231(s): + """Decode string according to RFC 2231""" + parts = s.split(TICK, 2) + if len(parts) <= 2: + return None, None, s + return parts + + +def encode_rfc2231(s, charset=None, language=None): + """Encode string according to RFC 2231. + + If neither charset nor language is given, then s is returned as-is. If + charset is given but not language, the string is encoded using the empty + string for language. + """ + import urllib + s = urllib.quote(s, safe='') + if charset is None and language is None: + return s + if language is None: + language = '' + return "%s'%s'%s" % (charset, language, s) + + +rfc2231_continuation = re.compile(r'^(?P<name>\w+)\*((?P<num>[0-9]+)\*?)?$') + +def decode_params(params): + """Decode parameters list according to RFC 2231. + + params is a sequence of 2-tuples containing (param name, string value). + """ + # Copy params so we don't mess with the original + params = params[:] + new_params = [] + # Map parameter's name to a list of continuations. The values are a + # 3-tuple of the continuation number, the string value, and a flag + # specifying whether a particular segment is %-encoded. + rfc2231_params = {} + name, value = params.pop(0) + new_params.append((name, value)) + while params: + name, value = params.pop(0) + if name.endswith('*'): + encoded = True + else: + encoded = False + value = unquote(value) + mo = rfc2231_continuation.match(name) + if mo: + name, num = mo.group('name', 'num') + if num is not None: + num = int(num) + rfc2231_params.setdefault(name, []).append((num, value, encoded)) + else: + new_params.append((name, '"%s"' % quote(value))) + if rfc2231_params: + for name, continuations in rfc2231_params.items(): + value = [] + extended = False + # Sort by number + continuations.sort() + # And now append all values in numerical order, converting + # %-encodings for the encoded segments. If any of the + # continuation names ends in a *, then the entire string, after + # decoding segments and concatenating, must have the charset and + # language specifiers at the beginning of the string. + for num, s, encoded in continuations: + if encoded: + s = urllib.unquote(s) + extended = True + value.append(s) + value = quote(EMPTYSTRING.join(value)) + if extended: + charset, language, value = decode_rfc2231(value) + new_params.append((name, (charset, language, '"%s"' % value))) + else: + new_params.append((name, '"%s"' % value)) + return new_params + +def collapse_rfc2231_value(value, errors='replace', + fallback_charset='us-ascii'): + if isinstance(value, tuple): + rawval = unquote(value[2]) + charset = value[0] or 'us-ascii' + try: + return unicode(rawval, charset, errors) + except LookupError: + # XXX charset is unknown to Python. + return unicode(rawval, fallback_charset, errors) + else: + return unquote(value) diff --git a/src/main/resources/PythonLibs/encodings/__init__.py b/src/main/resources/PythonLibs/encodings/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b85ca823aecb5e7f005882d57dc893f84e9ac367 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/__init__.py @@ -0,0 +1,157 @@ +""" Standard "encodings" Package + + Standard Python encoding modules are stored in this package + directory. + + Codec modules must have names corresponding to normalized encoding + names as defined in the normalize_encoding() function below, e.g. + 'utf-8' must be implemented by the module 'utf_8.py'. + + Each codec module must export the following interface: + + * getregentry() -> codecs.CodecInfo object + The getregentry() API must a CodecInfo object with encoder, decoder, + incrementalencoder, incrementaldecoder, streamwriter and streamreader + atttributes which adhere to the Python Codec Interface Standard. + + In addition, a module may optionally also define the following + APIs which are then used by the package's codec search function: + + * getaliases() -> sequence of encoding name strings to use as aliases + + Alias names returned by getaliases() must be normalized encoding + names as defined by normalize_encoding(). + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +"""#" + +import codecs +from encodings import aliases +import __builtin__ + +_cache = {} +_unknown = '--unknown--' +_import_tail = ['*'] +_norm_encoding_map = (' . ' + '0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ ' + ' abcdefghijklmnopqrstuvwxyz ' + ' ' + ' ' + ' ') +_aliases = aliases.aliases + +class CodecRegistryError(LookupError, SystemError): + pass + +def normalize_encoding(encoding): + + """ Normalize an encoding name. + + Normalization works as follows: all non-alphanumeric + characters except the dot used for Python package names are + collapsed and replaced with a single underscore, e.g. ' -;#' + becomes '_'. Leading and trailing underscores are removed. + + Note that encoding names should be ASCII only; if they do use + non-ASCII characters, these must be Latin-1 compatible. + + """ + # Make sure we have an 8-bit string, because .translate() works + # differently for Unicode strings. + if hasattr(__builtin__, "unicode") and isinstance(encoding, unicode): + # Note that .encode('latin-1') does *not* use the codec + # registry, so this call doesn't recurse. (See unicodeobject.c + # PyUnicode_AsEncodedString() for details) + encoding = encoding.encode('latin-1') + return '_'.join(encoding.translate(_norm_encoding_map).split()) + +def search_function(encoding): + + # Cache lookup + entry = _cache.get(encoding, _unknown) + if entry is not _unknown: + return entry + + # Import the module: + # + # First try to find an alias for the normalized encoding + # name and lookup the module using the aliased name, then try to + # lookup the module using the standard import scheme, i.e. first + # try in the encodings package, then at top-level. + # + norm_encoding = normalize_encoding(encoding) + aliased_encoding = _aliases.get(norm_encoding) or \ + _aliases.get(norm_encoding.replace('.', '_')) + if aliased_encoding is not None: + modnames = [aliased_encoding, + norm_encoding] + else: + modnames = [norm_encoding] + for modname in modnames: + if not modname or '.' in modname: + continue + try: + # Import is absolute to prevent the possibly malicious import of a + # module with side-effects that is not in the 'encodings' package. + mod = __import__('encodings.' + modname, fromlist=_import_tail, + level=0) + except ImportError: + pass + else: + break + else: + mod = None + + try: + getregentry = mod.getregentry + except AttributeError: + # Not a codec module + mod = None + + if mod is None: + # Cache misses + _cache[encoding] = None + return None + + # Now ask the module for the registry entry + entry = getregentry() + if not isinstance(entry, codecs.CodecInfo): + if not 4 <= len(entry) <= 7: + raise CodecRegistryError,\ + 'module "%s" (%s) failed to register' % \ + (mod.__name__, mod.__file__) + if not hasattr(entry[0], '__call__') or \ + not hasattr(entry[1], '__call__') or \ + (entry[2] is not None and not hasattr(entry[2], '__call__')) or \ + (entry[3] is not None and not hasattr(entry[3], '__call__')) or \ + (len(entry) > 4 and entry[4] is not None and not hasattr(entry[4], '__call__')) or \ + (len(entry) > 5 and entry[5] is not None and not hasattr(entry[5], '__call__')): + raise CodecRegistryError,\ + 'incompatible codecs in module "%s" (%s)' % \ + (mod.__name__, mod.__file__) + if len(entry)<7 or entry[6] is None: + entry += (None,)*(6-len(entry)) + (mod.__name__.split(".", 1)[1],) + entry = codecs.CodecInfo(*entry) + + # Cache the codec registry entry + _cache[encoding] = entry + + # Register its aliases (without overwriting previously registered + # aliases) + try: + codecaliases = mod.getaliases() + except AttributeError: + pass + else: + for alias in codecaliases: + if alias not in _aliases: + _aliases[alias] = modname + + # Return the registry entry + return entry + +# Register the search_function in the Python codec registry +codecs.register(search_function) diff --git a/src/main/resources/PythonLibs/encodings/aliases.py b/src/main/resources/PythonLibs/encodings/aliases.py new file mode 100644 index 0000000000000000000000000000000000000000..a54cf774b7b1dd5f6079dc4b6b07320055326404 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/aliases.py @@ -0,0 +1,527 @@ +""" Encoding Aliases Support + + This module is used by the encodings package search function to + map encodings names to module names. + + Note that the search function normalizes the encoding names before + doing the lookup, so the mapping will have to map normalized + encoding names to module names. + + Contents: + + The following aliases dictionary contains mappings of all IANA + character set names for which the Python core library provides + codecs. In addition to these, a few Python specific codec + aliases have also been added. + +""" +aliases = { + + # Please keep this list sorted alphabetically by value ! + + # ascii codec + '646' : 'ascii', + 'ansi_x3.4_1968' : 'ascii', + 'ansi_x3_4_1968' : 'ascii', # some email headers use this non-standard name + 'ansi_x3.4_1986' : 'ascii', + 'cp367' : 'ascii', + 'csascii' : 'ascii', + 'ibm367' : 'ascii', + 'iso646_us' : 'ascii', + 'iso_646.irv_1991' : 'ascii', + 'iso_ir_6' : 'ascii', + 'us' : 'ascii', + 'us_ascii' : 'ascii', + + # base64_codec codec + 'base64' : 'base64_codec', + 'base_64' : 'base64_codec', + + # big5 codec + 'big5_tw' : 'big5', + 'csbig5' : 'big5', + + # big5hkscs codec + 'big5_hkscs' : 'big5hkscs', + 'hkscs' : 'big5hkscs', + + # bz2_codec codec + 'bz2' : 'bz2_codec', + + # cp037 codec + '037' : 'cp037', + 'csibm037' : 'cp037', + 'ebcdic_cp_ca' : 'cp037', + 'ebcdic_cp_nl' : 'cp037', + 'ebcdic_cp_us' : 'cp037', + 'ebcdic_cp_wt' : 'cp037', + 'ibm037' : 'cp037', + 'ibm039' : 'cp037', + + # cp1026 codec + '1026' : 'cp1026', + 'csibm1026' : 'cp1026', + 'ibm1026' : 'cp1026', + + # cp1140 codec + '1140' : 'cp1140', + 'ibm1140' : 'cp1140', + + # cp1250 codec + '1250' : 'cp1250', + 'windows_1250' : 'cp1250', + + # cp1251 codec + '1251' : 'cp1251', + 'windows_1251' : 'cp1251', + + # cp1252 codec + '1252' : 'cp1252', + 'windows_1252' : 'cp1252', + + # cp1253 codec + '1253' : 'cp1253', + 'windows_1253' : 'cp1253', + + # cp1254 codec + '1254' : 'cp1254', + 'windows_1254' : 'cp1254', + + # cp1255 codec + '1255' : 'cp1255', + 'windows_1255' : 'cp1255', + + # cp1256 codec + '1256' : 'cp1256', + 'windows_1256' : 'cp1256', + + # cp1257 codec + '1257' : 'cp1257', + 'windows_1257' : 'cp1257', + + # cp1258 codec + '1258' : 'cp1258', + 'windows_1258' : 'cp1258', + + # cp424 codec + '424' : 'cp424', + 'csibm424' : 'cp424', + 'ebcdic_cp_he' : 'cp424', + 'ibm424' : 'cp424', + + # cp437 codec + '437' : 'cp437', + 'cspc8codepage437' : 'cp437', + 'ibm437' : 'cp437', + + # cp500 codec + '500' : 'cp500', + 'csibm500' : 'cp500', + 'ebcdic_cp_be' : 'cp500', + 'ebcdic_cp_ch' : 'cp500', + 'ibm500' : 'cp500', + + # cp775 codec + '775' : 'cp775', + 'cspc775baltic' : 'cp775', + 'ibm775' : 'cp775', + + # cp850 codec + '850' : 'cp850', + 'cspc850multilingual' : 'cp850', + 'ibm850' : 'cp850', + + # cp852 codec + '852' : 'cp852', + 'cspcp852' : 'cp852', + 'ibm852' : 'cp852', + + # cp855 codec + '855' : 'cp855', + 'csibm855' : 'cp855', + 'ibm855' : 'cp855', + + # cp857 codec + '857' : 'cp857', + 'csibm857' : 'cp857', + 'ibm857' : 'cp857', + + # cp858 codec + '858' : 'cp858', + 'csibm858' : 'cp858', + 'ibm858' : 'cp858', + + # cp860 codec + '860' : 'cp860', + 'csibm860' : 'cp860', + 'ibm860' : 'cp860', + + # cp861 codec + '861' : 'cp861', + 'cp_is' : 'cp861', + 'csibm861' : 'cp861', + 'ibm861' : 'cp861', + + # cp862 codec + '862' : 'cp862', + 'cspc862latinhebrew' : 'cp862', + 'ibm862' : 'cp862', + + # cp863 codec + '863' : 'cp863', + 'csibm863' : 'cp863', + 'ibm863' : 'cp863', + + # cp864 codec + '864' : 'cp864', + 'csibm864' : 'cp864', + 'ibm864' : 'cp864', + + # cp865 codec + '865' : 'cp865', + 'csibm865' : 'cp865', + 'ibm865' : 'cp865', + + # cp866 codec + '866' : 'cp866', + 'csibm866' : 'cp866', + 'ibm866' : 'cp866', + + # cp869 codec + '869' : 'cp869', + 'cp_gr' : 'cp869', + 'csibm869' : 'cp869', + 'ibm869' : 'cp869', + + # cp932 codec + '932' : 'cp932', + 'ms932' : 'cp932', + 'mskanji' : 'cp932', + 'ms_kanji' : 'cp932', + + # cp949 codec + '949' : 'cp949', + 'ms949' : 'cp949', + 'uhc' : 'cp949', + + # cp950 codec + '950' : 'cp950', + 'ms950' : 'cp950', + + # euc_jis_2004 codec + 'jisx0213' : 'euc_jis_2004', + 'eucjis2004' : 'euc_jis_2004', + 'euc_jis2004' : 'euc_jis_2004', + + # euc_jisx0213 codec + 'eucjisx0213' : 'euc_jisx0213', + + # euc_jp codec + 'eucjp' : 'euc_jp', + 'ujis' : 'euc_jp', + 'u_jis' : 'euc_jp', + + # euc_kr codec + 'euckr' : 'euc_kr', + 'korean' : 'euc_kr', + 'ksc5601' : 'euc_kr', + 'ks_c_5601' : 'euc_kr', + 'ks_c_5601_1987' : 'euc_kr', + 'ksx1001' : 'euc_kr', + 'ks_x_1001' : 'euc_kr', + + # gb18030 codec + 'gb18030_2000' : 'gb18030', + + # gb2312 codec + 'chinese' : 'gb2312', + 'csiso58gb231280' : 'gb2312', + 'euc_cn' : 'gb2312', + 'euccn' : 'gb2312', + 'eucgb2312_cn' : 'gb2312', + 'gb2312_1980' : 'gb2312', + 'gb2312_80' : 'gb2312', + 'iso_ir_58' : 'gb2312', + + # gbk codec + '936' : 'gbk', + 'cp936' : 'gbk', + 'ms936' : 'gbk', + + # hex_codec codec + 'hex' : 'hex_codec', + + # hp_roman8 codec + 'roman8' : 'hp_roman8', + 'r8' : 'hp_roman8', + 'csHPRoman8' : 'hp_roman8', + + # hz codec + 'hzgb' : 'hz', + 'hz_gb' : 'hz', + 'hz_gb_2312' : 'hz', + + # iso2022_jp codec + 'csiso2022jp' : 'iso2022_jp', + 'iso2022jp' : 'iso2022_jp', + 'iso_2022_jp' : 'iso2022_jp', + + # iso2022_jp_1 codec + 'iso2022jp_1' : 'iso2022_jp_1', + 'iso_2022_jp_1' : 'iso2022_jp_1', + + # iso2022_jp_2 codec + 'iso2022jp_2' : 'iso2022_jp_2', + 'iso_2022_jp_2' : 'iso2022_jp_2', + + # iso2022_jp_2004 codec + 'iso_2022_jp_2004' : 'iso2022_jp_2004', + 'iso2022jp_2004' : 'iso2022_jp_2004', + + # iso2022_jp_3 codec + 'iso2022jp_3' : 'iso2022_jp_3', + 'iso_2022_jp_3' : 'iso2022_jp_3', + + # iso2022_jp_ext codec + 'iso2022jp_ext' : 'iso2022_jp_ext', + 'iso_2022_jp_ext' : 'iso2022_jp_ext', + + # iso2022_kr codec + 'csiso2022kr' : 'iso2022_kr', + 'iso2022kr' : 'iso2022_kr', + 'iso_2022_kr' : 'iso2022_kr', + + # iso8859_10 codec + 'csisolatin6' : 'iso8859_10', + 'iso_8859_10' : 'iso8859_10', + 'iso_8859_10_1992' : 'iso8859_10', + 'iso_ir_157' : 'iso8859_10', + 'l6' : 'iso8859_10', + 'latin6' : 'iso8859_10', + + # iso8859_11 codec + 'thai' : 'iso8859_11', + 'iso_8859_11' : 'iso8859_11', + 'iso_8859_11_2001' : 'iso8859_11', + + # iso8859_13 codec + 'iso_8859_13' : 'iso8859_13', + 'l7' : 'iso8859_13', + 'latin7' : 'iso8859_13', + + # iso8859_14 codec + 'iso_8859_14' : 'iso8859_14', + 'iso_8859_14_1998' : 'iso8859_14', + 'iso_celtic' : 'iso8859_14', + 'iso_ir_199' : 'iso8859_14', + 'l8' : 'iso8859_14', + 'latin8' : 'iso8859_14', + + # iso8859_15 codec + 'iso_8859_15' : 'iso8859_15', + 'l9' : 'iso8859_15', + 'latin9' : 'iso8859_15', + + # iso8859_16 codec + 'iso_8859_16' : 'iso8859_16', + 'iso_8859_16_2001' : 'iso8859_16', + 'iso_ir_226' : 'iso8859_16', + 'l10' : 'iso8859_16', + 'latin10' : 'iso8859_16', + + # iso8859_2 codec + 'csisolatin2' : 'iso8859_2', + 'iso_8859_2' : 'iso8859_2', + 'iso_8859_2_1987' : 'iso8859_2', + 'iso_ir_101' : 'iso8859_2', + 'l2' : 'iso8859_2', + 'latin2' : 'iso8859_2', + + # iso8859_3 codec + 'csisolatin3' : 'iso8859_3', + 'iso_8859_3' : 'iso8859_3', + 'iso_8859_3_1988' : 'iso8859_3', + 'iso_ir_109' : 'iso8859_3', + 'l3' : 'iso8859_3', + 'latin3' : 'iso8859_3', + + # iso8859_4 codec + 'csisolatin4' : 'iso8859_4', + 'iso_8859_4' : 'iso8859_4', + 'iso_8859_4_1988' : 'iso8859_4', + 'iso_ir_110' : 'iso8859_4', + 'l4' : 'iso8859_4', + 'latin4' : 'iso8859_4', + + # iso8859_5 codec + 'csisolatincyrillic' : 'iso8859_5', + 'cyrillic' : 'iso8859_5', + 'iso_8859_5' : 'iso8859_5', + 'iso_8859_5_1988' : 'iso8859_5', + 'iso_ir_144' : 'iso8859_5', + + # iso8859_6 codec + 'arabic' : 'iso8859_6', + 'asmo_708' : 'iso8859_6', + 'csisolatinarabic' : 'iso8859_6', + 'ecma_114' : 'iso8859_6', + 'iso_8859_6' : 'iso8859_6', + 'iso_8859_6_1987' : 'iso8859_6', + 'iso_ir_127' : 'iso8859_6', + + # iso8859_7 codec + 'csisolatingreek' : 'iso8859_7', + 'ecma_118' : 'iso8859_7', + 'elot_928' : 'iso8859_7', + 'greek' : 'iso8859_7', + 'greek8' : 'iso8859_7', + 'iso_8859_7' : 'iso8859_7', + 'iso_8859_7_1987' : 'iso8859_7', + 'iso_ir_126' : 'iso8859_7', + + # iso8859_8 codec + 'csisolatinhebrew' : 'iso8859_8', + 'hebrew' : 'iso8859_8', + 'iso_8859_8' : 'iso8859_8', + 'iso_8859_8_1988' : 'iso8859_8', + 'iso_ir_138' : 'iso8859_8', + + # iso8859_9 codec + 'csisolatin5' : 'iso8859_9', + 'iso_8859_9' : 'iso8859_9', + 'iso_8859_9_1989' : 'iso8859_9', + 'iso_ir_148' : 'iso8859_9', + 'l5' : 'iso8859_9', + 'latin5' : 'iso8859_9', + + # johab codec + 'cp1361' : 'johab', + 'ms1361' : 'johab', + + # koi8_r codec + 'cskoi8r' : 'koi8_r', + + # latin_1 codec + # + # Note that the latin_1 codec is implemented internally in C and a + # lot faster than the charmap codec iso8859_1 which uses the same + # encoding. This is why we discourage the use of the iso8859_1 + # codec and alias it to latin_1 instead. + # + '8859' : 'latin_1', + 'cp819' : 'latin_1', + 'csisolatin1' : 'latin_1', + 'ibm819' : 'latin_1', + 'iso8859' : 'latin_1', + 'iso8859_1' : 'latin_1', + 'iso_8859_1' : 'latin_1', + 'iso_8859_1_1987' : 'latin_1', + 'iso_ir_100' : 'latin_1', + 'l1' : 'latin_1', + 'latin' : 'latin_1', + 'latin1' : 'latin_1', + + # mac_cyrillic codec + 'maccyrillic' : 'mac_cyrillic', + + # mac_greek codec + 'macgreek' : 'mac_greek', + + # mac_iceland codec + 'maciceland' : 'mac_iceland', + + # mac_latin2 codec + 'maccentraleurope' : 'mac_latin2', + 'maclatin2' : 'mac_latin2', + + # mac_roman codec + 'macroman' : 'mac_roman', + + # mac_turkish codec + 'macturkish' : 'mac_turkish', + + # mbcs codec + 'dbcs' : 'mbcs', + + # ptcp154 codec + 'csptcp154' : 'ptcp154', + 'pt154' : 'ptcp154', + 'cp154' : 'ptcp154', + 'cyrillic_asian' : 'ptcp154', + + # quopri_codec codec + 'quopri' : 'quopri_codec', + 'quoted_printable' : 'quopri_codec', + 'quotedprintable' : 'quopri_codec', + + # rot_13 codec + 'rot13' : 'rot_13', + + # shift_jis codec + 'csshiftjis' : 'shift_jis', + 'shiftjis' : 'shift_jis', + 'sjis' : 'shift_jis', + 's_jis' : 'shift_jis', + + # shift_jis_2004 codec + 'shiftjis2004' : 'shift_jis_2004', + 'sjis_2004' : 'shift_jis_2004', + 's_jis_2004' : 'shift_jis_2004', + + # shift_jisx0213 codec + 'shiftjisx0213' : 'shift_jisx0213', + 'sjisx0213' : 'shift_jisx0213', + 's_jisx0213' : 'shift_jisx0213', + + # tactis codec + 'tis260' : 'tactis', + + # tis_620 codec + 'tis620' : 'tis_620', + 'tis_620_0' : 'tis_620', + 'tis_620_2529_0' : 'tis_620', + 'tis_620_2529_1' : 'tis_620', + 'iso_ir_166' : 'tis_620', + + # utf_16 codec + 'u16' : 'utf_16', + 'utf16' : 'utf_16', + + # utf_16_be codec + 'unicodebigunmarked' : 'utf_16_be', + 'utf_16be' : 'utf_16_be', + + # utf_16_le codec + 'unicodelittleunmarked' : 'utf_16_le', + 'utf_16le' : 'utf_16_le', + + # utf_32 codec + 'u32' : 'utf_32', + 'utf32' : 'utf_32', + + # utf_32_be codec + 'utf_32be' : 'utf_32_be', + + # utf_32_le codec + 'utf_32le' : 'utf_32_le', + + # utf_7 codec + 'u7' : 'utf_7', + 'utf7' : 'utf_7', + 'unicode_1_1_utf_7' : 'utf_7', + + # utf_8 codec + 'u8' : 'utf_8', + 'utf' : 'utf_8', + 'utf8' : 'utf_8', + 'utf8_ucs2' : 'utf_8', + 'utf8_ucs4' : 'utf_8', + + # uu_codec codec + 'uu' : 'uu_codec', + + # zlib_codec codec + 'zip' : 'zlib_codec', + 'zlib' : 'zlib_codec', + +} diff --git a/src/main/resources/PythonLibs/encodings/ascii.py b/src/main/resources/PythonLibs/encodings/ascii.py new file mode 100644 index 0000000000000000000000000000000000000000..2033cde97484a9ba86f9008dabd15ac846c663ee --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/ascii.py @@ -0,0 +1,50 @@ +""" Python 'ascii' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.ascii_encode + decode = codecs.ascii_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.ascii_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.ascii_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +class StreamConverter(StreamWriter,StreamReader): + + encode = codecs.ascii_decode + decode = codecs.ascii_encode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='ascii', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/base64_codec.py b/src/main/resources/PythonLibs/encodings/base64_codec.py new file mode 100644 index 0000000000000000000000000000000000000000..f84e7808e99433f8666b986d5abb35d446047065 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/base64_codec.py @@ -0,0 +1,79 @@ +""" Python 'base64_codec' Codec - base64 content transfer encoding + + Unlike most of the other codecs which target Unicode, this codec + will return Python string objects for both encode and decode. + + Written by Marc-Andre Lemburg (mal@lemburg.com). + +""" +import codecs, base64 + +### Codec APIs + +def base64_encode(input,errors='strict'): + + """ Encodes the object input and returns a tuple (output + object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = base64.encodestring(input) + return (output, len(input)) + +def base64_decode(input,errors='strict'): + + """ Decodes the object input and returns a tuple (output + object, length consumed). + + input must be an object which provides the bf_getreadbuf + buffer slot. Python strings, buffer objects and memory + mapped files are examples of objects providing this slot. + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = base64.decodestring(input) + return (output, len(input)) + +class Codec(codecs.Codec): + + def encode(self, input,errors='strict'): + return base64_encode(input,errors) + def decode(self, input,errors='strict'): + return base64_decode(input,errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + assert self.errors == 'strict' + return base64.encodestring(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + assert self.errors == 'strict' + return base64.decodestring(input) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='base64', + encode=base64_encode, + decode=base64_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/big5.py b/src/main/resources/PythonLibs/encodings/big5.py new file mode 100644 index 0000000000000000000000000000000000000000..7adeb0e1605274414014ee7849c36b203f7589f7 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/big5.py @@ -0,0 +1,39 @@ +# +# big5.py: Python Unicode Codec for BIG5 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_tw, codecs +import _multibytecodec as mbc + +codec = _codecs_tw.getcodec('big5') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='big5', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/big5hkscs.py b/src/main/resources/PythonLibs/encodings/big5hkscs.py new file mode 100644 index 0000000000000000000000000000000000000000..350df37baaedafcd75120723bf8e9b85a7e2a4b8 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/big5hkscs.py @@ -0,0 +1,39 @@ +# +# big5hkscs.py: Python Unicode Codec for BIG5HKSCS +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_hk, codecs +import _multibytecodec as mbc + +codec = _codecs_hk.getcodec('big5hkscs') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='big5hkscs', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/bz2_codec.py b/src/main/resources/PythonLibs/encodings/bz2_codec.py new file mode 100644 index 0000000000000000000000000000000000000000..054b36b401a66e54ba39c6a96485a9d0f19c9713 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/bz2_codec.py @@ -0,0 +1,102 @@ +""" Python 'bz2_codec' Codec - bz2 compression encoding + + Unlike most of the other codecs which target Unicode, this codec + will return Python string objects for both encode and decode. + + Adapted by Raymond Hettinger from zlib_codec.py which was written + by Marc-Andre Lemburg (mal@lemburg.com). + +""" +import codecs +import bz2 # this codec needs the optional bz2 module ! + +### Codec APIs + +def bz2_encode(input,errors='strict'): + + """ Encodes the object input and returns a tuple (output + object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = bz2.compress(input) + return (output, len(input)) + +def bz2_decode(input,errors='strict'): + + """ Decodes the object input and returns a tuple (output + object, length consumed). + + input must be an object which provides the bf_getreadbuf + buffer slot. Python strings, buffer objects and memory + mapped files are examples of objects providing this slot. + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = bz2.decompress(input) + return (output, len(input)) + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return bz2_encode(input, errors) + def decode(self, input, errors='strict'): + return bz2_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.compressobj = bz2.BZ2Compressor() + + def encode(self, input, final=False): + if final: + c = self.compressobj.compress(input) + return c + self.compressobj.flush() + else: + return self.compressobj.compress(input) + + def reset(self): + self.compressobj = bz2.BZ2Compressor() + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.decompressobj = bz2.BZ2Decompressor() + + def decode(self, input, final=False): + try: + return self.decompressobj.decompress(input) + except EOFError: + return '' + + def reset(self): + self.decompressobj = bz2.BZ2Decompressor() + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name="bz2", + encode=bz2_encode, + decode=bz2_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/charmap.py b/src/main/resources/PythonLibs/encodings/charmap.py new file mode 100644 index 0000000000000000000000000000000000000000..81189b161a64ad2edbe9172597d848e64b28b28c --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/charmap.py @@ -0,0 +1,69 @@ +""" Generic Python Character Mapping Codec. + + Use this codec directly rather than through the automatic + conversion mechanisms supplied by unicode() and .encode(). + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.charmap_encode + decode = codecs.charmap_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict', mapping=None): + codecs.IncrementalEncoder.__init__(self, errors) + self.mapping = mapping + + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, self.mapping)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict', mapping=None): + codecs.IncrementalDecoder.__init__(self, errors) + self.mapping = mapping + + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, self.mapping)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + + def __init__(self,stream,errors='strict',mapping=None): + codecs.StreamWriter.__init__(self,stream,errors) + self.mapping = mapping + + def encode(self,input,errors='strict'): + return Codec.encode(input,errors,self.mapping) + +class StreamReader(Codec,codecs.StreamReader): + + def __init__(self,stream,errors='strict',mapping=None): + codecs.StreamReader.__init__(self,stream,errors) + self.mapping = mapping + + def decode(self,input,errors='strict'): + return Codec.decode(input,errors,self.mapping) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='charmap', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/cp037.py b/src/main/resources/PythonLibs/encodings/cp037.py new file mode 100644 index 0000000000000000000000000000000000000000..c802b899af2eed0d366bb79f6f371c92de3bcebf --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp037.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp037 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP037.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp037', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x9c' # 0x04 -> CONTROL + u'\t' # 0x05 -> HORIZONTAL TABULATION + u'\x86' # 0x06 -> CONTROL + u'\x7f' # 0x07 -> DELETE + u'\x97' # 0x08 -> CONTROL + u'\x8d' # 0x09 -> CONTROL + u'\x8e' # 0x0A -> CONTROL + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x9d' # 0x14 -> CONTROL + u'\x85' # 0x15 -> CONTROL + u'\x08' # 0x16 -> BACKSPACE + u'\x87' # 0x17 -> CONTROL + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x92' # 0x1A -> CONTROL + u'\x8f' # 0x1B -> CONTROL + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u'\x80' # 0x20 -> CONTROL + u'\x81' # 0x21 -> CONTROL + u'\x82' # 0x22 -> CONTROL + u'\x83' # 0x23 -> CONTROL + u'\x84' # 0x24 -> CONTROL + u'\n' # 0x25 -> LINE FEED + u'\x17' # 0x26 -> END OF TRANSMISSION BLOCK + u'\x1b' # 0x27 -> ESCAPE + u'\x88' # 0x28 -> CONTROL + u'\x89' # 0x29 -> CONTROL + u'\x8a' # 0x2A -> CONTROL + u'\x8b' # 0x2B -> CONTROL + u'\x8c' # 0x2C -> CONTROL + u'\x05' # 0x2D -> ENQUIRY + u'\x06' # 0x2E -> ACKNOWLEDGE + u'\x07' # 0x2F -> BELL + u'\x90' # 0x30 -> CONTROL + u'\x91' # 0x31 -> CONTROL + u'\x16' # 0x32 -> SYNCHRONOUS IDLE + u'\x93' # 0x33 -> CONTROL + u'\x94' # 0x34 -> CONTROL + u'\x95' # 0x35 -> CONTROL + u'\x96' # 0x36 -> CONTROL + u'\x04' # 0x37 -> END OF TRANSMISSION + u'\x98' # 0x38 -> CONTROL + u'\x99' # 0x39 -> CONTROL + u'\x9a' # 0x3A -> CONTROL + u'\x9b' # 0x3B -> CONTROL + u'\x14' # 0x3C -> DEVICE CONTROL FOUR + u'\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + u'\x9e' # 0x3E -> CONTROL + u'\x1a' # 0x3F -> SUBSTITUTE + u' ' # 0x40 -> SPACE + u'\xa0' # 0x41 -> NO-BREAK SPACE + u'\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + u'\xa2' # 0x4A -> CENT SIGN + u'.' # 0x4B -> FULL STOP + u'<' # 0x4C -> LESS-THAN SIGN + u'(' # 0x4D -> LEFT PARENTHESIS + u'+' # 0x4E -> PLUS SIGN + u'|' # 0x4F -> VERTICAL LINE + u'&' # 0x50 -> AMPERSAND + u'\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + u'\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + u'\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + u'!' # 0x5A -> EXCLAMATION MARK + u'$' # 0x5B -> DOLLAR SIGN + u'*' # 0x5C -> ASTERISK + u')' # 0x5D -> RIGHT PARENTHESIS + u';' # 0x5E -> SEMICOLON + u'\xac' # 0x5F -> NOT SIGN + u'-' # 0x60 -> HYPHEN-MINUS + u'/' # 0x61 -> SOLIDUS + u'\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xa6' # 0x6A -> BROKEN BAR + u',' # 0x6B -> COMMA + u'%' # 0x6C -> PERCENT SIGN + u'_' # 0x6D -> LOW LINE + u'>' # 0x6E -> GREATER-THAN SIGN + u'?' # 0x6F -> QUESTION MARK + u'\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + u'\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + u'`' # 0x79 -> GRAVE ACCENT + u':' # 0x7A -> COLON + u'#' # 0x7B -> NUMBER SIGN + u'@' # 0x7C -> COMMERCIAL AT + u"'" # 0x7D -> APOSTROPHE + u'=' # 0x7E -> EQUALS SIGN + u'"' # 0x7F -> QUOTATION MARK + u'\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + u'a' # 0x81 -> LATIN SMALL LETTER A + u'b' # 0x82 -> LATIN SMALL LETTER B + u'c' # 0x83 -> LATIN SMALL LETTER C + u'd' # 0x84 -> LATIN SMALL LETTER D + u'e' # 0x85 -> LATIN SMALL LETTER E + u'f' # 0x86 -> LATIN SMALL LETTER F + u'g' # 0x87 -> LATIN SMALL LETTER G + u'h' # 0x88 -> LATIN SMALL LETTER H + u'i' # 0x89 -> LATIN SMALL LETTER I + u'\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + u'\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + u'\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + u'\xb1' # 0x8F -> PLUS-MINUS SIGN + u'\xb0' # 0x90 -> DEGREE SIGN + u'j' # 0x91 -> LATIN SMALL LETTER J + u'k' # 0x92 -> LATIN SMALL LETTER K + u'l' # 0x93 -> LATIN SMALL LETTER L + u'm' # 0x94 -> LATIN SMALL LETTER M + u'n' # 0x95 -> LATIN SMALL LETTER N + u'o' # 0x96 -> LATIN SMALL LETTER O + u'p' # 0x97 -> LATIN SMALL LETTER P + u'q' # 0x98 -> LATIN SMALL LETTER Q + u'r' # 0x99 -> LATIN SMALL LETTER R + u'\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + u'\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + u'\xb8' # 0x9D -> CEDILLA + u'\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + u'\xa4' # 0x9F -> CURRENCY SIGN + u'\xb5' # 0xA0 -> MICRO SIGN + u'~' # 0xA1 -> TILDE + u's' # 0xA2 -> LATIN SMALL LETTER S + u't' # 0xA3 -> LATIN SMALL LETTER T + u'u' # 0xA4 -> LATIN SMALL LETTER U + u'v' # 0xA5 -> LATIN SMALL LETTER V + u'w' # 0xA6 -> LATIN SMALL LETTER W + u'x' # 0xA7 -> LATIN SMALL LETTER X + u'y' # 0xA8 -> LATIN SMALL LETTER Y + u'z' # 0xA9 -> LATIN SMALL LETTER Z + u'\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + u'\xbf' # 0xAB -> INVERTED QUESTION MARK + u'\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + u'\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + u'\xae' # 0xAF -> REGISTERED SIGN + u'^' # 0xB0 -> CIRCUMFLEX ACCENT + u'\xa3' # 0xB1 -> POUND SIGN + u'\xa5' # 0xB2 -> YEN SIGN + u'\xb7' # 0xB3 -> MIDDLE DOT + u'\xa9' # 0xB4 -> COPYRIGHT SIGN + u'\xa7' # 0xB5 -> SECTION SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + u'[' # 0xBA -> LEFT SQUARE BRACKET + u']' # 0xBB -> RIGHT SQUARE BRACKET + u'\xaf' # 0xBC -> MACRON + u'\xa8' # 0xBD -> DIAERESIS + u'\xb4' # 0xBE -> ACUTE ACCENT + u'\xd7' # 0xBF -> MULTIPLICATION SIGN + u'{' # 0xC0 -> LEFT CURLY BRACKET + u'A' # 0xC1 -> LATIN CAPITAL LETTER A + u'B' # 0xC2 -> LATIN CAPITAL LETTER B + u'C' # 0xC3 -> LATIN CAPITAL LETTER C + u'D' # 0xC4 -> LATIN CAPITAL LETTER D + u'E' # 0xC5 -> LATIN CAPITAL LETTER E + u'F' # 0xC6 -> LATIN CAPITAL LETTER F + u'G' # 0xC7 -> LATIN CAPITAL LETTER G + u'H' # 0xC8 -> LATIN CAPITAL LETTER H + u'I' # 0xC9 -> LATIN CAPITAL LETTER I + u'\xad' # 0xCA -> SOFT HYPHEN + u'\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + u'\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + u'}' # 0xD0 -> RIGHT CURLY BRACKET + u'J' # 0xD1 -> LATIN CAPITAL LETTER J + u'K' # 0xD2 -> LATIN CAPITAL LETTER K + u'L' # 0xD3 -> LATIN CAPITAL LETTER L + u'M' # 0xD4 -> LATIN CAPITAL LETTER M + u'N' # 0xD5 -> LATIN CAPITAL LETTER N + u'O' # 0xD6 -> LATIN CAPITAL LETTER O + u'P' # 0xD7 -> LATIN CAPITAL LETTER P + u'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + u'R' # 0xD9 -> LATIN CAPITAL LETTER R + u'\xb9' # 0xDA -> SUPERSCRIPT ONE + u'\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + u'\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\\' # 0xE0 -> REVERSE SOLIDUS + u'\xf7' # 0xE1 -> DIVISION SIGN + u'S' # 0xE2 -> LATIN CAPITAL LETTER S + u'T' # 0xE3 -> LATIN CAPITAL LETTER T + u'U' # 0xE4 -> LATIN CAPITAL LETTER U + u'V' # 0xE5 -> LATIN CAPITAL LETTER V + u'W' # 0xE6 -> LATIN CAPITAL LETTER W + u'X' # 0xE7 -> LATIN CAPITAL LETTER X + u'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + u'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + u'\xb2' # 0xEA -> SUPERSCRIPT TWO + u'\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + u'0' # 0xF0 -> DIGIT ZERO + u'1' # 0xF1 -> DIGIT ONE + u'2' # 0xF2 -> DIGIT TWO + u'3' # 0xF3 -> DIGIT THREE + u'4' # 0xF4 -> DIGIT FOUR + u'5' # 0xF5 -> DIGIT FIVE + u'6' # 0xF6 -> DIGIT SIX + u'7' # 0xF7 -> DIGIT SEVEN + u'8' # 0xF8 -> DIGIT EIGHT + u'9' # 0xF9 -> DIGIT NINE + u'\xb3' # 0xFA -> SUPERSCRIPT THREE + u'\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + u'\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1006.py b/src/main/resources/PythonLibs/encodings/cp1006.py new file mode 100644 index 0000000000000000000000000000000000000000..e21e804eb9b6e03f4c637036eb1167530e9cce34 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1006.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1006 generated from 'MAPPINGS/VENDORS/MISC/CP1006.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1006', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u06f0' # 0xA1 -> EXTENDED ARABIC-INDIC DIGIT ZERO + u'\u06f1' # 0xA2 -> EXTENDED ARABIC-INDIC DIGIT ONE + u'\u06f2' # 0xA3 -> EXTENDED ARABIC-INDIC DIGIT TWO + u'\u06f3' # 0xA4 -> EXTENDED ARABIC-INDIC DIGIT THREE + u'\u06f4' # 0xA5 -> EXTENDED ARABIC-INDIC DIGIT FOUR + u'\u06f5' # 0xA6 -> EXTENDED ARABIC-INDIC DIGIT FIVE + u'\u06f6' # 0xA7 -> EXTENDED ARABIC-INDIC DIGIT SIX + u'\u06f7' # 0xA8 -> EXTENDED ARABIC-INDIC DIGIT SEVEN + u'\u06f8' # 0xA9 -> EXTENDED ARABIC-INDIC DIGIT EIGHT + u'\u06f9' # 0xAA -> EXTENDED ARABIC-INDIC DIGIT NINE + u'\u060c' # 0xAB -> ARABIC COMMA + u'\u061b' # 0xAC -> ARABIC SEMICOLON + u'\xad' # 0xAD -> SOFT HYPHEN + u'\u061f' # 0xAE -> ARABIC QUESTION MARK + u'\ufe81' # 0xAF -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + u'\ufe8d' # 0xB0 -> ARABIC LETTER ALEF ISOLATED FORM + u'\ufe8e' # 0xB1 -> ARABIC LETTER ALEF FINAL FORM + u'\ufe8e' # 0xB2 -> ARABIC LETTER ALEF FINAL FORM + u'\ufe8f' # 0xB3 -> ARABIC LETTER BEH ISOLATED FORM + u'\ufe91' # 0xB4 -> ARABIC LETTER BEH INITIAL FORM + u'\ufb56' # 0xB5 -> ARABIC LETTER PEH ISOLATED FORM + u'\ufb58' # 0xB6 -> ARABIC LETTER PEH INITIAL FORM + u'\ufe93' # 0xB7 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM + u'\ufe95' # 0xB8 -> ARABIC LETTER TEH ISOLATED FORM + u'\ufe97' # 0xB9 -> ARABIC LETTER TEH INITIAL FORM + u'\ufb66' # 0xBA -> ARABIC LETTER TTEH ISOLATED FORM + u'\ufb68' # 0xBB -> ARABIC LETTER TTEH INITIAL FORM + u'\ufe99' # 0xBC -> ARABIC LETTER THEH ISOLATED FORM + u'\ufe9b' # 0xBD -> ARABIC LETTER THEH INITIAL FORM + u'\ufe9d' # 0xBE -> ARABIC LETTER JEEM ISOLATED FORM + u'\ufe9f' # 0xBF -> ARABIC LETTER JEEM INITIAL FORM + u'\ufb7a' # 0xC0 -> ARABIC LETTER TCHEH ISOLATED FORM + u'\ufb7c' # 0xC1 -> ARABIC LETTER TCHEH INITIAL FORM + u'\ufea1' # 0xC2 -> ARABIC LETTER HAH ISOLATED FORM + u'\ufea3' # 0xC3 -> ARABIC LETTER HAH INITIAL FORM + u'\ufea5' # 0xC4 -> ARABIC LETTER KHAH ISOLATED FORM + u'\ufea7' # 0xC5 -> ARABIC LETTER KHAH INITIAL FORM + u'\ufea9' # 0xC6 -> ARABIC LETTER DAL ISOLATED FORM + u'\ufb84' # 0xC7 -> ARABIC LETTER DAHAL ISOLATED FORMN + u'\ufeab' # 0xC8 -> ARABIC LETTER THAL ISOLATED FORM + u'\ufead' # 0xC9 -> ARABIC LETTER REH ISOLATED FORM + u'\ufb8c' # 0xCA -> ARABIC LETTER RREH ISOLATED FORM + u'\ufeaf' # 0xCB -> ARABIC LETTER ZAIN ISOLATED FORM + u'\ufb8a' # 0xCC -> ARABIC LETTER JEH ISOLATED FORM + u'\ufeb1' # 0xCD -> ARABIC LETTER SEEN ISOLATED FORM + u'\ufeb3' # 0xCE -> ARABIC LETTER SEEN INITIAL FORM + u'\ufeb5' # 0xCF -> ARABIC LETTER SHEEN ISOLATED FORM + u'\ufeb7' # 0xD0 -> ARABIC LETTER SHEEN INITIAL FORM + u'\ufeb9' # 0xD1 -> ARABIC LETTER SAD ISOLATED FORM + u'\ufebb' # 0xD2 -> ARABIC LETTER SAD INITIAL FORM + u'\ufebd' # 0xD3 -> ARABIC LETTER DAD ISOLATED FORM + u'\ufebf' # 0xD4 -> ARABIC LETTER DAD INITIAL FORM + u'\ufec1' # 0xD5 -> ARABIC LETTER TAH ISOLATED FORM + u'\ufec5' # 0xD6 -> ARABIC LETTER ZAH ISOLATED FORM + u'\ufec9' # 0xD7 -> ARABIC LETTER AIN ISOLATED FORM + u'\ufeca' # 0xD8 -> ARABIC LETTER AIN FINAL FORM + u'\ufecb' # 0xD9 -> ARABIC LETTER AIN INITIAL FORM + u'\ufecc' # 0xDA -> ARABIC LETTER AIN MEDIAL FORM + u'\ufecd' # 0xDB -> ARABIC LETTER GHAIN ISOLATED FORM + u'\ufece' # 0xDC -> ARABIC LETTER GHAIN FINAL FORM + u'\ufecf' # 0xDD -> ARABIC LETTER GHAIN INITIAL FORM + u'\ufed0' # 0xDE -> ARABIC LETTER GHAIN MEDIAL FORM + u'\ufed1' # 0xDF -> ARABIC LETTER FEH ISOLATED FORM + u'\ufed3' # 0xE0 -> ARABIC LETTER FEH INITIAL FORM + u'\ufed5' # 0xE1 -> ARABIC LETTER QAF ISOLATED FORM + u'\ufed7' # 0xE2 -> ARABIC LETTER QAF INITIAL FORM + u'\ufed9' # 0xE3 -> ARABIC LETTER KAF ISOLATED FORM + u'\ufedb' # 0xE4 -> ARABIC LETTER KAF INITIAL FORM + u'\ufb92' # 0xE5 -> ARABIC LETTER GAF ISOLATED FORM + u'\ufb94' # 0xE6 -> ARABIC LETTER GAF INITIAL FORM + u'\ufedd' # 0xE7 -> ARABIC LETTER LAM ISOLATED FORM + u'\ufedf' # 0xE8 -> ARABIC LETTER LAM INITIAL FORM + u'\ufee0' # 0xE9 -> ARABIC LETTER LAM MEDIAL FORM + u'\ufee1' # 0xEA -> ARABIC LETTER MEEM ISOLATED FORM + u'\ufee3' # 0xEB -> ARABIC LETTER MEEM INITIAL FORM + u'\ufb9e' # 0xEC -> ARABIC LETTER NOON GHUNNA ISOLATED FORM + u'\ufee5' # 0xED -> ARABIC LETTER NOON ISOLATED FORM + u'\ufee7' # 0xEE -> ARABIC LETTER NOON INITIAL FORM + u'\ufe85' # 0xEF -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + u'\ufeed' # 0xF0 -> ARABIC LETTER WAW ISOLATED FORM + u'\ufba6' # 0xF1 -> ARABIC LETTER HEH GOAL ISOLATED FORM + u'\ufba8' # 0xF2 -> ARABIC LETTER HEH GOAL INITIAL FORM + u'\ufba9' # 0xF3 -> ARABIC LETTER HEH GOAL MEDIAL FORM + u'\ufbaa' # 0xF4 -> ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM + u'\ufe80' # 0xF5 -> ARABIC LETTER HAMZA ISOLATED FORM + u'\ufe89' # 0xF6 -> ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM + u'\ufe8a' # 0xF7 -> ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM + u'\ufe8b' # 0xF8 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + u'\ufef1' # 0xF9 -> ARABIC LETTER YEH ISOLATED FORM + u'\ufef2' # 0xFA -> ARABIC LETTER YEH FINAL FORM + u'\ufef3' # 0xFB -> ARABIC LETTER YEH INITIAL FORM + u'\ufbb0' # 0xFC -> ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM + u'\ufbae' # 0xFD -> ARABIC LETTER YEH BARREE ISOLATED FORM + u'\ufe7c' # 0xFE -> ARABIC SHADDA ISOLATED FORM + u'\ufe7d' # 0xFF -> ARABIC SHADDA MEDIAL FORM +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1026.py b/src/main/resources/PythonLibs/encodings/cp1026.py new file mode 100644 index 0000000000000000000000000000000000000000..45bbe626fdf78f9d3d6fe6fc12dd25dcf4acb3d4 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1026.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1026 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1026', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x9c' # 0x04 -> CONTROL + u'\t' # 0x05 -> HORIZONTAL TABULATION + u'\x86' # 0x06 -> CONTROL + u'\x7f' # 0x07 -> DELETE + u'\x97' # 0x08 -> CONTROL + u'\x8d' # 0x09 -> CONTROL + u'\x8e' # 0x0A -> CONTROL + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x9d' # 0x14 -> CONTROL + u'\x85' # 0x15 -> CONTROL + u'\x08' # 0x16 -> BACKSPACE + u'\x87' # 0x17 -> CONTROL + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x92' # 0x1A -> CONTROL + u'\x8f' # 0x1B -> CONTROL + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u'\x80' # 0x20 -> CONTROL + u'\x81' # 0x21 -> CONTROL + u'\x82' # 0x22 -> CONTROL + u'\x83' # 0x23 -> CONTROL + u'\x84' # 0x24 -> CONTROL + u'\n' # 0x25 -> LINE FEED + u'\x17' # 0x26 -> END OF TRANSMISSION BLOCK + u'\x1b' # 0x27 -> ESCAPE + u'\x88' # 0x28 -> CONTROL + u'\x89' # 0x29 -> CONTROL + u'\x8a' # 0x2A -> CONTROL + u'\x8b' # 0x2B -> CONTROL + u'\x8c' # 0x2C -> CONTROL + u'\x05' # 0x2D -> ENQUIRY + u'\x06' # 0x2E -> ACKNOWLEDGE + u'\x07' # 0x2F -> BELL + u'\x90' # 0x30 -> CONTROL + u'\x91' # 0x31 -> CONTROL + u'\x16' # 0x32 -> SYNCHRONOUS IDLE + u'\x93' # 0x33 -> CONTROL + u'\x94' # 0x34 -> CONTROL + u'\x95' # 0x35 -> CONTROL + u'\x96' # 0x36 -> CONTROL + u'\x04' # 0x37 -> END OF TRANSMISSION + u'\x98' # 0x38 -> CONTROL + u'\x99' # 0x39 -> CONTROL + u'\x9a' # 0x3A -> CONTROL + u'\x9b' # 0x3B -> CONTROL + u'\x14' # 0x3C -> DEVICE CONTROL FOUR + u'\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + u'\x9e' # 0x3E -> CONTROL + u'\x1a' # 0x3F -> SUBSTITUTE + u' ' # 0x40 -> SPACE + u'\xa0' # 0x41 -> NO-BREAK SPACE + u'\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + u'{' # 0x48 -> LEFT CURLY BRACKET + u'\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + u'\xc7' # 0x4A -> LATIN CAPITAL LETTER C WITH CEDILLA + u'.' # 0x4B -> FULL STOP + u'<' # 0x4C -> LESS-THAN SIGN + u'(' # 0x4D -> LEFT PARENTHESIS + u'+' # 0x4E -> PLUS SIGN + u'!' # 0x4F -> EXCLAMATION MARK + u'&' # 0x50 -> AMPERSAND + u'\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + u'\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + u'\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + u'\u011e' # 0x5A -> LATIN CAPITAL LETTER G WITH BREVE + u'\u0130' # 0x5B -> LATIN CAPITAL LETTER I WITH DOT ABOVE + u'*' # 0x5C -> ASTERISK + u')' # 0x5D -> RIGHT PARENTHESIS + u';' # 0x5E -> SEMICOLON + u'^' # 0x5F -> CIRCUMFLEX ACCENT + u'-' # 0x60 -> HYPHEN-MINUS + u'/' # 0x61 -> SOLIDUS + u'\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'[' # 0x68 -> LEFT SQUARE BRACKET + u'\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + u'\u015f' # 0x6A -> LATIN SMALL LETTER S WITH CEDILLA + u',' # 0x6B -> COMMA + u'%' # 0x6C -> PERCENT SIGN + u'_' # 0x6D -> LOW LINE + u'>' # 0x6E -> GREATER-THAN SIGN + u'?' # 0x6F -> QUESTION MARK + u'\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + u'\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + u'\u0131' # 0x79 -> LATIN SMALL LETTER DOTLESS I + u':' # 0x7A -> COLON + u'\xd6' # 0x7B -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\u015e' # 0x7C -> LATIN CAPITAL LETTER S WITH CEDILLA + u"'" # 0x7D -> APOSTROPHE + u'=' # 0x7E -> EQUALS SIGN + u'\xdc' # 0x7F -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + u'a' # 0x81 -> LATIN SMALL LETTER A + u'b' # 0x82 -> LATIN SMALL LETTER B + u'c' # 0x83 -> LATIN SMALL LETTER C + u'd' # 0x84 -> LATIN SMALL LETTER D + u'e' # 0x85 -> LATIN SMALL LETTER E + u'f' # 0x86 -> LATIN SMALL LETTER F + u'g' # 0x87 -> LATIN SMALL LETTER G + u'h' # 0x88 -> LATIN SMALL LETTER H + u'i' # 0x89 -> LATIN SMALL LETTER I + u'\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'}' # 0x8C -> RIGHT CURLY BRACKET + u'`' # 0x8D -> GRAVE ACCENT + u'\xa6' # 0x8E -> BROKEN BAR + u'\xb1' # 0x8F -> PLUS-MINUS SIGN + u'\xb0' # 0x90 -> DEGREE SIGN + u'j' # 0x91 -> LATIN SMALL LETTER J + u'k' # 0x92 -> LATIN SMALL LETTER K + u'l' # 0x93 -> LATIN SMALL LETTER L + u'm' # 0x94 -> LATIN SMALL LETTER M + u'n' # 0x95 -> LATIN SMALL LETTER N + u'o' # 0x96 -> LATIN SMALL LETTER O + u'p' # 0x97 -> LATIN SMALL LETTER P + u'q' # 0x98 -> LATIN SMALL LETTER Q + u'r' # 0x99 -> LATIN SMALL LETTER R + u'\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + u'\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + u'\xb8' # 0x9D -> CEDILLA + u'\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + u'\xa4' # 0x9F -> CURRENCY SIGN + u'\xb5' # 0xA0 -> MICRO SIGN + u'\xf6' # 0xA1 -> LATIN SMALL LETTER O WITH DIAERESIS + u's' # 0xA2 -> LATIN SMALL LETTER S + u't' # 0xA3 -> LATIN SMALL LETTER T + u'u' # 0xA4 -> LATIN SMALL LETTER U + u'v' # 0xA5 -> LATIN SMALL LETTER V + u'w' # 0xA6 -> LATIN SMALL LETTER W + u'x' # 0xA7 -> LATIN SMALL LETTER X + u'y' # 0xA8 -> LATIN SMALL LETTER Y + u'z' # 0xA9 -> LATIN SMALL LETTER Z + u'\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + u'\xbf' # 0xAB -> INVERTED QUESTION MARK + u']' # 0xAC -> RIGHT SQUARE BRACKET + u'$' # 0xAD -> DOLLAR SIGN + u'@' # 0xAE -> COMMERCIAL AT + u'\xae' # 0xAF -> REGISTERED SIGN + u'\xa2' # 0xB0 -> CENT SIGN + u'\xa3' # 0xB1 -> POUND SIGN + u'\xa5' # 0xB2 -> YEN SIGN + u'\xb7' # 0xB3 -> MIDDLE DOT + u'\xa9' # 0xB4 -> COPYRIGHT SIGN + u'\xa7' # 0xB5 -> SECTION SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + u'\xac' # 0xBA -> NOT SIGN + u'|' # 0xBB -> VERTICAL LINE + u'\xaf' # 0xBC -> MACRON + u'\xa8' # 0xBD -> DIAERESIS + u'\xb4' # 0xBE -> ACUTE ACCENT + u'\xd7' # 0xBF -> MULTIPLICATION SIGN + u'\xe7' # 0xC0 -> LATIN SMALL LETTER C WITH CEDILLA + u'A' # 0xC1 -> LATIN CAPITAL LETTER A + u'B' # 0xC2 -> LATIN CAPITAL LETTER B + u'C' # 0xC3 -> LATIN CAPITAL LETTER C + u'D' # 0xC4 -> LATIN CAPITAL LETTER D + u'E' # 0xC5 -> LATIN CAPITAL LETTER E + u'F' # 0xC6 -> LATIN CAPITAL LETTER F + u'G' # 0xC7 -> LATIN CAPITAL LETTER G + u'H' # 0xC8 -> LATIN CAPITAL LETTER H + u'I' # 0xC9 -> LATIN CAPITAL LETTER I + u'\xad' # 0xCA -> SOFT HYPHEN + u'\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'~' # 0xCC -> TILDE + u'\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + u'\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + u'\u011f' # 0xD0 -> LATIN SMALL LETTER G WITH BREVE + u'J' # 0xD1 -> LATIN CAPITAL LETTER J + u'K' # 0xD2 -> LATIN CAPITAL LETTER K + u'L' # 0xD3 -> LATIN CAPITAL LETTER L + u'M' # 0xD4 -> LATIN CAPITAL LETTER M + u'N' # 0xD5 -> LATIN CAPITAL LETTER N + u'O' # 0xD6 -> LATIN CAPITAL LETTER O + u'P' # 0xD7 -> LATIN CAPITAL LETTER P + u'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + u'R' # 0xD9 -> LATIN CAPITAL LETTER R + u'\xb9' # 0xDA -> SUPERSCRIPT ONE + u'\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\\' # 0xDC -> REVERSE SOLIDUS + u'\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + u'\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\xfc' # 0xE0 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xf7' # 0xE1 -> DIVISION SIGN + u'S' # 0xE2 -> LATIN CAPITAL LETTER S + u'T' # 0xE3 -> LATIN CAPITAL LETTER T + u'U' # 0xE4 -> LATIN CAPITAL LETTER U + u'V' # 0xE5 -> LATIN CAPITAL LETTER V + u'W' # 0xE6 -> LATIN CAPITAL LETTER W + u'X' # 0xE7 -> LATIN CAPITAL LETTER X + u'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + u'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + u'\xb2' # 0xEA -> SUPERSCRIPT TWO + u'\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'#' # 0xEC -> NUMBER SIGN + u'\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + u'0' # 0xF0 -> DIGIT ZERO + u'1' # 0xF1 -> DIGIT ONE + u'2' # 0xF2 -> DIGIT TWO + u'3' # 0xF3 -> DIGIT THREE + u'4' # 0xF4 -> DIGIT FOUR + u'5' # 0xF5 -> DIGIT FIVE + u'6' # 0xF6 -> DIGIT SIX + u'7' # 0xF7 -> DIGIT SEVEN + u'8' # 0xF8 -> DIGIT EIGHT + u'9' # 0xF9 -> DIGIT NINE + u'\xb3' # 0xFA -> SUPERSCRIPT THREE + u'\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'"' # 0xFC -> QUOTATION MARK + u'\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + u'\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1140.py b/src/main/resources/PythonLibs/encodings/cp1140.py new file mode 100644 index 0000000000000000000000000000000000000000..7e507fd8530762fea37044237408b54604cacff1 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1140.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1140 generated from 'python-mappings/CP1140.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1140', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x9c' # 0x04 -> CONTROL + u'\t' # 0x05 -> HORIZONTAL TABULATION + u'\x86' # 0x06 -> CONTROL + u'\x7f' # 0x07 -> DELETE + u'\x97' # 0x08 -> CONTROL + u'\x8d' # 0x09 -> CONTROL + u'\x8e' # 0x0A -> CONTROL + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x9d' # 0x14 -> CONTROL + u'\x85' # 0x15 -> CONTROL + u'\x08' # 0x16 -> BACKSPACE + u'\x87' # 0x17 -> CONTROL + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x92' # 0x1A -> CONTROL + u'\x8f' # 0x1B -> CONTROL + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u'\x80' # 0x20 -> CONTROL + u'\x81' # 0x21 -> CONTROL + u'\x82' # 0x22 -> CONTROL + u'\x83' # 0x23 -> CONTROL + u'\x84' # 0x24 -> CONTROL + u'\n' # 0x25 -> LINE FEED + u'\x17' # 0x26 -> END OF TRANSMISSION BLOCK + u'\x1b' # 0x27 -> ESCAPE + u'\x88' # 0x28 -> CONTROL + u'\x89' # 0x29 -> CONTROL + u'\x8a' # 0x2A -> CONTROL + u'\x8b' # 0x2B -> CONTROL + u'\x8c' # 0x2C -> CONTROL + u'\x05' # 0x2D -> ENQUIRY + u'\x06' # 0x2E -> ACKNOWLEDGE + u'\x07' # 0x2F -> BELL + u'\x90' # 0x30 -> CONTROL + u'\x91' # 0x31 -> CONTROL + u'\x16' # 0x32 -> SYNCHRONOUS IDLE + u'\x93' # 0x33 -> CONTROL + u'\x94' # 0x34 -> CONTROL + u'\x95' # 0x35 -> CONTROL + u'\x96' # 0x36 -> CONTROL + u'\x04' # 0x37 -> END OF TRANSMISSION + u'\x98' # 0x38 -> CONTROL + u'\x99' # 0x39 -> CONTROL + u'\x9a' # 0x3A -> CONTROL + u'\x9b' # 0x3B -> CONTROL + u'\x14' # 0x3C -> DEVICE CONTROL FOUR + u'\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + u'\x9e' # 0x3E -> CONTROL + u'\x1a' # 0x3F -> SUBSTITUTE + u' ' # 0x40 -> SPACE + u'\xa0' # 0x41 -> NO-BREAK SPACE + u'\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + u'\xa2' # 0x4A -> CENT SIGN + u'.' # 0x4B -> FULL STOP + u'<' # 0x4C -> LESS-THAN SIGN + u'(' # 0x4D -> LEFT PARENTHESIS + u'+' # 0x4E -> PLUS SIGN + u'|' # 0x4F -> VERTICAL LINE + u'&' # 0x50 -> AMPERSAND + u'\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + u'\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + u'\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + u'!' # 0x5A -> EXCLAMATION MARK + u'$' # 0x5B -> DOLLAR SIGN + u'*' # 0x5C -> ASTERISK + u')' # 0x5D -> RIGHT PARENTHESIS + u';' # 0x5E -> SEMICOLON + u'\xac' # 0x5F -> NOT SIGN + u'-' # 0x60 -> HYPHEN-MINUS + u'/' # 0x61 -> SOLIDUS + u'\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xa6' # 0x6A -> BROKEN BAR + u',' # 0x6B -> COMMA + u'%' # 0x6C -> PERCENT SIGN + u'_' # 0x6D -> LOW LINE + u'>' # 0x6E -> GREATER-THAN SIGN + u'?' # 0x6F -> QUESTION MARK + u'\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + u'\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + u'`' # 0x79 -> GRAVE ACCENT + u':' # 0x7A -> COLON + u'#' # 0x7B -> NUMBER SIGN + u'@' # 0x7C -> COMMERCIAL AT + u"'" # 0x7D -> APOSTROPHE + u'=' # 0x7E -> EQUALS SIGN + u'"' # 0x7F -> QUOTATION MARK + u'\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + u'a' # 0x81 -> LATIN SMALL LETTER A + u'b' # 0x82 -> LATIN SMALL LETTER B + u'c' # 0x83 -> LATIN SMALL LETTER C + u'd' # 0x84 -> LATIN SMALL LETTER D + u'e' # 0x85 -> LATIN SMALL LETTER E + u'f' # 0x86 -> LATIN SMALL LETTER F + u'g' # 0x87 -> LATIN SMALL LETTER G + u'h' # 0x88 -> LATIN SMALL LETTER H + u'i' # 0x89 -> LATIN SMALL LETTER I + u'\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + u'\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + u'\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + u'\xb1' # 0x8F -> PLUS-MINUS SIGN + u'\xb0' # 0x90 -> DEGREE SIGN + u'j' # 0x91 -> LATIN SMALL LETTER J + u'k' # 0x92 -> LATIN SMALL LETTER K + u'l' # 0x93 -> LATIN SMALL LETTER L + u'm' # 0x94 -> LATIN SMALL LETTER M + u'n' # 0x95 -> LATIN SMALL LETTER N + u'o' # 0x96 -> LATIN SMALL LETTER O + u'p' # 0x97 -> LATIN SMALL LETTER P + u'q' # 0x98 -> LATIN SMALL LETTER Q + u'r' # 0x99 -> LATIN SMALL LETTER R + u'\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + u'\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + u'\xb8' # 0x9D -> CEDILLA + u'\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + u'\u20ac' # 0x9F -> EURO SIGN + u'\xb5' # 0xA0 -> MICRO SIGN + u'~' # 0xA1 -> TILDE + u's' # 0xA2 -> LATIN SMALL LETTER S + u't' # 0xA3 -> LATIN SMALL LETTER T + u'u' # 0xA4 -> LATIN SMALL LETTER U + u'v' # 0xA5 -> LATIN SMALL LETTER V + u'w' # 0xA6 -> LATIN SMALL LETTER W + u'x' # 0xA7 -> LATIN SMALL LETTER X + u'y' # 0xA8 -> LATIN SMALL LETTER Y + u'z' # 0xA9 -> LATIN SMALL LETTER Z + u'\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + u'\xbf' # 0xAB -> INVERTED QUESTION MARK + u'\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + u'\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + u'\xae' # 0xAF -> REGISTERED SIGN + u'^' # 0xB0 -> CIRCUMFLEX ACCENT + u'\xa3' # 0xB1 -> POUND SIGN + u'\xa5' # 0xB2 -> YEN SIGN + u'\xb7' # 0xB3 -> MIDDLE DOT + u'\xa9' # 0xB4 -> COPYRIGHT SIGN + u'\xa7' # 0xB5 -> SECTION SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + u'[' # 0xBA -> LEFT SQUARE BRACKET + u']' # 0xBB -> RIGHT SQUARE BRACKET + u'\xaf' # 0xBC -> MACRON + u'\xa8' # 0xBD -> DIAERESIS + u'\xb4' # 0xBE -> ACUTE ACCENT + u'\xd7' # 0xBF -> MULTIPLICATION SIGN + u'{' # 0xC0 -> LEFT CURLY BRACKET + u'A' # 0xC1 -> LATIN CAPITAL LETTER A + u'B' # 0xC2 -> LATIN CAPITAL LETTER B + u'C' # 0xC3 -> LATIN CAPITAL LETTER C + u'D' # 0xC4 -> LATIN CAPITAL LETTER D + u'E' # 0xC5 -> LATIN CAPITAL LETTER E + u'F' # 0xC6 -> LATIN CAPITAL LETTER F + u'G' # 0xC7 -> LATIN CAPITAL LETTER G + u'H' # 0xC8 -> LATIN CAPITAL LETTER H + u'I' # 0xC9 -> LATIN CAPITAL LETTER I + u'\xad' # 0xCA -> SOFT HYPHEN + u'\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + u'\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + u'}' # 0xD0 -> RIGHT CURLY BRACKET + u'J' # 0xD1 -> LATIN CAPITAL LETTER J + u'K' # 0xD2 -> LATIN CAPITAL LETTER K + u'L' # 0xD3 -> LATIN CAPITAL LETTER L + u'M' # 0xD4 -> LATIN CAPITAL LETTER M + u'N' # 0xD5 -> LATIN CAPITAL LETTER N + u'O' # 0xD6 -> LATIN CAPITAL LETTER O + u'P' # 0xD7 -> LATIN CAPITAL LETTER P + u'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + u'R' # 0xD9 -> LATIN CAPITAL LETTER R + u'\xb9' # 0xDA -> SUPERSCRIPT ONE + u'\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + u'\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\\' # 0xE0 -> REVERSE SOLIDUS + u'\xf7' # 0xE1 -> DIVISION SIGN + u'S' # 0xE2 -> LATIN CAPITAL LETTER S + u'T' # 0xE3 -> LATIN CAPITAL LETTER T + u'U' # 0xE4 -> LATIN CAPITAL LETTER U + u'V' # 0xE5 -> LATIN CAPITAL LETTER V + u'W' # 0xE6 -> LATIN CAPITAL LETTER W + u'X' # 0xE7 -> LATIN CAPITAL LETTER X + u'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + u'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + u'\xb2' # 0xEA -> SUPERSCRIPT TWO + u'\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + u'0' # 0xF0 -> DIGIT ZERO + u'1' # 0xF1 -> DIGIT ONE + u'2' # 0xF2 -> DIGIT TWO + u'3' # 0xF3 -> DIGIT THREE + u'4' # 0xF4 -> DIGIT FOUR + u'5' # 0xF5 -> DIGIT FIVE + u'6' # 0xF6 -> DIGIT SIX + u'7' # 0xF7 -> DIGIT SEVEN + u'8' # 0xF8 -> DIGIT EIGHT + u'9' # 0xF9 -> DIGIT NINE + u'\xb3' # 0xFA -> SUPERSCRIPT THREE + u'\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + u'\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1250.py b/src/main/resources/PythonLibs/encodings/cp1250.py new file mode 100644 index 0000000000000000000000000000000000000000..d620b893358ab5c37a239846862b0dd754ad0a17 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1250.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1250 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1250', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\ufffe' # 0x83 -> UNDEFINED + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\ufffe' # 0x88 -> UNDEFINED + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u015a' # 0x8C -> LATIN CAPITAL LETTER S WITH ACUTE + u'\u0164' # 0x8D -> LATIN CAPITAL LETTER T WITH CARON + u'\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON + u'\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\ufffe' # 0x98 -> UNDEFINED + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u015b' # 0x9C -> LATIN SMALL LETTER S WITH ACUTE + u'\u0165' # 0x9D -> LATIN SMALL LETTER T WITH CARON + u'\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON + u'\u017a' # 0x9F -> LATIN SMALL LETTER Z WITH ACUTE + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u02c7' # 0xA1 -> CARON + u'\u02d8' # 0xA2 -> BREVE + u'\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\u0104' # 0xA5 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u02db' # 0xB2 -> OGONEK + u'\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\u0105' # 0xB9 -> LATIN SMALL LETTER A WITH OGONEK + u'\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u013d' # 0xBC -> LATIN CAPITAL LETTER L WITH CARON + u'\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT + u'\u013e' # 0xBE -> LATIN SMALL LETTER L WITH CARON + u'\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE + u'\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON + u'\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + u'\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON + u'\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE + u'\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON + u'\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + u'\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + u'\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON + u'\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + u'\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA + u'\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1251.py b/src/main/resources/PythonLibs/encodings/cp1251.py new file mode 100644 index 0000000000000000000000000000000000000000..216771fa4cc9ff1a5faf1fe5b480c5b8bb1a030a --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1251.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1251 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1251', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE + u'\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\u20ac' # 0x88 -> EURO SIGN + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE + u'\u040c' # 0x8D -> CYRILLIC CAPITAL LETTER KJE + u'\u040b' # 0x8E -> CYRILLIC CAPITAL LETTER TSHE + u'\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE + u'\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\ufffe' # 0x98 -> UNDEFINED + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE + u'\u045c' # 0x9D -> CYRILLIC SMALL LETTER KJE + u'\u045b' # 0x9E -> CYRILLIC SMALL LETTER TSHE + u'\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u040e' # 0xA1 -> CYRILLIC CAPITAL LETTER SHORT U + u'\u045e' # 0xA2 -> CYRILLIC SMALL LETTER SHORT U + u'\u0408' # 0xA3 -> CYRILLIC CAPITAL LETTER JE + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\u0490' # 0xA5 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u0404' # 0xAA -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\u0407' # 0xAF -> CYRILLIC CAPITAL LETTER YI + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0491' # 0xB4 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + u'\u2116' # 0xB9 -> NUMERO SIGN + u'\u0454' # 0xBA -> CYRILLIC SMALL LETTER UKRAINIAN IE + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u0458' # 0xBC -> CYRILLIC SMALL LETTER JE + u'\u0405' # 0xBD -> CYRILLIC CAPITAL LETTER DZE + u'\u0455' # 0xBE -> CYRILLIC SMALL LETTER DZE + u'\u0457' # 0xBF -> CYRILLIC SMALL LETTER YI + u'\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + u'\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + u'\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + u'\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + u'\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + u'\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + u'\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + u'\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + u'\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + u'\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + u'\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + u'\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + u'\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + u'\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + u'\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + u'\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + u'\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + u'\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + u'\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + u'\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + u'\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + u'\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + u'\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + u'\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + u'\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + u'\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + u'\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + u'\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + u'\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + u'\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + u'\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + u'\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + u'\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + u'\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + u'\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + u'\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + u'\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + u'\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + u'\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + u'\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + u'\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + u'\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + u'\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + u'\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + u'\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + u'\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + u'\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + u'\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + u'\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + u'\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + u'\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + u'\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + u'\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + u'\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + u'\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + u'\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + u'\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + u'\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + u'\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + u'\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + u'\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + u'\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + u'\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + u'\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1252.py b/src/main/resources/PythonLibs/encodings/cp1252.py new file mode 100644 index 0000000000000000000000000000000000000000..e60a328db40385dbffd823e1ff0e38619aaa4115 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1252.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1252 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1252', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + u'\ufffe' # 0x8D -> UNDEFINED + u'\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON + u'\ufffe' # 0x8F -> UNDEFINED + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\u02dc' # 0x98 -> SMALL TILDE + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + u'\ufffe' # 0x9D -> UNDEFINED + u'\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON + u'\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xbf' # 0xBF -> INVERTED QUESTION MARK + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf0' # 0xF0 -> LATIN SMALL LETTER ETH + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + u'\xfe' # 0xFE -> LATIN SMALL LETTER THORN + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1253.py b/src/main/resources/PythonLibs/encodings/cp1253.py new file mode 100644 index 0000000000000000000000000000000000000000..49f6cccbd2334d8a022132194ff09325a52a5275 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1253.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1253 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1253', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\ufffe' # 0x88 -> UNDEFINED + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\ufffe' # 0x8A -> UNDEFINED + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\ufffe' # 0x8C -> UNDEFINED + u'\ufffe' # 0x8D -> UNDEFINED + u'\ufffe' # 0x8E -> UNDEFINED + u'\ufffe' # 0x8F -> UNDEFINED + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\ufffe' # 0x98 -> UNDEFINED + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\ufffe' # 0x9A -> UNDEFINED + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\ufffe' # 0x9C -> UNDEFINED + u'\ufffe' # 0x9D -> UNDEFINED + u'\ufffe' # 0x9E -> UNDEFINED + u'\ufffe' # 0x9F -> UNDEFINED + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0385' # 0xA1 -> GREEK DIALYTIKA TONOS + u'\u0386' # 0xA2 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\ufffe' # 0xAA -> UNDEFINED + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\u2015' # 0xAF -> HORIZONTAL BAR + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\u0384' # 0xB4 -> GREEK TONOS + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + u'\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS + u'\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS + u'\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + u'\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + u'\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA + u'\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA + u'\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA + u'\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA + u'\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON + u'\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA + u'\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA + u'\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA + u'\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA + u'\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA + u'\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA + u'\u039c' # 0xCC -> GREEK CAPITAL LETTER MU + u'\u039d' # 0xCD -> GREEK CAPITAL LETTER NU + u'\u039e' # 0xCE -> GREEK CAPITAL LETTER XI + u'\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON + u'\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI + u'\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO + u'\ufffe' # 0xD2 -> UNDEFINED + u'\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA + u'\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU + u'\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON + u'\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI + u'\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI + u'\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI + u'\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA + u'\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + u'\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + u'\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS + u'\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS + u'\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS + u'\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS + u'\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + u'\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + u'\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + u'\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA + u'\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + u'\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + u'\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA + u'\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA + u'\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA + u'\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + u'\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA + u'\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA + u'\u03bc' # 0xEC -> GREEK SMALL LETTER MU + u'\u03bd' # 0xED -> GREEK SMALL LETTER NU + u'\u03be' # 0xEE -> GREEK SMALL LETTER XI + u'\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + u'\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + u'\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO + u'\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA + u'\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + u'\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + u'\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON + u'\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI + u'\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI + u'\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI + u'\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA + u'\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + u'\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + u'\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS + u'\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS + u'\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS + u'\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1254.py b/src/main/resources/PythonLibs/encodings/cp1254.py new file mode 100644 index 0000000000000000000000000000000000000000..65530ab546178e127225c459cd1ca9ef8cd65aa0 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1254.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1254 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1254', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + u'\ufffe' # 0x8D -> UNDEFINED + u'\ufffe' # 0x8E -> UNDEFINED + u'\ufffe' # 0x8F -> UNDEFINED + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\u02dc' # 0x98 -> SMALL TILDE + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + u'\ufffe' # 0x9D -> UNDEFINED + u'\ufffe' # 0x9E -> UNDEFINED + u'\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xbf' # 0xBF -> INVERTED QUESTION MARK + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE + u'\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I + u'\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1255.py b/src/main/resources/PythonLibs/encodings/cp1255.py new file mode 100644 index 0000000000000000000000000000000000000000..fd1456fab6e0b416891f0bc24a220cf2e74fe04f --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1255.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1255 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1255', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\ufffe' # 0x8A -> UNDEFINED + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\ufffe' # 0x8C -> UNDEFINED + u'\ufffe' # 0x8D -> UNDEFINED + u'\ufffe' # 0x8E -> UNDEFINED + u'\ufffe' # 0x8F -> UNDEFINED + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\u02dc' # 0x98 -> SMALL TILDE + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\ufffe' # 0x9A -> UNDEFINED + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\ufffe' # 0x9C -> UNDEFINED + u'\ufffe' # 0x9D -> UNDEFINED + u'\ufffe' # 0x9E -> UNDEFINED + u'\ufffe' # 0x9F -> UNDEFINED + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\u20aa' # 0xA4 -> NEW SHEQEL SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xd7' # 0xAA -> MULTIPLICATION SIGN + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xf7' # 0xBA -> DIVISION SIGN + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xbf' # 0xBF -> INVERTED QUESTION MARK + u'\u05b0' # 0xC0 -> HEBREW POINT SHEVA + u'\u05b1' # 0xC1 -> HEBREW POINT HATAF SEGOL + u'\u05b2' # 0xC2 -> HEBREW POINT HATAF PATAH + u'\u05b3' # 0xC3 -> HEBREW POINT HATAF QAMATS + u'\u05b4' # 0xC4 -> HEBREW POINT HIRIQ + u'\u05b5' # 0xC5 -> HEBREW POINT TSERE + u'\u05b6' # 0xC6 -> HEBREW POINT SEGOL + u'\u05b7' # 0xC7 -> HEBREW POINT PATAH + u'\u05b8' # 0xC8 -> HEBREW POINT QAMATS + u'\u05b9' # 0xC9 -> HEBREW POINT HOLAM + u'\ufffe' # 0xCA -> UNDEFINED + u'\u05bb' # 0xCB -> HEBREW POINT QUBUTS + u'\u05bc' # 0xCC -> HEBREW POINT DAGESH OR MAPIQ + u'\u05bd' # 0xCD -> HEBREW POINT METEG + u'\u05be' # 0xCE -> HEBREW PUNCTUATION MAQAF + u'\u05bf' # 0xCF -> HEBREW POINT RAFE + u'\u05c0' # 0xD0 -> HEBREW PUNCTUATION PASEQ + u'\u05c1' # 0xD1 -> HEBREW POINT SHIN DOT + u'\u05c2' # 0xD2 -> HEBREW POINT SIN DOT + u'\u05c3' # 0xD3 -> HEBREW PUNCTUATION SOF PASUQ + u'\u05f0' # 0xD4 -> HEBREW LIGATURE YIDDISH DOUBLE VAV + u'\u05f1' # 0xD5 -> HEBREW LIGATURE YIDDISH VAV YOD + u'\u05f2' # 0xD6 -> HEBREW LIGATURE YIDDISH DOUBLE YOD + u'\u05f3' # 0xD7 -> HEBREW PUNCTUATION GERESH + u'\u05f4' # 0xD8 -> HEBREW PUNCTUATION GERSHAYIM + u'\ufffe' # 0xD9 -> UNDEFINED + u'\ufffe' # 0xDA -> UNDEFINED + u'\ufffe' # 0xDB -> UNDEFINED + u'\ufffe' # 0xDC -> UNDEFINED + u'\ufffe' # 0xDD -> UNDEFINED + u'\ufffe' # 0xDE -> UNDEFINED + u'\ufffe' # 0xDF -> UNDEFINED + u'\u05d0' # 0xE0 -> HEBREW LETTER ALEF + u'\u05d1' # 0xE1 -> HEBREW LETTER BET + u'\u05d2' # 0xE2 -> HEBREW LETTER GIMEL + u'\u05d3' # 0xE3 -> HEBREW LETTER DALET + u'\u05d4' # 0xE4 -> HEBREW LETTER HE + u'\u05d5' # 0xE5 -> HEBREW LETTER VAV + u'\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN + u'\u05d7' # 0xE7 -> HEBREW LETTER HET + u'\u05d8' # 0xE8 -> HEBREW LETTER TET + u'\u05d9' # 0xE9 -> HEBREW LETTER YOD + u'\u05da' # 0xEA -> HEBREW LETTER FINAL KAF + u'\u05db' # 0xEB -> HEBREW LETTER KAF + u'\u05dc' # 0xEC -> HEBREW LETTER LAMED + u'\u05dd' # 0xED -> HEBREW LETTER FINAL MEM + u'\u05de' # 0xEE -> HEBREW LETTER MEM + u'\u05df' # 0xEF -> HEBREW LETTER FINAL NUN + u'\u05e0' # 0xF0 -> HEBREW LETTER NUN + u'\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH + u'\u05e2' # 0xF2 -> HEBREW LETTER AYIN + u'\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE + u'\u05e4' # 0xF4 -> HEBREW LETTER PE + u'\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI + u'\u05e6' # 0xF6 -> HEBREW LETTER TSADI + u'\u05e7' # 0xF7 -> HEBREW LETTER QOF + u'\u05e8' # 0xF8 -> HEBREW LETTER RESH + u'\u05e9' # 0xF9 -> HEBREW LETTER SHIN + u'\u05ea' # 0xFA -> HEBREW LETTER TAV + u'\ufffe' # 0xFB -> UNDEFINED + u'\ufffe' # 0xFC -> UNDEFINED + u'\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + u'\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + u'\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1256.py b/src/main/resources/PythonLibs/encodings/cp1256.py new file mode 100644 index 0000000000000000000000000000000000000000..302b5fa0662a6cda6f165da5ae94067052b71c9f --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1256.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1256 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1256', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\u067e' # 0x81 -> ARABIC LETTER PEH + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\u0679' # 0x8A -> ARABIC LETTER TTEH + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + u'\u0686' # 0x8D -> ARABIC LETTER TCHEH + u'\u0698' # 0x8E -> ARABIC LETTER JEH + u'\u0688' # 0x8F -> ARABIC LETTER DDAL + u'\u06af' # 0x90 -> ARABIC LETTER GAF + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\u06a9' # 0x98 -> ARABIC LETTER KEHEH + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\u0691' # 0x9A -> ARABIC LETTER RREH + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + u'\u200c' # 0x9D -> ZERO WIDTH NON-JOINER + u'\u200d' # 0x9E -> ZERO WIDTH JOINER + u'\u06ba' # 0x9F -> ARABIC LETTER NOON GHUNNA + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u060c' # 0xA1 -> ARABIC COMMA + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u06be' # 0xAA -> ARABIC LETTER HEH DOACHASHMEE + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\u061b' # 0xBA -> ARABIC SEMICOLON + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\u061f' # 0xBF -> ARABIC QUESTION MARK + u'\u06c1' # 0xC0 -> ARABIC LETTER HEH GOAL + u'\u0621' # 0xC1 -> ARABIC LETTER HAMZA + u'\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + u'\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + u'\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + u'\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + u'\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + u'\u0627' # 0xC7 -> ARABIC LETTER ALEF + u'\u0628' # 0xC8 -> ARABIC LETTER BEH + u'\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + u'\u062a' # 0xCA -> ARABIC LETTER TEH + u'\u062b' # 0xCB -> ARABIC LETTER THEH + u'\u062c' # 0xCC -> ARABIC LETTER JEEM + u'\u062d' # 0xCD -> ARABIC LETTER HAH + u'\u062e' # 0xCE -> ARABIC LETTER KHAH + u'\u062f' # 0xCF -> ARABIC LETTER DAL + u'\u0630' # 0xD0 -> ARABIC LETTER THAL + u'\u0631' # 0xD1 -> ARABIC LETTER REH + u'\u0632' # 0xD2 -> ARABIC LETTER ZAIN + u'\u0633' # 0xD3 -> ARABIC LETTER SEEN + u'\u0634' # 0xD4 -> ARABIC LETTER SHEEN + u'\u0635' # 0xD5 -> ARABIC LETTER SAD + u'\u0636' # 0xD6 -> ARABIC LETTER DAD + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\u0637' # 0xD8 -> ARABIC LETTER TAH + u'\u0638' # 0xD9 -> ARABIC LETTER ZAH + u'\u0639' # 0xDA -> ARABIC LETTER AIN + u'\u063a' # 0xDB -> ARABIC LETTER GHAIN + u'\u0640' # 0xDC -> ARABIC TATWEEL + u'\u0641' # 0xDD -> ARABIC LETTER FEH + u'\u0642' # 0xDE -> ARABIC LETTER QAF + u'\u0643' # 0xDF -> ARABIC LETTER KAF + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\u0644' # 0xE1 -> ARABIC LETTER LAM + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\u0645' # 0xE3 -> ARABIC LETTER MEEM + u'\u0646' # 0xE4 -> ARABIC LETTER NOON + u'\u0647' # 0xE5 -> ARABIC LETTER HEH + u'\u0648' # 0xE6 -> ARABIC LETTER WAW + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\u0649' # 0xEC -> ARABIC LETTER ALEF MAKSURA + u'\u064a' # 0xED -> ARABIC LETTER YEH + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\u064b' # 0xF0 -> ARABIC FATHATAN + u'\u064c' # 0xF1 -> ARABIC DAMMATAN + u'\u064d' # 0xF2 -> ARABIC KASRATAN + u'\u064e' # 0xF3 -> ARABIC FATHA + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\u064f' # 0xF5 -> ARABIC DAMMA + u'\u0650' # 0xF6 -> ARABIC KASRA + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\u0651' # 0xF8 -> ARABIC SHADDA + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\u0652' # 0xFA -> ARABIC SUKUN + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + u'\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + u'\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1257.py b/src/main/resources/PythonLibs/encodings/cp1257.py new file mode 100644 index 0000000000000000000000000000000000000000..53a6b29d5b00e86798614570d0e4188866f56bab --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1257.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1257 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1257', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\ufffe' # 0x83 -> UNDEFINED + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\ufffe' # 0x88 -> UNDEFINED + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\ufffe' # 0x8A -> UNDEFINED + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\ufffe' # 0x8C -> UNDEFINED + u'\xa8' # 0x8D -> DIAERESIS + u'\u02c7' # 0x8E -> CARON + u'\xb8' # 0x8F -> CEDILLA + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\ufffe' # 0x98 -> UNDEFINED + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\ufffe' # 0x9A -> UNDEFINED + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\ufffe' # 0x9C -> UNDEFINED + u'\xaf' # 0x9D -> MACRON + u'\u02db' # 0x9E -> OGONEK + u'\ufffe' # 0x9F -> UNDEFINED + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\ufffe' # 0xA1 -> UNDEFINED + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\ufffe' # 0xA5 -> UNDEFINED + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xc6' # 0xAF -> LATIN CAPITAL LETTER AE + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xe6' # 0xBF -> LATIN SMALL LETTER AE + u'\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK + u'\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON + u'\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK + u'\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON + u'\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE + u'\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA + u'\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA + u'\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON + u'\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA + u'\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON + u'\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK + u'\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE + u'\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE + u'\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK + u'\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK + u'\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON + u'\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK + u'\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON + u'\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE + u'\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE + u'\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA + u'\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA + u'\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON + u'\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA + u'\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON + u'\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + u'\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK + u'\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE + u'\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE + u'\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON + u'\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp1258.py b/src/main/resources/PythonLibs/encodings/cp1258.py new file mode 100644 index 0000000000000000000000000000000000000000..4b25d8e7e801e7b8e15c7599da717490f4b6d34b --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp1258.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1258 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1258', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + u'\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + u'\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\u2020' # 0x86 -> DAGGER + u'\u2021' # 0x87 -> DOUBLE DAGGER + u'\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u2030' # 0x89 -> PER MILLE SIGN + u'\ufffe' # 0x8A -> UNDEFINED + u'\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + u'\ufffe' # 0x8D -> UNDEFINED + u'\ufffe' # 0x8E -> UNDEFINED + u'\ufffe' # 0x8F -> UNDEFINED + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\u02dc' # 0x98 -> SMALL TILDE + u'\u2122' # 0x99 -> TRADE MARK SIGN + u'\ufffe' # 0x9A -> UNDEFINED + u'\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + u'\ufffe' # 0x9D -> UNDEFINED + u'\ufffe' # 0x9E -> UNDEFINED + u'\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xbf' # 0xBF -> INVERTED QUESTION MARK + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\u0300' # 0xCC -> COMBINING GRAVE ACCENT + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\u0309' # 0xD2 -> COMBINING HOOK ABOVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u01a0' # 0xD5 -> LATIN CAPITAL LETTER O WITH HORN + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u01af' # 0xDD -> LATIN CAPITAL LETTER U WITH HORN + u'\u0303' # 0xDE -> COMBINING TILDE + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\u0301' # 0xEC -> COMBINING ACUTE ACCENT + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\u0323' # 0xF2 -> COMBINING DOT BELOW + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\u01a1' # 0xF5 -> LATIN SMALL LETTER O WITH HORN + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u01b0' # 0xFD -> LATIN SMALL LETTER U WITH HORN + u'\u20ab' # 0xFE -> DONG SIGN + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp424.py b/src/main/resources/PythonLibs/encodings/cp424.py new file mode 100644 index 0000000000000000000000000000000000000000..d3ade2277687900698f62b2e087f59c064cb9955 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp424.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp424 generated from 'MAPPINGS/VENDORS/MISC/CP424.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp424', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x9c' # 0x04 -> SELECT + u'\t' # 0x05 -> HORIZONTAL TABULATION + u'\x86' # 0x06 -> REQUIRED NEW LINE + u'\x7f' # 0x07 -> DELETE + u'\x97' # 0x08 -> GRAPHIC ESCAPE + u'\x8d' # 0x09 -> SUPERSCRIPT + u'\x8e' # 0x0A -> REPEAT + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x9d' # 0x14 -> RESTORE/ENABLE PRESENTATION + u'\x85' # 0x15 -> NEW LINE + u'\x08' # 0x16 -> BACKSPACE + u'\x87' # 0x17 -> PROGRAM OPERATOR COMMUNICATION + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x92' # 0x1A -> UNIT BACK SPACE + u'\x8f' # 0x1B -> CUSTOMER USE ONE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u'\x80' # 0x20 -> DIGIT SELECT + u'\x81' # 0x21 -> START OF SIGNIFICANCE + u'\x82' # 0x22 -> FIELD SEPARATOR + u'\x83' # 0x23 -> WORD UNDERSCORE + u'\x84' # 0x24 -> BYPASS OR INHIBIT PRESENTATION + u'\n' # 0x25 -> LINE FEED + u'\x17' # 0x26 -> END OF TRANSMISSION BLOCK + u'\x1b' # 0x27 -> ESCAPE + u'\x88' # 0x28 -> SET ATTRIBUTE + u'\x89' # 0x29 -> START FIELD EXTENDED + u'\x8a' # 0x2A -> SET MODE OR SWITCH + u'\x8b' # 0x2B -> CONTROL SEQUENCE PREFIX + u'\x8c' # 0x2C -> MODIFY FIELD ATTRIBUTE + u'\x05' # 0x2D -> ENQUIRY + u'\x06' # 0x2E -> ACKNOWLEDGE + u'\x07' # 0x2F -> BELL + u'\x90' # 0x30 -> <reserved> + u'\x91' # 0x31 -> <reserved> + u'\x16' # 0x32 -> SYNCHRONOUS IDLE + u'\x93' # 0x33 -> INDEX RETURN + u'\x94' # 0x34 -> PRESENTATION POSITION + u'\x95' # 0x35 -> TRANSPARENT + u'\x96' # 0x36 -> NUMERIC BACKSPACE + u'\x04' # 0x37 -> END OF TRANSMISSION + u'\x98' # 0x38 -> SUBSCRIPT + u'\x99' # 0x39 -> INDENT TABULATION + u'\x9a' # 0x3A -> REVERSE FORM FEED + u'\x9b' # 0x3B -> CUSTOMER USE THREE + u'\x14' # 0x3C -> DEVICE CONTROL FOUR + u'\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + u'\x9e' # 0x3E -> <reserved> + u'\x1a' # 0x3F -> SUBSTITUTE + u' ' # 0x40 -> SPACE + u'\u05d0' # 0x41 -> HEBREW LETTER ALEF + u'\u05d1' # 0x42 -> HEBREW LETTER BET + u'\u05d2' # 0x43 -> HEBREW LETTER GIMEL + u'\u05d3' # 0x44 -> HEBREW LETTER DALET + u'\u05d4' # 0x45 -> HEBREW LETTER HE + u'\u05d5' # 0x46 -> HEBREW LETTER VAV + u'\u05d6' # 0x47 -> HEBREW LETTER ZAYIN + u'\u05d7' # 0x48 -> HEBREW LETTER HET + u'\u05d8' # 0x49 -> HEBREW LETTER TET + u'\xa2' # 0x4A -> CENT SIGN + u'.' # 0x4B -> FULL STOP + u'<' # 0x4C -> LESS-THAN SIGN + u'(' # 0x4D -> LEFT PARENTHESIS + u'+' # 0x4E -> PLUS SIGN + u'|' # 0x4F -> VERTICAL LINE + u'&' # 0x50 -> AMPERSAND + u'\u05d9' # 0x51 -> HEBREW LETTER YOD + u'\u05da' # 0x52 -> HEBREW LETTER FINAL KAF + u'\u05db' # 0x53 -> HEBREW LETTER KAF + u'\u05dc' # 0x54 -> HEBREW LETTER LAMED + u'\u05dd' # 0x55 -> HEBREW LETTER FINAL MEM + u'\u05de' # 0x56 -> HEBREW LETTER MEM + u'\u05df' # 0x57 -> HEBREW LETTER FINAL NUN + u'\u05e0' # 0x58 -> HEBREW LETTER NUN + u'\u05e1' # 0x59 -> HEBREW LETTER SAMEKH + u'!' # 0x5A -> EXCLAMATION MARK + u'$' # 0x5B -> DOLLAR SIGN + u'*' # 0x5C -> ASTERISK + u')' # 0x5D -> RIGHT PARENTHESIS + u';' # 0x5E -> SEMICOLON + u'\xac' # 0x5F -> NOT SIGN + u'-' # 0x60 -> HYPHEN-MINUS + u'/' # 0x61 -> SOLIDUS + u'\u05e2' # 0x62 -> HEBREW LETTER AYIN + u'\u05e3' # 0x63 -> HEBREW LETTER FINAL PE + u'\u05e4' # 0x64 -> HEBREW LETTER PE + u'\u05e5' # 0x65 -> HEBREW LETTER FINAL TSADI + u'\u05e6' # 0x66 -> HEBREW LETTER TSADI + u'\u05e7' # 0x67 -> HEBREW LETTER QOF + u'\u05e8' # 0x68 -> HEBREW LETTER RESH + u'\u05e9' # 0x69 -> HEBREW LETTER SHIN + u'\xa6' # 0x6A -> BROKEN BAR + u',' # 0x6B -> COMMA + u'%' # 0x6C -> PERCENT SIGN + u'_' # 0x6D -> LOW LINE + u'>' # 0x6E -> GREATER-THAN SIGN + u'?' # 0x6F -> QUESTION MARK + u'\ufffe' # 0x70 -> UNDEFINED + u'\u05ea' # 0x71 -> HEBREW LETTER TAV + u'\ufffe' # 0x72 -> UNDEFINED + u'\ufffe' # 0x73 -> UNDEFINED + u'\xa0' # 0x74 -> NO-BREAK SPACE + u'\ufffe' # 0x75 -> UNDEFINED + u'\ufffe' # 0x76 -> UNDEFINED + u'\ufffe' # 0x77 -> UNDEFINED + u'\u2017' # 0x78 -> DOUBLE LOW LINE + u'`' # 0x79 -> GRAVE ACCENT + u':' # 0x7A -> COLON + u'#' # 0x7B -> NUMBER SIGN + u'@' # 0x7C -> COMMERCIAL AT + u"'" # 0x7D -> APOSTROPHE + u'=' # 0x7E -> EQUALS SIGN + u'"' # 0x7F -> QUOTATION MARK + u'\ufffe' # 0x80 -> UNDEFINED + u'a' # 0x81 -> LATIN SMALL LETTER A + u'b' # 0x82 -> LATIN SMALL LETTER B + u'c' # 0x83 -> LATIN SMALL LETTER C + u'd' # 0x84 -> LATIN SMALL LETTER D + u'e' # 0x85 -> LATIN SMALL LETTER E + u'f' # 0x86 -> LATIN SMALL LETTER F + u'g' # 0x87 -> LATIN SMALL LETTER G + u'h' # 0x88 -> LATIN SMALL LETTER H + u'i' # 0x89 -> LATIN SMALL LETTER I + u'\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\ufffe' # 0x8C -> UNDEFINED + u'\ufffe' # 0x8D -> UNDEFINED + u'\ufffe' # 0x8E -> UNDEFINED + u'\xb1' # 0x8F -> PLUS-MINUS SIGN + u'\xb0' # 0x90 -> DEGREE SIGN + u'j' # 0x91 -> LATIN SMALL LETTER J + u'k' # 0x92 -> LATIN SMALL LETTER K + u'l' # 0x93 -> LATIN SMALL LETTER L + u'm' # 0x94 -> LATIN SMALL LETTER M + u'n' # 0x95 -> LATIN SMALL LETTER N + u'o' # 0x96 -> LATIN SMALL LETTER O + u'p' # 0x97 -> LATIN SMALL LETTER P + u'q' # 0x98 -> LATIN SMALL LETTER Q + u'r' # 0x99 -> LATIN SMALL LETTER R + u'\ufffe' # 0x9A -> UNDEFINED + u'\ufffe' # 0x9B -> UNDEFINED + u'\ufffe' # 0x9C -> UNDEFINED + u'\xb8' # 0x9D -> CEDILLA + u'\ufffe' # 0x9E -> UNDEFINED + u'\xa4' # 0x9F -> CURRENCY SIGN + u'\xb5' # 0xA0 -> MICRO SIGN + u'~' # 0xA1 -> TILDE + u's' # 0xA2 -> LATIN SMALL LETTER S + u't' # 0xA3 -> LATIN SMALL LETTER T + u'u' # 0xA4 -> LATIN SMALL LETTER U + u'v' # 0xA5 -> LATIN SMALL LETTER V + u'w' # 0xA6 -> LATIN SMALL LETTER W + u'x' # 0xA7 -> LATIN SMALL LETTER X + u'y' # 0xA8 -> LATIN SMALL LETTER Y + u'z' # 0xA9 -> LATIN SMALL LETTER Z + u'\ufffe' # 0xAA -> UNDEFINED + u'\ufffe' # 0xAB -> UNDEFINED + u'\ufffe' # 0xAC -> UNDEFINED + u'\ufffe' # 0xAD -> UNDEFINED + u'\ufffe' # 0xAE -> UNDEFINED + u'\xae' # 0xAF -> REGISTERED SIGN + u'^' # 0xB0 -> CIRCUMFLEX ACCENT + u'\xa3' # 0xB1 -> POUND SIGN + u'\xa5' # 0xB2 -> YEN SIGN + u'\xb7' # 0xB3 -> MIDDLE DOT + u'\xa9' # 0xB4 -> COPYRIGHT SIGN + u'\xa7' # 0xB5 -> SECTION SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + u'[' # 0xBA -> LEFT SQUARE BRACKET + u']' # 0xBB -> RIGHT SQUARE BRACKET + u'\xaf' # 0xBC -> MACRON + u'\xa8' # 0xBD -> DIAERESIS + u'\xb4' # 0xBE -> ACUTE ACCENT + u'\xd7' # 0xBF -> MULTIPLICATION SIGN + u'{' # 0xC0 -> LEFT CURLY BRACKET + u'A' # 0xC1 -> LATIN CAPITAL LETTER A + u'B' # 0xC2 -> LATIN CAPITAL LETTER B + u'C' # 0xC3 -> LATIN CAPITAL LETTER C + u'D' # 0xC4 -> LATIN CAPITAL LETTER D + u'E' # 0xC5 -> LATIN CAPITAL LETTER E + u'F' # 0xC6 -> LATIN CAPITAL LETTER F + u'G' # 0xC7 -> LATIN CAPITAL LETTER G + u'H' # 0xC8 -> LATIN CAPITAL LETTER H + u'I' # 0xC9 -> LATIN CAPITAL LETTER I + u'\xad' # 0xCA -> SOFT HYPHEN + u'\ufffe' # 0xCB -> UNDEFINED + u'\ufffe' # 0xCC -> UNDEFINED + u'\ufffe' # 0xCD -> UNDEFINED + u'\ufffe' # 0xCE -> UNDEFINED + u'\ufffe' # 0xCF -> UNDEFINED + u'}' # 0xD0 -> RIGHT CURLY BRACKET + u'J' # 0xD1 -> LATIN CAPITAL LETTER J + u'K' # 0xD2 -> LATIN CAPITAL LETTER K + u'L' # 0xD3 -> LATIN CAPITAL LETTER L + u'M' # 0xD4 -> LATIN CAPITAL LETTER M + u'N' # 0xD5 -> LATIN CAPITAL LETTER N + u'O' # 0xD6 -> LATIN CAPITAL LETTER O + u'P' # 0xD7 -> LATIN CAPITAL LETTER P + u'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + u'R' # 0xD9 -> LATIN CAPITAL LETTER R + u'\xb9' # 0xDA -> SUPERSCRIPT ONE + u'\ufffe' # 0xDB -> UNDEFINED + u'\ufffe' # 0xDC -> UNDEFINED + u'\ufffe' # 0xDD -> UNDEFINED + u'\ufffe' # 0xDE -> UNDEFINED + u'\ufffe' # 0xDF -> UNDEFINED + u'\\' # 0xE0 -> REVERSE SOLIDUS + u'\xf7' # 0xE1 -> DIVISION SIGN + u'S' # 0xE2 -> LATIN CAPITAL LETTER S + u'T' # 0xE3 -> LATIN CAPITAL LETTER T + u'U' # 0xE4 -> LATIN CAPITAL LETTER U + u'V' # 0xE5 -> LATIN CAPITAL LETTER V + u'W' # 0xE6 -> LATIN CAPITAL LETTER W + u'X' # 0xE7 -> LATIN CAPITAL LETTER X + u'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + u'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + u'\xb2' # 0xEA -> SUPERSCRIPT TWO + u'\ufffe' # 0xEB -> UNDEFINED + u'\ufffe' # 0xEC -> UNDEFINED + u'\ufffe' # 0xED -> UNDEFINED + u'\ufffe' # 0xEE -> UNDEFINED + u'\ufffe' # 0xEF -> UNDEFINED + u'0' # 0xF0 -> DIGIT ZERO + u'1' # 0xF1 -> DIGIT ONE + u'2' # 0xF2 -> DIGIT TWO + u'3' # 0xF3 -> DIGIT THREE + u'4' # 0xF4 -> DIGIT FOUR + u'5' # 0xF5 -> DIGIT FIVE + u'6' # 0xF6 -> DIGIT SIX + u'7' # 0xF7 -> DIGIT SEVEN + u'8' # 0xF8 -> DIGIT EIGHT + u'9' # 0xF9 -> DIGIT NINE + u'\xb3' # 0xFA -> SUPERSCRIPT THREE + u'\ufffe' # 0xFB -> UNDEFINED + u'\ufffe' # 0xFC -> UNDEFINED + u'\ufffe' # 0xFD -> UNDEFINED + u'\ufffe' # 0xFE -> UNDEFINED + u'\x9f' # 0xFF -> EIGHT ONES +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp437.py b/src/main/resources/PythonLibs/encodings/cp437.py new file mode 100644 index 0000000000000000000000000000000000000000..52cd8829428cbb923f10403b5a02c40b7cc2bb85 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp437.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec cp437 generated from 'VENDORS/MICSFT/PC/CP437.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp437', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00a5, # YEN SIGN + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + u'\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + u'\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + u'\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xa2' # 0x009b -> CENT SIGN + u'\xa3' # 0x009c -> POUND SIGN + u'\xa5' # 0x009d -> YEN SIGN + u'\u20a7' # 0x009e -> PESETA SIGN + u'\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + u'\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\u2310' # 0x00a9 -> REVERSED NOT SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + u'\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + u'\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + u'\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + u'\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + u'\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + u'\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + u'\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + u'\u221e' # 0x00ec -> INFINITY + u'\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + u'\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + u'\u2229' # 0x00ef -> INTERSECTION + u'\u2261' # 0x00f0 -> IDENTICAL TO + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + u'\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + u'\u2320' # 0x00f4 -> TOP HALF INTEGRAL + u'\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u2248' # 0x00f7 -> ALMOST EQUAL TO + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a5: 0x009d, # YEN SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp500.py b/src/main/resources/PythonLibs/encodings/cp500.py new file mode 100644 index 0000000000000000000000000000000000000000..60766c0393b4047f44d8d174d74b0a547007d72d --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp500.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp500 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp500', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x9c' # 0x04 -> CONTROL + u'\t' # 0x05 -> HORIZONTAL TABULATION + u'\x86' # 0x06 -> CONTROL + u'\x7f' # 0x07 -> DELETE + u'\x97' # 0x08 -> CONTROL + u'\x8d' # 0x09 -> CONTROL + u'\x8e' # 0x0A -> CONTROL + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x9d' # 0x14 -> CONTROL + u'\x85' # 0x15 -> CONTROL + u'\x08' # 0x16 -> BACKSPACE + u'\x87' # 0x17 -> CONTROL + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x92' # 0x1A -> CONTROL + u'\x8f' # 0x1B -> CONTROL + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u'\x80' # 0x20 -> CONTROL + u'\x81' # 0x21 -> CONTROL + u'\x82' # 0x22 -> CONTROL + u'\x83' # 0x23 -> CONTROL + u'\x84' # 0x24 -> CONTROL + u'\n' # 0x25 -> LINE FEED + u'\x17' # 0x26 -> END OF TRANSMISSION BLOCK + u'\x1b' # 0x27 -> ESCAPE + u'\x88' # 0x28 -> CONTROL + u'\x89' # 0x29 -> CONTROL + u'\x8a' # 0x2A -> CONTROL + u'\x8b' # 0x2B -> CONTROL + u'\x8c' # 0x2C -> CONTROL + u'\x05' # 0x2D -> ENQUIRY + u'\x06' # 0x2E -> ACKNOWLEDGE + u'\x07' # 0x2F -> BELL + u'\x90' # 0x30 -> CONTROL + u'\x91' # 0x31 -> CONTROL + u'\x16' # 0x32 -> SYNCHRONOUS IDLE + u'\x93' # 0x33 -> CONTROL + u'\x94' # 0x34 -> CONTROL + u'\x95' # 0x35 -> CONTROL + u'\x96' # 0x36 -> CONTROL + u'\x04' # 0x37 -> END OF TRANSMISSION + u'\x98' # 0x38 -> CONTROL + u'\x99' # 0x39 -> CONTROL + u'\x9a' # 0x3A -> CONTROL + u'\x9b' # 0x3B -> CONTROL + u'\x14' # 0x3C -> DEVICE CONTROL FOUR + u'\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + u'\x9e' # 0x3E -> CONTROL + u'\x1a' # 0x3F -> SUBSTITUTE + u' ' # 0x40 -> SPACE + u'\xa0' # 0x41 -> NO-BREAK SPACE + u'\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + u'[' # 0x4A -> LEFT SQUARE BRACKET + u'.' # 0x4B -> FULL STOP + u'<' # 0x4C -> LESS-THAN SIGN + u'(' # 0x4D -> LEFT PARENTHESIS + u'+' # 0x4E -> PLUS SIGN + u'!' # 0x4F -> EXCLAMATION MARK + u'&' # 0x50 -> AMPERSAND + u'\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + u'\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + u'\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + u']' # 0x5A -> RIGHT SQUARE BRACKET + u'$' # 0x5B -> DOLLAR SIGN + u'*' # 0x5C -> ASTERISK + u')' # 0x5D -> RIGHT PARENTHESIS + u';' # 0x5E -> SEMICOLON + u'^' # 0x5F -> CIRCUMFLEX ACCENT + u'-' # 0x60 -> HYPHEN-MINUS + u'/' # 0x61 -> SOLIDUS + u'\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xa6' # 0x6A -> BROKEN BAR + u',' # 0x6B -> COMMA + u'%' # 0x6C -> PERCENT SIGN + u'_' # 0x6D -> LOW LINE + u'>' # 0x6E -> GREATER-THAN SIGN + u'?' # 0x6F -> QUESTION MARK + u'\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + u'\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + u'`' # 0x79 -> GRAVE ACCENT + u':' # 0x7A -> COLON + u'#' # 0x7B -> NUMBER SIGN + u'@' # 0x7C -> COMMERCIAL AT + u"'" # 0x7D -> APOSTROPHE + u'=' # 0x7E -> EQUALS SIGN + u'"' # 0x7F -> QUOTATION MARK + u'\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + u'a' # 0x81 -> LATIN SMALL LETTER A + u'b' # 0x82 -> LATIN SMALL LETTER B + u'c' # 0x83 -> LATIN SMALL LETTER C + u'd' # 0x84 -> LATIN SMALL LETTER D + u'e' # 0x85 -> LATIN SMALL LETTER E + u'f' # 0x86 -> LATIN SMALL LETTER F + u'g' # 0x87 -> LATIN SMALL LETTER G + u'h' # 0x88 -> LATIN SMALL LETTER H + u'i' # 0x89 -> LATIN SMALL LETTER I + u'\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + u'\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + u'\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + u'\xb1' # 0x8F -> PLUS-MINUS SIGN + u'\xb0' # 0x90 -> DEGREE SIGN + u'j' # 0x91 -> LATIN SMALL LETTER J + u'k' # 0x92 -> LATIN SMALL LETTER K + u'l' # 0x93 -> LATIN SMALL LETTER L + u'm' # 0x94 -> LATIN SMALL LETTER M + u'n' # 0x95 -> LATIN SMALL LETTER N + u'o' # 0x96 -> LATIN SMALL LETTER O + u'p' # 0x97 -> LATIN SMALL LETTER P + u'q' # 0x98 -> LATIN SMALL LETTER Q + u'r' # 0x99 -> LATIN SMALL LETTER R + u'\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + u'\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + u'\xb8' # 0x9D -> CEDILLA + u'\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + u'\xa4' # 0x9F -> CURRENCY SIGN + u'\xb5' # 0xA0 -> MICRO SIGN + u'~' # 0xA1 -> TILDE + u's' # 0xA2 -> LATIN SMALL LETTER S + u't' # 0xA3 -> LATIN SMALL LETTER T + u'u' # 0xA4 -> LATIN SMALL LETTER U + u'v' # 0xA5 -> LATIN SMALL LETTER V + u'w' # 0xA6 -> LATIN SMALL LETTER W + u'x' # 0xA7 -> LATIN SMALL LETTER X + u'y' # 0xA8 -> LATIN SMALL LETTER Y + u'z' # 0xA9 -> LATIN SMALL LETTER Z + u'\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + u'\xbf' # 0xAB -> INVERTED QUESTION MARK + u'\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + u'\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + u'\xae' # 0xAF -> REGISTERED SIGN + u'\xa2' # 0xB0 -> CENT SIGN + u'\xa3' # 0xB1 -> POUND SIGN + u'\xa5' # 0xB2 -> YEN SIGN + u'\xb7' # 0xB3 -> MIDDLE DOT + u'\xa9' # 0xB4 -> COPYRIGHT SIGN + u'\xa7' # 0xB5 -> SECTION SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + u'\xac' # 0xBA -> NOT SIGN + u'|' # 0xBB -> VERTICAL LINE + u'\xaf' # 0xBC -> MACRON + u'\xa8' # 0xBD -> DIAERESIS + u'\xb4' # 0xBE -> ACUTE ACCENT + u'\xd7' # 0xBF -> MULTIPLICATION SIGN + u'{' # 0xC0 -> LEFT CURLY BRACKET + u'A' # 0xC1 -> LATIN CAPITAL LETTER A + u'B' # 0xC2 -> LATIN CAPITAL LETTER B + u'C' # 0xC3 -> LATIN CAPITAL LETTER C + u'D' # 0xC4 -> LATIN CAPITAL LETTER D + u'E' # 0xC5 -> LATIN CAPITAL LETTER E + u'F' # 0xC6 -> LATIN CAPITAL LETTER F + u'G' # 0xC7 -> LATIN CAPITAL LETTER G + u'H' # 0xC8 -> LATIN CAPITAL LETTER H + u'I' # 0xC9 -> LATIN CAPITAL LETTER I + u'\xad' # 0xCA -> SOFT HYPHEN + u'\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + u'\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + u'}' # 0xD0 -> RIGHT CURLY BRACKET + u'J' # 0xD1 -> LATIN CAPITAL LETTER J + u'K' # 0xD2 -> LATIN CAPITAL LETTER K + u'L' # 0xD3 -> LATIN CAPITAL LETTER L + u'M' # 0xD4 -> LATIN CAPITAL LETTER M + u'N' # 0xD5 -> LATIN CAPITAL LETTER N + u'O' # 0xD6 -> LATIN CAPITAL LETTER O + u'P' # 0xD7 -> LATIN CAPITAL LETTER P + u'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + u'R' # 0xD9 -> LATIN CAPITAL LETTER R + u'\xb9' # 0xDA -> SUPERSCRIPT ONE + u'\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + u'\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\\' # 0xE0 -> REVERSE SOLIDUS + u'\xf7' # 0xE1 -> DIVISION SIGN + u'S' # 0xE2 -> LATIN CAPITAL LETTER S + u'T' # 0xE3 -> LATIN CAPITAL LETTER T + u'U' # 0xE4 -> LATIN CAPITAL LETTER U + u'V' # 0xE5 -> LATIN CAPITAL LETTER V + u'W' # 0xE6 -> LATIN CAPITAL LETTER W + u'X' # 0xE7 -> LATIN CAPITAL LETTER X + u'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + u'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + u'\xb2' # 0xEA -> SUPERSCRIPT TWO + u'\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + u'0' # 0xF0 -> DIGIT ZERO + u'1' # 0xF1 -> DIGIT ONE + u'2' # 0xF2 -> DIGIT TWO + u'3' # 0xF3 -> DIGIT THREE + u'4' # 0xF4 -> DIGIT FOUR + u'5' # 0xF5 -> DIGIT FIVE + u'6' # 0xF6 -> DIGIT SIX + u'7' # 0xF7 -> DIGIT SEVEN + u'8' # 0xF8 -> DIGIT EIGHT + u'9' # 0xF9 -> DIGIT NINE + u'\xb3' # 0xFA -> SUPERSCRIPT THREE + u'\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + u'\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp720.py b/src/main/resources/PythonLibs/encodings/cp720.py new file mode 100644 index 0000000000000000000000000000000000000000..5c96d9813cf26dc245dcd55b64452be0a333e681 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp720.py @@ -0,0 +1,309 @@ +"""Python Character Mapping Codec cp720 generated on Windows: +Vista 6.0.6002 SP2 Multiprocessor Free with the command: + python Tools/unicode/genwincodec.py 720 +"""#" + + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp720', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\x80' + u'\x81' + u'\xe9' # 0x82 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x83 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\x84' + u'\xe0' # 0x85 -> LATIN SMALL LETTER A WITH GRAVE + u'\x86' + u'\xe7' # 0x87 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x88 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x89 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x8A -> LATIN SMALL LETTER E WITH GRAVE + u'\xef' # 0x8B -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xee' # 0x8C -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\x8d' + u'\x8e' + u'\x8f' + u'\x90' + u'\u0651' # 0x91 -> ARABIC SHADDA + u'\u0652' # 0x92 -> ARABIC SUKUN + u'\xf4' # 0x93 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xa4' # 0x94 -> CURRENCY SIGN + u'\u0640' # 0x95 -> ARABIC TATWEEL + u'\xfb' # 0x96 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xf9' # 0x97 -> LATIN SMALL LETTER U WITH GRAVE + u'\u0621' # 0x98 -> ARABIC LETTER HAMZA + u'\u0622' # 0x99 -> ARABIC LETTER ALEF WITH MADDA ABOVE + u'\u0623' # 0x9A -> ARABIC LETTER ALEF WITH HAMZA ABOVE + u'\u0624' # 0x9B -> ARABIC LETTER WAW WITH HAMZA ABOVE + u'\xa3' # 0x9C -> POUND SIGN + u'\u0625' # 0x9D -> ARABIC LETTER ALEF WITH HAMZA BELOW + u'\u0626' # 0x9E -> ARABIC LETTER YEH WITH HAMZA ABOVE + u'\u0627' # 0x9F -> ARABIC LETTER ALEF + u'\u0628' # 0xA0 -> ARABIC LETTER BEH + u'\u0629' # 0xA1 -> ARABIC LETTER TEH MARBUTA + u'\u062a' # 0xA2 -> ARABIC LETTER TEH + u'\u062b' # 0xA3 -> ARABIC LETTER THEH + u'\u062c' # 0xA4 -> ARABIC LETTER JEEM + u'\u062d' # 0xA5 -> ARABIC LETTER HAH + u'\u062e' # 0xA6 -> ARABIC LETTER KHAH + u'\u062f' # 0xA7 -> ARABIC LETTER DAL + u'\u0630' # 0xA8 -> ARABIC LETTER THAL + u'\u0631' # 0xA9 -> ARABIC LETTER REH + u'\u0632' # 0xAA -> ARABIC LETTER ZAIN + u'\u0633' # 0xAB -> ARABIC LETTER SEEN + u'\u0634' # 0xAC -> ARABIC LETTER SHEEN + u'\u0635' # 0xAD -> ARABIC LETTER SAD + u'\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0xB0 -> LIGHT SHADE + u'\u2592' # 0xB1 -> MEDIUM SHADE + u'\u2593' # 0xB2 -> DARK SHADE + u'\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0xB5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0xB6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0xB8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0xBD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0xBE -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0xC6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0xC7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0xCF -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0xD0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0xD1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0xD2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0xD3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0xD4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0xD5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0xD6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0xD7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0xD8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0xDB -> FULL BLOCK + u'\u2584' # 0xDC -> LOWER HALF BLOCK + u'\u258c' # 0xDD -> LEFT HALF BLOCK + u'\u2590' # 0xDE -> RIGHT HALF BLOCK + u'\u2580' # 0xDF -> UPPER HALF BLOCK + u'\u0636' # 0xE0 -> ARABIC LETTER DAD + u'\u0637' # 0xE1 -> ARABIC LETTER TAH + u'\u0638' # 0xE2 -> ARABIC LETTER ZAH + u'\u0639' # 0xE3 -> ARABIC LETTER AIN + u'\u063a' # 0xE4 -> ARABIC LETTER GHAIN + u'\u0641' # 0xE5 -> ARABIC LETTER FEH + u'\xb5' # 0xE6 -> MICRO SIGN + u'\u0642' # 0xE7 -> ARABIC LETTER QAF + u'\u0643' # 0xE8 -> ARABIC LETTER KAF + u'\u0644' # 0xE9 -> ARABIC LETTER LAM + u'\u0645' # 0xEA -> ARABIC LETTER MEEM + u'\u0646' # 0xEB -> ARABIC LETTER NOON + u'\u0647' # 0xEC -> ARABIC LETTER HEH + u'\u0648' # 0xED -> ARABIC LETTER WAW + u'\u0649' # 0xEE -> ARABIC LETTER ALEF MAKSURA + u'\u064a' # 0xEF -> ARABIC LETTER YEH + u'\u2261' # 0xF0 -> IDENTICAL TO + u'\u064b' # 0xF1 -> ARABIC FATHATAN + u'\u064c' # 0xF2 -> ARABIC DAMMATAN + u'\u064d' # 0xF3 -> ARABIC KASRATAN + u'\u064e' # 0xF4 -> ARABIC FATHA + u'\u064f' # 0xF5 -> ARABIC DAMMA + u'\u0650' # 0xF6 -> ARABIC KASRA + u'\u2248' # 0xF7 -> ALMOST EQUAL TO + u'\xb0' # 0xF8 -> DEGREE SIGN + u'\u2219' # 0xF9 -> BULLET OPERATOR + u'\xb7' # 0xFA -> MIDDLE DOT + u'\u221a' # 0xFB -> SQUARE ROOT + u'\u207f' # 0xFC -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0xFD -> SUPERSCRIPT TWO + u'\u25a0' # 0xFE -> BLACK SQUARE + u'\xa0' # 0xFF -> NO-BREAK SPACE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp737.py b/src/main/resources/PythonLibs/encodings/cp737.py new file mode 100644 index 0000000000000000000000000000000000000000..d6544482d2ddbdc6c4db296952db7081a9d9478a --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp737.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec cp737 generated from 'VENDORS/MICSFT/PC/CP737.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp737', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0391, # GREEK CAPITAL LETTER ALPHA + 0x0081: 0x0392, # GREEK CAPITAL LETTER BETA + 0x0082: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x0083: 0x0394, # GREEK CAPITAL LETTER DELTA + 0x0084: 0x0395, # GREEK CAPITAL LETTER EPSILON + 0x0085: 0x0396, # GREEK CAPITAL LETTER ZETA + 0x0086: 0x0397, # GREEK CAPITAL LETTER ETA + 0x0087: 0x0398, # GREEK CAPITAL LETTER THETA + 0x0088: 0x0399, # GREEK CAPITAL LETTER IOTA + 0x0089: 0x039a, # GREEK CAPITAL LETTER KAPPA + 0x008a: 0x039b, # GREEK CAPITAL LETTER LAMDA + 0x008b: 0x039c, # GREEK CAPITAL LETTER MU + 0x008c: 0x039d, # GREEK CAPITAL LETTER NU + 0x008d: 0x039e, # GREEK CAPITAL LETTER XI + 0x008e: 0x039f, # GREEK CAPITAL LETTER OMICRON + 0x008f: 0x03a0, # GREEK CAPITAL LETTER PI + 0x0090: 0x03a1, # GREEK CAPITAL LETTER RHO + 0x0091: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x0092: 0x03a4, # GREEK CAPITAL LETTER TAU + 0x0093: 0x03a5, # GREEK CAPITAL LETTER UPSILON + 0x0094: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x0095: 0x03a7, # GREEK CAPITAL LETTER CHI + 0x0096: 0x03a8, # GREEK CAPITAL LETTER PSI + 0x0097: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x0098: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x0099: 0x03b2, # GREEK SMALL LETTER BETA + 0x009a: 0x03b3, # GREEK SMALL LETTER GAMMA + 0x009b: 0x03b4, # GREEK SMALL LETTER DELTA + 0x009c: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x009d: 0x03b6, # GREEK SMALL LETTER ZETA + 0x009e: 0x03b7, # GREEK SMALL LETTER ETA + 0x009f: 0x03b8, # GREEK SMALL LETTER THETA + 0x00a0: 0x03b9, # GREEK SMALL LETTER IOTA + 0x00a1: 0x03ba, # GREEK SMALL LETTER KAPPA + 0x00a2: 0x03bb, # GREEK SMALL LETTER LAMDA + 0x00a3: 0x03bc, # GREEK SMALL LETTER MU + 0x00a4: 0x03bd, # GREEK SMALL LETTER NU + 0x00a5: 0x03be, # GREEK SMALL LETTER XI + 0x00a6: 0x03bf, # GREEK SMALL LETTER OMICRON + 0x00a7: 0x03c0, # GREEK SMALL LETTER PI + 0x00a8: 0x03c1, # GREEK SMALL LETTER RHO + 0x00a9: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00aa: 0x03c2, # GREEK SMALL LETTER FINAL SIGMA + 0x00ab: 0x03c4, # GREEK SMALL LETTER TAU + 0x00ac: 0x03c5, # GREEK SMALL LETTER UPSILON + 0x00ad: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ae: 0x03c7, # GREEK SMALL LETTER CHI + 0x00af: 0x03c8, # GREEK SMALL LETTER PSI + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03c9, # GREEK SMALL LETTER OMEGA + 0x00e1: 0x03ac, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x00e2: 0x03ad, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x00e3: 0x03ae, # GREEK SMALL LETTER ETA WITH TONOS + 0x00e4: 0x03ca, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x00e5: 0x03af, # GREEK SMALL LETTER IOTA WITH TONOS + 0x00e6: 0x03cc, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x00e7: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x00e8: 0x03cb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x00e9: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x00ea: 0x0386, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x00eb: 0x0388, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x00ec: 0x0389, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x00ed: 0x038a, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x00ee: 0x038c, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x00ef: 0x038e, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x00f0: 0x038f, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x03aa, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x00f5: 0x03ab, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\u0391' # 0x0080 -> GREEK CAPITAL LETTER ALPHA + u'\u0392' # 0x0081 -> GREEK CAPITAL LETTER BETA + u'\u0393' # 0x0082 -> GREEK CAPITAL LETTER GAMMA + u'\u0394' # 0x0083 -> GREEK CAPITAL LETTER DELTA + u'\u0395' # 0x0084 -> GREEK CAPITAL LETTER EPSILON + u'\u0396' # 0x0085 -> GREEK CAPITAL LETTER ZETA + u'\u0397' # 0x0086 -> GREEK CAPITAL LETTER ETA + u'\u0398' # 0x0087 -> GREEK CAPITAL LETTER THETA + u'\u0399' # 0x0088 -> GREEK CAPITAL LETTER IOTA + u'\u039a' # 0x0089 -> GREEK CAPITAL LETTER KAPPA + u'\u039b' # 0x008a -> GREEK CAPITAL LETTER LAMDA + u'\u039c' # 0x008b -> GREEK CAPITAL LETTER MU + u'\u039d' # 0x008c -> GREEK CAPITAL LETTER NU + u'\u039e' # 0x008d -> GREEK CAPITAL LETTER XI + u'\u039f' # 0x008e -> GREEK CAPITAL LETTER OMICRON + u'\u03a0' # 0x008f -> GREEK CAPITAL LETTER PI + u'\u03a1' # 0x0090 -> GREEK CAPITAL LETTER RHO + u'\u03a3' # 0x0091 -> GREEK CAPITAL LETTER SIGMA + u'\u03a4' # 0x0092 -> GREEK CAPITAL LETTER TAU + u'\u03a5' # 0x0093 -> GREEK CAPITAL LETTER UPSILON + u'\u03a6' # 0x0094 -> GREEK CAPITAL LETTER PHI + u'\u03a7' # 0x0095 -> GREEK CAPITAL LETTER CHI + u'\u03a8' # 0x0096 -> GREEK CAPITAL LETTER PSI + u'\u03a9' # 0x0097 -> GREEK CAPITAL LETTER OMEGA + u'\u03b1' # 0x0098 -> GREEK SMALL LETTER ALPHA + u'\u03b2' # 0x0099 -> GREEK SMALL LETTER BETA + u'\u03b3' # 0x009a -> GREEK SMALL LETTER GAMMA + u'\u03b4' # 0x009b -> GREEK SMALL LETTER DELTA + u'\u03b5' # 0x009c -> GREEK SMALL LETTER EPSILON + u'\u03b6' # 0x009d -> GREEK SMALL LETTER ZETA + u'\u03b7' # 0x009e -> GREEK SMALL LETTER ETA + u'\u03b8' # 0x009f -> GREEK SMALL LETTER THETA + u'\u03b9' # 0x00a0 -> GREEK SMALL LETTER IOTA + u'\u03ba' # 0x00a1 -> GREEK SMALL LETTER KAPPA + u'\u03bb' # 0x00a2 -> GREEK SMALL LETTER LAMDA + u'\u03bc' # 0x00a3 -> GREEK SMALL LETTER MU + u'\u03bd' # 0x00a4 -> GREEK SMALL LETTER NU + u'\u03be' # 0x00a5 -> GREEK SMALL LETTER XI + u'\u03bf' # 0x00a6 -> GREEK SMALL LETTER OMICRON + u'\u03c0' # 0x00a7 -> GREEK SMALL LETTER PI + u'\u03c1' # 0x00a8 -> GREEK SMALL LETTER RHO + u'\u03c3' # 0x00a9 -> GREEK SMALL LETTER SIGMA + u'\u03c2' # 0x00aa -> GREEK SMALL LETTER FINAL SIGMA + u'\u03c4' # 0x00ab -> GREEK SMALL LETTER TAU + u'\u03c5' # 0x00ac -> GREEK SMALL LETTER UPSILON + u'\u03c6' # 0x00ad -> GREEK SMALL LETTER PHI + u'\u03c7' # 0x00ae -> GREEK SMALL LETTER CHI + u'\u03c8' # 0x00af -> GREEK SMALL LETTER PSI + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03c9' # 0x00e0 -> GREEK SMALL LETTER OMEGA + u'\u03ac' # 0x00e1 -> GREEK SMALL LETTER ALPHA WITH TONOS + u'\u03ad' # 0x00e2 -> GREEK SMALL LETTER EPSILON WITH TONOS + u'\u03ae' # 0x00e3 -> GREEK SMALL LETTER ETA WITH TONOS + u'\u03ca' # 0x00e4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + u'\u03af' # 0x00e5 -> GREEK SMALL LETTER IOTA WITH TONOS + u'\u03cc' # 0x00e6 -> GREEK SMALL LETTER OMICRON WITH TONOS + u'\u03cd' # 0x00e7 -> GREEK SMALL LETTER UPSILON WITH TONOS + u'\u03cb' # 0x00e8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + u'\u03ce' # 0x00e9 -> GREEK SMALL LETTER OMEGA WITH TONOS + u'\u0386' # 0x00ea -> GREEK CAPITAL LETTER ALPHA WITH TONOS + u'\u0388' # 0x00eb -> GREEK CAPITAL LETTER EPSILON WITH TONOS + u'\u0389' # 0x00ec -> GREEK CAPITAL LETTER ETA WITH TONOS + u'\u038a' # 0x00ed -> GREEK CAPITAL LETTER IOTA WITH TONOS + u'\u038c' # 0x00ee -> GREEK CAPITAL LETTER OMICRON WITH TONOS + u'\u038e' # 0x00ef -> GREEK CAPITAL LETTER UPSILON WITH TONOS + u'\u038f' # 0x00f0 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + u'\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + u'\u03aa' # 0x00f4 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + u'\u03ab' # 0x00f5 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u2248' # 0x00f7 -> ALMOST EQUAL TO + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00f7: 0x00f6, # DIVISION SIGN + 0x0386: 0x00ea, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0388: 0x00eb, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x0389: 0x00ec, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x038a: 0x00ed, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x038c: 0x00ee, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x038e: 0x00ef, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x038f: 0x00f0, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0391: 0x0080, # GREEK CAPITAL LETTER ALPHA + 0x0392: 0x0081, # GREEK CAPITAL LETTER BETA + 0x0393: 0x0082, # GREEK CAPITAL LETTER GAMMA + 0x0394: 0x0083, # GREEK CAPITAL LETTER DELTA + 0x0395: 0x0084, # GREEK CAPITAL LETTER EPSILON + 0x0396: 0x0085, # GREEK CAPITAL LETTER ZETA + 0x0397: 0x0086, # GREEK CAPITAL LETTER ETA + 0x0398: 0x0087, # GREEK CAPITAL LETTER THETA + 0x0399: 0x0088, # GREEK CAPITAL LETTER IOTA + 0x039a: 0x0089, # GREEK CAPITAL LETTER KAPPA + 0x039b: 0x008a, # GREEK CAPITAL LETTER LAMDA + 0x039c: 0x008b, # GREEK CAPITAL LETTER MU + 0x039d: 0x008c, # GREEK CAPITAL LETTER NU + 0x039e: 0x008d, # GREEK CAPITAL LETTER XI + 0x039f: 0x008e, # GREEK CAPITAL LETTER OMICRON + 0x03a0: 0x008f, # GREEK CAPITAL LETTER PI + 0x03a1: 0x0090, # GREEK CAPITAL LETTER RHO + 0x03a3: 0x0091, # GREEK CAPITAL LETTER SIGMA + 0x03a4: 0x0092, # GREEK CAPITAL LETTER TAU + 0x03a5: 0x0093, # GREEK CAPITAL LETTER UPSILON + 0x03a6: 0x0094, # GREEK CAPITAL LETTER PHI + 0x03a7: 0x0095, # GREEK CAPITAL LETTER CHI + 0x03a8: 0x0096, # GREEK CAPITAL LETTER PSI + 0x03a9: 0x0097, # GREEK CAPITAL LETTER OMEGA + 0x03aa: 0x00f4, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x03ab: 0x00f5, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x03ac: 0x00e1, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x03ad: 0x00e2, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x03ae: 0x00e3, # GREEK SMALL LETTER ETA WITH TONOS + 0x03af: 0x00e5, # GREEK SMALL LETTER IOTA WITH TONOS + 0x03b1: 0x0098, # GREEK SMALL LETTER ALPHA + 0x03b2: 0x0099, # GREEK SMALL LETTER BETA + 0x03b3: 0x009a, # GREEK SMALL LETTER GAMMA + 0x03b4: 0x009b, # GREEK SMALL LETTER DELTA + 0x03b5: 0x009c, # GREEK SMALL LETTER EPSILON + 0x03b6: 0x009d, # GREEK SMALL LETTER ZETA + 0x03b7: 0x009e, # GREEK SMALL LETTER ETA + 0x03b8: 0x009f, # GREEK SMALL LETTER THETA + 0x03b9: 0x00a0, # GREEK SMALL LETTER IOTA + 0x03ba: 0x00a1, # GREEK SMALL LETTER KAPPA + 0x03bb: 0x00a2, # GREEK SMALL LETTER LAMDA + 0x03bc: 0x00a3, # GREEK SMALL LETTER MU + 0x03bd: 0x00a4, # GREEK SMALL LETTER NU + 0x03be: 0x00a5, # GREEK SMALL LETTER XI + 0x03bf: 0x00a6, # GREEK SMALL LETTER OMICRON + 0x03c0: 0x00a7, # GREEK SMALL LETTER PI + 0x03c1: 0x00a8, # GREEK SMALL LETTER RHO + 0x03c2: 0x00aa, # GREEK SMALL LETTER FINAL SIGMA + 0x03c3: 0x00a9, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00ab, # GREEK SMALL LETTER TAU + 0x03c5: 0x00ac, # GREEK SMALL LETTER UPSILON + 0x03c6: 0x00ad, # GREEK SMALL LETTER PHI + 0x03c7: 0x00ae, # GREEK SMALL LETTER CHI + 0x03c8: 0x00af, # GREEK SMALL LETTER PSI + 0x03c9: 0x00e0, # GREEK SMALL LETTER OMEGA + 0x03ca: 0x00e4, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x03cb: 0x00e8, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x03cc: 0x00e6, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x03cd: 0x00e7, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x03ce: 0x00e9, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp775.py b/src/main/resources/PythonLibs/encodings/cp775.py new file mode 100644 index 0000000000000000000000000000000000000000..6a456a5825e4c3682bd08ab8abe52df7425f65d1 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp775.py @@ -0,0 +1,697 @@ +""" Python Character Mapping Codec cp775 generated from 'VENDORS/MICSFT/PC/CP775.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp775', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x0101, # LATIN SMALL LETTER A WITH MACRON + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x0123, # LATIN SMALL LETTER G WITH CEDILLA + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x0107, # LATIN SMALL LETTER C WITH ACUTE + 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE + 0x0089: 0x0113, # LATIN SMALL LETTER E WITH MACRON + 0x008a: 0x0156, # LATIN CAPITAL LETTER R WITH CEDILLA + 0x008b: 0x0157, # LATIN SMALL LETTER R WITH CEDILLA + 0x008c: 0x012b, # LATIN SMALL LETTER I WITH MACRON + 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x014d, # LATIN SMALL LETTER O WITH MACRON + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA + 0x0096: 0x00a2, # CENT SIGN + 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE + 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x00a4, # CURRENCY SIGN + 0x00a0: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON + 0x00a1: 0x012a, # LATIN CAPITAL LETTER I WITH MACRON + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x00a4: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00a5: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE + 0x00a6: 0x201d, # RIGHT DOUBLE QUOTATION MARK + 0x00a7: 0x00a6, # BROKEN BAR + 0x00a8: 0x00a9, # COPYRIGHT SIGN + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK + 0x00b6: 0x010c, # LATIN CAPITAL LETTER C WITH CARON + 0x00b7: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK + 0x00b8: 0x0116, # LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x012e, # LATIN CAPITAL LETTER I WITH OGONEK + 0x00be: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x0172, # LATIN CAPITAL LETTER U WITH OGONEK + 0x00c7: 0x016a, # LATIN CAPITAL LETTER U WITH MACRON + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON + 0x00d0: 0x0105, # LATIN SMALL LETTER A WITH OGONEK + 0x00d1: 0x010d, # LATIN SMALL LETTER C WITH CARON + 0x00d2: 0x0119, # LATIN SMALL LETTER E WITH OGONEK + 0x00d3: 0x0117, # LATIN SMALL LETTER E WITH DOT ABOVE + 0x00d4: 0x012f, # LATIN SMALL LETTER I WITH OGONEK + 0x00d5: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00d6: 0x0173, # LATIN SMALL LETTER U WITH OGONEK + 0x00d7: 0x016b, # LATIN SMALL LETTER U WITH MACRON + 0x00d8: 0x017e, # LATIN SMALL LETTER Z WITH CARON + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e2: 0x014c, # LATIN CAPITAL LETTER O WITH MACRON + 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x0144, # LATIN SMALL LETTER N WITH ACUTE + 0x00e8: 0x0136, # LATIN CAPITAL LETTER K WITH CEDILLA + 0x00e9: 0x0137, # LATIN SMALL LETTER K WITH CEDILLA + 0x00ea: 0x013b, # LATIN CAPITAL LETTER L WITH CEDILLA + 0x00eb: 0x013c, # LATIN SMALL LETTER L WITH CEDILLA + 0x00ec: 0x0146, # LATIN SMALL LETTER N WITH CEDILLA + 0x00ed: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON + 0x00ee: 0x0145, # LATIN CAPITAL LETTER N WITH CEDILLA + 0x00ef: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x201c, # LEFT DOUBLE QUOTATION MARK + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x201e, # DOUBLE LOW-9 QUOTATION MARK + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\u0106' # 0x0080 -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\u0101' # 0x0083 -> LATIN SMALL LETTER A WITH MACRON + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u0123' # 0x0085 -> LATIN SMALL LETTER G WITH CEDILLA + u'\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\u0107' # 0x0087 -> LATIN SMALL LETTER C WITH ACUTE + u'\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE + u'\u0113' # 0x0089 -> LATIN SMALL LETTER E WITH MACRON + u'\u0156' # 0x008a -> LATIN CAPITAL LETTER R WITH CEDILLA + u'\u0157' # 0x008b -> LATIN SMALL LETTER R WITH CEDILLA + u'\u012b' # 0x008c -> LATIN SMALL LETTER I WITH MACRON + u'\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + u'\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + u'\u014d' # 0x0093 -> LATIN SMALL LETTER O WITH MACRON + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\u0122' # 0x0095 -> LATIN CAPITAL LETTER G WITH CEDILLA + u'\xa2' # 0x0096 -> CENT SIGN + u'\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE + u'\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + u'\xa3' # 0x009c -> POUND SIGN + u'\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd7' # 0x009e -> MULTIPLICATION SIGN + u'\xa4' # 0x009f -> CURRENCY SIGN + u'\u0100' # 0x00a0 -> LATIN CAPITAL LETTER A WITH MACRON + u'\u012a' # 0x00a1 -> LATIN CAPITAL LETTER I WITH MACRON + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\u017b' # 0x00a3 -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\u017c' # 0x00a4 -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\u017a' # 0x00a5 -> LATIN SMALL LETTER Z WITH ACUTE + u'\u201d' # 0x00a6 -> RIGHT DOUBLE QUOTATION MARK + u'\xa6' # 0x00a7 -> BROKEN BAR + u'\xa9' # 0x00a8 -> COPYRIGHT SIGN + u'\xae' # 0x00a9 -> REGISTERED SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\u0141' # 0x00ad -> LATIN CAPITAL LETTER L WITH STROKE + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u0104' # 0x00b5 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u010c' # 0x00b6 -> LATIN CAPITAL LETTER C WITH CARON + u'\u0118' # 0x00b7 -> LATIN CAPITAL LETTER E WITH OGONEK + u'\u0116' # 0x00b8 -> LATIN CAPITAL LETTER E WITH DOT ABOVE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u012e' # 0x00bd -> LATIN CAPITAL LETTER I WITH OGONEK + u'\u0160' # 0x00be -> LATIN CAPITAL LETTER S WITH CARON + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u0172' # 0x00c6 -> LATIN CAPITAL LETTER U WITH OGONEK + u'\u016a' # 0x00c7 -> LATIN CAPITAL LETTER U WITH MACRON + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u017d' # 0x00cf -> LATIN CAPITAL LETTER Z WITH CARON + u'\u0105' # 0x00d0 -> LATIN SMALL LETTER A WITH OGONEK + u'\u010d' # 0x00d1 -> LATIN SMALL LETTER C WITH CARON + u'\u0119' # 0x00d2 -> LATIN SMALL LETTER E WITH OGONEK + u'\u0117' # 0x00d3 -> LATIN SMALL LETTER E WITH DOT ABOVE + u'\u012f' # 0x00d4 -> LATIN SMALL LETTER I WITH OGONEK + u'\u0161' # 0x00d5 -> LATIN SMALL LETTER S WITH CARON + u'\u0173' # 0x00d6 -> LATIN SMALL LETTER U WITH OGONEK + u'\u016b' # 0x00d7 -> LATIN SMALL LETTER U WITH MACRON + u'\u017e' # 0x00d8 -> LATIN SMALL LETTER Z WITH CARON + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) + u'\u014c' # 0x00e2 -> LATIN CAPITAL LETTER O WITH MACRON + u'\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + u'\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\u0144' # 0x00e7 -> LATIN SMALL LETTER N WITH ACUTE + u'\u0136' # 0x00e8 -> LATIN CAPITAL LETTER K WITH CEDILLA + u'\u0137' # 0x00e9 -> LATIN SMALL LETTER K WITH CEDILLA + u'\u013b' # 0x00ea -> LATIN CAPITAL LETTER L WITH CEDILLA + u'\u013c' # 0x00eb -> LATIN SMALL LETTER L WITH CEDILLA + u'\u0146' # 0x00ec -> LATIN SMALL LETTER N WITH CEDILLA + u'\u0112' # 0x00ed -> LATIN CAPITAL LETTER E WITH MACRON + u'\u0145' # 0x00ee -> LATIN CAPITAL LETTER N WITH CEDILLA + u'\u2019' # 0x00ef -> RIGHT SINGLE QUOTATION MARK + u'\xad' # 0x00f0 -> SOFT HYPHEN + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u201c' # 0x00f2 -> LEFT DOUBLE QUOTATION MARK + u'\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + u'\xb6' # 0x00f4 -> PILCROW SIGN + u'\xa7' # 0x00f5 -> SECTION SIGN + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u201e' # 0x00f7 -> DOUBLE LOW-9 QUOTATION MARK + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\xb9' # 0x00fb -> SUPERSCRIPT ONE + u'\xb3' # 0x00fc -> SUPERSCRIPT THREE + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a2: 0x0096, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x009f, # CURRENCY SIGN + 0x00a6: 0x00a7, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a9: 0x00a8, # COPYRIGHT SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0100: 0x00a0, # LATIN CAPITAL LETTER A WITH MACRON + 0x0101: 0x0083, # LATIN SMALL LETTER A WITH MACRON + 0x0104: 0x00b5, # LATIN CAPITAL LETTER A WITH OGONEK + 0x0105: 0x00d0, # LATIN SMALL LETTER A WITH OGONEK + 0x0106: 0x0080, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0107: 0x0087, # LATIN SMALL LETTER C WITH ACUTE + 0x010c: 0x00b6, # LATIN CAPITAL LETTER C WITH CARON + 0x010d: 0x00d1, # LATIN SMALL LETTER C WITH CARON + 0x0112: 0x00ed, # LATIN CAPITAL LETTER E WITH MACRON + 0x0113: 0x0089, # LATIN SMALL LETTER E WITH MACRON + 0x0116: 0x00b8, # LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x0117: 0x00d3, # LATIN SMALL LETTER E WITH DOT ABOVE + 0x0118: 0x00b7, # LATIN CAPITAL LETTER E WITH OGONEK + 0x0119: 0x00d2, # LATIN SMALL LETTER E WITH OGONEK + 0x0122: 0x0095, # LATIN CAPITAL LETTER G WITH CEDILLA + 0x0123: 0x0085, # LATIN SMALL LETTER G WITH CEDILLA + 0x012a: 0x00a1, # LATIN CAPITAL LETTER I WITH MACRON + 0x012b: 0x008c, # LATIN SMALL LETTER I WITH MACRON + 0x012e: 0x00bd, # LATIN CAPITAL LETTER I WITH OGONEK + 0x012f: 0x00d4, # LATIN SMALL LETTER I WITH OGONEK + 0x0136: 0x00e8, # LATIN CAPITAL LETTER K WITH CEDILLA + 0x0137: 0x00e9, # LATIN SMALL LETTER K WITH CEDILLA + 0x013b: 0x00ea, # LATIN CAPITAL LETTER L WITH CEDILLA + 0x013c: 0x00eb, # LATIN SMALL LETTER L WITH CEDILLA + 0x0141: 0x00ad, # LATIN CAPITAL LETTER L WITH STROKE + 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE + 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE + 0x0144: 0x00e7, # LATIN SMALL LETTER N WITH ACUTE + 0x0145: 0x00ee, # LATIN CAPITAL LETTER N WITH CEDILLA + 0x0146: 0x00ec, # LATIN SMALL LETTER N WITH CEDILLA + 0x014c: 0x00e2, # LATIN CAPITAL LETTER O WITH MACRON + 0x014d: 0x0093, # LATIN SMALL LETTER O WITH MACRON + 0x0156: 0x008a, # LATIN CAPITAL LETTER R WITH CEDILLA + 0x0157: 0x008b, # LATIN SMALL LETTER R WITH CEDILLA + 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE + 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE + 0x0160: 0x00be, # LATIN CAPITAL LETTER S WITH CARON + 0x0161: 0x00d5, # LATIN SMALL LETTER S WITH CARON + 0x016a: 0x00c7, # LATIN CAPITAL LETTER U WITH MACRON + 0x016b: 0x00d7, # LATIN SMALL LETTER U WITH MACRON + 0x0172: 0x00c6, # LATIN CAPITAL LETTER U WITH OGONEK + 0x0173: 0x00d6, # LATIN SMALL LETTER U WITH OGONEK + 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x017a: 0x00a5, # LATIN SMALL LETTER Z WITH ACUTE + 0x017b: 0x00a3, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x017c: 0x00a4, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x017d: 0x00cf, # LATIN CAPITAL LETTER Z WITH CARON + 0x017e: 0x00d8, # LATIN SMALL LETTER Z WITH CARON + 0x2019: 0x00ef, # RIGHT SINGLE QUOTATION MARK + 0x201c: 0x00f2, # LEFT DOUBLE QUOTATION MARK + 0x201d: 0x00a6, # RIGHT DOUBLE QUOTATION MARK + 0x201e: 0x00f7, # DOUBLE LOW-9 QUOTATION MARK + 0x2219: 0x00f9, # BULLET OPERATOR + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp850.py b/src/main/resources/PythonLibs/encodings/cp850.py new file mode 100644 index 0000000000000000000000000000000000000000..0c8478c8b205a8ce69eac95a00b75f319d49c5e1 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp850.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP850.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp850', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH + 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: 0x0131, # LATIN SMALL LETTER DOTLESS I + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN + 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2017, # DOUBLE LOW LINE + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + u'\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + u'\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + u'\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + u'\xa3' # 0x009c -> POUND SIGN + u'\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd7' # 0x009e -> MULTIPLICATION SIGN + u'\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + u'\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\xae' # 0x00a9 -> REGISTERED SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xa9' # 0x00b8 -> COPYRIGHT SIGN + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\xa2' # 0x00bd -> CENT SIGN + u'\xa5' # 0x00be -> YEN SIGN + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + u'\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa4' # 0x00cf -> CURRENCY SIGN + u'\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH + u'\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH + u'\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\u0131' # 0x00d5 -> LATIN SMALL LETTER DOTLESS I + u'\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\xa6' # 0x00dd -> BROKEN BAR + u'\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + u'\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN + u'\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN + u'\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + u'\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xaf' # 0x00ee -> MACRON + u'\xb4' # 0x00ef -> ACUTE ACCENT + u'\xad' # 0x00f0 -> SOFT HYPHEN + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2017' # 0x00f2 -> DOUBLE LOW LINE + u'\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + u'\xb6' # 0x00f4 -> PILCROW SIGN + u'\xa7' # 0x00f5 -> SECTION SIGN + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\xb8' # 0x00f7 -> CEDILLA + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\xa8' # 0x00f9 -> DIAERESIS + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\xb9' # 0x00fb -> SUPERSCRIPT ONE + u'\xb3' # 0x00fc -> SUPERSCRIPT THREE + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0131: 0x00d5, # LATIN SMALL LETTER DOTLESS I + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x2017: 0x00f2, # DOUBLE LOW LINE + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp852.py b/src/main/resources/PythonLibs/encodings/cp852.py new file mode 100644 index 0000000000000000000000000000000000000000..069d5473b500050939696adeb78c41ae0ac9bdce --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp852.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP852.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp852', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x016f, # LATIN SMALL LETTER U WITH RING ABOVE + 0x0086: 0x0107, # LATIN SMALL LETTER C WITH ACUTE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x0150, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + 0x008b: 0x0151, # LATIN SMALL LETTER O WITH DOUBLE ACUTE + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x0139, # LATIN CAPITAL LETTER L WITH ACUTE + 0x0092: 0x013a, # LATIN SMALL LETTER L WITH ACUTE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x013d, # LATIN CAPITAL LETTER L WITH CARON + 0x0096: 0x013e, # LATIN SMALL LETTER L WITH CARON + 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE + 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x0164, # LATIN CAPITAL LETTER T WITH CARON + 0x009c: 0x0165, # LATIN SMALL LETTER T WITH CARON + 0x009d: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x010d, # LATIN SMALL LETTER C WITH CARON + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK + 0x00a5: 0x0105, # LATIN SMALL LETTER A WITH OGONEK + 0x00a6: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON + 0x00a7: 0x017e, # LATIN SMALL LETTER Z WITH CARON + 0x00a8: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK + 0x00a9: 0x0119, # LATIN SMALL LETTER E WITH OGONEK + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE + 0x00ac: 0x010c, # LATIN CAPITAL LETTER C WITH CARON + 0x00ad: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x011a, # LATIN CAPITAL LETTER E WITH CARON + 0x00b8: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x00be: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x0102, # LATIN CAPITAL LETTER A WITH BREVE + 0x00c7: 0x0103, # LATIN SMALL LETTER A WITH BREVE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x0111, # LATIN SMALL LETTER D WITH STROKE + 0x00d1: 0x0110, # LATIN CAPITAL LETTER D WITH STROKE + 0x00d2: 0x010e, # LATIN CAPITAL LETTER D WITH CARON + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x010f, # LATIN SMALL LETTER D WITH CARON + 0x00d5: 0x0147, # LATIN CAPITAL LETTER N WITH CARON + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x011b, # LATIN SMALL LETTER E WITH CARON + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x0162, # LATIN CAPITAL LETTER T WITH CEDILLA + 0x00de: 0x016e, # LATIN CAPITAL LETTER U WITH RING ABOVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE + 0x00e4: 0x0144, # LATIN SMALL LETTER N WITH ACUTE + 0x00e5: 0x0148, # LATIN SMALL LETTER N WITH CARON + 0x00e6: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00e7: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00e8: 0x0154, # LATIN CAPITAL LETTER R WITH ACUTE + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x0155, # LATIN SMALL LETTER R WITH ACUTE + 0x00eb: 0x0170, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x02dd, # DOUBLE ACUTE ACCENT + 0x00f2: 0x02db, # OGONEK + 0x00f3: 0x02c7, # CARON + 0x00f4: 0x02d8, # BREVE + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x02d9, # DOT ABOVE + 0x00fb: 0x0171, # LATIN SMALL LETTER U WITH DOUBLE ACUTE + 0x00fc: 0x0158, # LATIN CAPITAL LETTER R WITH CARON + 0x00fd: 0x0159, # LATIN SMALL LETTER R WITH CARON + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u016f' # 0x0085 -> LATIN SMALL LETTER U WITH RING ABOVE + u'\u0107' # 0x0086 -> LATIN SMALL LETTER C WITH ACUTE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\u0150' # 0x008a -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + u'\u0151' # 0x008b -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + u'\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\u0106' # 0x008f -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0139' # 0x0091 -> LATIN CAPITAL LETTER L WITH ACUTE + u'\u013a' # 0x0092 -> LATIN SMALL LETTER L WITH ACUTE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\u013d' # 0x0095 -> LATIN CAPITAL LETTER L WITH CARON + u'\u013e' # 0x0096 -> LATIN SMALL LETTER L WITH CARON + u'\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE + u'\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u0164' # 0x009b -> LATIN CAPITAL LETTER T WITH CARON + u'\u0165' # 0x009c -> LATIN SMALL LETTER T WITH CARON + u'\u0141' # 0x009d -> LATIN CAPITAL LETTER L WITH STROKE + u'\xd7' # 0x009e -> MULTIPLICATION SIGN + u'\u010d' # 0x009f -> LATIN SMALL LETTER C WITH CARON + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\u0104' # 0x00a4 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u0105' # 0x00a5 -> LATIN SMALL LETTER A WITH OGONEK + u'\u017d' # 0x00a6 -> LATIN CAPITAL LETTER Z WITH CARON + u'\u017e' # 0x00a7 -> LATIN SMALL LETTER Z WITH CARON + u'\u0118' # 0x00a8 -> LATIN CAPITAL LETTER E WITH OGONEK + u'\u0119' # 0x00a9 -> LATIN SMALL LETTER E WITH OGONEK + u'\xac' # 0x00aa -> NOT SIGN + u'\u017a' # 0x00ab -> LATIN SMALL LETTER Z WITH ACUTE + u'\u010c' # 0x00ac -> LATIN CAPITAL LETTER C WITH CARON + u'\u015f' # 0x00ad -> LATIN SMALL LETTER S WITH CEDILLA + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\u011a' # 0x00b7 -> LATIN CAPITAL LETTER E WITH CARON + u'\u015e' # 0x00b8 -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u017b' # 0x00bd -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\u017c' # 0x00be -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u0102' # 0x00c6 -> LATIN CAPITAL LETTER A WITH BREVE + u'\u0103' # 0x00c7 -> LATIN SMALL LETTER A WITH BREVE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa4' # 0x00cf -> CURRENCY SIGN + u'\u0111' # 0x00d0 -> LATIN SMALL LETTER D WITH STROKE + u'\u0110' # 0x00d1 -> LATIN CAPITAL LETTER D WITH STROKE + u'\u010e' # 0x00d2 -> LATIN CAPITAL LETTER D WITH CARON + u'\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\u010f' # 0x00d4 -> LATIN SMALL LETTER D WITH CARON + u'\u0147' # 0x00d5 -> LATIN CAPITAL LETTER N WITH CARON + u'\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\u011b' # 0x00d8 -> LATIN SMALL LETTER E WITH CARON + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u0162' # 0x00dd -> LATIN CAPITAL LETTER T WITH CEDILLA + u'\u016e' # 0x00de -> LATIN CAPITAL LETTER U WITH RING ABOVE + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\u0144' # 0x00e4 -> LATIN SMALL LETTER N WITH ACUTE + u'\u0148' # 0x00e5 -> LATIN SMALL LETTER N WITH CARON + u'\u0160' # 0x00e6 -> LATIN CAPITAL LETTER S WITH CARON + u'\u0161' # 0x00e7 -> LATIN SMALL LETTER S WITH CARON + u'\u0154' # 0x00e8 -> LATIN CAPITAL LETTER R WITH ACUTE + u'\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\u0155' # 0x00ea -> LATIN SMALL LETTER R WITH ACUTE + u'\u0170' # 0x00eb -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + u'\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + u'\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\u0163' # 0x00ee -> LATIN SMALL LETTER T WITH CEDILLA + u'\xb4' # 0x00ef -> ACUTE ACCENT + u'\xad' # 0x00f0 -> SOFT HYPHEN + u'\u02dd' # 0x00f1 -> DOUBLE ACUTE ACCENT + u'\u02db' # 0x00f2 -> OGONEK + u'\u02c7' # 0x00f3 -> CARON + u'\u02d8' # 0x00f4 -> BREVE + u'\xa7' # 0x00f5 -> SECTION SIGN + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\xb8' # 0x00f7 -> CEDILLA + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\xa8' # 0x00f9 -> DIAERESIS + u'\u02d9' # 0x00fa -> DOT ABOVE + u'\u0171' # 0x00fb -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + u'\u0158' # 0x00fc -> LATIN CAPITAL LETTER R WITH CARON + u'\u0159' # 0x00fd -> LATIN SMALL LETTER R WITH CARON + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b8: 0x00f7, # CEDILLA + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x0102: 0x00c6, # LATIN CAPITAL LETTER A WITH BREVE + 0x0103: 0x00c7, # LATIN SMALL LETTER A WITH BREVE + 0x0104: 0x00a4, # LATIN CAPITAL LETTER A WITH OGONEK + 0x0105: 0x00a5, # LATIN SMALL LETTER A WITH OGONEK + 0x0106: 0x008f, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0107: 0x0086, # LATIN SMALL LETTER C WITH ACUTE + 0x010c: 0x00ac, # LATIN CAPITAL LETTER C WITH CARON + 0x010d: 0x009f, # LATIN SMALL LETTER C WITH CARON + 0x010e: 0x00d2, # LATIN CAPITAL LETTER D WITH CARON + 0x010f: 0x00d4, # LATIN SMALL LETTER D WITH CARON + 0x0110: 0x00d1, # LATIN CAPITAL LETTER D WITH STROKE + 0x0111: 0x00d0, # LATIN SMALL LETTER D WITH STROKE + 0x0118: 0x00a8, # LATIN CAPITAL LETTER E WITH OGONEK + 0x0119: 0x00a9, # LATIN SMALL LETTER E WITH OGONEK + 0x011a: 0x00b7, # LATIN CAPITAL LETTER E WITH CARON + 0x011b: 0x00d8, # LATIN SMALL LETTER E WITH CARON + 0x0139: 0x0091, # LATIN CAPITAL LETTER L WITH ACUTE + 0x013a: 0x0092, # LATIN SMALL LETTER L WITH ACUTE + 0x013d: 0x0095, # LATIN CAPITAL LETTER L WITH CARON + 0x013e: 0x0096, # LATIN SMALL LETTER L WITH CARON + 0x0141: 0x009d, # LATIN CAPITAL LETTER L WITH STROKE + 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE + 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE + 0x0144: 0x00e4, # LATIN SMALL LETTER N WITH ACUTE + 0x0147: 0x00d5, # LATIN CAPITAL LETTER N WITH CARON + 0x0148: 0x00e5, # LATIN SMALL LETTER N WITH CARON + 0x0150: 0x008a, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + 0x0151: 0x008b, # LATIN SMALL LETTER O WITH DOUBLE ACUTE + 0x0154: 0x00e8, # LATIN CAPITAL LETTER R WITH ACUTE + 0x0155: 0x00ea, # LATIN SMALL LETTER R WITH ACUTE + 0x0158: 0x00fc, # LATIN CAPITAL LETTER R WITH CARON + 0x0159: 0x00fd, # LATIN SMALL LETTER R WITH CARON + 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE + 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE + 0x015e: 0x00b8, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x015f: 0x00ad, # LATIN SMALL LETTER S WITH CEDILLA + 0x0160: 0x00e6, # LATIN CAPITAL LETTER S WITH CARON + 0x0161: 0x00e7, # LATIN SMALL LETTER S WITH CARON + 0x0162: 0x00dd, # LATIN CAPITAL LETTER T WITH CEDILLA + 0x0163: 0x00ee, # LATIN SMALL LETTER T WITH CEDILLA + 0x0164: 0x009b, # LATIN CAPITAL LETTER T WITH CARON + 0x0165: 0x009c, # LATIN SMALL LETTER T WITH CARON + 0x016e: 0x00de, # LATIN CAPITAL LETTER U WITH RING ABOVE + 0x016f: 0x0085, # LATIN SMALL LETTER U WITH RING ABOVE + 0x0170: 0x00eb, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + 0x0171: 0x00fb, # LATIN SMALL LETTER U WITH DOUBLE ACUTE + 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x017a: 0x00ab, # LATIN SMALL LETTER Z WITH ACUTE + 0x017b: 0x00bd, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x017c: 0x00be, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x017d: 0x00a6, # LATIN CAPITAL LETTER Z WITH CARON + 0x017e: 0x00a7, # LATIN SMALL LETTER Z WITH CARON + 0x02c7: 0x00f3, # CARON + 0x02d8: 0x00f4, # BREVE + 0x02d9: 0x00fa, # DOT ABOVE + 0x02db: 0x00f2, # OGONEK + 0x02dd: 0x00f1, # DOUBLE ACUTE ACCENT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp855.py b/src/main/resources/PythonLibs/encodings/cp855.py new file mode 100644 index 0000000000000000000000000000000000000000..241ef9d1e86e4edb1c8452d8aecafb8670c8a2d0 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp855.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP855.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp855', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0452, # CYRILLIC SMALL LETTER DJE + 0x0081: 0x0402, # CYRILLIC CAPITAL LETTER DJE + 0x0082: 0x0453, # CYRILLIC SMALL LETTER GJE + 0x0083: 0x0403, # CYRILLIC CAPITAL LETTER GJE + 0x0084: 0x0451, # CYRILLIC SMALL LETTER IO + 0x0085: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x0086: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0087: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0088: 0x0455, # CYRILLIC SMALL LETTER DZE + 0x0089: 0x0405, # CYRILLIC CAPITAL LETTER DZE + 0x008a: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x008b: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x008c: 0x0457, # CYRILLIC SMALL LETTER YI + 0x008d: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x008e: 0x0458, # CYRILLIC SMALL LETTER JE + 0x008f: 0x0408, # CYRILLIC CAPITAL LETTER JE + 0x0090: 0x0459, # CYRILLIC SMALL LETTER LJE + 0x0091: 0x0409, # CYRILLIC CAPITAL LETTER LJE + 0x0092: 0x045a, # CYRILLIC SMALL LETTER NJE + 0x0093: 0x040a, # CYRILLIC CAPITAL LETTER NJE + 0x0094: 0x045b, # CYRILLIC SMALL LETTER TSHE + 0x0095: 0x040b, # CYRILLIC CAPITAL LETTER TSHE + 0x0096: 0x045c, # CYRILLIC SMALL LETTER KJE + 0x0097: 0x040c, # CYRILLIC CAPITAL LETTER KJE + 0x0098: 0x045e, # CYRILLIC SMALL LETTER SHORT U + 0x0099: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U + 0x009a: 0x045f, # CYRILLIC SMALL LETTER DZHE + 0x009b: 0x040f, # CYRILLIC CAPITAL LETTER DZHE + 0x009c: 0x044e, # CYRILLIC SMALL LETTER YU + 0x009d: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009e: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x009f: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x00a2: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a3: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x00a4: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00a5: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x00a6: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a7: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x00a8: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a9: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x00aa: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00ab: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x00ac: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00ad: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00b6: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x00b7: 0x0438, # CYRILLIC SMALL LETTER I + 0x00b8: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00be: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00c7: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00d1: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x00d2: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00d3: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x00d4: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00d5: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x00d6: 0x043e, # CYRILLIC SMALL LETTER O + 0x00d7: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x00d8: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x00de: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00e1: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e2: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x00e3: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e4: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x00e5: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e6: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x00e7: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e8: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x00e9: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00ea: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x00eb: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00ec: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x00ed: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ee: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x00ef: 0x2116, # NUMERO SIGN + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00f2: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x00f3: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00f4: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x00f5: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00f6: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x00f7: 0x044d, # CYRILLIC SMALL LETTER E + 0x00f8: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x00f9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00fa: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x00fb: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00fc: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x00fd: 0x00a7, # SECTION SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\u0452' # 0x0080 -> CYRILLIC SMALL LETTER DJE + u'\u0402' # 0x0081 -> CYRILLIC CAPITAL LETTER DJE + u'\u0453' # 0x0082 -> CYRILLIC SMALL LETTER GJE + u'\u0403' # 0x0083 -> CYRILLIC CAPITAL LETTER GJE + u'\u0451' # 0x0084 -> CYRILLIC SMALL LETTER IO + u'\u0401' # 0x0085 -> CYRILLIC CAPITAL LETTER IO + u'\u0454' # 0x0086 -> CYRILLIC SMALL LETTER UKRAINIAN IE + u'\u0404' # 0x0087 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + u'\u0455' # 0x0088 -> CYRILLIC SMALL LETTER DZE + u'\u0405' # 0x0089 -> CYRILLIC CAPITAL LETTER DZE + u'\u0456' # 0x008a -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0406' # 0x008b -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0457' # 0x008c -> CYRILLIC SMALL LETTER YI + u'\u0407' # 0x008d -> CYRILLIC CAPITAL LETTER YI + u'\u0458' # 0x008e -> CYRILLIC SMALL LETTER JE + u'\u0408' # 0x008f -> CYRILLIC CAPITAL LETTER JE + u'\u0459' # 0x0090 -> CYRILLIC SMALL LETTER LJE + u'\u0409' # 0x0091 -> CYRILLIC CAPITAL LETTER LJE + u'\u045a' # 0x0092 -> CYRILLIC SMALL LETTER NJE + u'\u040a' # 0x0093 -> CYRILLIC CAPITAL LETTER NJE + u'\u045b' # 0x0094 -> CYRILLIC SMALL LETTER TSHE + u'\u040b' # 0x0095 -> CYRILLIC CAPITAL LETTER TSHE + u'\u045c' # 0x0096 -> CYRILLIC SMALL LETTER KJE + u'\u040c' # 0x0097 -> CYRILLIC CAPITAL LETTER KJE + u'\u045e' # 0x0098 -> CYRILLIC SMALL LETTER SHORT U + u'\u040e' # 0x0099 -> CYRILLIC CAPITAL LETTER SHORT U + u'\u045f' # 0x009a -> CYRILLIC SMALL LETTER DZHE + u'\u040f' # 0x009b -> CYRILLIC CAPITAL LETTER DZHE + u'\u044e' # 0x009c -> CYRILLIC SMALL LETTER YU + u'\u042e' # 0x009d -> CYRILLIC CAPITAL LETTER YU + u'\u044a' # 0x009e -> CYRILLIC SMALL LETTER HARD SIGN + u'\u042a' # 0x009f -> CYRILLIC CAPITAL LETTER HARD SIGN + u'\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + u'\u0410' # 0x00a1 -> CYRILLIC CAPITAL LETTER A + u'\u0431' # 0x00a2 -> CYRILLIC SMALL LETTER BE + u'\u0411' # 0x00a3 -> CYRILLIC CAPITAL LETTER BE + u'\u0446' # 0x00a4 -> CYRILLIC SMALL LETTER TSE + u'\u0426' # 0x00a5 -> CYRILLIC CAPITAL LETTER TSE + u'\u0434' # 0x00a6 -> CYRILLIC SMALL LETTER DE + u'\u0414' # 0x00a7 -> CYRILLIC CAPITAL LETTER DE + u'\u0435' # 0x00a8 -> CYRILLIC SMALL LETTER IE + u'\u0415' # 0x00a9 -> CYRILLIC CAPITAL LETTER IE + u'\u0444' # 0x00aa -> CYRILLIC SMALL LETTER EF + u'\u0424' # 0x00ab -> CYRILLIC CAPITAL LETTER EF + u'\u0433' # 0x00ac -> CYRILLIC SMALL LETTER GHE + u'\u0413' # 0x00ad -> CYRILLIC CAPITAL LETTER GHE + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u0445' # 0x00b5 -> CYRILLIC SMALL LETTER HA + u'\u0425' # 0x00b6 -> CYRILLIC CAPITAL LETTER HA + u'\u0438' # 0x00b7 -> CYRILLIC SMALL LETTER I + u'\u0418' # 0x00b8 -> CYRILLIC CAPITAL LETTER I + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u0439' # 0x00bd -> CYRILLIC SMALL LETTER SHORT I + u'\u0419' # 0x00be -> CYRILLIC CAPITAL LETTER SHORT I + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u043a' # 0x00c6 -> CYRILLIC SMALL LETTER KA + u'\u041a' # 0x00c7 -> CYRILLIC CAPITAL LETTER KA + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa4' # 0x00cf -> CURRENCY SIGN + u'\u043b' # 0x00d0 -> CYRILLIC SMALL LETTER EL + u'\u041b' # 0x00d1 -> CYRILLIC CAPITAL LETTER EL + u'\u043c' # 0x00d2 -> CYRILLIC SMALL LETTER EM + u'\u041c' # 0x00d3 -> CYRILLIC CAPITAL LETTER EM + u'\u043d' # 0x00d4 -> CYRILLIC SMALL LETTER EN + u'\u041d' # 0x00d5 -> CYRILLIC CAPITAL LETTER EN + u'\u043e' # 0x00d6 -> CYRILLIC SMALL LETTER O + u'\u041e' # 0x00d7 -> CYRILLIC CAPITAL LETTER O + u'\u043f' # 0x00d8 -> CYRILLIC SMALL LETTER PE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u041f' # 0x00dd -> CYRILLIC CAPITAL LETTER PE + u'\u044f' # 0x00de -> CYRILLIC SMALL LETTER YA + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u042f' # 0x00e0 -> CYRILLIC CAPITAL LETTER YA + u'\u0440' # 0x00e1 -> CYRILLIC SMALL LETTER ER + u'\u0420' # 0x00e2 -> CYRILLIC CAPITAL LETTER ER + u'\u0441' # 0x00e3 -> CYRILLIC SMALL LETTER ES + u'\u0421' # 0x00e4 -> CYRILLIC CAPITAL LETTER ES + u'\u0442' # 0x00e5 -> CYRILLIC SMALL LETTER TE + u'\u0422' # 0x00e6 -> CYRILLIC CAPITAL LETTER TE + u'\u0443' # 0x00e7 -> CYRILLIC SMALL LETTER U + u'\u0423' # 0x00e8 -> CYRILLIC CAPITAL LETTER U + u'\u0436' # 0x00e9 -> CYRILLIC SMALL LETTER ZHE + u'\u0416' # 0x00ea -> CYRILLIC CAPITAL LETTER ZHE + u'\u0432' # 0x00eb -> CYRILLIC SMALL LETTER VE + u'\u0412' # 0x00ec -> CYRILLIC CAPITAL LETTER VE + u'\u044c' # 0x00ed -> CYRILLIC SMALL LETTER SOFT SIGN + u'\u042c' # 0x00ee -> CYRILLIC CAPITAL LETTER SOFT SIGN + u'\u2116' # 0x00ef -> NUMERO SIGN + u'\xad' # 0x00f0 -> SOFT HYPHEN + u'\u044b' # 0x00f1 -> CYRILLIC SMALL LETTER YERU + u'\u042b' # 0x00f2 -> CYRILLIC CAPITAL LETTER YERU + u'\u0437' # 0x00f3 -> CYRILLIC SMALL LETTER ZE + u'\u0417' # 0x00f4 -> CYRILLIC CAPITAL LETTER ZE + u'\u0448' # 0x00f5 -> CYRILLIC SMALL LETTER SHA + u'\u0428' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHA + u'\u044d' # 0x00f7 -> CYRILLIC SMALL LETTER E + u'\u042d' # 0x00f8 -> CYRILLIC CAPITAL LETTER E + u'\u0449' # 0x00f9 -> CYRILLIC SMALL LETTER SHCHA + u'\u0429' # 0x00fa -> CYRILLIC CAPITAL LETTER SHCHA + u'\u0447' # 0x00fb -> CYRILLIC SMALL LETTER CHE + u'\u0427' # 0x00fc -> CYRILLIC CAPITAL LETTER CHE + u'\xa7' # 0x00fd -> SECTION SIGN + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a7: 0x00fd, # SECTION SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x0401: 0x0085, # CYRILLIC CAPITAL LETTER IO + 0x0402: 0x0081, # CYRILLIC CAPITAL LETTER DJE + 0x0403: 0x0083, # CYRILLIC CAPITAL LETTER GJE + 0x0404: 0x0087, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0405: 0x0089, # CYRILLIC CAPITAL LETTER DZE + 0x0406: 0x008b, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0407: 0x008d, # CYRILLIC CAPITAL LETTER YI + 0x0408: 0x008f, # CYRILLIC CAPITAL LETTER JE + 0x0409: 0x0091, # CYRILLIC CAPITAL LETTER LJE + 0x040a: 0x0093, # CYRILLIC CAPITAL LETTER NJE + 0x040b: 0x0095, # CYRILLIC CAPITAL LETTER TSHE + 0x040c: 0x0097, # CYRILLIC CAPITAL LETTER KJE + 0x040e: 0x0099, # CYRILLIC CAPITAL LETTER SHORT U + 0x040f: 0x009b, # CYRILLIC CAPITAL LETTER DZHE + 0x0410: 0x00a1, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x00a3, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x00ec, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x00ad, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x00a7, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x00a9, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x00ea, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x00f4, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x00b8, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x00be, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x00c7, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x00d1, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x00d3, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x00d5, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x00d7, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x00dd, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x00e2, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x00e4, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x00e6, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x00e8, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x00ab, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x00b6, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x00a5, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x00fc, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x00f6, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x00fa, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009f, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x00f2, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x00ee, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x00f8, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009d, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x00e0, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a2, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00eb, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00ac, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a6, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a8, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00e9, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00f3, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00b7, # CYRILLIC SMALL LETTER I + 0x0439: 0x00bd, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00c6, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00d0, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00d2, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00d4, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00d6, # CYRILLIC SMALL LETTER O + 0x043f: 0x00d8, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e1, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e3, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e5, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e7, # CYRILLIC SMALL LETTER U + 0x0444: 0x00aa, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00b5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00a4, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00fb, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00f5, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00f9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x009e, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00f1, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ed, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00f7, # CYRILLIC SMALL LETTER E + 0x044e: 0x009c, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00de, # CYRILLIC SMALL LETTER YA + 0x0451: 0x0084, # CYRILLIC SMALL LETTER IO + 0x0452: 0x0080, # CYRILLIC SMALL LETTER DJE + 0x0453: 0x0082, # CYRILLIC SMALL LETTER GJE + 0x0454: 0x0086, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0455: 0x0088, # CYRILLIC SMALL LETTER DZE + 0x0456: 0x008a, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0457: 0x008c, # CYRILLIC SMALL LETTER YI + 0x0458: 0x008e, # CYRILLIC SMALL LETTER JE + 0x0459: 0x0090, # CYRILLIC SMALL LETTER LJE + 0x045a: 0x0092, # CYRILLIC SMALL LETTER NJE + 0x045b: 0x0094, # CYRILLIC SMALL LETTER TSHE + 0x045c: 0x0096, # CYRILLIC SMALL LETTER KJE + 0x045e: 0x0098, # CYRILLIC SMALL LETTER SHORT U + 0x045f: 0x009a, # CYRILLIC SMALL LETTER DZHE + 0x2116: 0x00ef, # NUMERO SIGN + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp856.py b/src/main/resources/PythonLibs/encodings/cp856.py new file mode 100644 index 0000000000000000000000000000000000000000..203c2c4ca0f9edde3bab1786719b592d624894ce --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp856.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp856 generated from 'MAPPINGS/VENDORS/MISC/CP856.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp856', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u05d0' # 0x80 -> HEBREW LETTER ALEF + u'\u05d1' # 0x81 -> HEBREW LETTER BET + u'\u05d2' # 0x82 -> HEBREW LETTER GIMEL + u'\u05d3' # 0x83 -> HEBREW LETTER DALET + u'\u05d4' # 0x84 -> HEBREW LETTER HE + u'\u05d5' # 0x85 -> HEBREW LETTER VAV + u'\u05d6' # 0x86 -> HEBREW LETTER ZAYIN + u'\u05d7' # 0x87 -> HEBREW LETTER HET + u'\u05d8' # 0x88 -> HEBREW LETTER TET + u'\u05d9' # 0x89 -> HEBREW LETTER YOD + u'\u05da' # 0x8A -> HEBREW LETTER FINAL KAF + u'\u05db' # 0x8B -> HEBREW LETTER KAF + u'\u05dc' # 0x8C -> HEBREW LETTER LAMED + u'\u05dd' # 0x8D -> HEBREW LETTER FINAL MEM + u'\u05de' # 0x8E -> HEBREW LETTER MEM + u'\u05df' # 0x8F -> HEBREW LETTER FINAL NUN + u'\u05e0' # 0x90 -> HEBREW LETTER NUN + u'\u05e1' # 0x91 -> HEBREW LETTER SAMEKH + u'\u05e2' # 0x92 -> HEBREW LETTER AYIN + u'\u05e3' # 0x93 -> HEBREW LETTER FINAL PE + u'\u05e4' # 0x94 -> HEBREW LETTER PE + u'\u05e5' # 0x95 -> HEBREW LETTER FINAL TSADI + u'\u05e6' # 0x96 -> HEBREW LETTER TSADI + u'\u05e7' # 0x97 -> HEBREW LETTER QOF + u'\u05e8' # 0x98 -> HEBREW LETTER RESH + u'\u05e9' # 0x99 -> HEBREW LETTER SHIN + u'\u05ea' # 0x9A -> HEBREW LETTER TAV + u'\ufffe' # 0x9B -> UNDEFINED + u'\xa3' # 0x9C -> POUND SIGN + u'\ufffe' # 0x9D -> UNDEFINED + u'\xd7' # 0x9E -> MULTIPLICATION SIGN + u'\ufffe' # 0x9F -> UNDEFINED + u'\ufffe' # 0xA0 -> UNDEFINED + u'\ufffe' # 0xA1 -> UNDEFINED + u'\ufffe' # 0xA2 -> UNDEFINED + u'\ufffe' # 0xA3 -> UNDEFINED + u'\ufffe' # 0xA4 -> UNDEFINED + u'\ufffe' # 0xA5 -> UNDEFINED + u'\ufffe' # 0xA6 -> UNDEFINED + u'\ufffe' # 0xA7 -> UNDEFINED + u'\ufffe' # 0xA8 -> UNDEFINED + u'\xae' # 0xA9 -> REGISTERED SIGN + u'\xac' # 0xAA -> NOT SIGN + u'\xbd' # 0xAB -> VULGAR FRACTION ONE HALF + u'\xbc' # 0xAC -> VULGAR FRACTION ONE QUARTER + u'\ufffe' # 0xAD -> UNDEFINED + u'\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0xB0 -> LIGHT SHADE + u'\u2592' # 0xB1 -> MEDIUM SHADE + u'\u2593' # 0xB2 -> DARK SHADE + u'\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\ufffe' # 0xB5 -> UNDEFINED + u'\ufffe' # 0xB6 -> UNDEFINED + u'\ufffe' # 0xB7 -> UNDEFINED + u'\xa9' # 0xB8 -> COPYRIGHT SIGN + u'\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\xa2' # 0xBD -> CENT SIGN + u'\xa5' # 0xBE -> YEN SIGN + u'\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\ufffe' # 0xC6 -> UNDEFINED + u'\ufffe' # 0xC7 -> UNDEFINED + u'\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa4' # 0xCF -> CURRENCY SIGN + u'\ufffe' # 0xD0 -> UNDEFINED + u'\ufffe' # 0xD1 -> UNDEFINED + u'\ufffe' # 0xD2 -> UNDEFINED + u'\ufffe' # 0xD3 -> UNDEFINEDS + u'\ufffe' # 0xD4 -> UNDEFINED + u'\ufffe' # 0xD5 -> UNDEFINED + u'\ufffe' # 0xD6 -> UNDEFINEDE + u'\ufffe' # 0xD7 -> UNDEFINED + u'\ufffe' # 0xD8 -> UNDEFINED + u'\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0xDB -> FULL BLOCK + u'\u2584' # 0xDC -> LOWER HALF BLOCK + u'\xa6' # 0xDD -> BROKEN BAR + u'\ufffe' # 0xDE -> UNDEFINED + u'\u2580' # 0xDF -> UPPER HALF BLOCK + u'\ufffe' # 0xE0 -> UNDEFINED + u'\ufffe' # 0xE1 -> UNDEFINED + u'\ufffe' # 0xE2 -> UNDEFINED + u'\ufffe' # 0xE3 -> UNDEFINED + u'\ufffe' # 0xE4 -> UNDEFINED + u'\ufffe' # 0xE5 -> UNDEFINED + u'\xb5' # 0xE6 -> MICRO SIGN + u'\ufffe' # 0xE7 -> UNDEFINED + u'\ufffe' # 0xE8 -> UNDEFINED + u'\ufffe' # 0xE9 -> UNDEFINED + u'\ufffe' # 0xEA -> UNDEFINED + u'\ufffe' # 0xEB -> UNDEFINED + u'\ufffe' # 0xEC -> UNDEFINED + u'\ufffe' # 0xED -> UNDEFINED + u'\xaf' # 0xEE -> MACRON + u'\xb4' # 0xEF -> ACUTE ACCENT + u'\xad' # 0xF0 -> SOFT HYPHEN + u'\xb1' # 0xF1 -> PLUS-MINUS SIGN + u'\u2017' # 0xF2 -> DOUBLE LOW LINE + u'\xbe' # 0xF3 -> VULGAR FRACTION THREE QUARTERS + u'\xb6' # 0xF4 -> PILCROW SIGN + u'\xa7' # 0xF5 -> SECTION SIGN + u'\xf7' # 0xF6 -> DIVISION SIGN + u'\xb8' # 0xF7 -> CEDILLA + u'\xb0' # 0xF8 -> DEGREE SIGN + u'\xa8' # 0xF9 -> DIAERESIS + u'\xb7' # 0xFA -> MIDDLE DOT + u'\xb9' # 0xFB -> SUPERSCRIPT ONE + u'\xb3' # 0xFC -> SUPERSCRIPT THREE + u'\xb2' # 0xFD -> SUPERSCRIPT TWO + u'\u25a0' # 0xFE -> BLACK SQUARE + u'\xa0' # 0xFF -> NO-BREAK SPACE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp857.py b/src/main/resources/PythonLibs/encodings/cp857.py new file mode 100644 index 0000000000000000000000000000000000000000..c24191b04dc40f4b9544fe49c6a19b1512f5d851 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp857.py @@ -0,0 +1,694 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP857.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp857', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x0131, # LATIN SMALL LETTER DOTLESS I + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x009f: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x011e, # LATIN CAPITAL LETTER G WITH BREVE + 0x00a7: 0x011f, # LATIN SMALL LETTER G WITH BREVE + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00d1: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: None, # UNDEFINED + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: None, # UNDEFINED + 0x00e8: 0x00d7, # MULTIPLICATION SIGN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ed: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: None, # UNDEFINED + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\u0131' # 0x008d -> LATIN SMALL LETTER DOTLESS I + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + u'\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + u'\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + u'\u0130' # 0x0098 -> LATIN CAPITAL LETTER I WITH DOT ABOVE + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + u'\xa3' # 0x009c -> POUND SIGN + u'\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + u'\u015e' # 0x009e -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\u015f' # 0x009f -> LATIN SMALL LETTER S WITH CEDILLA + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + u'\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + u'\u011e' # 0x00a6 -> LATIN CAPITAL LETTER G WITH BREVE + u'\u011f' # 0x00a7 -> LATIN SMALL LETTER G WITH BREVE + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\xae' # 0x00a9 -> REGISTERED SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xa9' # 0x00b8 -> COPYRIGHT SIGN + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\xa2' # 0x00bd -> CENT SIGN + u'\xa5' # 0x00be -> YEN SIGN + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + u'\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa4' # 0x00cf -> CURRENCY SIGN + u'\xba' # 0x00d0 -> MASCULINE ORDINAL INDICATOR + u'\xaa' # 0x00d1 -> FEMININE ORDINAL INDICATOR + u'\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\ufffe' # 0x00d5 -> UNDEFINED + u'\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\xa6' # 0x00dd -> BROKEN BAR + u'\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + u'\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\ufffe' # 0x00e7 -> UNDEFINED + u'\xd7' # 0x00e8 -> MULTIPLICATION SIGN + u'\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xec' # 0x00ec -> LATIN SMALL LETTER I WITH GRAVE + u'\xff' # 0x00ed -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\xaf' # 0x00ee -> MACRON + u'\xb4' # 0x00ef -> ACUTE ACCENT + u'\xad' # 0x00f0 -> SOFT HYPHEN + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\ufffe' # 0x00f2 -> UNDEFINED + u'\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + u'\xb6' # 0x00f4 -> PILCROW SIGN + u'\xa7' # 0x00f5 -> SECTION SIGN + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\xb8' # 0x00f7 -> CEDILLA + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\xa8' # 0x00f9 -> DIAERESIS + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\xb9' # 0x00fb -> SUPERSCRIPT ONE + u'\xb3' # 0x00fc -> SUPERSCRIPT THREE + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00d1, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00d0, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x00e8, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x00ed, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x011e: 0x00a6, # LATIN CAPITAL LETTER G WITH BREVE + 0x011f: 0x00a7, # LATIN SMALL LETTER G WITH BREVE + 0x0130: 0x0098, # LATIN CAPITAL LETTER I WITH DOT ABOVE + 0x0131: 0x008d, # LATIN SMALL LETTER DOTLESS I + 0x015e: 0x009e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x015f: 0x009f, # LATIN SMALL LETTER S WITH CEDILLA + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp858.py b/src/main/resources/PythonLibs/encodings/cp858.py new file mode 100644 index 0000000000000000000000000000000000000000..7ba7621f8fbe2091a1f383c050393aea49e00d2a --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp858.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec for CP858, modified from cp850. + +""" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp858', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH + 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: 0x20ac, # EURO SIGN + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN + 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2017, # DOUBLE LOW LINE + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + u'\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + u'\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + u'\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + u'\xa3' # 0x009c -> POUND SIGN + u'\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd7' # 0x009e -> MULTIPLICATION SIGN + u'\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + u'\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\xae' # 0x00a9 -> REGISTERED SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xa9' # 0x00b8 -> COPYRIGHT SIGN + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\xa2' # 0x00bd -> CENT SIGN + u'\xa5' # 0x00be -> YEN SIGN + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + u'\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa4' # 0x00cf -> CURRENCY SIGN + u'\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH + u'\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH + u'\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\u20ac' # 0x00d5 -> EURO SIGN + u'\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\xa6' # 0x00dd -> BROKEN BAR + u'\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + u'\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN + u'\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN + u'\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + u'\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xaf' # 0x00ee -> MACRON + u'\xb4' # 0x00ef -> ACUTE ACCENT + u'\xad' # 0x00f0 -> SOFT HYPHEN + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2017' # 0x00f2 -> DOUBLE LOW LINE + u'\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + u'\xb6' # 0x00f4 -> PILCROW SIGN + u'\xa7' # 0x00f5 -> SECTION SIGN + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\xb8' # 0x00f7 -> CEDILLA + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\xa8' # 0x00f9 -> DIAERESIS + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\xb9' # 0x00fb -> SUPERSCRIPT ONE + u'\xb3' # 0x00fc -> SUPERSCRIPT THREE + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x20ac: 0x00d5, # EURO SIGN + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x2017: 0x00f2, # DOUBLE LOW LINE + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp860.py b/src/main/resources/PythonLibs/encodings/cp860.py new file mode 100644 index 0000000000000000000000000000000000000000..4acb0cf36269eff1ff4ba7b4806c0db8fbde1146 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp860.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP860.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp860', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x008c: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x008f: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x0092: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x0099: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0x0084 -> LATIN SMALL LETTER A WITH TILDE + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xc1' # 0x0086 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xca' # 0x0089 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xcd' # 0x008b -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xd4' # 0x008c -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + u'\xc3' # 0x008e -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc2' # 0x008f -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xc0' # 0x0091 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc8' # 0x0092 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0x0094 -> LATIN SMALL LETTER O WITH TILDE + u'\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + u'\xda' # 0x0096 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + u'\xcc' # 0x0098 -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xd5' # 0x0099 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xa2' # 0x009b -> CENT SIGN + u'\xa3' # 0x009c -> POUND SIGN + u'\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE + u'\u20a7' # 0x009e -> PESETA SIGN + u'\xd3' # 0x009f -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + u'\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\xd2' # 0x00a9 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + u'\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + u'\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + u'\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + u'\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + u'\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + u'\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + u'\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + u'\u221e' # 0x00ec -> INFINITY + u'\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + u'\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + u'\u2229' # 0x00ef -> INTERSECTION + u'\u2261' # 0x00f0 -> IDENTICAL TO + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + u'\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + u'\u2320' # 0x00f4 -> TOP HALF INTEGRAL + u'\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u2248' # 0x00f7 -> ALMOST EQUAL TO + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x0091, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x0086, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x008f, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x008e, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x0092, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x0089, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cc: 0x0098, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x008b, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00a9, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x009f, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x008c, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x0099, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x0096, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x0084, # LATIN SMALL LETTER A WITH TILDE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x0094, # LATIN SMALL LETTER O WITH TILDE + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp861.py b/src/main/resources/PythonLibs/encodings/cp861.py new file mode 100644 index 0000000000000000000000000000000000000000..0939b5b1eefcb2033be8a26d2462d2263093fdb6 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp861.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP861.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp861', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x008c: 0x00f0, # LATIN SMALL LETTER ETH + 0x008d: 0x00de, # LATIN CAPITAL LETTER THORN + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00fe, # LATIN SMALL LETTER THORN + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x0098: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00a5: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00a6: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00a7: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xd0' # 0x008b -> LATIN CAPITAL LETTER ETH + u'\xf0' # 0x008c -> LATIN SMALL LETTER ETH + u'\xde' # 0x008d -> LATIN CAPITAL LETTER THORN + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + u'\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xfe' # 0x0095 -> LATIN SMALL LETTER THORN + u'\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xdd' # 0x0097 -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xfd' # 0x0098 -> LATIN SMALL LETTER Y WITH ACUTE + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + u'\xa3' # 0x009c -> POUND SIGN + u'\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + u'\u20a7' # 0x009e -> PESETA SIGN + u'\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xc1' # 0x00a4 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xcd' # 0x00a5 -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xd3' # 0x00a6 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xda' # 0x00a7 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\u2310' # 0x00a9 -> REVERSED NOT SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + u'\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + u'\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + u'\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + u'\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + u'\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + u'\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + u'\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + u'\u221e' # 0x00ec -> INFINITY + u'\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + u'\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + u'\u2229' # 0x00ef -> INTERSECTION + u'\u2261' # 0x00f0 -> IDENTICAL TO + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + u'\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + u'\u2320' # 0x00f4 -> TOP HALF INTEGRAL + u'\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u2248' # 0x00f7 -> ALMOST EQUAL TO + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a3: 0x009c, # POUND SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c1: 0x00a4, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00cd: 0x00a5, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d0: 0x008b, # LATIN CAPITAL LETTER ETH + 0x00d3: 0x00a6, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00da: 0x00a7, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x0097, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x008d, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f0: 0x008c, # LATIN SMALL LETTER ETH + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x0098, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x0095, # LATIN SMALL LETTER THORN + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp862.py b/src/main/resources/PythonLibs/encodings/cp862.py new file mode 100644 index 0000000000000000000000000000000000000000..ea0405ca1ba4c2e280afefc2d4050c35e8077b48 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp862.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP862.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp862', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x05d0, # HEBREW LETTER ALEF + 0x0081: 0x05d1, # HEBREW LETTER BET + 0x0082: 0x05d2, # HEBREW LETTER GIMEL + 0x0083: 0x05d3, # HEBREW LETTER DALET + 0x0084: 0x05d4, # HEBREW LETTER HE + 0x0085: 0x05d5, # HEBREW LETTER VAV + 0x0086: 0x05d6, # HEBREW LETTER ZAYIN + 0x0087: 0x05d7, # HEBREW LETTER HET + 0x0088: 0x05d8, # HEBREW LETTER TET + 0x0089: 0x05d9, # HEBREW LETTER YOD + 0x008a: 0x05da, # HEBREW LETTER FINAL KAF + 0x008b: 0x05db, # HEBREW LETTER KAF + 0x008c: 0x05dc, # HEBREW LETTER LAMED + 0x008d: 0x05dd, # HEBREW LETTER FINAL MEM + 0x008e: 0x05de, # HEBREW LETTER MEM + 0x008f: 0x05df, # HEBREW LETTER FINAL NUN + 0x0090: 0x05e0, # HEBREW LETTER NUN + 0x0091: 0x05e1, # HEBREW LETTER SAMEKH + 0x0092: 0x05e2, # HEBREW LETTER AYIN + 0x0093: 0x05e3, # HEBREW LETTER FINAL PE + 0x0094: 0x05e4, # HEBREW LETTER PE + 0x0095: 0x05e5, # HEBREW LETTER FINAL TSADI + 0x0096: 0x05e6, # HEBREW LETTER TSADI + 0x0097: 0x05e7, # HEBREW LETTER QOF + 0x0098: 0x05e8, # HEBREW LETTER RESH + 0x0099: 0x05e9, # HEBREW LETTER SHIN + 0x009a: 0x05ea, # HEBREW LETTER TAV + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00a5, # YEN SIGN + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\u05d0' # 0x0080 -> HEBREW LETTER ALEF + u'\u05d1' # 0x0081 -> HEBREW LETTER BET + u'\u05d2' # 0x0082 -> HEBREW LETTER GIMEL + u'\u05d3' # 0x0083 -> HEBREW LETTER DALET + u'\u05d4' # 0x0084 -> HEBREW LETTER HE + u'\u05d5' # 0x0085 -> HEBREW LETTER VAV + u'\u05d6' # 0x0086 -> HEBREW LETTER ZAYIN + u'\u05d7' # 0x0087 -> HEBREW LETTER HET + u'\u05d8' # 0x0088 -> HEBREW LETTER TET + u'\u05d9' # 0x0089 -> HEBREW LETTER YOD + u'\u05da' # 0x008a -> HEBREW LETTER FINAL KAF + u'\u05db' # 0x008b -> HEBREW LETTER KAF + u'\u05dc' # 0x008c -> HEBREW LETTER LAMED + u'\u05dd' # 0x008d -> HEBREW LETTER FINAL MEM + u'\u05de' # 0x008e -> HEBREW LETTER MEM + u'\u05df' # 0x008f -> HEBREW LETTER FINAL NUN + u'\u05e0' # 0x0090 -> HEBREW LETTER NUN + u'\u05e1' # 0x0091 -> HEBREW LETTER SAMEKH + u'\u05e2' # 0x0092 -> HEBREW LETTER AYIN + u'\u05e3' # 0x0093 -> HEBREW LETTER FINAL PE + u'\u05e4' # 0x0094 -> HEBREW LETTER PE + u'\u05e5' # 0x0095 -> HEBREW LETTER FINAL TSADI + u'\u05e6' # 0x0096 -> HEBREW LETTER TSADI + u'\u05e7' # 0x0097 -> HEBREW LETTER QOF + u'\u05e8' # 0x0098 -> HEBREW LETTER RESH + u'\u05e9' # 0x0099 -> HEBREW LETTER SHIN + u'\u05ea' # 0x009a -> HEBREW LETTER TAV + u'\xa2' # 0x009b -> CENT SIGN + u'\xa3' # 0x009c -> POUND SIGN + u'\xa5' # 0x009d -> YEN SIGN + u'\u20a7' # 0x009e -> PESETA SIGN + u'\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + u'\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\u2310' # 0x00a9 -> REVERSED NOT SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) + u'\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + u'\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + u'\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + u'\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + u'\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + u'\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + u'\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + u'\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + u'\u221e' # 0x00ec -> INFINITY + u'\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + u'\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + u'\u2229' # 0x00ef -> INTERSECTION + u'\u2261' # 0x00f0 -> IDENTICAL TO + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + u'\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + u'\u2320' # 0x00f4 -> TOP HALF INTEGRAL + u'\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u2248' # 0x00f7 -> ALMOST EQUAL TO + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a5: 0x009d, # YEN SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x05d0: 0x0080, # HEBREW LETTER ALEF + 0x05d1: 0x0081, # HEBREW LETTER BET + 0x05d2: 0x0082, # HEBREW LETTER GIMEL + 0x05d3: 0x0083, # HEBREW LETTER DALET + 0x05d4: 0x0084, # HEBREW LETTER HE + 0x05d5: 0x0085, # HEBREW LETTER VAV + 0x05d6: 0x0086, # HEBREW LETTER ZAYIN + 0x05d7: 0x0087, # HEBREW LETTER HET + 0x05d8: 0x0088, # HEBREW LETTER TET + 0x05d9: 0x0089, # HEBREW LETTER YOD + 0x05da: 0x008a, # HEBREW LETTER FINAL KAF + 0x05db: 0x008b, # HEBREW LETTER KAF + 0x05dc: 0x008c, # HEBREW LETTER LAMED + 0x05dd: 0x008d, # HEBREW LETTER FINAL MEM + 0x05de: 0x008e, # HEBREW LETTER MEM + 0x05df: 0x008f, # HEBREW LETTER FINAL NUN + 0x05e0: 0x0090, # HEBREW LETTER NUN + 0x05e1: 0x0091, # HEBREW LETTER SAMEKH + 0x05e2: 0x0092, # HEBREW LETTER AYIN + 0x05e3: 0x0093, # HEBREW LETTER FINAL PE + 0x05e4: 0x0094, # HEBREW LETTER PE + 0x05e5: 0x0095, # HEBREW LETTER FINAL TSADI + 0x05e6: 0x0096, # HEBREW LETTER TSADI + 0x05e7: 0x0097, # HEBREW LETTER QOF + 0x05e8: 0x0098, # HEBREW LETTER RESH + 0x05e9: 0x0099, # HEBREW LETTER SHIN + 0x05ea: 0x009a, # HEBREW LETTER TAV + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp863.py b/src/main/resources/PythonLibs/encodings/cp863.py new file mode 100644 index 0000000000000000000000000000000000000000..62dfabf66ab0d19644b626f1638d4a5c8ef3a7ab --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp863.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP863.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp863', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00b6, # PILCROW SIGN + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x2017, # DOUBLE LOW LINE + 0x008e: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x008f: 0x00a7, # SECTION SIGN + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x0092: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x0095: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00a4, # CURRENCY SIGN + 0x0099: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x009e: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00a6, # BROKEN BAR + 0x00a1: 0x00b4, # ACUTE ACCENT + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00a8, # DIAERESIS + 0x00a5: 0x00b8, # CEDILLA + 0x00a6: 0x00b3, # SUPERSCRIPT THREE + 0x00a7: 0x00af, # MACRON + 0x00a8: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xc2' # 0x0084 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xb6' # 0x0086 -> PILCROW SIGN + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\u2017' # 0x008d -> DOUBLE LOW LINE + u'\xc0' # 0x008e -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xa7' # 0x008f -> SECTION SIGN + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xc8' # 0x0091 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xca' # 0x0092 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xcb' # 0x0094 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcf' # 0x0095 -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + u'\xa4' # 0x0098 -> CURRENCY SIGN + u'\xd4' # 0x0099 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xa2' # 0x009b -> CENT SIGN + u'\xa3' # 0x009c -> POUND SIGN + u'\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xdb' # 0x009e -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + u'\xa6' # 0x00a0 -> BROKEN BAR + u'\xb4' # 0x00a1 -> ACUTE ACCENT + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xa8' # 0x00a4 -> DIAERESIS + u'\xb8' # 0x00a5 -> CEDILLA + u'\xb3' # 0x00a6 -> SUPERSCRIPT THREE + u'\xaf' # 0x00a7 -> MACRON + u'\xce' # 0x00a8 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\u2310' # 0x00a9 -> REVERSED NOT SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xbe' # 0x00ad -> VULGAR FRACTION THREE QUARTERS + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + u'\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + u'\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + u'\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + u'\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + u'\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + u'\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + u'\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + u'\u221e' # 0x00ec -> INFINITY + u'\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + u'\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + u'\u2229' # 0x00ef -> INTERSECTION + u'\u2261' # 0x00f0 -> IDENTICAL TO + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + u'\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + u'\u2320' # 0x00f4 -> TOP HALF INTEGRAL + u'\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u2248' # 0x00f7 -> ALMOST EQUAL TO + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x0098, # CURRENCY SIGN + 0x00a6: 0x00a0, # BROKEN BAR + 0x00a7: 0x008f, # SECTION SIGN + 0x00a8: 0x00a4, # DIAERESIS + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00af: 0x00a7, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00a6, # SUPERSCRIPT THREE + 0x00b4: 0x00a1, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x0086, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00a5, # CEDILLA + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00ad, # VULGAR FRACTION THREE QUARTERS + 0x00c0: 0x008e, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c2: 0x0084, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x0091, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x0092, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x0094, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00ce: 0x00a8, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x0095, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d4: 0x0099, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00db: 0x009e, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x2017: 0x008d, # DOUBLE LOW LINE + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp864.py b/src/main/resources/PythonLibs/encodings/cp864.py new file mode 100644 index 0000000000000000000000000000000000000000..02a0e733a8733743343bad41f0c4c4c77dfe86eb --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp864.py @@ -0,0 +1,690 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP864.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp864', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0025: 0x066a, # ARABIC PERCENT SIGN + 0x0080: 0x00b0, # DEGREE SIGN + 0x0081: 0x00b7, # MIDDLE DOT + 0x0082: 0x2219, # BULLET OPERATOR + 0x0083: 0x221a, # SQUARE ROOT + 0x0084: 0x2592, # MEDIUM SHADE + 0x0085: 0x2500, # FORMS LIGHT HORIZONTAL + 0x0086: 0x2502, # FORMS LIGHT VERTICAL + 0x0087: 0x253c, # FORMS LIGHT VERTICAL AND HORIZONTAL + 0x0088: 0x2524, # FORMS LIGHT VERTICAL AND LEFT + 0x0089: 0x252c, # FORMS LIGHT DOWN AND HORIZONTAL + 0x008a: 0x251c, # FORMS LIGHT VERTICAL AND RIGHT + 0x008b: 0x2534, # FORMS LIGHT UP AND HORIZONTAL + 0x008c: 0x2510, # FORMS LIGHT DOWN AND LEFT + 0x008d: 0x250c, # FORMS LIGHT DOWN AND RIGHT + 0x008e: 0x2514, # FORMS LIGHT UP AND RIGHT + 0x008f: 0x2518, # FORMS LIGHT UP AND LEFT + 0x0090: 0x03b2, # GREEK SMALL BETA + 0x0091: 0x221e, # INFINITY + 0x0092: 0x03c6, # GREEK SMALL PHI + 0x0093: 0x00b1, # PLUS-OR-MINUS SIGN + 0x0094: 0x00bd, # FRACTION 1/2 + 0x0095: 0x00bc, # FRACTION 1/4 + 0x0096: 0x2248, # ALMOST EQUAL TO + 0x0097: 0x00ab, # LEFT POINTING GUILLEMET + 0x0098: 0x00bb, # RIGHT POINTING GUILLEMET + 0x0099: 0xfef7, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + 0x009a: 0xfef8, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + 0x009b: None, # UNDEFINED + 0x009c: None, # UNDEFINED + 0x009d: 0xfefb, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + 0x009e: 0xfefc, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM + 0x009f: None, # UNDEFINED + 0x00a1: 0x00ad, # SOFT HYPHEN + 0x00a2: 0xfe82, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + 0x00a5: 0xfe84, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + 0x00a6: None, # UNDEFINED + 0x00a7: None, # UNDEFINED + 0x00a8: 0xfe8e, # ARABIC LETTER ALEF FINAL FORM + 0x00a9: 0xfe8f, # ARABIC LETTER BEH ISOLATED FORM + 0x00aa: 0xfe95, # ARABIC LETTER TEH ISOLATED FORM + 0x00ab: 0xfe99, # ARABIC LETTER THEH ISOLATED FORM + 0x00ac: 0x060c, # ARABIC COMMA + 0x00ad: 0xfe9d, # ARABIC LETTER JEEM ISOLATED FORM + 0x00ae: 0xfea1, # ARABIC LETTER HAH ISOLATED FORM + 0x00af: 0xfea5, # ARABIC LETTER KHAH ISOLATED FORM + 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO + 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE + 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO + 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE + 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR + 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE + 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX + 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN + 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT + 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE + 0x00ba: 0xfed1, # ARABIC LETTER FEH ISOLATED FORM + 0x00bb: 0x061b, # ARABIC SEMICOLON + 0x00bc: 0xfeb1, # ARABIC LETTER SEEN ISOLATED FORM + 0x00bd: 0xfeb5, # ARABIC LETTER SHEEN ISOLATED FORM + 0x00be: 0xfeb9, # ARABIC LETTER SAD ISOLATED FORM + 0x00bf: 0x061f, # ARABIC QUESTION MARK + 0x00c0: 0x00a2, # CENT SIGN + 0x00c1: 0xfe80, # ARABIC LETTER HAMZA ISOLATED FORM + 0x00c2: 0xfe81, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + 0x00c3: 0xfe83, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + 0x00c4: 0xfe85, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + 0x00c5: 0xfeca, # ARABIC LETTER AIN FINAL FORM + 0x00c6: 0xfe8b, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + 0x00c7: 0xfe8d, # ARABIC LETTER ALEF ISOLATED FORM + 0x00c8: 0xfe91, # ARABIC LETTER BEH INITIAL FORM + 0x00c9: 0xfe93, # ARABIC LETTER TEH MARBUTA ISOLATED FORM + 0x00ca: 0xfe97, # ARABIC LETTER TEH INITIAL FORM + 0x00cb: 0xfe9b, # ARABIC LETTER THEH INITIAL FORM + 0x00cc: 0xfe9f, # ARABIC LETTER JEEM INITIAL FORM + 0x00cd: 0xfea3, # ARABIC LETTER HAH INITIAL FORM + 0x00ce: 0xfea7, # ARABIC LETTER KHAH INITIAL FORM + 0x00cf: 0xfea9, # ARABIC LETTER DAL ISOLATED FORM + 0x00d0: 0xfeab, # ARABIC LETTER THAL ISOLATED FORM + 0x00d1: 0xfead, # ARABIC LETTER REH ISOLATED FORM + 0x00d2: 0xfeaf, # ARABIC LETTER ZAIN ISOLATED FORM + 0x00d3: 0xfeb3, # ARABIC LETTER SEEN INITIAL FORM + 0x00d4: 0xfeb7, # ARABIC LETTER SHEEN INITIAL FORM + 0x00d5: 0xfebb, # ARABIC LETTER SAD INITIAL FORM + 0x00d6: 0xfebf, # ARABIC LETTER DAD INITIAL FORM + 0x00d7: 0xfec1, # ARABIC LETTER TAH ISOLATED FORM + 0x00d8: 0xfec5, # ARABIC LETTER ZAH ISOLATED FORM + 0x00d9: 0xfecb, # ARABIC LETTER AIN INITIAL FORM + 0x00da: 0xfecf, # ARABIC LETTER GHAIN INITIAL FORM + 0x00db: 0x00a6, # BROKEN VERTICAL BAR + 0x00dc: 0x00ac, # NOT SIGN + 0x00dd: 0x00f7, # DIVISION SIGN + 0x00de: 0x00d7, # MULTIPLICATION SIGN + 0x00df: 0xfec9, # ARABIC LETTER AIN ISOLATED FORM + 0x00e0: 0x0640, # ARABIC TATWEEL + 0x00e1: 0xfed3, # ARABIC LETTER FEH INITIAL FORM + 0x00e2: 0xfed7, # ARABIC LETTER QAF INITIAL FORM + 0x00e3: 0xfedb, # ARABIC LETTER KAF INITIAL FORM + 0x00e4: 0xfedf, # ARABIC LETTER LAM INITIAL FORM + 0x00e5: 0xfee3, # ARABIC LETTER MEEM INITIAL FORM + 0x00e6: 0xfee7, # ARABIC LETTER NOON INITIAL FORM + 0x00e7: 0xfeeb, # ARABIC LETTER HEH INITIAL FORM + 0x00e8: 0xfeed, # ARABIC LETTER WAW ISOLATED FORM + 0x00e9: 0xfeef, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM + 0x00ea: 0xfef3, # ARABIC LETTER YEH INITIAL FORM + 0x00eb: 0xfebd, # ARABIC LETTER DAD ISOLATED FORM + 0x00ec: 0xfecc, # ARABIC LETTER AIN MEDIAL FORM + 0x00ed: 0xfece, # ARABIC LETTER GHAIN FINAL FORM + 0x00ee: 0xfecd, # ARABIC LETTER GHAIN ISOLATED FORM + 0x00ef: 0xfee1, # ARABIC LETTER MEEM ISOLATED FORM + 0x00f0: 0xfe7d, # ARABIC SHADDA MEDIAL FORM + 0x00f1: 0x0651, # ARABIC SHADDAH + 0x00f2: 0xfee5, # ARABIC LETTER NOON ISOLATED FORM + 0x00f3: 0xfee9, # ARABIC LETTER HEH ISOLATED FORM + 0x00f4: 0xfeec, # ARABIC LETTER HEH MEDIAL FORM + 0x00f5: 0xfef0, # ARABIC LETTER ALEF MAKSURA FINAL FORM + 0x00f6: 0xfef2, # ARABIC LETTER YEH FINAL FORM + 0x00f7: 0xfed0, # ARABIC LETTER GHAIN MEDIAL FORM + 0x00f8: 0xfed5, # ARABIC LETTER QAF ISOLATED FORM + 0x00f9: 0xfef5, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + 0x00fa: 0xfef6, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + 0x00fb: 0xfedd, # ARABIC LETTER LAM ISOLATED FORM + 0x00fc: 0xfed9, # ARABIC LETTER KAF ISOLATED FORM + 0x00fd: 0xfef1, # ARABIC LETTER YEH ISOLATED FORM + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: None, # UNDEFINED +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'\u066a' # 0x0025 -> ARABIC PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xb0' # 0x0080 -> DEGREE SIGN + u'\xb7' # 0x0081 -> MIDDLE DOT + u'\u2219' # 0x0082 -> BULLET OPERATOR + u'\u221a' # 0x0083 -> SQUARE ROOT + u'\u2592' # 0x0084 -> MEDIUM SHADE + u'\u2500' # 0x0085 -> FORMS LIGHT HORIZONTAL + u'\u2502' # 0x0086 -> FORMS LIGHT VERTICAL + u'\u253c' # 0x0087 -> FORMS LIGHT VERTICAL AND HORIZONTAL + u'\u2524' # 0x0088 -> FORMS LIGHT VERTICAL AND LEFT + u'\u252c' # 0x0089 -> FORMS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x008a -> FORMS LIGHT VERTICAL AND RIGHT + u'\u2534' # 0x008b -> FORMS LIGHT UP AND HORIZONTAL + u'\u2510' # 0x008c -> FORMS LIGHT DOWN AND LEFT + u'\u250c' # 0x008d -> FORMS LIGHT DOWN AND RIGHT + u'\u2514' # 0x008e -> FORMS LIGHT UP AND RIGHT + u'\u2518' # 0x008f -> FORMS LIGHT UP AND LEFT + u'\u03b2' # 0x0090 -> GREEK SMALL BETA + u'\u221e' # 0x0091 -> INFINITY + u'\u03c6' # 0x0092 -> GREEK SMALL PHI + u'\xb1' # 0x0093 -> PLUS-OR-MINUS SIGN + u'\xbd' # 0x0094 -> FRACTION 1/2 + u'\xbc' # 0x0095 -> FRACTION 1/4 + u'\u2248' # 0x0096 -> ALMOST EQUAL TO + u'\xab' # 0x0097 -> LEFT POINTING GUILLEMET + u'\xbb' # 0x0098 -> RIGHT POINTING GUILLEMET + u'\ufef7' # 0x0099 -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + u'\ufef8' # 0x009a -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + u'\ufffe' # 0x009b -> UNDEFINED + u'\ufffe' # 0x009c -> UNDEFINED + u'\ufefb' # 0x009d -> ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + u'\ufefc' # 0x009e -> ARABIC LIGATURE LAM WITH ALEF FINAL FORM + u'\ufffe' # 0x009f -> UNDEFINED + u'\xa0' # 0x00a0 -> NON-BREAKING SPACE + u'\xad' # 0x00a1 -> SOFT HYPHEN + u'\ufe82' # 0x00a2 -> ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + u'\xa3' # 0x00a3 -> POUND SIGN + u'\xa4' # 0x00a4 -> CURRENCY SIGN + u'\ufe84' # 0x00a5 -> ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + u'\ufffe' # 0x00a6 -> UNDEFINED + u'\ufffe' # 0x00a7 -> UNDEFINED + u'\ufe8e' # 0x00a8 -> ARABIC LETTER ALEF FINAL FORM + u'\ufe8f' # 0x00a9 -> ARABIC LETTER BEH ISOLATED FORM + u'\ufe95' # 0x00aa -> ARABIC LETTER TEH ISOLATED FORM + u'\ufe99' # 0x00ab -> ARABIC LETTER THEH ISOLATED FORM + u'\u060c' # 0x00ac -> ARABIC COMMA + u'\ufe9d' # 0x00ad -> ARABIC LETTER JEEM ISOLATED FORM + u'\ufea1' # 0x00ae -> ARABIC LETTER HAH ISOLATED FORM + u'\ufea5' # 0x00af -> ARABIC LETTER KHAH ISOLATED FORM + u'\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO + u'\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE + u'\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO + u'\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE + u'\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR + u'\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE + u'\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX + u'\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN + u'\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT + u'\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE + u'\ufed1' # 0x00ba -> ARABIC LETTER FEH ISOLATED FORM + u'\u061b' # 0x00bb -> ARABIC SEMICOLON + u'\ufeb1' # 0x00bc -> ARABIC LETTER SEEN ISOLATED FORM + u'\ufeb5' # 0x00bd -> ARABIC LETTER SHEEN ISOLATED FORM + u'\ufeb9' # 0x00be -> ARABIC LETTER SAD ISOLATED FORM + u'\u061f' # 0x00bf -> ARABIC QUESTION MARK + u'\xa2' # 0x00c0 -> CENT SIGN + u'\ufe80' # 0x00c1 -> ARABIC LETTER HAMZA ISOLATED FORM + u'\ufe81' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + u'\ufe83' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + u'\ufe85' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + u'\ufeca' # 0x00c5 -> ARABIC LETTER AIN FINAL FORM + u'\ufe8b' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + u'\ufe8d' # 0x00c7 -> ARABIC LETTER ALEF ISOLATED FORM + u'\ufe91' # 0x00c8 -> ARABIC LETTER BEH INITIAL FORM + u'\ufe93' # 0x00c9 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM + u'\ufe97' # 0x00ca -> ARABIC LETTER TEH INITIAL FORM + u'\ufe9b' # 0x00cb -> ARABIC LETTER THEH INITIAL FORM + u'\ufe9f' # 0x00cc -> ARABIC LETTER JEEM INITIAL FORM + u'\ufea3' # 0x00cd -> ARABIC LETTER HAH INITIAL FORM + u'\ufea7' # 0x00ce -> ARABIC LETTER KHAH INITIAL FORM + u'\ufea9' # 0x00cf -> ARABIC LETTER DAL ISOLATED FORM + u'\ufeab' # 0x00d0 -> ARABIC LETTER THAL ISOLATED FORM + u'\ufead' # 0x00d1 -> ARABIC LETTER REH ISOLATED FORM + u'\ufeaf' # 0x00d2 -> ARABIC LETTER ZAIN ISOLATED FORM + u'\ufeb3' # 0x00d3 -> ARABIC LETTER SEEN INITIAL FORM + u'\ufeb7' # 0x00d4 -> ARABIC LETTER SHEEN INITIAL FORM + u'\ufebb' # 0x00d5 -> ARABIC LETTER SAD INITIAL FORM + u'\ufebf' # 0x00d6 -> ARABIC LETTER DAD INITIAL FORM + u'\ufec1' # 0x00d7 -> ARABIC LETTER TAH ISOLATED FORM + u'\ufec5' # 0x00d8 -> ARABIC LETTER ZAH ISOLATED FORM + u'\ufecb' # 0x00d9 -> ARABIC LETTER AIN INITIAL FORM + u'\ufecf' # 0x00da -> ARABIC LETTER GHAIN INITIAL FORM + u'\xa6' # 0x00db -> BROKEN VERTICAL BAR + u'\xac' # 0x00dc -> NOT SIGN + u'\xf7' # 0x00dd -> DIVISION SIGN + u'\xd7' # 0x00de -> MULTIPLICATION SIGN + u'\ufec9' # 0x00df -> ARABIC LETTER AIN ISOLATED FORM + u'\u0640' # 0x00e0 -> ARABIC TATWEEL + u'\ufed3' # 0x00e1 -> ARABIC LETTER FEH INITIAL FORM + u'\ufed7' # 0x00e2 -> ARABIC LETTER QAF INITIAL FORM + u'\ufedb' # 0x00e3 -> ARABIC LETTER KAF INITIAL FORM + u'\ufedf' # 0x00e4 -> ARABIC LETTER LAM INITIAL FORM + u'\ufee3' # 0x00e5 -> ARABIC LETTER MEEM INITIAL FORM + u'\ufee7' # 0x00e6 -> ARABIC LETTER NOON INITIAL FORM + u'\ufeeb' # 0x00e7 -> ARABIC LETTER HEH INITIAL FORM + u'\ufeed' # 0x00e8 -> ARABIC LETTER WAW ISOLATED FORM + u'\ufeef' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA ISOLATED FORM + u'\ufef3' # 0x00ea -> ARABIC LETTER YEH INITIAL FORM + u'\ufebd' # 0x00eb -> ARABIC LETTER DAD ISOLATED FORM + u'\ufecc' # 0x00ec -> ARABIC LETTER AIN MEDIAL FORM + u'\ufece' # 0x00ed -> ARABIC LETTER GHAIN FINAL FORM + u'\ufecd' # 0x00ee -> ARABIC LETTER GHAIN ISOLATED FORM + u'\ufee1' # 0x00ef -> ARABIC LETTER MEEM ISOLATED FORM + u'\ufe7d' # 0x00f0 -> ARABIC SHADDA MEDIAL FORM + u'\u0651' # 0x00f1 -> ARABIC SHADDAH + u'\ufee5' # 0x00f2 -> ARABIC LETTER NOON ISOLATED FORM + u'\ufee9' # 0x00f3 -> ARABIC LETTER HEH ISOLATED FORM + u'\ufeec' # 0x00f4 -> ARABIC LETTER HEH MEDIAL FORM + u'\ufef0' # 0x00f5 -> ARABIC LETTER ALEF MAKSURA FINAL FORM + u'\ufef2' # 0x00f6 -> ARABIC LETTER YEH FINAL FORM + u'\ufed0' # 0x00f7 -> ARABIC LETTER GHAIN MEDIAL FORM + u'\ufed5' # 0x00f8 -> ARABIC LETTER QAF ISOLATED FORM + u'\ufef5' # 0x00f9 -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + u'\ufef6' # 0x00fa -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + u'\ufedd' # 0x00fb -> ARABIC LETTER LAM ISOLATED FORM + u'\ufed9' # 0x00fc -> ARABIC LETTER KAF ISOLATED FORM + u'\ufef1' # 0x00fd -> ARABIC LETTER YEH ISOLATED FORM + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\ufffe' # 0x00ff -> UNDEFINED +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00a0, # NON-BREAKING SPACE + 0x00a2: 0x00c0, # CENT SIGN + 0x00a3: 0x00a3, # POUND SIGN + 0x00a4: 0x00a4, # CURRENCY SIGN + 0x00a6: 0x00db, # BROKEN VERTICAL BAR + 0x00ab: 0x0097, # LEFT POINTING GUILLEMET + 0x00ac: 0x00dc, # NOT SIGN + 0x00ad: 0x00a1, # SOFT HYPHEN + 0x00b0: 0x0080, # DEGREE SIGN + 0x00b1: 0x0093, # PLUS-OR-MINUS SIGN + 0x00b7: 0x0081, # MIDDLE DOT + 0x00bb: 0x0098, # RIGHT POINTING GUILLEMET + 0x00bc: 0x0095, # FRACTION 1/4 + 0x00bd: 0x0094, # FRACTION 1/2 + 0x00d7: 0x00de, # MULTIPLICATION SIGN + 0x00f7: 0x00dd, # DIVISION SIGN + 0x03b2: 0x0090, # GREEK SMALL BETA + 0x03c6: 0x0092, # GREEK SMALL PHI + 0x060c: 0x00ac, # ARABIC COMMA + 0x061b: 0x00bb, # ARABIC SEMICOLON + 0x061f: 0x00bf, # ARABIC QUESTION MARK + 0x0640: 0x00e0, # ARABIC TATWEEL + 0x0651: 0x00f1, # ARABIC SHADDAH + 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO + 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE + 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO + 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE + 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR + 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE + 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX + 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN + 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT + 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE + 0x066a: 0x0025, # ARABIC PERCENT SIGN + 0x2219: 0x0082, # BULLET OPERATOR + 0x221a: 0x0083, # SQUARE ROOT + 0x221e: 0x0091, # INFINITY + 0x2248: 0x0096, # ALMOST EQUAL TO + 0x2500: 0x0085, # FORMS LIGHT HORIZONTAL + 0x2502: 0x0086, # FORMS LIGHT VERTICAL + 0x250c: 0x008d, # FORMS LIGHT DOWN AND RIGHT + 0x2510: 0x008c, # FORMS LIGHT DOWN AND LEFT + 0x2514: 0x008e, # FORMS LIGHT UP AND RIGHT + 0x2518: 0x008f, # FORMS LIGHT UP AND LEFT + 0x251c: 0x008a, # FORMS LIGHT VERTICAL AND RIGHT + 0x2524: 0x0088, # FORMS LIGHT VERTICAL AND LEFT + 0x252c: 0x0089, # FORMS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x008b, # FORMS LIGHT UP AND HORIZONTAL + 0x253c: 0x0087, # FORMS LIGHT VERTICAL AND HORIZONTAL + 0x2592: 0x0084, # MEDIUM SHADE + 0x25a0: 0x00fe, # BLACK SQUARE + 0xfe7d: 0x00f0, # ARABIC SHADDA MEDIAL FORM + 0xfe80: 0x00c1, # ARABIC LETTER HAMZA ISOLATED FORM + 0xfe81: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + 0xfe82: 0x00a2, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + 0xfe83: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + 0xfe84: 0x00a5, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + 0xfe85: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + 0xfe8b: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + 0xfe8d: 0x00c7, # ARABIC LETTER ALEF ISOLATED FORM + 0xfe8e: 0x00a8, # ARABIC LETTER ALEF FINAL FORM + 0xfe8f: 0x00a9, # ARABIC LETTER BEH ISOLATED FORM + 0xfe91: 0x00c8, # ARABIC LETTER BEH INITIAL FORM + 0xfe93: 0x00c9, # ARABIC LETTER TEH MARBUTA ISOLATED FORM + 0xfe95: 0x00aa, # ARABIC LETTER TEH ISOLATED FORM + 0xfe97: 0x00ca, # ARABIC LETTER TEH INITIAL FORM + 0xfe99: 0x00ab, # ARABIC LETTER THEH ISOLATED FORM + 0xfe9b: 0x00cb, # ARABIC LETTER THEH INITIAL FORM + 0xfe9d: 0x00ad, # ARABIC LETTER JEEM ISOLATED FORM + 0xfe9f: 0x00cc, # ARABIC LETTER JEEM INITIAL FORM + 0xfea1: 0x00ae, # ARABIC LETTER HAH ISOLATED FORM + 0xfea3: 0x00cd, # ARABIC LETTER HAH INITIAL FORM + 0xfea5: 0x00af, # ARABIC LETTER KHAH ISOLATED FORM + 0xfea7: 0x00ce, # ARABIC LETTER KHAH INITIAL FORM + 0xfea9: 0x00cf, # ARABIC LETTER DAL ISOLATED FORM + 0xfeab: 0x00d0, # ARABIC LETTER THAL ISOLATED FORM + 0xfead: 0x00d1, # ARABIC LETTER REH ISOLATED FORM + 0xfeaf: 0x00d2, # ARABIC LETTER ZAIN ISOLATED FORM + 0xfeb1: 0x00bc, # ARABIC LETTER SEEN ISOLATED FORM + 0xfeb3: 0x00d3, # ARABIC LETTER SEEN INITIAL FORM + 0xfeb5: 0x00bd, # ARABIC LETTER SHEEN ISOLATED FORM + 0xfeb7: 0x00d4, # ARABIC LETTER SHEEN INITIAL FORM + 0xfeb9: 0x00be, # ARABIC LETTER SAD ISOLATED FORM + 0xfebb: 0x00d5, # ARABIC LETTER SAD INITIAL FORM + 0xfebd: 0x00eb, # ARABIC LETTER DAD ISOLATED FORM + 0xfebf: 0x00d6, # ARABIC LETTER DAD INITIAL FORM + 0xfec1: 0x00d7, # ARABIC LETTER TAH ISOLATED FORM + 0xfec5: 0x00d8, # ARABIC LETTER ZAH ISOLATED FORM + 0xfec9: 0x00df, # ARABIC LETTER AIN ISOLATED FORM + 0xfeca: 0x00c5, # ARABIC LETTER AIN FINAL FORM + 0xfecb: 0x00d9, # ARABIC LETTER AIN INITIAL FORM + 0xfecc: 0x00ec, # ARABIC LETTER AIN MEDIAL FORM + 0xfecd: 0x00ee, # ARABIC LETTER GHAIN ISOLATED FORM + 0xfece: 0x00ed, # ARABIC LETTER GHAIN FINAL FORM + 0xfecf: 0x00da, # ARABIC LETTER GHAIN INITIAL FORM + 0xfed0: 0x00f7, # ARABIC LETTER GHAIN MEDIAL FORM + 0xfed1: 0x00ba, # ARABIC LETTER FEH ISOLATED FORM + 0xfed3: 0x00e1, # ARABIC LETTER FEH INITIAL FORM + 0xfed5: 0x00f8, # ARABIC LETTER QAF ISOLATED FORM + 0xfed7: 0x00e2, # ARABIC LETTER QAF INITIAL FORM + 0xfed9: 0x00fc, # ARABIC LETTER KAF ISOLATED FORM + 0xfedb: 0x00e3, # ARABIC LETTER KAF INITIAL FORM + 0xfedd: 0x00fb, # ARABIC LETTER LAM ISOLATED FORM + 0xfedf: 0x00e4, # ARABIC LETTER LAM INITIAL FORM + 0xfee1: 0x00ef, # ARABIC LETTER MEEM ISOLATED FORM + 0xfee3: 0x00e5, # ARABIC LETTER MEEM INITIAL FORM + 0xfee5: 0x00f2, # ARABIC LETTER NOON ISOLATED FORM + 0xfee7: 0x00e6, # ARABIC LETTER NOON INITIAL FORM + 0xfee9: 0x00f3, # ARABIC LETTER HEH ISOLATED FORM + 0xfeeb: 0x00e7, # ARABIC LETTER HEH INITIAL FORM + 0xfeec: 0x00f4, # ARABIC LETTER HEH MEDIAL FORM + 0xfeed: 0x00e8, # ARABIC LETTER WAW ISOLATED FORM + 0xfeef: 0x00e9, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM + 0xfef0: 0x00f5, # ARABIC LETTER ALEF MAKSURA FINAL FORM + 0xfef1: 0x00fd, # ARABIC LETTER YEH ISOLATED FORM + 0xfef2: 0x00f6, # ARABIC LETTER YEH FINAL FORM + 0xfef3: 0x00ea, # ARABIC LETTER YEH INITIAL FORM + 0xfef5: 0x00f9, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + 0xfef6: 0x00fa, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + 0xfef7: 0x0099, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + 0xfef8: 0x009a, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + 0xfefb: 0x009d, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + 0xfefc: 0x009e, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM +} diff --git a/src/main/resources/PythonLibs/encodings/cp865.py b/src/main/resources/PythonLibs/encodings/cp865.py new file mode 100644 index 0000000000000000000000000000000000000000..e9f45f1b508b8f86aa72a11caacf4c682411186b --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp865.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP865.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp865', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00a4, # CURRENCY SIGN + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + u'\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + u'\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + u'\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + u'\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + u'\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + u'\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + u'\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + u'\xa3' # 0x009c -> POUND SIGN + u'\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + u'\u20a7' # 0x009e -> PESETA SIGN + u'\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + u'\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + u'\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + u'\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + u'\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + u'\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + u'\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + u'\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + u'\xbf' # 0x00a8 -> INVERTED QUESTION MARK + u'\u2310' # 0x00a9 -> REVERSED NOT SIGN + u'\xac' # 0x00aa -> NOT SIGN + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + u'\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xa4' # 0x00af -> CURRENCY SIGN + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + u'\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + u'\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + u'\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + u'\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + u'\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + u'\xb5' # 0x00e6 -> MICRO SIGN + u'\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + u'\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + u'\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + u'\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + u'\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + u'\u221e' # 0x00ec -> INFINITY + u'\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + u'\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + u'\u2229' # 0x00ef -> INTERSECTION + u'\u2261' # 0x00f0 -> IDENTICAL TO + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + u'\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + u'\u2320' # 0x00f4 -> TOP HALF INTEGRAL + u'\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + u'\xf7' # 0x00f6 -> DIVISION SIGN + u'\u2248' # 0x00f7 -> ALMOST EQUAL TO + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + u'\xb2' # 0x00fd -> SUPERSCRIPT TWO + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00af, # CURRENCY SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp866.py b/src/main/resources/PythonLibs/encodings/cp866.py new file mode 100644 index 0000000000000000000000000000000000000000..29cd85a3f10b05eac36ef93749ba593a485f816e --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp866.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP866.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp866', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x0082: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x0083: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x0084: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x0085: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x0086: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x0087: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x0088: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x0089: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x008a: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x008b: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x008c: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x008d: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x008e: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x008f: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x0090: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x0091: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x0092: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x0093: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x0094: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x0095: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x0096: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x0097: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x0098: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x0099: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x009a: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x009b: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x009c: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x009d: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x009e: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009f: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a2: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00a3: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00a4: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a5: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a6: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00a7: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00a8: 0x0438, # CYRILLIC SMALL LETTER I + 0x00a9: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00aa: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00ab: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00ac: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00ad: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00ae: 0x043e, # CYRILLIC SMALL LETTER O + 0x00af: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e1: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e2: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e3: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e4: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00e5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00e6: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00e7: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00e8: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00e9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00ea: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x00eb: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00ec: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ed: 0x044d, # CYRILLIC SMALL LETTER E + 0x00ee: 0x044e, # CYRILLIC SMALL LETTER YU + 0x00ef: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00f0: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x00f1: 0x0451, # CYRILLIC SMALL LETTER IO + 0x00f2: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x00f3: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x00f4: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x00f5: 0x0457, # CYRILLIC SMALL LETTER YI + 0x00f6: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U + 0x00f7: 0x045e, # CYRILLIC SMALL LETTER SHORT U + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x2116, # NUMERO SIGN + 0x00fd: 0x00a4, # CURRENCY SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\u0410' # 0x0080 -> CYRILLIC CAPITAL LETTER A + u'\u0411' # 0x0081 -> CYRILLIC CAPITAL LETTER BE + u'\u0412' # 0x0082 -> CYRILLIC CAPITAL LETTER VE + u'\u0413' # 0x0083 -> CYRILLIC CAPITAL LETTER GHE + u'\u0414' # 0x0084 -> CYRILLIC CAPITAL LETTER DE + u'\u0415' # 0x0085 -> CYRILLIC CAPITAL LETTER IE + u'\u0416' # 0x0086 -> CYRILLIC CAPITAL LETTER ZHE + u'\u0417' # 0x0087 -> CYRILLIC CAPITAL LETTER ZE + u'\u0418' # 0x0088 -> CYRILLIC CAPITAL LETTER I + u'\u0419' # 0x0089 -> CYRILLIC CAPITAL LETTER SHORT I + u'\u041a' # 0x008a -> CYRILLIC CAPITAL LETTER KA + u'\u041b' # 0x008b -> CYRILLIC CAPITAL LETTER EL + u'\u041c' # 0x008c -> CYRILLIC CAPITAL LETTER EM + u'\u041d' # 0x008d -> CYRILLIC CAPITAL LETTER EN + u'\u041e' # 0x008e -> CYRILLIC CAPITAL LETTER O + u'\u041f' # 0x008f -> CYRILLIC CAPITAL LETTER PE + u'\u0420' # 0x0090 -> CYRILLIC CAPITAL LETTER ER + u'\u0421' # 0x0091 -> CYRILLIC CAPITAL LETTER ES + u'\u0422' # 0x0092 -> CYRILLIC CAPITAL LETTER TE + u'\u0423' # 0x0093 -> CYRILLIC CAPITAL LETTER U + u'\u0424' # 0x0094 -> CYRILLIC CAPITAL LETTER EF + u'\u0425' # 0x0095 -> CYRILLIC CAPITAL LETTER HA + u'\u0426' # 0x0096 -> CYRILLIC CAPITAL LETTER TSE + u'\u0427' # 0x0097 -> CYRILLIC CAPITAL LETTER CHE + u'\u0428' # 0x0098 -> CYRILLIC CAPITAL LETTER SHA + u'\u0429' # 0x0099 -> CYRILLIC CAPITAL LETTER SHCHA + u'\u042a' # 0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN + u'\u042b' # 0x009b -> CYRILLIC CAPITAL LETTER YERU + u'\u042c' # 0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN + u'\u042d' # 0x009d -> CYRILLIC CAPITAL LETTER E + u'\u042e' # 0x009e -> CYRILLIC CAPITAL LETTER YU + u'\u042f' # 0x009f -> CYRILLIC CAPITAL LETTER YA + u'\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + u'\u0431' # 0x00a1 -> CYRILLIC SMALL LETTER BE + u'\u0432' # 0x00a2 -> CYRILLIC SMALL LETTER VE + u'\u0433' # 0x00a3 -> CYRILLIC SMALL LETTER GHE + u'\u0434' # 0x00a4 -> CYRILLIC SMALL LETTER DE + u'\u0435' # 0x00a5 -> CYRILLIC SMALL LETTER IE + u'\u0436' # 0x00a6 -> CYRILLIC SMALL LETTER ZHE + u'\u0437' # 0x00a7 -> CYRILLIC SMALL LETTER ZE + u'\u0438' # 0x00a8 -> CYRILLIC SMALL LETTER I + u'\u0439' # 0x00a9 -> CYRILLIC SMALL LETTER SHORT I + u'\u043a' # 0x00aa -> CYRILLIC SMALL LETTER KA + u'\u043b' # 0x00ab -> CYRILLIC SMALL LETTER EL + u'\u043c' # 0x00ac -> CYRILLIC SMALL LETTER EM + u'\u043d' # 0x00ad -> CYRILLIC SMALL LETTER EN + u'\u043e' # 0x00ae -> CYRILLIC SMALL LETTER O + u'\u043f' # 0x00af -> CYRILLIC SMALL LETTER PE + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u258c' # 0x00dd -> LEFT HALF BLOCK + u'\u2590' # 0x00de -> RIGHT HALF BLOCK + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u0440' # 0x00e0 -> CYRILLIC SMALL LETTER ER + u'\u0441' # 0x00e1 -> CYRILLIC SMALL LETTER ES + u'\u0442' # 0x00e2 -> CYRILLIC SMALL LETTER TE + u'\u0443' # 0x00e3 -> CYRILLIC SMALL LETTER U + u'\u0444' # 0x00e4 -> CYRILLIC SMALL LETTER EF + u'\u0445' # 0x00e5 -> CYRILLIC SMALL LETTER HA + u'\u0446' # 0x00e6 -> CYRILLIC SMALL LETTER TSE + u'\u0447' # 0x00e7 -> CYRILLIC SMALL LETTER CHE + u'\u0448' # 0x00e8 -> CYRILLIC SMALL LETTER SHA + u'\u0449' # 0x00e9 -> CYRILLIC SMALL LETTER SHCHA + u'\u044a' # 0x00ea -> CYRILLIC SMALL LETTER HARD SIGN + u'\u044b' # 0x00eb -> CYRILLIC SMALL LETTER YERU + u'\u044c' # 0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN + u'\u044d' # 0x00ed -> CYRILLIC SMALL LETTER E + u'\u044e' # 0x00ee -> CYRILLIC SMALL LETTER YU + u'\u044f' # 0x00ef -> CYRILLIC SMALL LETTER YA + u'\u0401' # 0x00f0 -> CYRILLIC CAPITAL LETTER IO + u'\u0451' # 0x00f1 -> CYRILLIC SMALL LETTER IO + u'\u0404' # 0x00f2 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + u'\u0454' # 0x00f3 -> CYRILLIC SMALL LETTER UKRAINIAN IE + u'\u0407' # 0x00f4 -> CYRILLIC CAPITAL LETTER YI + u'\u0457' # 0x00f5 -> CYRILLIC SMALL LETTER YI + u'\u040e' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHORT U + u'\u045e' # 0x00f7 -> CYRILLIC SMALL LETTER SHORT U + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\u2219' # 0x00f9 -> BULLET OPERATOR + u'\xb7' # 0x00fa -> MIDDLE DOT + u'\u221a' # 0x00fb -> SQUARE ROOT + u'\u2116' # 0x00fc -> NUMERO SIGN + u'\xa4' # 0x00fd -> CURRENCY SIGN + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00fd, # CURRENCY SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x0401: 0x00f0, # CYRILLIC CAPITAL LETTER IO + 0x0404: 0x00f2, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0407: 0x00f4, # CYRILLIC CAPITAL LETTER YI + 0x040e: 0x00f6, # CYRILLIC CAPITAL LETTER SHORT U + 0x0410: 0x0080, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x0081, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x0082, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x0083, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x0084, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x0085, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x0086, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x0087, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x0088, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x0089, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x008a, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x008b, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x008c, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x008d, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x008e, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x008f, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x0090, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x0091, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x0092, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x0093, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x0094, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x0095, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x0096, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x0097, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x0098, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x0099, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x009b, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x009c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x009d, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009e, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x009f, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a1, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00a2, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00a3, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a4, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a5, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00a6, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00a7, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00a8, # CYRILLIC SMALL LETTER I + 0x0439: 0x00a9, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00aa, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00ab, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00ac, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00ad, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00ae, # CYRILLIC SMALL LETTER O + 0x043f: 0x00af, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e0, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e1, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e2, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e3, # CYRILLIC SMALL LETTER U + 0x0444: 0x00e4, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00e5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00e6, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00e7, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00e8, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00e9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x00ea, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00eb, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ec, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00ed, # CYRILLIC SMALL LETTER E + 0x044e: 0x00ee, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00ef, # CYRILLIC SMALL LETTER YA + 0x0451: 0x00f1, # CYRILLIC SMALL LETTER IO + 0x0454: 0x00f3, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0457: 0x00f5, # CYRILLIC SMALL LETTER YI + 0x045e: 0x00f7, # CYRILLIC SMALL LETTER SHORT U + 0x2116: 0x00fc, # NUMERO SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp869.py b/src/main/resources/PythonLibs/encodings/cp869.py new file mode 100644 index 0000000000000000000000000000000000000000..b4dc99bf2540b7767f70bc70ed8e67998c2c0fa7 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp869.py @@ -0,0 +1,689 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP869.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp869', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: None, # UNDEFINED + 0x0081: None, # UNDEFINED + 0x0082: None, # UNDEFINED + 0x0083: None, # UNDEFINED + 0x0084: None, # UNDEFINED + 0x0085: None, # UNDEFINED + 0x0086: 0x0386, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0087: None, # UNDEFINED + 0x0088: 0x00b7, # MIDDLE DOT + 0x0089: 0x00ac, # NOT SIGN + 0x008a: 0x00a6, # BROKEN BAR + 0x008b: 0x2018, # LEFT SINGLE QUOTATION MARK + 0x008c: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x008d: 0x0388, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x008e: 0x2015, # HORIZONTAL BAR + 0x008f: 0x0389, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x0090: 0x038a, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x0091: 0x03aa, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x0092: 0x038c, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x0093: None, # UNDEFINED + 0x0094: None, # UNDEFINED + 0x0095: 0x038e, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x0096: 0x03ab, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x0097: 0x00a9, # COPYRIGHT SIGN + 0x0098: 0x038f, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0099: 0x00b2, # SUPERSCRIPT TWO + 0x009a: 0x00b3, # SUPERSCRIPT THREE + 0x009b: 0x03ac, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x03ad, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x009e: 0x03ae, # GREEK SMALL LETTER ETA WITH TONOS + 0x009f: 0x03af, # GREEK SMALL LETTER IOTA WITH TONOS + 0x00a0: 0x03ca, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x00a1: 0x0390, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x00a2: 0x03cc, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x00a3: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x00a4: 0x0391, # GREEK CAPITAL LETTER ALPHA + 0x00a5: 0x0392, # GREEK CAPITAL LETTER BETA + 0x00a6: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00a7: 0x0394, # GREEK CAPITAL LETTER DELTA + 0x00a8: 0x0395, # GREEK CAPITAL LETTER EPSILON + 0x00a9: 0x0396, # GREEK CAPITAL LETTER ZETA + 0x00aa: 0x0397, # GREEK CAPITAL LETTER ETA + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ad: 0x0399, # GREEK CAPITAL LETTER IOTA + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x039a, # GREEK CAPITAL LETTER KAPPA + 0x00b6: 0x039b, # GREEK CAPITAL LETTER LAMDA + 0x00b7: 0x039c, # GREEK CAPITAL LETTER MU + 0x00b8: 0x039d, # GREEK CAPITAL LETTER NU + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x039e, # GREEK CAPITAL LETTER XI + 0x00be: 0x039f, # GREEK CAPITAL LETTER OMICRON + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x03a0, # GREEK CAPITAL LETTER PI + 0x00c7: 0x03a1, # GREEK CAPITAL LETTER RHO + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00d0: 0x03a4, # GREEK CAPITAL LETTER TAU + 0x00d1: 0x03a5, # GREEK CAPITAL LETTER UPSILON + 0x00d2: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00d3: 0x03a7, # GREEK CAPITAL LETTER CHI + 0x00d4: 0x03a8, # GREEK CAPITAL LETTER PSI + 0x00d5: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00d6: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00d7: 0x03b2, # GREEK SMALL LETTER BETA + 0x00d8: 0x03b3, # GREEK SMALL LETTER GAMMA + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00de: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b6, # GREEK SMALL LETTER ZETA + 0x00e1: 0x03b7, # GREEK SMALL LETTER ETA + 0x00e2: 0x03b8, # GREEK SMALL LETTER THETA + 0x00e3: 0x03b9, # GREEK SMALL LETTER IOTA + 0x00e4: 0x03ba, # GREEK SMALL LETTER KAPPA + 0x00e5: 0x03bb, # GREEK SMALL LETTER LAMDA + 0x00e6: 0x03bc, # GREEK SMALL LETTER MU + 0x00e7: 0x03bd, # GREEK SMALL LETTER NU + 0x00e8: 0x03be, # GREEK SMALL LETTER XI + 0x00e9: 0x03bf, # GREEK SMALL LETTER OMICRON + 0x00ea: 0x03c0, # GREEK SMALL LETTER PI + 0x00eb: 0x03c1, # GREEK SMALL LETTER RHO + 0x00ec: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00ed: 0x03c2, # GREEK SMALL LETTER FINAL SIGMA + 0x00ee: 0x03c4, # GREEK SMALL LETTER TAU + 0x00ef: 0x0384, # GREEK TONOS + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x03c5, # GREEK SMALL LETTER UPSILON + 0x00f3: 0x03c6, # GREEK SMALL LETTER PHI + 0x00f4: 0x03c7, # GREEK SMALL LETTER CHI + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x03c8, # GREEK SMALL LETTER PSI + 0x00f7: 0x0385, # GREEK DIALYTIKA TONOS + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x03c9, # GREEK SMALL LETTER OMEGA + 0x00fb: 0x03cb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x00fc: 0x03b0, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x00fd: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> NULL + u'\x01' # 0x0001 -> START OF HEADING + u'\x02' # 0x0002 -> START OF TEXT + u'\x03' # 0x0003 -> END OF TEXT + u'\x04' # 0x0004 -> END OF TRANSMISSION + u'\x05' # 0x0005 -> ENQUIRY + u'\x06' # 0x0006 -> ACKNOWLEDGE + u'\x07' # 0x0007 -> BELL + u'\x08' # 0x0008 -> BACKSPACE + u'\t' # 0x0009 -> HORIZONTAL TABULATION + u'\n' # 0x000a -> LINE FEED + u'\x0b' # 0x000b -> VERTICAL TABULATION + u'\x0c' # 0x000c -> FORM FEED + u'\r' # 0x000d -> CARRIAGE RETURN + u'\x0e' # 0x000e -> SHIFT OUT + u'\x0f' # 0x000f -> SHIFT IN + u'\x10' # 0x0010 -> DATA LINK ESCAPE + u'\x11' # 0x0011 -> DEVICE CONTROL ONE + u'\x12' # 0x0012 -> DEVICE CONTROL TWO + u'\x13' # 0x0013 -> DEVICE CONTROL THREE + u'\x14' # 0x0014 -> DEVICE CONTROL FOUR + u'\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x0016 -> SYNCHRONOUS IDLE + u'\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x0018 -> CANCEL + u'\x19' # 0x0019 -> END OF MEDIUM + u'\x1a' # 0x001a -> SUBSTITUTE + u'\x1b' # 0x001b -> ESCAPE + u'\x1c' # 0x001c -> FILE SEPARATOR + u'\x1d' # 0x001d -> GROUP SEPARATOR + u'\x1e' # 0x001e -> RECORD SEPARATOR + u'\x1f' # 0x001f -> UNIT SEPARATOR + u' ' # 0x0020 -> SPACE + u'!' # 0x0021 -> EXCLAMATION MARK + u'"' # 0x0022 -> QUOTATION MARK + u'#' # 0x0023 -> NUMBER SIGN + u'$' # 0x0024 -> DOLLAR SIGN + u'%' # 0x0025 -> PERCENT SIGN + u'&' # 0x0026 -> AMPERSAND + u"'" # 0x0027 -> APOSTROPHE + u'(' # 0x0028 -> LEFT PARENTHESIS + u')' # 0x0029 -> RIGHT PARENTHESIS + u'*' # 0x002a -> ASTERISK + u'+' # 0x002b -> PLUS SIGN + u',' # 0x002c -> COMMA + u'-' # 0x002d -> HYPHEN-MINUS + u'.' # 0x002e -> FULL STOP + u'/' # 0x002f -> SOLIDUS + u'0' # 0x0030 -> DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE + u':' # 0x003a -> COLON + u';' # 0x003b -> SEMICOLON + u'<' # 0x003c -> LESS-THAN SIGN + u'=' # 0x003d -> EQUALS SIGN + u'>' # 0x003e -> GREATER-THAN SIGN + u'?' # 0x003f -> QUESTION MARK + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET + u'\\' # 0x005c -> REVERSE SOLIDUS + u']' # 0x005d -> RIGHT SQUARE BRACKET + u'^' # 0x005e -> CIRCUMFLEX ACCENT + u'_' # 0x005f -> LOW LINE + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET + u'|' # 0x007c -> VERTICAL LINE + u'}' # 0x007d -> RIGHT CURLY BRACKET + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> DELETE + u'\ufffe' # 0x0080 -> UNDEFINED + u'\ufffe' # 0x0081 -> UNDEFINED + u'\ufffe' # 0x0082 -> UNDEFINED + u'\ufffe' # 0x0083 -> UNDEFINED + u'\ufffe' # 0x0084 -> UNDEFINED + u'\ufffe' # 0x0085 -> UNDEFINED + u'\u0386' # 0x0086 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + u'\ufffe' # 0x0087 -> UNDEFINED + u'\xb7' # 0x0088 -> MIDDLE DOT + u'\xac' # 0x0089 -> NOT SIGN + u'\xa6' # 0x008a -> BROKEN BAR + u'\u2018' # 0x008b -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x008c -> RIGHT SINGLE QUOTATION MARK + u'\u0388' # 0x008d -> GREEK CAPITAL LETTER EPSILON WITH TONOS + u'\u2015' # 0x008e -> HORIZONTAL BAR + u'\u0389' # 0x008f -> GREEK CAPITAL LETTER ETA WITH TONOS + u'\u038a' # 0x0090 -> GREEK CAPITAL LETTER IOTA WITH TONOS + u'\u03aa' # 0x0091 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + u'\u038c' # 0x0092 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + u'\ufffe' # 0x0093 -> UNDEFINED + u'\ufffe' # 0x0094 -> UNDEFINED + u'\u038e' # 0x0095 -> GREEK CAPITAL LETTER UPSILON WITH TONOS + u'\u03ab' # 0x0096 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + u'\xa9' # 0x0097 -> COPYRIGHT SIGN + u'\u038f' # 0x0098 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + u'\xb2' # 0x0099 -> SUPERSCRIPT TWO + u'\xb3' # 0x009a -> SUPERSCRIPT THREE + u'\u03ac' # 0x009b -> GREEK SMALL LETTER ALPHA WITH TONOS + u'\xa3' # 0x009c -> POUND SIGN + u'\u03ad' # 0x009d -> GREEK SMALL LETTER EPSILON WITH TONOS + u'\u03ae' # 0x009e -> GREEK SMALL LETTER ETA WITH TONOS + u'\u03af' # 0x009f -> GREEK SMALL LETTER IOTA WITH TONOS + u'\u03ca' # 0x00a0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + u'\u0390' # 0x00a1 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + u'\u03cc' # 0x00a2 -> GREEK SMALL LETTER OMICRON WITH TONOS + u'\u03cd' # 0x00a3 -> GREEK SMALL LETTER UPSILON WITH TONOS + u'\u0391' # 0x00a4 -> GREEK CAPITAL LETTER ALPHA + u'\u0392' # 0x00a5 -> GREEK CAPITAL LETTER BETA + u'\u0393' # 0x00a6 -> GREEK CAPITAL LETTER GAMMA + u'\u0394' # 0x00a7 -> GREEK CAPITAL LETTER DELTA + u'\u0395' # 0x00a8 -> GREEK CAPITAL LETTER EPSILON + u'\u0396' # 0x00a9 -> GREEK CAPITAL LETTER ZETA + u'\u0397' # 0x00aa -> GREEK CAPITAL LETTER ETA + u'\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + u'\u0398' # 0x00ac -> GREEK CAPITAL LETTER THETA + u'\u0399' # 0x00ad -> GREEK CAPITAL LETTER IOTA + u'\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2591' # 0x00b0 -> LIGHT SHADE + u'\u2592' # 0x00b1 -> MEDIUM SHADE + u'\u2593' # 0x00b2 -> DARK SHADE + u'\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + u'\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u039a' # 0x00b5 -> GREEK CAPITAL LETTER KAPPA + u'\u039b' # 0x00b6 -> GREEK CAPITAL LETTER LAMDA + u'\u039c' # 0x00b7 -> GREEK CAPITAL LETTER MU + u'\u039d' # 0x00b8 -> GREEK CAPITAL LETTER NU + u'\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u039e' # 0x00bd -> GREEK CAPITAL LETTER XI + u'\u039f' # 0x00be -> GREEK CAPITAL LETTER OMICRON + u'\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u03a0' # 0x00c6 -> GREEK CAPITAL LETTER PI + u'\u03a1' # 0x00c7 -> GREEK CAPITAL LETTER RHO + u'\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\u03a3' # 0x00cf -> GREEK CAPITAL LETTER SIGMA + u'\u03a4' # 0x00d0 -> GREEK CAPITAL LETTER TAU + u'\u03a5' # 0x00d1 -> GREEK CAPITAL LETTER UPSILON + u'\u03a6' # 0x00d2 -> GREEK CAPITAL LETTER PHI + u'\u03a7' # 0x00d3 -> GREEK CAPITAL LETTER CHI + u'\u03a8' # 0x00d4 -> GREEK CAPITAL LETTER PSI + u'\u03a9' # 0x00d5 -> GREEK CAPITAL LETTER OMEGA + u'\u03b1' # 0x00d6 -> GREEK SMALL LETTER ALPHA + u'\u03b2' # 0x00d7 -> GREEK SMALL LETTER BETA + u'\u03b3' # 0x00d8 -> GREEK SMALL LETTER GAMMA + u'\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2588' # 0x00db -> FULL BLOCK + u'\u2584' # 0x00dc -> LOWER HALF BLOCK + u'\u03b4' # 0x00dd -> GREEK SMALL LETTER DELTA + u'\u03b5' # 0x00de -> GREEK SMALL LETTER EPSILON + u'\u2580' # 0x00df -> UPPER HALF BLOCK + u'\u03b6' # 0x00e0 -> GREEK SMALL LETTER ZETA + u'\u03b7' # 0x00e1 -> GREEK SMALL LETTER ETA + u'\u03b8' # 0x00e2 -> GREEK SMALL LETTER THETA + u'\u03b9' # 0x00e3 -> GREEK SMALL LETTER IOTA + u'\u03ba' # 0x00e4 -> GREEK SMALL LETTER KAPPA + u'\u03bb' # 0x00e5 -> GREEK SMALL LETTER LAMDA + u'\u03bc' # 0x00e6 -> GREEK SMALL LETTER MU + u'\u03bd' # 0x00e7 -> GREEK SMALL LETTER NU + u'\u03be' # 0x00e8 -> GREEK SMALL LETTER XI + u'\u03bf' # 0x00e9 -> GREEK SMALL LETTER OMICRON + u'\u03c0' # 0x00ea -> GREEK SMALL LETTER PI + u'\u03c1' # 0x00eb -> GREEK SMALL LETTER RHO + u'\u03c3' # 0x00ec -> GREEK SMALL LETTER SIGMA + u'\u03c2' # 0x00ed -> GREEK SMALL LETTER FINAL SIGMA + u'\u03c4' # 0x00ee -> GREEK SMALL LETTER TAU + u'\u0384' # 0x00ef -> GREEK TONOS + u'\xad' # 0x00f0 -> SOFT HYPHEN + u'\xb1' # 0x00f1 -> PLUS-MINUS SIGN + u'\u03c5' # 0x00f2 -> GREEK SMALL LETTER UPSILON + u'\u03c6' # 0x00f3 -> GREEK SMALL LETTER PHI + u'\u03c7' # 0x00f4 -> GREEK SMALL LETTER CHI + u'\xa7' # 0x00f5 -> SECTION SIGN + u'\u03c8' # 0x00f6 -> GREEK SMALL LETTER PSI + u'\u0385' # 0x00f7 -> GREEK DIALYTIKA TONOS + u'\xb0' # 0x00f8 -> DEGREE SIGN + u'\xa8' # 0x00f9 -> DIAERESIS + u'\u03c9' # 0x00fa -> GREEK SMALL LETTER OMEGA + u'\u03cb' # 0x00fb -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + u'\u03b0' # 0x00fc -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + u'\u03ce' # 0x00fd -> GREEK SMALL LETTER OMEGA WITH TONOS + u'\u25a0' # 0x00fe -> BLACK SQUARE + u'\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a3: 0x009c, # POUND SIGN + 0x00a6: 0x008a, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x0097, # COPYRIGHT SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x0089, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x0099, # SUPERSCRIPT TWO + 0x00b3: 0x009a, # SUPERSCRIPT THREE + 0x00b7: 0x0088, # MIDDLE DOT + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x0384: 0x00ef, # GREEK TONOS + 0x0385: 0x00f7, # GREEK DIALYTIKA TONOS + 0x0386: 0x0086, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0388: 0x008d, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x0389: 0x008f, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x038a: 0x0090, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x038c: 0x0092, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x038e: 0x0095, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x038f: 0x0098, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0390: 0x00a1, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x0391: 0x00a4, # GREEK CAPITAL LETTER ALPHA + 0x0392: 0x00a5, # GREEK CAPITAL LETTER BETA + 0x0393: 0x00a6, # GREEK CAPITAL LETTER GAMMA + 0x0394: 0x00a7, # GREEK CAPITAL LETTER DELTA + 0x0395: 0x00a8, # GREEK CAPITAL LETTER EPSILON + 0x0396: 0x00a9, # GREEK CAPITAL LETTER ZETA + 0x0397: 0x00aa, # GREEK CAPITAL LETTER ETA + 0x0398: 0x00ac, # GREEK CAPITAL LETTER THETA + 0x0399: 0x00ad, # GREEK CAPITAL LETTER IOTA + 0x039a: 0x00b5, # GREEK CAPITAL LETTER KAPPA + 0x039b: 0x00b6, # GREEK CAPITAL LETTER LAMDA + 0x039c: 0x00b7, # GREEK CAPITAL LETTER MU + 0x039d: 0x00b8, # GREEK CAPITAL LETTER NU + 0x039e: 0x00bd, # GREEK CAPITAL LETTER XI + 0x039f: 0x00be, # GREEK CAPITAL LETTER OMICRON + 0x03a0: 0x00c6, # GREEK CAPITAL LETTER PI + 0x03a1: 0x00c7, # GREEK CAPITAL LETTER RHO + 0x03a3: 0x00cf, # GREEK CAPITAL LETTER SIGMA + 0x03a4: 0x00d0, # GREEK CAPITAL LETTER TAU + 0x03a5: 0x00d1, # GREEK CAPITAL LETTER UPSILON + 0x03a6: 0x00d2, # GREEK CAPITAL LETTER PHI + 0x03a7: 0x00d3, # GREEK CAPITAL LETTER CHI + 0x03a8: 0x00d4, # GREEK CAPITAL LETTER PSI + 0x03a9: 0x00d5, # GREEK CAPITAL LETTER OMEGA + 0x03aa: 0x0091, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x03ab: 0x0096, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x03ac: 0x009b, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x03ad: 0x009d, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x03ae: 0x009e, # GREEK SMALL LETTER ETA WITH TONOS + 0x03af: 0x009f, # GREEK SMALL LETTER IOTA WITH TONOS + 0x03b0: 0x00fc, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x03b1: 0x00d6, # GREEK SMALL LETTER ALPHA + 0x03b2: 0x00d7, # GREEK SMALL LETTER BETA + 0x03b3: 0x00d8, # GREEK SMALL LETTER GAMMA + 0x03b4: 0x00dd, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00de, # GREEK SMALL LETTER EPSILON + 0x03b6: 0x00e0, # GREEK SMALL LETTER ZETA + 0x03b7: 0x00e1, # GREEK SMALL LETTER ETA + 0x03b8: 0x00e2, # GREEK SMALL LETTER THETA + 0x03b9: 0x00e3, # GREEK SMALL LETTER IOTA + 0x03ba: 0x00e4, # GREEK SMALL LETTER KAPPA + 0x03bb: 0x00e5, # GREEK SMALL LETTER LAMDA + 0x03bc: 0x00e6, # GREEK SMALL LETTER MU + 0x03bd: 0x00e7, # GREEK SMALL LETTER NU + 0x03be: 0x00e8, # GREEK SMALL LETTER XI + 0x03bf: 0x00e9, # GREEK SMALL LETTER OMICRON + 0x03c0: 0x00ea, # GREEK SMALL LETTER PI + 0x03c1: 0x00eb, # GREEK SMALL LETTER RHO + 0x03c2: 0x00ed, # GREEK SMALL LETTER FINAL SIGMA + 0x03c3: 0x00ec, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00ee, # GREEK SMALL LETTER TAU + 0x03c5: 0x00f2, # GREEK SMALL LETTER UPSILON + 0x03c6: 0x00f3, # GREEK SMALL LETTER PHI + 0x03c7: 0x00f4, # GREEK SMALL LETTER CHI + 0x03c8: 0x00f6, # GREEK SMALL LETTER PSI + 0x03c9: 0x00fa, # GREEK SMALL LETTER OMEGA + 0x03ca: 0x00a0, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x03cb: 0x00fb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x03cc: 0x00a2, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x03cd: 0x00a3, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x03ce: 0x00fd, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x2015: 0x008e, # HORIZONTAL BAR + 0x2018: 0x008b, # LEFT SINGLE QUOTATION MARK + 0x2019: 0x008c, # RIGHT SINGLE QUOTATION MARK + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/src/main/resources/PythonLibs/encodings/cp874.py b/src/main/resources/PythonLibs/encodings/cp874.py new file mode 100644 index 0000000000000000000000000000000000000000..6110f46e5b5cecfe7f1ecd125beeafc33acea006 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp874.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp874 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp874', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u20ac' # 0x80 -> EURO SIGN + u'\ufffe' # 0x81 -> UNDEFINED + u'\ufffe' # 0x82 -> UNDEFINED + u'\ufffe' # 0x83 -> UNDEFINED + u'\ufffe' # 0x84 -> UNDEFINED + u'\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + u'\ufffe' # 0x86 -> UNDEFINED + u'\ufffe' # 0x87 -> UNDEFINED + u'\ufffe' # 0x88 -> UNDEFINED + u'\ufffe' # 0x89 -> UNDEFINED + u'\ufffe' # 0x8A -> UNDEFINED + u'\ufffe' # 0x8B -> UNDEFINED + u'\ufffe' # 0x8C -> UNDEFINED + u'\ufffe' # 0x8D -> UNDEFINED + u'\ufffe' # 0x8E -> UNDEFINED + u'\ufffe' # 0x8F -> UNDEFINED + u'\ufffe' # 0x90 -> UNDEFINED + u'\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + u'\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + u'\u2022' # 0x95 -> BULLET + u'\u2013' # 0x96 -> EN DASH + u'\u2014' # 0x97 -> EM DASH + u'\ufffe' # 0x98 -> UNDEFINED + u'\ufffe' # 0x99 -> UNDEFINED + u'\ufffe' # 0x9A -> UNDEFINED + u'\ufffe' # 0x9B -> UNDEFINED + u'\ufffe' # 0x9C -> UNDEFINED + u'\ufffe' # 0x9D -> UNDEFINED + u'\ufffe' # 0x9E -> UNDEFINED + u'\ufffe' # 0x9F -> UNDEFINED + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + u'\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + u'\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + u'\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + u'\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + u'\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + u'\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + u'\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + u'\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + u'\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + u'\u0e0b' # 0xAB -> THAI CHARACTER SO SO + u'\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + u'\u0e0d' # 0xAD -> THAI CHARACTER YO YING + u'\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + u'\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + u'\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + u'\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + u'\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + u'\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + u'\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + u'\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + u'\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + u'\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + u'\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + u'\u0e19' # 0xB9 -> THAI CHARACTER NO NU + u'\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + u'\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + u'\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + u'\u0e1d' # 0xBD -> THAI CHARACTER FO FA + u'\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + u'\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + u'\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + u'\u0e21' # 0xC1 -> THAI CHARACTER MO MA + u'\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + u'\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + u'\u0e24' # 0xC4 -> THAI CHARACTER RU + u'\u0e25' # 0xC5 -> THAI CHARACTER LO LING + u'\u0e26' # 0xC6 -> THAI CHARACTER LU + u'\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + u'\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + u'\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + u'\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + u'\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + u'\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + u'\u0e2d' # 0xCD -> THAI CHARACTER O ANG + u'\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + u'\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + u'\u0e30' # 0xD0 -> THAI CHARACTER SARA A + u'\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + u'\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + u'\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + u'\u0e34' # 0xD4 -> THAI CHARACTER SARA I + u'\u0e35' # 0xD5 -> THAI CHARACTER SARA II + u'\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + u'\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + u'\u0e38' # 0xD8 -> THAI CHARACTER SARA U + u'\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + u'\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + u'\ufffe' # 0xDB -> UNDEFINED + u'\ufffe' # 0xDC -> UNDEFINED + u'\ufffe' # 0xDD -> UNDEFINED + u'\ufffe' # 0xDE -> UNDEFINED + u'\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + u'\u0e40' # 0xE0 -> THAI CHARACTER SARA E + u'\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + u'\u0e42' # 0xE2 -> THAI CHARACTER SARA O + u'\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + u'\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + u'\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + u'\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + u'\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + u'\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + u'\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + u'\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + u'\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + u'\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + u'\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + u'\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + u'\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + u'\u0e50' # 0xF0 -> THAI DIGIT ZERO + u'\u0e51' # 0xF1 -> THAI DIGIT ONE + u'\u0e52' # 0xF2 -> THAI DIGIT TWO + u'\u0e53' # 0xF3 -> THAI DIGIT THREE + u'\u0e54' # 0xF4 -> THAI DIGIT FOUR + u'\u0e55' # 0xF5 -> THAI DIGIT FIVE + u'\u0e56' # 0xF6 -> THAI DIGIT SIX + u'\u0e57' # 0xF7 -> THAI DIGIT SEVEN + u'\u0e58' # 0xF8 -> THAI DIGIT EIGHT + u'\u0e59' # 0xF9 -> THAI DIGIT NINE + u'\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + u'\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + u'\ufffe' # 0xFC -> UNDEFINED + u'\ufffe' # 0xFD -> UNDEFINED + u'\ufffe' # 0xFE -> UNDEFINED + u'\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp875.py b/src/main/resources/PythonLibs/encodings/cp875.py new file mode 100644 index 0000000000000000000000000000000000000000..72b160b02f7908d91f18c5a7d873847ec9c1db77 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp875.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp875 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp875', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x9c' # 0x04 -> CONTROL + u'\t' # 0x05 -> HORIZONTAL TABULATION + u'\x86' # 0x06 -> CONTROL + u'\x7f' # 0x07 -> DELETE + u'\x97' # 0x08 -> CONTROL + u'\x8d' # 0x09 -> CONTROL + u'\x8e' # 0x0A -> CONTROL + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x9d' # 0x14 -> CONTROL + u'\x85' # 0x15 -> CONTROL + u'\x08' # 0x16 -> BACKSPACE + u'\x87' # 0x17 -> CONTROL + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x92' # 0x1A -> CONTROL + u'\x8f' # 0x1B -> CONTROL + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u'\x80' # 0x20 -> CONTROL + u'\x81' # 0x21 -> CONTROL + u'\x82' # 0x22 -> CONTROL + u'\x83' # 0x23 -> CONTROL + u'\x84' # 0x24 -> CONTROL + u'\n' # 0x25 -> LINE FEED + u'\x17' # 0x26 -> END OF TRANSMISSION BLOCK + u'\x1b' # 0x27 -> ESCAPE + u'\x88' # 0x28 -> CONTROL + u'\x89' # 0x29 -> CONTROL + u'\x8a' # 0x2A -> CONTROL + u'\x8b' # 0x2B -> CONTROL + u'\x8c' # 0x2C -> CONTROL + u'\x05' # 0x2D -> ENQUIRY + u'\x06' # 0x2E -> ACKNOWLEDGE + u'\x07' # 0x2F -> BELL + u'\x90' # 0x30 -> CONTROL + u'\x91' # 0x31 -> CONTROL + u'\x16' # 0x32 -> SYNCHRONOUS IDLE + u'\x93' # 0x33 -> CONTROL + u'\x94' # 0x34 -> CONTROL + u'\x95' # 0x35 -> CONTROL + u'\x96' # 0x36 -> CONTROL + u'\x04' # 0x37 -> END OF TRANSMISSION + u'\x98' # 0x38 -> CONTROL + u'\x99' # 0x39 -> CONTROL + u'\x9a' # 0x3A -> CONTROL + u'\x9b' # 0x3B -> CONTROL + u'\x14' # 0x3C -> DEVICE CONTROL FOUR + u'\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + u'\x9e' # 0x3E -> CONTROL + u'\x1a' # 0x3F -> SUBSTITUTE + u' ' # 0x40 -> SPACE + u'\u0391' # 0x41 -> GREEK CAPITAL LETTER ALPHA + u'\u0392' # 0x42 -> GREEK CAPITAL LETTER BETA + u'\u0393' # 0x43 -> GREEK CAPITAL LETTER GAMMA + u'\u0394' # 0x44 -> GREEK CAPITAL LETTER DELTA + u'\u0395' # 0x45 -> GREEK CAPITAL LETTER EPSILON + u'\u0396' # 0x46 -> GREEK CAPITAL LETTER ZETA + u'\u0397' # 0x47 -> GREEK CAPITAL LETTER ETA + u'\u0398' # 0x48 -> GREEK CAPITAL LETTER THETA + u'\u0399' # 0x49 -> GREEK CAPITAL LETTER IOTA + u'[' # 0x4A -> LEFT SQUARE BRACKET + u'.' # 0x4B -> FULL STOP + u'<' # 0x4C -> LESS-THAN SIGN + u'(' # 0x4D -> LEFT PARENTHESIS + u'+' # 0x4E -> PLUS SIGN + u'!' # 0x4F -> EXCLAMATION MARK + u'&' # 0x50 -> AMPERSAND + u'\u039a' # 0x51 -> GREEK CAPITAL LETTER KAPPA + u'\u039b' # 0x52 -> GREEK CAPITAL LETTER LAMDA + u'\u039c' # 0x53 -> GREEK CAPITAL LETTER MU + u'\u039d' # 0x54 -> GREEK CAPITAL LETTER NU + u'\u039e' # 0x55 -> GREEK CAPITAL LETTER XI + u'\u039f' # 0x56 -> GREEK CAPITAL LETTER OMICRON + u'\u03a0' # 0x57 -> GREEK CAPITAL LETTER PI + u'\u03a1' # 0x58 -> GREEK CAPITAL LETTER RHO + u'\u03a3' # 0x59 -> GREEK CAPITAL LETTER SIGMA + u']' # 0x5A -> RIGHT SQUARE BRACKET + u'$' # 0x5B -> DOLLAR SIGN + u'*' # 0x5C -> ASTERISK + u')' # 0x5D -> RIGHT PARENTHESIS + u';' # 0x5E -> SEMICOLON + u'^' # 0x5F -> CIRCUMFLEX ACCENT + u'-' # 0x60 -> HYPHEN-MINUS + u'/' # 0x61 -> SOLIDUS + u'\u03a4' # 0x62 -> GREEK CAPITAL LETTER TAU + u'\u03a5' # 0x63 -> GREEK CAPITAL LETTER UPSILON + u'\u03a6' # 0x64 -> GREEK CAPITAL LETTER PHI + u'\u03a7' # 0x65 -> GREEK CAPITAL LETTER CHI + u'\u03a8' # 0x66 -> GREEK CAPITAL LETTER PSI + u'\u03a9' # 0x67 -> GREEK CAPITAL LETTER OMEGA + u'\u03aa' # 0x68 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + u'\u03ab' # 0x69 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + u'|' # 0x6A -> VERTICAL LINE + u',' # 0x6B -> COMMA + u'%' # 0x6C -> PERCENT SIGN + u'_' # 0x6D -> LOW LINE + u'>' # 0x6E -> GREATER-THAN SIGN + u'?' # 0x6F -> QUESTION MARK + u'\xa8' # 0x70 -> DIAERESIS + u'\u0386' # 0x71 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + u'\u0388' # 0x72 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + u'\u0389' # 0x73 -> GREEK CAPITAL LETTER ETA WITH TONOS + u'\xa0' # 0x74 -> NO-BREAK SPACE + u'\u038a' # 0x75 -> GREEK CAPITAL LETTER IOTA WITH TONOS + u'\u038c' # 0x76 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + u'\u038e' # 0x77 -> GREEK CAPITAL LETTER UPSILON WITH TONOS + u'\u038f' # 0x78 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + u'`' # 0x79 -> GRAVE ACCENT + u':' # 0x7A -> COLON + u'#' # 0x7B -> NUMBER SIGN + u'@' # 0x7C -> COMMERCIAL AT + u"'" # 0x7D -> APOSTROPHE + u'=' # 0x7E -> EQUALS SIGN + u'"' # 0x7F -> QUOTATION MARK + u'\u0385' # 0x80 -> GREEK DIALYTIKA TONOS + u'a' # 0x81 -> LATIN SMALL LETTER A + u'b' # 0x82 -> LATIN SMALL LETTER B + u'c' # 0x83 -> LATIN SMALL LETTER C + u'd' # 0x84 -> LATIN SMALL LETTER D + u'e' # 0x85 -> LATIN SMALL LETTER E + u'f' # 0x86 -> LATIN SMALL LETTER F + u'g' # 0x87 -> LATIN SMALL LETTER G + u'h' # 0x88 -> LATIN SMALL LETTER H + u'i' # 0x89 -> LATIN SMALL LETTER I + u'\u03b1' # 0x8A -> GREEK SMALL LETTER ALPHA + u'\u03b2' # 0x8B -> GREEK SMALL LETTER BETA + u'\u03b3' # 0x8C -> GREEK SMALL LETTER GAMMA + u'\u03b4' # 0x8D -> GREEK SMALL LETTER DELTA + u'\u03b5' # 0x8E -> GREEK SMALL LETTER EPSILON + u'\u03b6' # 0x8F -> GREEK SMALL LETTER ZETA + u'\xb0' # 0x90 -> DEGREE SIGN + u'j' # 0x91 -> LATIN SMALL LETTER J + u'k' # 0x92 -> LATIN SMALL LETTER K + u'l' # 0x93 -> LATIN SMALL LETTER L + u'm' # 0x94 -> LATIN SMALL LETTER M + u'n' # 0x95 -> LATIN SMALL LETTER N + u'o' # 0x96 -> LATIN SMALL LETTER O + u'p' # 0x97 -> LATIN SMALL LETTER P + u'q' # 0x98 -> LATIN SMALL LETTER Q + u'r' # 0x99 -> LATIN SMALL LETTER R + u'\u03b7' # 0x9A -> GREEK SMALL LETTER ETA + u'\u03b8' # 0x9B -> GREEK SMALL LETTER THETA + u'\u03b9' # 0x9C -> GREEK SMALL LETTER IOTA + u'\u03ba' # 0x9D -> GREEK SMALL LETTER KAPPA + u'\u03bb' # 0x9E -> GREEK SMALL LETTER LAMDA + u'\u03bc' # 0x9F -> GREEK SMALL LETTER MU + u'\xb4' # 0xA0 -> ACUTE ACCENT + u'~' # 0xA1 -> TILDE + u's' # 0xA2 -> LATIN SMALL LETTER S + u't' # 0xA3 -> LATIN SMALL LETTER T + u'u' # 0xA4 -> LATIN SMALL LETTER U + u'v' # 0xA5 -> LATIN SMALL LETTER V + u'w' # 0xA6 -> LATIN SMALL LETTER W + u'x' # 0xA7 -> LATIN SMALL LETTER X + u'y' # 0xA8 -> LATIN SMALL LETTER Y + u'z' # 0xA9 -> LATIN SMALL LETTER Z + u'\u03bd' # 0xAA -> GREEK SMALL LETTER NU + u'\u03be' # 0xAB -> GREEK SMALL LETTER XI + u'\u03bf' # 0xAC -> GREEK SMALL LETTER OMICRON + u'\u03c0' # 0xAD -> GREEK SMALL LETTER PI + u'\u03c1' # 0xAE -> GREEK SMALL LETTER RHO + u'\u03c3' # 0xAF -> GREEK SMALL LETTER SIGMA + u'\xa3' # 0xB0 -> POUND SIGN + u'\u03ac' # 0xB1 -> GREEK SMALL LETTER ALPHA WITH TONOS + u'\u03ad' # 0xB2 -> GREEK SMALL LETTER EPSILON WITH TONOS + u'\u03ae' # 0xB3 -> GREEK SMALL LETTER ETA WITH TONOS + u'\u03ca' # 0xB4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + u'\u03af' # 0xB5 -> GREEK SMALL LETTER IOTA WITH TONOS + u'\u03cc' # 0xB6 -> GREEK SMALL LETTER OMICRON WITH TONOS + u'\u03cd' # 0xB7 -> GREEK SMALL LETTER UPSILON WITH TONOS + u'\u03cb' # 0xB8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + u'\u03ce' # 0xB9 -> GREEK SMALL LETTER OMEGA WITH TONOS + u'\u03c2' # 0xBA -> GREEK SMALL LETTER FINAL SIGMA + u'\u03c4' # 0xBB -> GREEK SMALL LETTER TAU + u'\u03c5' # 0xBC -> GREEK SMALL LETTER UPSILON + u'\u03c6' # 0xBD -> GREEK SMALL LETTER PHI + u'\u03c7' # 0xBE -> GREEK SMALL LETTER CHI + u'\u03c8' # 0xBF -> GREEK SMALL LETTER PSI + u'{' # 0xC0 -> LEFT CURLY BRACKET + u'A' # 0xC1 -> LATIN CAPITAL LETTER A + u'B' # 0xC2 -> LATIN CAPITAL LETTER B + u'C' # 0xC3 -> LATIN CAPITAL LETTER C + u'D' # 0xC4 -> LATIN CAPITAL LETTER D + u'E' # 0xC5 -> LATIN CAPITAL LETTER E + u'F' # 0xC6 -> LATIN CAPITAL LETTER F + u'G' # 0xC7 -> LATIN CAPITAL LETTER G + u'H' # 0xC8 -> LATIN CAPITAL LETTER H + u'I' # 0xC9 -> LATIN CAPITAL LETTER I + u'\xad' # 0xCA -> SOFT HYPHEN + u'\u03c9' # 0xCB -> GREEK SMALL LETTER OMEGA + u'\u0390' # 0xCC -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + u'\u03b0' # 0xCD -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + u'\u2018' # 0xCE -> LEFT SINGLE QUOTATION MARK + u'\u2015' # 0xCF -> HORIZONTAL BAR + u'}' # 0xD0 -> RIGHT CURLY BRACKET + u'J' # 0xD1 -> LATIN CAPITAL LETTER J + u'K' # 0xD2 -> LATIN CAPITAL LETTER K + u'L' # 0xD3 -> LATIN CAPITAL LETTER L + u'M' # 0xD4 -> LATIN CAPITAL LETTER M + u'N' # 0xD5 -> LATIN CAPITAL LETTER N + u'O' # 0xD6 -> LATIN CAPITAL LETTER O + u'P' # 0xD7 -> LATIN CAPITAL LETTER P + u'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + u'R' # 0xD9 -> LATIN CAPITAL LETTER R + u'\xb1' # 0xDA -> PLUS-MINUS SIGN + u'\xbd' # 0xDB -> VULGAR FRACTION ONE HALF + u'\x1a' # 0xDC -> SUBSTITUTE + u'\u0387' # 0xDD -> GREEK ANO TELEIA + u'\u2019' # 0xDE -> RIGHT SINGLE QUOTATION MARK + u'\xa6' # 0xDF -> BROKEN BAR + u'\\' # 0xE0 -> REVERSE SOLIDUS + u'\x1a' # 0xE1 -> SUBSTITUTE + u'S' # 0xE2 -> LATIN CAPITAL LETTER S + u'T' # 0xE3 -> LATIN CAPITAL LETTER T + u'U' # 0xE4 -> LATIN CAPITAL LETTER U + u'V' # 0xE5 -> LATIN CAPITAL LETTER V + u'W' # 0xE6 -> LATIN CAPITAL LETTER W + u'X' # 0xE7 -> LATIN CAPITAL LETTER X + u'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + u'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + u'\xb2' # 0xEA -> SUPERSCRIPT TWO + u'\xa7' # 0xEB -> SECTION SIGN + u'\x1a' # 0xEC -> SUBSTITUTE + u'\x1a' # 0xED -> SUBSTITUTE + u'\xab' # 0xEE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xEF -> NOT SIGN + u'0' # 0xF0 -> DIGIT ZERO + u'1' # 0xF1 -> DIGIT ONE + u'2' # 0xF2 -> DIGIT TWO + u'3' # 0xF3 -> DIGIT THREE + u'4' # 0xF4 -> DIGIT FOUR + u'5' # 0xF5 -> DIGIT FIVE + u'6' # 0xF6 -> DIGIT SIX + u'7' # 0xF7 -> DIGIT SEVEN + u'8' # 0xF8 -> DIGIT EIGHT + u'9' # 0xF9 -> DIGIT NINE + u'\xb3' # 0xFA -> SUPERSCRIPT THREE + u'\xa9' # 0xFB -> COPYRIGHT SIGN + u'\x1a' # 0xFC -> SUBSTITUTE + u'\x1a' # 0xFD -> SUBSTITUTE + u'\xbb' # 0xFE -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/cp932.py b/src/main/resources/PythonLibs/encodings/cp932.py new file mode 100644 index 0000000000000000000000000000000000000000..e01f59b719057657c65f739e43fc0400722293e6 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp932.py @@ -0,0 +1,39 @@ +# +# cp932.py: Python Unicode Codec for CP932 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('cp932') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='cp932', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/cp949.py b/src/main/resources/PythonLibs/encodings/cp949.py new file mode 100644 index 0000000000000000000000000000000000000000..627c87125e2affe4bc75eae769f901a54e2f92fb --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp949.py @@ -0,0 +1,39 @@ +# +# cp949.py: Python Unicode Codec for CP949 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_kr, codecs +import _multibytecodec as mbc + +codec = _codecs_kr.getcodec('cp949') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='cp949', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/cp950.py b/src/main/resources/PythonLibs/encodings/cp950.py new file mode 100644 index 0000000000000000000000000000000000000000..39eec5ed0ddef9579cf1be928acfd1a2cf37d39b --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/cp950.py @@ -0,0 +1,39 @@ +# +# cp950.py: Python Unicode Codec for CP950 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_tw, codecs +import _multibytecodec as mbc + +codec = _codecs_tw.getcodec('cp950') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='cp950', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/euc_jis_2004.py b/src/main/resources/PythonLibs/encodings/euc_jis_2004.py new file mode 100644 index 0000000000000000000000000000000000000000..72b87aea68862f2fabbb7b30274e683a6654d4ae --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/euc_jis_2004.py @@ -0,0 +1,39 @@ +# +# euc_jis_2004.py: Python Unicode Codec for EUC_JIS_2004 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('euc_jis_2004') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_jis_2004', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/euc_jisx0213.py b/src/main/resources/PythonLibs/encodings/euc_jisx0213.py new file mode 100644 index 0000000000000000000000000000000000000000..cc47d04112a187d585dce4af4bd76a38e89e0f51 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/euc_jisx0213.py @@ -0,0 +1,39 @@ +# +# euc_jisx0213.py: Python Unicode Codec for EUC_JISX0213 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('euc_jisx0213') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_jisx0213', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/euc_jp.py b/src/main/resources/PythonLibs/encodings/euc_jp.py new file mode 100644 index 0000000000000000000000000000000000000000..7bcbe4147f2ad49c6a0d3a9cc6eb5417cdabdf2d --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/euc_jp.py @@ -0,0 +1,39 @@ +# +# euc_jp.py: Python Unicode Codec for EUC_JP +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('euc_jp') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_jp', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/euc_kr.py b/src/main/resources/PythonLibs/encodings/euc_kr.py new file mode 100644 index 0000000000000000000000000000000000000000..c1fb1260e879f0c42491be24b6a0cd0b8a365122 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/euc_kr.py @@ -0,0 +1,39 @@ +# +# euc_kr.py: Python Unicode Codec for EUC_KR +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_kr, codecs +import _multibytecodec as mbc + +codec = _codecs_kr.getcodec('euc_kr') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='euc_kr', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/gb18030.py b/src/main/resources/PythonLibs/encodings/gb18030.py new file mode 100644 index 0000000000000000000000000000000000000000..34fb6c366a76147b9e2b4a62f886b2a91eb6add8 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/gb18030.py @@ -0,0 +1,39 @@ +# +# gb18030.py: Python Unicode Codec for GB18030 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('gb18030') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='gb18030', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/gb2312.py b/src/main/resources/PythonLibs/encodings/gb2312.py new file mode 100644 index 0000000000000000000000000000000000000000..3c3b837d618ecd262007eec7d3bd786209e91c06 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/gb2312.py @@ -0,0 +1,39 @@ +# +# gb2312.py: Python Unicode Codec for GB2312 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('gb2312') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='gb2312', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/gbk.py b/src/main/resources/PythonLibs/encodings/gbk.py new file mode 100644 index 0000000000000000000000000000000000000000..1b45db89859cdf58931436a954e7eb304b5962b8 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/gbk.py @@ -0,0 +1,39 @@ +# +# gbk.py: Python Unicode Codec for GBK +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('gbk') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='gbk', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/hex_codec.py b/src/main/resources/PythonLibs/encodings/hex_codec.py new file mode 100644 index 0000000000000000000000000000000000000000..91b38d952e1f9e638e34b867ec74fa4eb2323e9f --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/hex_codec.py @@ -0,0 +1,79 @@ +""" Python 'hex_codec' Codec - 2-digit hex content transfer encoding + + Unlike most of the other codecs which target Unicode, this codec + will return Python string objects for both encode and decode. + + Written by Marc-Andre Lemburg (mal@lemburg.com). + +""" +import codecs, binascii + +### Codec APIs + +def hex_encode(input,errors='strict'): + + """ Encodes the object input and returns a tuple (output + object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = binascii.b2a_hex(input) + return (output, len(input)) + +def hex_decode(input,errors='strict'): + + """ Decodes the object input and returns a tuple (output + object, length consumed). + + input must be an object which provides the bf_getreadbuf + buffer slot. Python strings, buffer objects and memory + mapped files are examples of objects providing this slot. + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = binascii.a2b_hex(input) + return (output, len(input)) + +class Codec(codecs.Codec): + + def encode(self, input,errors='strict'): + return hex_encode(input,errors) + def decode(self, input,errors='strict'): + return hex_decode(input,errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + assert self.errors == 'strict' + return binascii.b2a_hex(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + assert self.errors == 'strict' + return binascii.a2b_hex(input) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='hex', + encode=hex_encode, + decode=hex_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/hp_roman8.py b/src/main/resources/PythonLibs/encodings/hp_roman8.py new file mode 100644 index 0000000000000000000000000000000000000000..dbaaa72d76dd0e8fdbac4b88319e861fe198f82a --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/hp_roman8.py @@ -0,0 +1,152 @@ +""" Python Character Mapping Codec generated from 'hp_roman8.txt' with gencodec.py. + + Based on data from ftp://dkuug.dk/i18n/charmaps/HP-ROMAN8 (Keld Simonsen) + + Original source: LaserJet IIP Printer User's Manual HP part no + 33471-90901, Hewlet-Packard, June 1989. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_map) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_map)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='hp-roman8', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x00a1: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00a2: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00a3: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00a4: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00a5: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00a6: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00a7: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00a8: 0x00b4, # ACUTE ACCENT + 0x00a9: 0x02cb, # MODIFIER LETTER GRAVE ACCENT (Mandarin Chinese fourth tone) + 0x00aa: 0x02c6, # MODIFIER LETTER CIRCUMFLEX ACCENT + 0x00ab: 0x00a8, # DIAERESIS + 0x00ac: 0x02dc, # SMALL TILDE + 0x00ad: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ae: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00af: 0x20a4, # LIRA SIGN + 0x00b0: 0x00af, # MACRON + 0x00b1: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00b2: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00b3: 0x00b0, # DEGREE SIGN + 0x00b4: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00b5: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x00b6: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00b7: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00b8: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00b9: 0x00bf, # INVERTED QUESTION MARK + 0x00ba: 0x00a4, # CURRENCY SIGN + 0x00bb: 0x00a3, # POUND SIGN + 0x00bc: 0x00a5, # YEN SIGN + 0x00bd: 0x00a7, # SECTION SIGN + 0x00be: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00bf: 0x00a2, # CENT SIGN + 0x00c0: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00c1: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00c2: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00c3: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00c4: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00c5: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x00c6: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00c7: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00c8: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x00c9: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x00ca: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x00cb: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x00cc: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00cd: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ce: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00cf: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00d0: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00d1: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00d2: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d3: 0x00c6, # LATIN CAPITAL LETTER AE + 0x00d4: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00d5: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00d6: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x00d7: 0x00e6, # LATIN SMALL LETTER AE + 0x00d8: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00d9: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x00da: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00db: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dc: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00dd: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00de: 0x00df, # LATIN SMALL LETTER SHARP S (German) + 0x00df: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e0: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00e1: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00e2: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00e3: 0x00d0, # LATIN CAPITAL LETTER ETH (Icelandic) + 0x00e4: 0x00f0, # LATIN SMALL LETTER ETH (Icelandic) + 0x00e5: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00e6: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00e7: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e8: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e9: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00ea: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00eb: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00ec: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00ed: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ee: 0x0178, # LATIN CAPITAL LETTER Y WITH DIAERESIS + 0x00ef: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x00f0: 0x00de, # LATIN CAPITAL LETTER THORN (Icelandic) + 0x00f1: 0x00fe, # LATIN SMALL LETTER THORN (Icelandic) + 0x00f2: 0x00b7, # MIDDLE DOT + 0x00f3: 0x00b5, # MICRO SIGN + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f6: 0x2014, # EM DASH + 0x00f7: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00f8: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00f9: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00fa: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00fb: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00fc: 0x25a0, # BLACK SQUARE + 0x00fd: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00fe: 0x00b1, # PLUS-MINUS SIGN + 0x00ff: None, +}) + +### Encoding Map + +encoding_map = codecs.make_encoding_map(decoding_map) diff --git a/src/main/resources/PythonLibs/encodings/hz.py b/src/main/resources/PythonLibs/encodings/hz.py new file mode 100644 index 0000000000000000000000000000000000000000..383442a3c9ac9ae5d093d972f1ff26fe758897d5 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/hz.py @@ -0,0 +1,39 @@ +# +# hz.py: Python Unicode Codec for HZ +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_cn, codecs +import _multibytecodec as mbc + +codec = _codecs_cn.getcodec('hz') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='hz', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/idna.py b/src/main/resources/PythonLibs/encodings/idna.py new file mode 100644 index 0000000000000000000000000000000000000000..23c91caad119996f349f571a4d5637e3bdc3b127 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/idna.py @@ -0,0 +1,173 @@ +import codecs +import re +from com.ibm.icu.text import StringPrep, StringPrepParseException +from java.net import IDN + + +# IDNA section 3.1 +dots = re.compile(u"[\u002E\u3002\uFF0E\uFF61]") + + +def nameprep(label): + try: + return StringPrep.getInstance(StringPrep.RFC3491_NAMEPREP).prepare( + label, StringPrep.ALLOW_UNASSIGNED) + except StringPrepParseException, e: + raise UnicodeError("Invalid character") + + +def ToASCII(label): + return IDN.toASCII(label) + + +def ToUnicode(label): + return IDN.toUnicode(label) + + +# BELOW is the implementation shared with CPython. TODO we should merge. + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self,input,errors='strict'): + + if errors != 'strict': + # IDNA is quite clear that implementations must be strict + raise UnicodeError("unsupported error handling "+errors) + + if not input: + return "", 0 + + result = [] + labels = dots.split(input) + if labels and len(labels[-1])==0: + trailing_dot = '.' + del labels[-1] + else: + trailing_dot = '' + for label in labels: + result.append(ToASCII(label)) + # Join with U+002E + return ".".join(result)+trailing_dot, len(input) + + def decode(self,input,errors='strict'): + + if errors != 'strict': + raise UnicodeError("Unsupported error handling "+errors) + + if not input: + return u"", 0 + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(input, unicode): + labels = dots.split(input) + else: + # Must be ASCII string + input = str(input) + unicode(input, "ascii") + labels = input.split(".") + + if labels and len(labels[-1]) == 0: + trailing_dot = u'.' + del labels[-1] + else: + trailing_dot = u'' + + result = [] + for label in labels: + result.append(ToUnicode(label)) + + return u".".join(result)+trailing_dot, len(input) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, input, errors, final): + if errors != 'strict': + # IDNA is quite clear that implementations must be strict + raise UnicodeError("unsupported error handling "+errors) + + if not input: + return ("", 0) + + labels = dots.split(input) + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(ToASCII(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, input, errors, final): + if errors != 'strict': + raise UnicodeError("Unsupported error handling "+errors) + + if not input: + return (u"", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(input, unicode): + labels = dots.split(input) + else: + # Must be ASCII string + input = str(input) + unicode(input, "ascii") + labels = input.split(".") + + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = u'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = u'.' + + result = [] + size = 0 + for label in labels: + result.append(ToUnicode(label)) + if size: + size += 1 + size += len(label) + + result = u".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso2022_jp.py b/src/main/resources/PythonLibs/encodings/iso2022_jp.py new file mode 100644 index 0000000000000000000000000000000000000000..ab0406069356e4dfd7cfcc4a981535c40c9c5574 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso2022_jp.py @@ -0,0 +1,39 @@ +# +# iso2022_jp.py: Python Unicode Codec for ISO2022_JP +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso2022_jp_1.py b/src/main/resources/PythonLibs/encodings/iso2022_jp_1.py new file mode 100644 index 0000000000000000000000000000000000000000..997044dc3787496be0ed70f2ed1b63d9ebe1b0ac --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso2022_jp_1.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_1.py: Python Unicode Codec for ISO2022_JP_1 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_1') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_1', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso2022_jp_2.py b/src/main/resources/PythonLibs/encodings/iso2022_jp_2.py new file mode 100644 index 0000000000000000000000000000000000000000..9106bf762512fdd3e9deb73cba91529ab0db94ac --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso2022_jp_2.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_2.py: Python Unicode Codec for ISO2022_JP_2 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_2') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso2022_jp_2004.py b/src/main/resources/PythonLibs/encodings/iso2022_jp_2004.py new file mode 100644 index 0000000000000000000000000000000000000000..40198bf098570be21f67335c42fbf9f956204725 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso2022_jp_2004.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_2004.py: Python Unicode Codec for ISO2022_JP_2004 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_2004') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_2004', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso2022_jp_3.py b/src/main/resources/PythonLibs/encodings/iso2022_jp_3.py new file mode 100644 index 0000000000000000000000000000000000000000..346e08beccbbafd347371743ec89333370d3b083 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso2022_jp_3.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_3.py: Python Unicode Codec for ISO2022_JP_3 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_3') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_3', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso2022_jp_ext.py b/src/main/resources/PythonLibs/encodings/iso2022_jp_ext.py new file mode 100644 index 0000000000000000000000000000000000000000..752bab9813a094e9446b084ae90957290f1324c0 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso2022_jp_ext.py @@ -0,0 +1,39 @@ +# +# iso2022_jp_ext.py: Python Unicode Codec for ISO2022_JP_EXT +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_jp_ext') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_jp_ext', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso2022_kr.py b/src/main/resources/PythonLibs/encodings/iso2022_kr.py new file mode 100644 index 0000000000000000000000000000000000000000..bf7018763eae38729d6c206379467f36e41910c3 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso2022_kr.py @@ -0,0 +1,39 @@ +# +# iso2022_kr.py: Python Unicode Codec for ISO2022_KR +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_iso2022, codecs +import _multibytecodec as mbc + +codec = _codecs_iso2022.getcodec('iso2022_kr') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='iso2022_kr', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_1.py b/src/main/resources/PythonLibs/encodings/iso8859_1.py new file mode 100644 index 0000000000000000000000000000000000000000..71bc13fcbb3d5a9e2907e7b7f097d13c8425eb75 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_1.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_1 generated from 'MAPPINGS/ISO8859/8859-1.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-1', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xbf' # 0xBF -> INVERTED QUESTION MARK + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + u'\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_10.py b/src/main/resources/PythonLibs/encodings/iso8859_10.py new file mode 100644 index 0000000000000000000000000000000000000000..757e5c5eb9a3cd45f7ef66fc335b6889f740384b --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_10.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_10 generated from 'MAPPINGS/ISO8859/8859-10.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-10', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u0112' # 0xA2 -> LATIN CAPITAL LETTER E WITH MACRON + u'\u0122' # 0xA3 -> LATIN CAPITAL LETTER G WITH CEDILLA + u'\u012a' # 0xA4 -> LATIN CAPITAL LETTER I WITH MACRON + u'\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE + u'\u0136' # 0xA6 -> LATIN CAPITAL LETTER K WITH CEDILLA + u'\xa7' # 0xA7 -> SECTION SIGN + u'\u013b' # 0xA8 -> LATIN CAPITAL LETTER L WITH CEDILLA + u'\u0110' # 0xA9 -> LATIN CAPITAL LETTER D WITH STROKE + u'\u0160' # 0xAA -> LATIN CAPITAL LETTER S WITH CARON + u'\u0166' # 0xAB -> LATIN CAPITAL LETTER T WITH STROKE + u'\u017d' # 0xAC -> LATIN CAPITAL LETTER Z WITH CARON + u'\xad' # 0xAD -> SOFT HYPHEN + u'\u016a' # 0xAE -> LATIN CAPITAL LETTER U WITH MACRON + u'\u014a' # 0xAF -> LATIN CAPITAL LETTER ENG + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + u'\u0113' # 0xB2 -> LATIN SMALL LETTER E WITH MACRON + u'\u0123' # 0xB3 -> LATIN SMALL LETTER G WITH CEDILLA + u'\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON + u'\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE + u'\u0137' # 0xB6 -> LATIN SMALL LETTER K WITH CEDILLA + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\u013c' # 0xB8 -> LATIN SMALL LETTER L WITH CEDILLA + u'\u0111' # 0xB9 -> LATIN SMALL LETTER D WITH STROKE + u'\u0161' # 0xBA -> LATIN SMALL LETTER S WITH CARON + u'\u0167' # 0xBB -> LATIN SMALL LETTER T WITH STROKE + u'\u017e' # 0xBC -> LATIN SMALL LETTER Z WITH CARON + u'\u2015' # 0xBD -> HORIZONTAL BAR + u'\u016b' # 0xBE -> LATIN SMALL LETTER U WITH MACRON + u'\u014b' # 0xBF -> LATIN SMALL LETTER ENG + u'\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK + u'\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + u'\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA + u'\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\u0168' # 0xD7 -> LATIN CAPITAL LETTER U WITH TILDE + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + u'\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK + u'\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + u'\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA + u'\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\u0169' # 0xF7 -> LATIN SMALL LETTER U WITH TILDE + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + u'\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + u'\u0138' # 0xFF -> LATIN SMALL LETTER KRA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_11.py b/src/main/resources/PythonLibs/encodings/iso8859_11.py new file mode 100644 index 0000000000000000000000000000000000000000..27ece8dc7b76ee71ae01ef2d7dbc8dff9ea423fb --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_11.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_11 generated from 'MAPPINGS/ISO8859/8859-11.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-11', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + u'\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + u'\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + u'\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + u'\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + u'\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + u'\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + u'\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + u'\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + u'\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + u'\u0e0b' # 0xAB -> THAI CHARACTER SO SO + u'\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + u'\u0e0d' # 0xAD -> THAI CHARACTER YO YING + u'\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + u'\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + u'\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + u'\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + u'\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + u'\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + u'\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + u'\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + u'\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + u'\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + u'\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + u'\u0e19' # 0xB9 -> THAI CHARACTER NO NU + u'\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + u'\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + u'\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + u'\u0e1d' # 0xBD -> THAI CHARACTER FO FA + u'\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + u'\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + u'\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + u'\u0e21' # 0xC1 -> THAI CHARACTER MO MA + u'\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + u'\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + u'\u0e24' # 0xC4 -> THAI CHARACTER RU + u'\u0e25' # 0xC5 -> THAI CHARACTER LO LING + u'\u0e26' # 0xC6 -> THAI CHARACTER LU + u'\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + u'\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + u'\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + u'\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + u'\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + u'\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + u'\u0e2d' # 0xCD -> THAI CHARACTER O ANG + u'\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + u'\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + u'\u0e30' # 0xD0 -> THAI CHARACTER SARA A + u'\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + u'\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + u'\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + u'\u0e34' # 0xD4 -> THAI CHARACTER SARA I + u'\u0e35' # 0xD5 -> THAI CHARACTER SARA II + u'\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + u'\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + u'\u0e38' # 0xD8 -> THAI CHARACTER SARA U + u'\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + u'\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + u'\u0e40' # 0xE0 -> THAI CHARACTER SARA E + u'\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + u'\u0e42' # 0xE2 -> THAI CHARACTER SARA O + u'\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + u'\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + u'\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + u'\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + u'\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + u'\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + u'\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + u'\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + u'\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + u'\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + u'\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + u'\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + u'\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + u'\u0e50' # 0xF0 -> THAI DIGIT ZERO + u'\u0e51' # 0xF1 -> THAI DIGIT ONE + u'\u0e52' # 0xF2 -> THAI DIGIT TWO + u'\u0e53' # 0xF3 -> THAI DIGIT THREE + u'\u0e54' # 0xF4 -> THAI DIGIT FOUR + u'\u0e55' # 0xF5 -> THAI DIGIT FIVE + u'\u0e56' # 0xF6 -> THAI DIGIT SIX + u'\u0e57' # 0xF7 -> THAI DIGIT SEVEN + u'\u0e58' # 0xF8 -> THAI DIGIT EIGHT + u'\u0e59' # 0xF9 -> THAI DIGIT NINE + u'\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + u'\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_13.py b/src/main/resources/PythonLibs/encodings/iso8859_13.py new file mode 100644 index 0000000000000000000000000000000000000000..71adb5c19a8851f1aa6c29d4accf1e772023bf80 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_13.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_13 generated from 'MAPPINGS/ISO8859/8859-13.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-13', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u201d' # 0xA1 -> RIGHT DOUBLE QUOTATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xc6' # 0xAF -> LATIN CAPITAL LETTER AE + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\u201c' # 0xB4 -> LEFT DOUBLE QUOTATION MARK + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xe6' # 0xBF -> LATIN SMALL LETTER AE + u'\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK + u'\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON + u'\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK + u'\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON + u'\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE + u'\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA + u'\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA + u'\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON + u'\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA + u'\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON + u'\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK + u'\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE + u'\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE + u'\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + u'\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK + u'\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK + u'\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON + u'\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK + u'\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON + u'\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE + u'\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE + u'\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA + u'\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA + u'\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON + u'\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA + u'\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON + u'\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + u'\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK + u'\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE + u'\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE + u'\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON + u'\u2019' # 0xFF -> RIGHT SINGLE QUOTATION MARK +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_14.py b/src/main/resources/PythonLibs/encodings/iso8859_14.py new file mode 100644 index 0000000000000000000000000000000000000000..56843d5fd09306231dc613dfb4f524a0eccbea88 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_14.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_14 generated from 'MAPPINGS/ISO8859/8859-14.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-14', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u1e02' # 0xA1 -> LATIN CAPITAL LETTER B WITH DOT ABOVE + u'\u1e03' # 0xA2 -> LATIN SMALL LETTER B WITH DOT ABOVE + u'\xa3' # 0xA3 -> POUND SIGN + u'\u010a' # 0xA4 -> LATIN CAPITAL LETTER C WITH DOT ABOVE + u'\u010b' # 0xA5 -> LATIN SMALL LETTER C WITH DOT ABOVE + u'\u1e0a' # 0xA6 -> LATIN CAPITAL LETTER D WITH DOT ABOVE + u'\xa7' # 0xA7 -> SECTION SIGN + u'\u1e80' # 0xA8 -> LATIN CAPITAL LETTER W WITH GRAVE + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u1e82' # 0xAA -> LATIN CAPITAL LETTER W WITH ACUTE + u'\u1e0b' # 0xAB -> LATIN SMALL LETTER D WITH DOT ABOVE + u'\u1ef2' # 0xAC -> LATIN CAPITAL LETTER Y WITH GRAVE + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\u0178' # 0xAF -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\u1e1e' # 0xB0 -> LATIN CAPITAL LETTER F WITH DOT ABOVE + u'\u1e1f' # 0xB1 -> LATIN SMALL LETTER F WITH DOT ABOVE + u'\u0120' # 0xB2 -> LATIN CAPITAL LETTER G WITH DOT ABOVE + u'\u0121' # 0xB3 -> LATIN SMALL LETTER G WITH DOT ABOVE + u'\u1e40' # 0xB4 -> LATIN CAPITAL LETTER M WITH DOT ABOVE + u'\u1e41' # 0xB5 -> LATIN SMALL LETTER M WITH DOT ABOVE + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\u1e56' # 0xB7 -> LATIN CAPITAL LETTER P WITH DOT ABOVE + u'\u1e81' # 0xB8 -> LATIN SMALL LETTER W WITH GRAVE + u'\u1e57' # 0xB9 -> LATIN SMALL LETTER P WITH DOT ABOVE + u'\u1e83' # 0xBA -> LATIN SMALL LETTER W WITH ACUTE + u'\u1e60' # 0xBB -> LATIN CAPITAL LETTER S WITH DOT ABOVE + u'\u1ef3' # 0xBC -> LATIN SMALL LETTER Y WITH GRAVE + u'\u1e84' # 0xBD -> LATIN CAPITAL LETTER W WITH DIAERESIS + u'\u1e85' # 0xBE -> LATIN SMALL LETTER W WITH DIAERESIS + u'\u1e61' # 0xBF -> LATIN SMALL LETTER S WITH DOT ABOVE + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u0174' # 0xD0 -> LATIN CAPITAL LETTER W WITH CIRCUMFLEX + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\u1e6a' # 0xD7 -> LATIN CAPITAL LETTER T WITH DOT ABOVE + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\u0176' # 0xDE -> LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\u0175' # 0xF0 -> LATIN SMALL LETTER W WITH CIRCUMFLEX + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\u1e6b' # 0xF7 -> LATIN SMALL LETTER T WITH DOT ABOVE + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + u'\u0177' # 0xFE -> LATIN SMALL LETTER Y WITH CIRCUMFLEX + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_15.py b/src/main/resources/PythonLibs/encodings/iso8859_15.py new file mode 100644 index 0000000000000000000000000000000000000000..13b140ca3bd225b5432f71467252e1ece31700b6 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_15.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_15 generated from 'MAPPINGS/ISO8859/8859-15.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-15', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\u20ac' # 0xA4 -> EURO SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON + u'\xa7' # 0xA7 -> SECTION SIGN + u'\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE + u'\u0153' # 0xBD -> LATIN SMALL LIGATURE OE + u'\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\xbf' # 0xBF -> INVERTED QUESTION MARK + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf0' # 0xF0 -> LATIN SMALL LETTER ETH + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + u'\xfe' # 0xFE -> LATIN SMALL LETTER THORN + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_16.py b/src/main/resources/PythonLibs/encodings/iso8859_16.py new file mode 100644 index 0000000000000000000000000000000000000000..00b9ac805556d110fb6b00bca187cf0e58309d6b --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_16.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_16 generated from 'MAPPINGS/ISO8859/8859-16.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-16', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u0105' # 0xA2 -> LATIN SMALL LETTER A WITH OGONEK + u'\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + u'\u20ac' # 0xA4 -> EURO SIGN + u'\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK + u'\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON + u'\xa7' # 0xA7 -> SECTION SIGN + u'\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u0218' # 0xAA -> LATIN CAPITAL LETTER S WITH COMMA BELOW + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\xad' # 0xAD -> SOFT HYPHEN + u'\u017a' # 0xAE -> LATIN SMALL LETTER Z WITH ACUTE + u'\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u010c' # 0xB2 -> LATIN CAPITAL LETTER C WITH CARON + u'\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + u'\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON + u'\u201d' # 0xB5 -> RIGHT DOUBLE QUOTATION MARK + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON + u'\u010d' # 0xB9 -> LATIN SMALL LETTER C WITH CARON + u'\u0219' # 0xBA -> LATIN SMALL LETTER S WITH COMMA BELOW + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE + u'\u0153' # 0xBD -> LATIN SMALL LIGATURE OE + u'\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\u0106' # 0xC5 -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + u'\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\u015a' # 0xD7 -> LATIN CAPITAL LETTER S WITH ACUTE + u'\u0170' # 0xD8 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u0118' # 0xDD -> LATIN CAPITAL LETTER E WITH OGONEK + u'\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u0107' # 0xE5 -> LATIN SMALL LETTER C WITH ACUTE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + u'\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\u015b' # 0xF7 -> LATIN SMALL LETTER S WITH ACUTE + u'\u0171' # 0xF8 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u0119' # 0xFD -> LATIN SMALL LETTER E WITH OGONEK + u'\u021b' # 0xFE -> LATIN SMALL LETTER T WITH COMMA BELOW + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_2.py b/src/main/resources/PythonLibs/encodings/iso8859_2.py new file mode 100644 index 0000000000000000000000000000000000000000..38e91d8e177595faefc7c3e7bcc0ca5604981da2 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_2.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_2 generated from 'MAPPINGS/ISO8859/8859-2.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u02d8' # 0xA2 -> BREVE + u'\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\u013d' # 0xA5 -> LATIN CAPITAL LETTER L WITH CARON + u'\u015a' # 0xA6 -> LATIN CAPITAL LETTER S WITH ACUTE + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + u'\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\u0164' # 0xAB -> LATIN CAPITAL LETTER T WITH CARON + u'\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\xad' # 0xAD -> SOFT HYPHEN + u'\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + u'\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + u'\u02db' # 0xB2 -> OGONEK + u'\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\u013e' # 0xB5 -> LATIN SMALL LETTER L WITH CARON + u'\u015b' # 0xB6 -> LATIN SMALL LETTER S WITH ACUTE + u'\u02c7' # 0xB7 -> CARON + u'\xb8' # 0xB8 -> CEDILLA + u'\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + u'\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + u'\u0165' # 0xBB -> LATIN SMALL LETTER T WITH CARON + u'\u017a' # 0xBC -> LATIN SMALL LETTER Z WITH ACUTE + u'\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT + u'\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + u'\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE + u'\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON + u'\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + u'\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON + u'\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE + u'\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON + u'\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + u'\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + u'\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON + u'\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + u'\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA + u'\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_3.py b/src/main/resources/PythonLibs/encodings/iso8859_3.py new file mode 100644 index 0000000000000000000000000000000000000000..23daafdbb1729f548d92255274a2795fc66ffe0c --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_3.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_3 generated from 'MAPPINGS/ISO8859/8859-3.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-3', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0126' # 0xA1 -> LATIN CAPITAL LETTER H WITH STROKE + u'\u02d8' # 0xA2 -> BREVE + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\ufffe' + u'\u0124' # 0xA6 -> LATIN CAPITAL LETTER H WITH CIRCUMFLEX + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\u0130' # 0xA9 -> LATIN CAPITAL LETTER I WITH DOT ABOVE + u'\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\u011e' # 0xAB -> LATIN CAPITAL LETTER G WITH BREVE + u'\u0134' # 0xAC -> LATIN CAPITAL LETTER J WITH CIRCUMFLEX + u'\xad' # 0xAD -> SOFT HYPHEN + u'\ufffe' + u'\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\u0127' # 0xB1 -> LATIN SMALL LETTER H WITH STROKE + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\u0125' # 0xB6 -> LATIN SMALL LETTER H WITH CIRCUMFLEX + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\u0131' # 0xB9 -> LATIN SMALL LETTER DOTLESS I + u'\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + u'\u011f' # 0xBB -> LATIN SMALL LETTER G WITH BREVE + u'\u0135' # 0xBC -> LATIN SMALL LETTER J WITH CIRCUMFLEX + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\ufffe' + u'\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\ufffe' + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\u010a' # 0xC5 -> LATIN CAPITAL LETTER C WITH DOT ABOVE + u'\u0108' # 0xC6 -> LATIN CAPITAL LETTER C WITH CIRCUMFLEX + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\ufffe' + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u0120' # 0xD5 -> LATIN CAPITAL LETTER G WITH DOT ABOVE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\u011c' # 0xD8 -> LATIN CAPITAL LETTER G WITH CIRCUMFLEX + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u016c' # 0xDD -> LATIN CAPITAL LETTER U WITH BREVE + u'\u015c' # 0xDE -> LATIN CAPITAL LETTER S WITH CIRCUMFLEX + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\ufffe' + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u010b' # 0xE5 -> LATIN SMALL LETTER C WITH DOT ABOVE + u'\u0109' # 0xE6 -> LATIN SMALL LETTER C WITH CIRCUMFLEX + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\ufffe' + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\u0121' # 0xF5 -> LATIN SMALL LETTER G WITH DOT ABOVE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\u011d' # 0xF8 -> LATIN SMALL LETTER G WITH CIRCUMFLEX + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u016d' # 0xFD -> LATIN SMALL LETTER U WITH BREVE + u'\u015d' # 0xFE -> LATIN SMALL LETTER S WITH CIRCUMFLEX + u'\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_4.py b/src/main/resources/PythonLibs/encodings/iso8859_4.py new file mode 100644 index 0000000000000000000000000000000000000000..c8e03b566ae91f3295f3ec42133360d5cf055769 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_4.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_4 generated from 'MAPPINGS/ISO8859/8859-4.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-4', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\u0138' # 0xA2 -> LATIN SMALL LETTER KRA + u'\u0156' # 0xA3 -> LATIN CAPITAL LETTER R WITH CEDILLA + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE + u'\u013b' # 0xA6 -> LATIN CAPITAL LETTER L WITH CEDILLA + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + u'\u0112' # 0xAA -> LATIN CAPITAL LETTER E WITH MACRON + u'\u0122' # 0xAB -> LATIN CAPITAL LETTER G WITH CEDILLA + u'\u0166' # 0xAC -> LATIN CAPITAL LETTER T WITH STROKE + u'\xad' # 0xAD -> SOFT HYPHEN + u'\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + u'\u02db' # 0xB2 -> OGONEK + u'\u0157' # 0xB3 -> LATIN SMALL LETTER R WITH CEDILLA + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE + u'\u013c' # 0xB6 -> LATIN SMALL LETTER L WITH CEDILLA + u'\u02c7' # 0xB7 -> CARON + u'\xb8' # 0xB8 -> CEDILLA + u'\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + u'\u0113' # 0xBA -> LATIN SMALL LETTER E WITH MACRON + u'\u0123' # 0xBB -> LATIN SMALL LETTER G WITH CEDILLA + u'\u0167' # 0xBC -> LATIN SMALL LETTER T WITH STROKE + u'\u014a' # 0xBD -> LATIN CAPITAL LETTER ENG + u'\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + u'\u014b' # 0xBF -> LATIN SMALL LETTER ENG + u'\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK + u'\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\u012a' # 0xCF -> LATIN CAPITAL LETTER I WITH MACRON + u'\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + u'\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA + u'\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON + u'\u0136' # 0xD3 -> LATIN CAPITAL LETTER K WITH CEDILLA + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u0168' # 0xDD -> LATIN CAPITAL LETTER U WITH TILDE + u'\u016a' # 0xDE -> LATIN CAPITAL LETTER U WITH MACRON + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK + u'\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\u012b' # 0xEF -> LATIN SMALL LETTER I WITH MACRON + u'\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + u'\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA + u'\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON + u'\u0137' # 0xF3 -> LATIN SMALL LETTER K WITH CEDILLA + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u0169' # 0xFD -> LATIN SMALL LETTER U WITH TILDE + u'\u016b' # 0xFE -> LATIN SMALL LETTER U WITH MACRON + u'\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_5.py b/src/main/resources/PythonLibs/encodings/iso8859_5.py new file mode 100644 index 0000000000000000000000000000000000000000..c01cd1caab3949d6ae4a15f6bfc7368347ad2749 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_5.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_5 generated from 'MAPPINGS/ISO8859/8859-5.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-5', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u0401' # 0xA1 -> CYRILLIC CAPITAL LETTER IO + u'\u0402' # 0xA2 -> CYRILLIC CAPITAL LETTER DJE + u'\u0403' # 0xA3 -> CYRILLIC CAPITAL LETTER GJE + u'\u0404' # 0xA4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + u'\u0405' # 0xA5 -> CYRILLIC CAPITAL LETTER DZE + u'\u0406' # 0xA6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0407' # 0xA7 -> CYRILLIC CAPITAL LETTER YI + u'\u0408' # 0xA8 -> CYRILLIC CAPITAL LETTER JE + u'\u0409' # 0xA9 -> CYRILLIC CAPITAL LETTER LJE + u'\u040a' # 0xAA -> CYRILLIC CAPITAL LETTER NJE + u'\u040b' # 0xAB -> CYRILLIC CAPITAL LETTER TSHE + u'\u040c' # 0xAC -> CYRILLIC CAPITAL LETTER KJE + u'\xad' # 0xAD -> SOFT HYPHEN + u'\u040e' # 0xAE -> CYRILLIC CAPITAL LETTER SHORT U + u'\u040f' # 0xAF -> CYRILLIC CAPITAL LETTER DZHE + u'\u0410' # 0xB0 -> CYRILLIC CAPITAL LETTER A + u'\u0411' # 0xB1 -> CYRILLIC CAPITAL LETTER BE + u'\u0412' # 0xB2 -> CYRILLIC CAPITAL LETTER VE + u'\u0413' # 0xB3 -> CYRILLIC CAPITAL LETTER GHE + u'\u0414' # 0xB4 -> CYRILLIC CAPITAL LETTER DE + u'\u0415' # 0xB5 -> CYRILLIC CAPITAL LETTER IE + u'\u0416' # 0xB6 -> CYRILLIC CAPITAL LETTER ZHE + u'\u0417' # 0xB7 -> CYRILLIC CAPITAL LETTER ZE + u'\u0418' # 0xB8 -> CYRILLIC CAPITAL LETTER I + u'\u0419' # 0xB9 -> CYRILLIC CAPITAL LETTER SHORT I + u'\u041a' # 0xBA -> CYRILLIC CAPITAL LETTER KA + u'\u041b' # 0xBB -> CYRILLIC CAPITAL LETTER EL + u'\u041c' # 0xBC -> CYRILLIC CAPITAL LETTER EM + u'\u041d' # 0xBD -> CYRILLIC CAPITAL LETTER EN + u'\u041e' # 0xBE -> CYRILLIC CAPITAL LETTER O + u'\u041f' # 0xBF -> CYRILLIC CAPITAL LETTER PE + u'\u0420' # 0xC0 -> CYRILLIC CAPITAL LETTER ER + u'\u0421' # 0xC1 -> CYRILLIC CAPITAL LETTER ES + u'\u0422' # 0xC2 -> CYRILLIC CAPITAL LETTER TE + u'\u0423' # 0xC3 -> CYRILLIC CAPITAL LETTER U + u'\u0424' # 0xC4 -> CYRILLIC CAPITAL LETTER EF + u'\u0425' # 0xC5 -> CYRILLIC CAPITAL LETTER HA + u'\u0426' # 0xC6 -> CYRILLIC CAPITAL LETTER TSE + u'\u0427' # 0xC7 -> CYRILLIC CAPITAL LETTER CHE + u'\u0428' # 0xC8 -> CYRILLIC CAPITAL LETTER SHA + u'\u0429' # 0xC9 -> CYRILLIC CAPITAL LETTER SHCHA + u'\u042a' # 0xCA -> CYRILLIC CAPITAL LETTER HARD SIGN + u'\u042b' # 0xCB -> CYRILLIC CAPITAL LETTER YERU + u'\u042c' # 0xCC -> CYRILLIC CAPITAL LETTER SOFT SIGN + u'\u042d' # 0xCD -> CYRILLIC CAPITAL LETTER E + u'\u042e' # 0xCE -> CYRILLIC CAPITAL LETTER YU + u'\u042f' # 0xCF -> CYRILLIC CAPITAL LETTER YA + u'\u0430' # 0xD0 -> CYRILLIC SMALL LETTER A + u'\u0431' # 0xD1 -> CYRILLIC SMALL LETTER BE + u'\u0432' # 0xD2 -> CYRILLIC SMALL LETTER VE + u'\u0433' # 0xD3 -> CYRILLIC SMALL LETTER GHE + u'\u0434' # 0xD4 -> CYRILLIC SMALL LETTER DE + u'\u0435' # 0xD5 -> CYRILLIC SMALL LETTER IE + u'\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + u'\u0437' # 0xD7 -> CYRILLIC SMALL LETTER ZE + u'\u0438' # 0xD8 -> CYRILLIC SMALL LETTER I + u'\u0439' # 0xD9 -> CYRILLIC SMALL LETTER SHORT I + u'\u043a' # 0xDA -> CYRILLIC SMALL LETTER KA + u'\u043b' # 0xDB -> CYRILLIC SMALL LETTER EL + u'\u043c' # 0xDC -> CYRILLIC SMALL LETTER EM + u'\u043d' # 0xDD -> CYRILLIC SMALL LETTER EN + u'\u043e' # 0xDE -> CYRILLIC SMALL LETTER O + u'\u043f' # 0xDF -> CYRILLIC SMALL LETTER PE + u'\u0440' # 0xE0 -> CYRILLIC SMALL LETTER ER + u'\u0441' # 0xE1 -> CYRILLIC SMALL LETTER ES + u'\u0442' # 0xE2 -> CYRILLIC SMALL LETTER TE + u'\u0443' # 0xE3 -> CYRILLIC SMALL LETTER U + u'\u0444' # 0xE4 -> CYRILLIC SMALL LETTER EF + u'\u0445' # 0xE5 -> CYRILLIC SMALL LETTER HA + u'\u0446' # 0xE6 -> CYRILLIC SMALL LETTER TSE + u'\u0447' # 0xE7 -> CYRILLIC SMALL LETTER CHE + u'\u0448' # 0xE8 -> CYRILLIC SMALL LETTER SHA + u'\u0449' # 0xE9 -> CYRILLIC SMALL LETTER SHCHA + u'\u044a' # 0xEA -> CYRILLIC SMALL LETTER HARD SIGN + u'\u044b' # 0xEB -> CYRILLIC SMALL LETTER YERU + u'\u044c' # 0xEC -> CYRILLIC SMALL LETTER SOFT SIGN + u'\u044d' # 0xED -> CYRILLIC SMALL LETTER E + u'\u044e' # 0xEE -> CYRILLIC SMALL LETTER YU + u'\u044f' # 0xEF -> CYRILLIC SMALL LETTER YA + u'\u2116' # 0xF0 -> NUMERO SIGN + u'\u0451' # 0xF1 -> CYRILLIC SMALL LETTER IO + u'\u0452' # 0xF2 -> CYRILLIC SMALL LETTER DJE + u'\u0453' # 0xF3 -> CYRILLIC SMALL LETTER GJE + u'\u0454' # 0xF4 -> CYRILLIC SMALL LETTER UKRAINIAN IE + u'\u0455' # 0xF5 -> CYRILLIC SMALL LETTER DZE + u'\u0456' # 0xF6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0457' # 0xF7 -> CYRILLIC SMALL LETTER YI + u'\u0458' # 0xF8 -> CYRILLIC SMALL LETTER JE + u'\u0459' # 0xF9 -> CYRILLIC SMALL LETTER LJE + u'\u045a' # 0xFA -> CYRILLIC SMALL LETTER NJE + u'\u045b' # 0xFB -> CYRILLIC SMALL LETTER TSHE + u'\u045c' # 0xFC -> CYRILLIC SMALL LETTER KJE + u'\xa7' # 0xFD -> SECTION SIGN + u'\u045e' # 0xFE -> CYRILLIC SMALL LETTER SHORT U + u'\u045f' # 0xFF -> CYRILLIC SMALL LETTER DZHE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_6.py b/src/main/resources/PythonLibs/encodings/iso8859_6.py new file mode 100644 index 0000000000000000000000000000000000000000..16c34a3f618e9e01ea8339b310e6e35c5e932bdd --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_6.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_6 generated from 'MAPPINGS/ISO8859/8859-6.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-6', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\u060c' # 0xAC -> ARABIC COMMA + u'\xad' # 0xAD -> SOFT HYPHEN + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\u061b' # 0xBB -> ARABIC SEMICOLON + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\u061f' # 0xBF -> ARABIC QUESTION MARK + u'\ufffe' + u'\u0621' # 0xC1 -> ARABIC LETTER HAMZA + u'\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + u'\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + u'\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + u'\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + u'\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + u'\u0627' # 0xC7 -> ARABIC LETTER ALEF + u'\u0628' # 0xC8 -> ARABIC LETTER BEH + u'\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + u'\u062a' # 0xCA -> ARABIC LETTER TEH + u'\u062b' # 0xCB -> ARABIC LETTER THEH + u'\u062c' # 0xCC -> ARABIC LETTER JEEM + u'\u062d' # 0xCD -> ARABIC LETTER HAH + u'\u062e' # 0xCE -> ARABIC LETTER KHAH + u'\u062f' # 0xCF -> ARABIC LETTER DAL + u'\u0630' # 0xD0 -> ARABIC LETTER THAL + u'\u0631' # 0xD1 -> ARABIC LETTER REH + u'\u0632' # 0xD2 -> ARABIC LETTER ZAIN + u'\u0633' # 0xD3 -> ARABIC LETTER SEEN + u'\u0634' # 0xD4 -> ARABIC LETTER SHEEN + u'\u0635' # 0xD5 -> ARABIC LETTER SAD + u'\u0636' # 0xD6 -> ARABIC LETTER DAD + u'\u0637' # 0xD7 -> ARABIC LETTER TAH + u'\u0638' # 0xD8 -> ARABIC LETTER ZAH + u'\u0639' # 0xD9 -> ARABIC LETTER AIN + u'\u063a' # 0xDA -> ARABIC LETTER GHAIN + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\u0640' # 0xE0 -> ARABIC TATWEEL + u'\u0641' # 0xE1 -> ARABIC LETTER FEH + u'\u0642' # 0xE2 -> ARABIC LETTER QAF + u'\u0643' # 0xE3 -> ARABIC LETTER KAF + u'\u0644' # 0xE4 -> ARABIC LETTER LAM + u'\u0645' # 0xE5 -> ARABIC LETTER MEEM + u'\u0646' # 0xE6 -> ARABIC LETTER NOON + u'\u0647' # 0xE7 -> ARABIC LETTER HEH + u'\u0648' # 0xE8 -> ARABIC LETTER WAW + u'\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA + u'\u064a' # 0xEA -> ARABIC LETTER YEH + u'\u064b' # 0xEB -> ARABIC FATHATAN + u'\u064c' # 0xEC -> ARABIC DAMMATAN + u'\u064d' # 0xED -> ARABIC KASRATAN + u'\u064e' # 0xEE -> ARABIC FATHA + u'\u064f' # 0xEF -> ARABIC DAMMA + u'\u0650' # 0xF0 -> ARABIC KASRA + u'\u0651' # 0xF1 -> ARABIC SHADDA + u'\u0652' # 0xF2 -> ARABIC SUKUN + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_7.py b/src/main/resources/PythonLibs/encodings/iso8859_7.py new file mode 100644 index 0000000000000000000000000000000000000000..a560023a08b4838c20762856b35967094fefe824 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_7.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_7 generated from 'MAPPINGS/ISO8859/8859-7.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-7', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\u2018' # 0xA1 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xA2 -> RIGHT SINGLE QUOTATION MARK + u'\xa3' # 0xA3 -> POUND SIGN + u'\u20ac' # 0xA4 -> EURO SIGN + u'\u20af' # 0xA5 -> DRACHMA SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u037a' # 0xAA -> GREEK YPOGEGRAMMENI + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\ufffe' + u'\u2015' # 0xAF -> HORIZONTAL BAR + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\u0384' # 0xB4 -> GREEK TONOS + u'\u0385' # 0xB5 -> GREEK DIALYTIKA TONOS + u'\u0386' # 0xB6 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + u'\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS + u'\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS + u'\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + u'\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + u'\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA + u'\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA + u'\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA + u'\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA + u'\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON + u'\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA + u'\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA + u'\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA + u'\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA + u'\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA + u'\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA + u'\u039c' # 0xCC -> GREEK CAPITAL LETTER MU + u'\u039d' # 0xCD -> GREEK CAPITAL LETTER NU + u'\u039e' # 0xCE -> GREEK CAPITAL LETTER XI + u'\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON + u'\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI + u'\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO + u'\ufffe' + u'\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA + u'\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU + u'\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON + u'\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI + u'\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI + u'\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI + u'\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA + u'\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + u'\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + u'\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS + u'\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS + u'\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS + u'\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS + u'\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + u'\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + u'\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + u'\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA + u'\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + u'\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + u'\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA + u'\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA + u'\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA + u'\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + u'\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA + u'\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA + u'\u03bc' # 0xEC -> GREEK SMALL LETTER MU + u'\u03bd' # 0xED -> GREEK SMALL LETTER NU + u'\u03be' # 0xEE -> GREEK SMALL LETTER XI + u'\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + u'\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + u'\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO + u'\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA + u'\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + u'\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + u'\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON + u'\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI + u'\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI + u'\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI + u'\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA + u'\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + u'\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + u'\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS + u'\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS + u'\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS + u'\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_8.py b/src/main/resources/PythonLibs/encodings/iso8859_8.py new file mode 100644 index 0000000000000000000000000000000000000000..43cf2138b532012c023b859691764ec0f4a872b4 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_8.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_8 generated from 'MAPPINGS/ISO8859/8859-8.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-8', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\ufffe' + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xd7' # 0xAA -> MULTIPLICATION SIGN + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xf7' # 0xBA -> DIVISION SIGN + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\u2017' # 0xDF -> DOUBLE LOW LINE + u'\u05d0' # 0xE0 -> HEBREW LETTER ALEF + u'\u05d1' # 0xE1 -> HEBREW LETTER BET + u'\u05d2' # 0xE2 -> HEBREW LETTER GIMEL + u'\u05d3' # 0xE3 -> HEBREW LETTER DALET + u'\u05d4' # 0xE4 -> HEBREW LETTER HE + u'\u05d5' # 0xE5 -> HEBREW LETTER VAV + u'\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN + u'\u05d7' # 0xE7 -> HEBREW LETTER HET + u'\u05d8' # 0xE8 -> HEBREW LETTER TET + u'\u05d9' # 0xE9 -> HEBREW LETTER YOD + u'\u05da' # 0xEA -> HEBREW LETTER FINAL KAF + u'\u05db' # 0xEB -> HEBREW LETTER KAF + u'\u05dc' # 0xEC -> HEBREW LETTER LAMED + u'\u05dd' # 0xED -> HEBREW LETTER FINAL MEM + u'\u05de' # 0xEE -> HEBREW LETTER MEM + u'\u05df' # 0xEF -> HEBREW LETTER FINAL NUN + u'\u05e0' # 0xF0 -> HEBREW LETTER NUN + u'\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH + u'\u05e2' # 0xF2 -> HEBREW LETTER AYIN + u'\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE + u'\u05e4' # 0xF4 -> HEBREW LETTER PE + u'\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI + u'\u05e6' # 0xF6 -> HEBREW LETTER TSADI + u'\u05e7' # 0xF7 -> HEBREW LETTER QOF + u'\u05e8' # 0xF8 -> HEBREW LETTER RESH + u'\u05e9' # 0xF9 -> HEBREW LETTER SHIN + u'\u05ea' # 0xFA -> HEBREW LETTER TAV + u'\ufffe' + u'\ufffe' + u'\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + u'\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + u'\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/iso8859_9.py b/src/main/resources/PythonLibs/encodings/iso8859_9.py new file mode 100644 index 0000000000000000000000000000000000000000..b8029382c0de6789719280d9e359d618b3b80d4d --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/iso8859_9.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_9 generated from 'MAPPINGS/ISO8859/8859-9.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-9', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\xa0' # 0xA0 -> NO-BREAK SPACE + u'\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa4' # 0xA4 -> CURRENCY SIGN + u'\xa5' # 0xA5 -> YEN SIGN + u'\xa6' # 0xA6 -> BROKEN BAR + u'\xa7' # 0xA7 -> SECTION SIGN + u'\xa8' # 0xA8 -> DIAERESIS + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + u'\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xac' # 0xAC -> NOT SIGN + u'\xad' # 0xAD -> SOFT HYPHEN + u'\xae' # 0xAE -> REGISTERED SIGN + u'\xaf' # 0xAF -> MACRON + u'\xb0' # 0xB0 -> DEGREE SIGN + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\xb2' # 0xB2 -> SUPERSCRIPT TWO + u'\xb3' # 0xB3 -> SUPERSCRIPT THREE + u'\xb4' # 0xB4 -> ACUTE ACCENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\xb6' # 0xB6 -> PILCROW SIGN + u'\xb7' # 0xB7 -> MIDDLE DOT + u'\xb8' # 0xB8 -> CEDILLA + u'\xb9' # 0xB9 -> SUPERSCRIPT ONE + u'\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + u'\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + u'\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + u'\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + u'\xbf' # 0xBF -> INVERTED QUESTION MARK + u'\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + u'\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + u'\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE + u'\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + u'\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xd7' # 0xD7 -> MULTIPLICATION SIGN + u'\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + u'\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE + u'\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + u'\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + u'\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe6' # 0xE6 -> LATIN SMALL LETTER AE + u'\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + u'\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + u'\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + u'\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + u'\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + u'\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE + u'\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + u'\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + u'\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0xF7 -> DIVISION SIGN + u'\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + u'\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + u'\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + u'\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I + u'\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA + u'\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/johab.py b/src/main/resources/PythonLibs/encodings/johab.py new file mode 100644 index 0000000000000000000000000000000000000000..512aeeb732b5221ba35585a97e3cc1b85d3c5b02 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/johab.py @@ -0,0 +1,39 @@ +# +# johab.py: Python Unicode Codec for JOHAB +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_kr, codecs +import _multibytecodec as mbc + +codec = _codecs_kr.getcodec('johab') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='johab', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/koi8_r.py b/src/main/resources/PythonLibs/encodings/koi8_r.py new file mode 100644 index 0000000000000000000000000000000000000000..f9eb82c0db47004e308a461947f9d3ce0b96e774 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/koi8_r.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec koi8_r generated from 'MAPPINGS/VENDORS/MISC/KOI8-R.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-r', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL + u'\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u2580' # 0x8B -> UPPER HALF BLOCK + u'\u2584' # 0x8C -> LOWER HALF BLOCK + u'\u2588' # 0x8D -> FULL BLOCK + u'\u258c' # 0x8E -> LEFT HALF BLOCK + u'\u2590' # 0x8F -> RIGHT HALF BLOCK + u'\u2591' # 0x90 -> LIGHT SHADE + u'\u2592' # 0x91 -> MEDIUM SHADE + u'\u2593' # 0x92 -> DARK SHADE + u'\u2320' # 0x93 -> TOP HALF INTEGRAL + u'\u25a0' # 0x94 -> BLACK SQUARE + u'\u2219' # 0x95 -> BULLET OPERATOR + u'\u221a' # 0x96 -> SQUARE ROOT + u'\u2248' # 0x97 -> ALMOST EQUAL TO + u'\u2264' # 0x98 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO + u'\xa0' # 0x9A -> NO-BREAK SPACE + u'\u2321' # 0x9B -> BOTTOM HALF INTEGRAL + u'\xb0' # 0x9C -> DEGREE SIGN + u'\xb2' # 0x9D -> SUPERSCRIPT TWO + u'\xb7' # 0x9E -> MIDDLE DOT + u'\xf7' # 0x9F -> DIVISION SIGN + u'\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + u'\u2553' # 0xA4 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + u'\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u2555' # 0xA6 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + u'\u2556' # 0xA7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + u'\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u255c' # 0xAD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + u'\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + u'\u2562' # 0xB4 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + u'\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u2564' # 0xB6 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + u'\u2565' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + u'\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u256b' # 0xBD -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + u'\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa9' # 0xBF -> COPYRIGHT SIGN + u'\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + u'\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + u'\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + u'\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + u'\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + u'\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + u'\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + u'\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + u'\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + u'\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + u'\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + u'\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + u'\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + u'\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + u'\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + u'\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + u'\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + u'\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + u'\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + u'\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + u'\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + u'\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + u'\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + u'\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + u'\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + u'\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + u'\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + u'\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + u'\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + u'\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + u'\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + u'\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + u'\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + u'\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + u'\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + u'\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + u'\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + u'\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + u'\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + u'\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + u'\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + u'\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + u'\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + u'\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + u'\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + u'\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + u'\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + u'\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + u'\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + u'\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + u'\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + u'\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + u'\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + u'\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + u'\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + u'\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + u'\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + u'\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + u'\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + u'\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + u'\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + u'\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + u'\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + u'\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/koi8_u.py b/src/main/resources/PythonLibs/encodings/koi8_u.py new file mode 100644 index 0000000000000000000000000000000000000000..a9317b12b773ecdabc5a190e55b02b93ca0df730 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/koi8_u.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec koi8_u generated from 'python-mappings/KOI8-U.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-u', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL + u'\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL + u'\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + u'\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT + u'\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT + u'\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT + u'\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + u'\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + u'\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + u'\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + u'\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + u'\u2580' # 0x8B -> UPPER HALF BLOCK + u'\u2584' # 0x8C -> LOWER HALF BLOCK + u'\u2588' # 0x8D -> FULL BLOCK + u'\u258c' # 0x8E -> LEFT HALF BLOCK + u'\u2590' # 0x8F -> RIGHT HALF BLOCK + u'\u2591' # 0x90 -> LIGHT SHADE + u'\u2592' # 0x91 -> MEDIUM SHADE + u'\u2593' # 0x92 -> DARK SHADE + u'\u2320' # 0x93 -> TOP HALF INTEGRAL + u'\u25a0' # 0x94 -> BLACK SQUARE + u'\u2219' # 0x95 -> BULLET OPERATOR + u'\u221a' # 0x96 -> SQUARE ROOT + u'\u2248' # 0x97 -> ALMOST EQUAL TO + u'\u2264' # 0x98 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO + u'\xa0' # 0x9A -> NO-BREAK SPACE + u'\u2321' # 0x9B -> BOTTOM HALF INTEGRAL + u'\xb0' # 0x9C -> DEGREE SIGN + u'\xb2' # 0x9D -> SUPERSCRIPT TWO + u'\xb7' # 0x9E -> MIDDLE DOT + u'\xf7' # 0x9F -> DIVISION SIGN + u'\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL + u'\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL + u'\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + u'\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + u'\u0454' # 0xA4 -> CYRILLIC SMALL LETTER UKRAINIAN IE + u'\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + u'\u0456' # 0xA6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0457' # 0xA7 -> CYRILLIC SMALL LETTER YI (UKRAINIAN) + u'\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT + u'\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + u'\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + u'\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT + u'\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + u'\u0491' # 0xAD -> CYRILLIC SMALL LETTER UKRAINIAN GHE WITH UPTURN + u'\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT + u'\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + u'\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + u'\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + u'\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + u'\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + u'\u0404' # 0xB4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + u'\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + u'\u0406' # 0xB6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + u'\u0407' # 0xB7 -> CYRILLIC CAPITAL LETTER YI (UKRAINIAN) + u'\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + u'\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + u'\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + u'\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + u'\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + u'\u0490' # 0xBD -> CYRILLIC CAPITAL LETTER UKRAINIAN GHE WITH UPTURN + u'\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + u'\xa9' # 0xBF -> COPYRIGHT SIGN + u'\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + u'\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + u'\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + u'\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + u'\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + u'\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + u'\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + u'\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + u'\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + u'\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + u'\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + u'\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + u'\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + u'\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + u'\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + u'\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + u'\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + u'\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + u'\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + u'\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + u'\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + u'\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + u'\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + u'\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + u'\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + u'\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + u'\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + u'\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + u'\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + u'\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + u'\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + u'\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + u'\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + u'\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + u'\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + u'\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + u'\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + u'\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + u'\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + u'\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + u'\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + u'\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + u'\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + u'\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + u'\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + u'\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + u'\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + u'\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + u'\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + u'\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + u'\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + u'\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + u'\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + u'\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + u'\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + u'\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + u'\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + u'\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + u'\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + u'\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + u'\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + u'\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + u'\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + u'\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/latin_1.py b/src/main/resources/PythonLibs/encodings/latin_1.py new file mode 100644 index 0000000000000000000000000000000000000000..370160c0cb512f25573985bce277ea2f590a420c --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/latin_1.py @@ -0,0 +1,50 @@ +""" Python 'latin-1' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.latin_1_encode + decode = codecs.latin_1_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.latin_1_encode(input,self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.latin_1_decode(input,self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +class StreamConverter(StreamWriter,StreamReader): + + encode = codecs.latin_1_decode + decode = codecs.latin_1_encode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-1', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/mac_arabic.py b/src/main/resources/PythonLibs/encodings/mac_arabic.py new file mode 100644 index 0000000000000000000000000000000000000000..7a7d3c5f7fe41be0b0ab8e1afbe25984789636d8 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_arabic.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/APPLE/ARABIC.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-arabic', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x0081: 0x00a0, # NO-BREAK SPACE, right-left + 0x0082: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0083: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0084: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x0085: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x0086: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x0087: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x0088: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0089: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x008a: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x008b: 0x06ba, # ARABIC LETTER NOON GHUNNA + 0x008c: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x008d: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x008e: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x008f: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x0090: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0091: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x0092: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x0093: 0x2026, # HORIZONTAL ELLIPSIS, right-left + 0x0094: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x0095: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x0096: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x0097: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x0098: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x0099: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x009a: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x009b: 0x00f7, # DIVISION SIGN, right-left + 0x009c: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x009d: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x009e: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x009f: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00a0: 0x0020, # SPACE, right-left + 0x00a1: 0x0021, # EXCLAMATION MARK, right-left + 0x00a2: 0x0022, # QUOTATION MARK, right-left + 0x00a3: 0x0023, # NUMBER SIGN, right-left + 0x00a4: 0x0024, # DOLLAR SIGN, right-left + 0x00a5: 0x066a, # ARABIC PERCENT SIGN + 0x00a6: 0x0026, # AMPERSAND, right-left + 0x00a7: 0x0027, # APOSTROPHE, right-left + 0x00a8: 0x0028, # LEFT PARENTHESIS, right-left + 0x00a9: 0x0029, # RIGHT PARENTHESIS, right-left + 0x00aa: 0x002a, # ASTERISK, right-left + 0x00ab: 0x002b, # PLUS SIGN, right-left + 0x00ac: 0x060c, # ARABIC COMMA + 0x00ad: 0x002d, # HYPHEN-MINUS, right-left + 0x00ae: 0x002e, # FULL STOP, right-left + 0x00af: 0x002f, # SOLIDUS, right-left + 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO, right-left (need override) + 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE, right-left (need override) + 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO, right-left (need override) + 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE, right-left (need override) + 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR, right-left (need override) + 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE, right-left (need override) + 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX, right-left (need override) + 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) + 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) + 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE, right-left (need override) + 0x00ba: 0x003a, # COLON, right-left + 0x00bb: 0x061b, # ARABIC SEMICOLON + 0x00bc: 0x003c, # LESS-THAN SIGN, right-left + 0x00bd: 0x003d, # EQUALS SIGN, right-left + 0x00be: 0x003e, # GREATER-THAN SIGN, right-left + 0x00bf: 0x061f, # ARABIC QUESTION MARK + 0x00c0: 0x274a, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + 0x00c1: 0x0621, # ARABIC LETTER HAMZA + 0x00c2: 0x0622, # ARABIC LETTER ALEF WITH MADDA ABOVE + 0x00c3: 0x0623, # ARABIC LETTER ALEF WITH HAMZA ABOVE + 0x00c4: 0x0624, # ARABIC LETTER WAW WITH HAMZA ABOVE + 0x00c5: 0x0625, # ARABIC LETTER ALEF WITH HAMZA BELOW + 0x00c6: 0x0626, # ARABIC LETTER YEH WITH HAMZA ABOVE + 0x00c7: 0x0627, # ARABIC LETTER ALEF + 0x00c8: 0x0628, # ARABIC LETTER BEH + 0x00c9: 0x0629, # ARABIC LETTER TEH MARBUTA + 0x00ca: 0x062a, # ARABIC LETTER TEH + 0x00cb: 0x062b, # ARABIC LETTER THEH + 0x00cc: 0x062c, # ARABIC LETTER JEEM + 0x00cd: 0x062d, # ARABIC LETTER HAH + 0x00ce: 0x062e, # ARABIC LETTER KHAH + 0x00cf: 0x062f, # ARABIC LETTER DAL + 0x00d0: 0x0630, # ARABIC LETTER THAL + 0x00d1: 0x0631, # ARABIC LETTER REH + 0x00d2: 0x0632, # ARABIC LETTER ZAIN + 0x00d3: 0x0633, # ARABIC LETTER SEEN + 0x00d4: 0x0634, # ARABIC LETTER SHEEN + 0x00d5: 0x0635, # ARABIC LETTER SAD + 0x00d6: 0x0636, # ARABIC LETTER DAD + 0x00d7: 0x0637, # ARABIC LETTER TAH + 0x00d8: 0x0638, # ARABIC LETTER ZAH + 0x00d9: 0x0639, # ARABIC LETTER AIN + 0x00da: 0x063a, # ARABIC LETTER GHAIN + 0x00db: 0x005b, # LEFT SQUARE BRACKET, right-left + 0x00dc: 0x005c, # REVERSE SOLIDUS, right-left + 0x00dd: 0x005d, # RIGHT SQUARE BRACKET, right-left + 0x00de: 0x005e, # CIRCUMFLEX ACCENT, right-left + 0x00df: 0x005f, # LOW LINE, right-left + 0x00e0: 0x0640, # ARABIC TATWEEL + 0x00e1: 0x0641, # ARABIC LETTER FEH + 0x00e2: 0x0642, # ARABIC LETTER QAF + 0x00e3: 0x0643, # ARABIC LETTER KAF + 0x00e4: 0x0644, # ARABIC LETTER LAM + 0x00e5: 0x0645, # ARABIC LETTER MEEM + 0x00e6: 0x0646, # ARABIC LETTER NOON + 0x00e7: 0x0647, # ARABIC LETTER HEH + 0x00e8: 0x0648, # ARABIC LETTER WAW + 0x00e9: 0x0649, # ARABIC LETTER ALEF MAKSURA + 0x00ea: 0x064a, # ARABIC LETTER YEH + 0x00eb: 0x064b, # ARABIC FATHATAN + 0x00ec: 0x064c, # ARABIC DAMMATAN + 0x00ed: 0x064d, # ARABIC KASRATAN + 0x00ee: 0x064e, # ARABIC FATHA + 0x00ef: 0x064f, # ARABIC DAMMA + 0x00f0: 0x0650, # ARABIC KASRA + 0x00f1: 0x0651, # ARABIC SHADDA + 0x00f2: 0x0652, # ARABIC SUKUN + 0x00f3: 0x067e, # ARABIC LETTER PEH + 0x00f4: 0x0679, # ARABIC LETTER TTEH + 0x00f5: 0x0686, # ARABIC LETTER TCHEH + 0x00f6: 0x06d5, # ARABIC LETTER AE + 0x00f7: 0x06a4, # ARABIC LETTER VEH + 0x00f8: 0x06af, # ARABIC LETTER GAF + 0x00f9: 0x0688, # ARABIC LETTER DDAL + 0x00fa: 0x0691, # ARABIC LETTER RREH + 0x00fb: 0x007b, # LEFT CURLY BRACKET, right-left + 0x00fc: 0x007c, # VERTICAL LINE, right-left + 0x00fd: 0x007d, # RIGHT CURLY BRACKET, right-left + 0x00fe: 0x0698, # ARABIC LETTER JEH + 0x00ff: 0x06d2, # ARABIC LETTER YEH BARREE +}) + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x0000 -> CONTROL CHARACTER + u'\x01' # 0x0001 -> CONTROL CHARACTER + u'\x02' # 0x0002 -> CONTROL CHARACTER + u'\x03' # 0x0003 -> CONTROL CHARACTER + u'\x04' # 0x0004 -> CONTROL CHARACTER + u'\x05' # 0x0005 -> CONTROL CHARACTER + u'\x06' # 0x0006 -> CONTROL CHARACTER + u'\x07' # 0x0007 -> CONTROL CHARACTER + u'\x08' # 0x0008 -> CONTROL CHARACTER + u'\t' # 0x0009 -> CONTROL CHARACTER + u'\n' # 0x000a -> CONTROL CHARACTER + u'\x0b' # 0x000b -> CONTROL CHARACTER + u'\x0c' # 0x000c -> CONTROL CHARACTER + u'\r' # 0x000d -> CONTROL CHARACTER + u'\x0e' # 0x000e -> CONTROL CHARACTER + u'\x0f' # 0x000f -> CONTROL CHARACTER + u'\x10' # 0x0010 -> CONTROL CHARACTER + u'\x11' # 0x0011 -> CONTROL CHARACTER + u'\x12' # 0x0012 -> CONTROL CHARACTER + u'\x13' # 0x0013 -> CONTROL CHARACTER + u'\x14' # 0x0014 -> CONTROL CHARACTER + u'\x15' # 0x0015 -> CONTROL CHARACTER + u'\x16' # 0x0016 -> CONTROL CHARACTER + u'\x17' # 0x0017 -> CONTROL CHARACTER + u'\x18' # 0x0018 -> CONTROL CHARACTER + u'\x19' # 0x0019 -> CONTROL CHARACTER + u'\x1a' # 0x001a -> CONTROL CHARACTER + u'\x1b' # 0x001b -> CONTROL CHARACTER + u'\x1c' # 0x001c -> CONTROL CHARACTER + u'\x1d' # 0x001d -> CONTROL CHARACTER + u'\x1e' # 0x001e -> CONTROL CHARACTER + u'\x1f' # 0x001f -> CONTROL CHARACTER + u' ' # 0x0020 -> SPACE, left-right + u'!' # 0x0021 -> EXCLAMATION MARK, left-right + u'"' # 0x0022 -> QUOTATION MARK, left-right + u'#' # 0x0023 -> NUMBER SIGN, left-right + u'$' # 0x0024 -> DOLLAR SIGN, left-right + u'%' # 0x0025 -> PERCENT SIGN, left-right + u'&' # 0x0026 -> AMPERSAND, left-right + u"'" # 0x0027 -> APOSTROPHE, left-right + u'(' # 0x0028 -> LEFT PARENTHESIS, left-right + u')' # 0x0029 -> RIGHT PARENTHESIS, left-right + u'*' # 0x002a -> ASTERISK, left-right + u'+' # 0x002b -> PLUS SIGN, left-right + u',' # 0x002c -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + u'-' # 0x002d -> HYPHEN-MINUS, left-right + u'.' # 0x002e -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + u'/' # 0x002f -> SOLIDUS, left-right + u'0' # 0x0030 -> DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO + u'1' # 0x0031 -> DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE + u'2' # 0x0032 -> DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO + u'3' # 0x0033 -> DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE + u'4' # 0x0034 -> DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR + u'5' # 0x0035 -> DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE + u'6' # 0x0036 -> DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX + u'7' # 0x0037 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN + u'8' # 0x0038 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT + u'9' # 0x0039 -> DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE + u':' # 0x003a -> COLON, left-right + u';' # 0x003b -> SEMICOLON, left-right + u'<' # 0x003c -> LESS-THAN SIGN, left-right + u'=' # 0x003d -> EQUALS SIGN, left-right + u'>' # 0x003e -> GREATER-THAN SIGN, left-right + u'?' # 0x003f -> QUESTION MARK, left-right + u'@' # 0x0040 -> COMMERCIAL AT + u'A' # 0x0041 -> LATIN CAPITAL LETTER A + u'B' # 0x0042 -> LATIN CAPITAL LETTER B + u'C' # 0x0043 -> LATIN CAPITAL LETTER C + u'D' # 0x0044 -> LATIN CAPITAL LETTER D + u'E' # 0x0045 -> LATIN CAPITAL LETTER E + u'F' # 0x0046 -> LATIN CAPITAL LETTER F + u'G' # 0x0047 -> LATIN CAPITAL LETTER G + u'H' # 0x0048 -> LATIN CAPITAL LETTER H + u'I' # 0x0049 -> LATIN CAPITAL LETTER I + u'J' # 0x004a -> LATIN CAPITAL LETTER J + u'K' # 0x004b -> LATIN CAPITAL LETTER K + u'L' # 0x004c -> LATIN CAPITAL LETTER L + u'M' # 0x004d -> LATIN CAPITAL LETTER M + u'N' # 0x004e -> LATIN CAPITAL LETTER N + u'O' # 0x004f -> LATIN CAPITAL LETTER O + u'P' # 0x0050 -> LATIN CAPITAL LETTER P + u'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + u'R' # 0x0052 -> LATIN CAPITAL LETTER R + u'S' # 0x0053 -> LATIN CAPITAL LETTER S + u'T' # 0x0054 -> LATIN CAPITAL LETTER T + u'U' # 0x0055 -> LATIN CAPITAL LETTER U + u'V' # 0x0056 -> LATIN CAPITAL LETTER V + u'W' # 0x0057 -> LATIN CAPITAL LETTER W + u'X' # 0x0058 -> LATIN CAPITAL LETTER X + u'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + u'Z' # 0x005a -> LATIN CAPITAL LETTER Z + u'[' # 0x005b -> LEFT SQUARE BRACKET, left-right + u'\\' # 0x005c -> REVERSE SOLIDUS, left-right + u']' # 0x005d -> RIGHT SQUARE BRACKET, left-right + u'^' # 0x005e -> CIRCUMFLEX ACCENT, left-right + u'_' # 0x005f -> LOW LINE, left-right + u'`' # 0x0060 -> GRAVE ACCENT + u'a' # 0x0061 -> LATIN SMALL LETTER A + u'b' # 0x0062 -> LATIN SMALL LETTER B + u'c' # 0x0063 -> LATIN SMALL LETTER C + u'd' # 0x0064 -> LATIN SMALL LETTER D + u'e' # 0x0065 -> LATIN SMALL LETTER E + u'f' # 0x0066 -> LATIN SMALL LETTER F + u'g' # 0x0067 -> LATIN SMALL LETTER G + u'h' # 0x0068 -> LATIN SMALL LETTER H + u'i' # 0x0069 -> LATIN SMALL LETTER I + u'j' # 0x006a -> LATIN SMALL LETTER J + u'k' # 0x006b -> LATIN SMALL LETTER K + u'l' # 0x006c -> LATIN SMALL LETTER L + u'm' # 0x006d -> LATIN SMALL LETTER M + u'n' # 0x006e -> LATIN SMALL LETTER N + u'o' # 0x006f -> LATIN SMALL LETTER O + u'p' # 0x0070 -> LATIN SMALL LETTER P + u'q' # 0x0071 -> LATIN SMALL LETTER Q + u'r' # 0x0072 -> LATIN SMALL LETTER R + u's' # 0x0073 -> LATIN SMALL LETTER S + u't' # 0x0074 -> LATIN SMALL LETTER T + u'u' # 0x0075 -> LATIN SMALL LETTER U + u'v' # 0x0076 -> LATIN SMALL LETTER V + u'w' # 0x0077 -> LATIN SMALL LETTER W + u'x' # 0x0078 -> LATIN SMALL LETTER X + u'y' # 0x0079 -> LATIN SMALL LETTER Y + u'z' # 0x007a -> LATIN SMALL LETTER Z + u'{' # 0x007b -> LEFT CURLY BRACKET, left-right + u'|' # 0x007c -> VERTICAL LINE, left-right + u'}' # 0x007d -> RIGHT CURLY BRACKET, left-right + u'~' # 0x007e -> TILDE + u'\x7f' # 0x007f -> CONTROL CHARACTER + u'\xc4' # 0x0080 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xa0' # 0x0081 -> NO-BREAK SPACE, right-left + u'\xc7' # 0x0082 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc9' # 0x0083 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xd1' # 0x0084 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd6' # 0x0085 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x0086 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x0087 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe0' # 0x0088 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x0089 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x008a -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u06ba' # 0x008b -> ARABIC LETTER NOON GHUNNA + u'\xab' # 0x008c -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + u'\xe7' # 0x008d -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x008e -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x008f -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x0090 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x0091 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xed' # 0x0092 -> LATIN SMALL LETTER I WITH ACUTE + u'\u2026' # 0x0093 -> HORIZONTAL ELLIPSIS, right-left + u'\xee' # 0x0094 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x0095 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf1' # 0x0096 -> LATIN SMALL LETTER N WITH TILDE + u'\xf3' # 0x0097 -> LATIN SMALL LETTER O WITH ACUTE + u'\xbb' # 0x0098 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + u'\xf4' # 0x0099 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x009a -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0x009b -> DIVISION SIGN, right-left + u'\xfa' # 0x009c -> LATIN SMALL LETTER U WITH ACUTE + u'\xf9' # 0x009d -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x009e -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x009f -> LATIN SMALL LETTER U WITH DIAERESIS + u' ' # 0x00a0 -> SPACE, right-left + u'!' # 0x00a1 -> EXCLAMATION MARK, right-left + u'"' # 0x00a2 -> QUOTATION MARK, right-left + u'#' # 0x00a3 -> NUMBER SIGN, right-left + u'$' # 0x00a4 -> DOLLAR SIGN, right-left + u'\u066a' # 0x00a5 -> ARABIC PERCENT SIGN + u'&' # 0x00a6 -> AMPERSAND, right-left + u"'" # 0x00a7 -> APOSTROPHE, right-left + u'(' # 0x00a8 -> LEFT PARENTHESIS, right-left + u')' # 0x00a9 -> RIGHT PARENTHESIS, right-left + u'*' # 0x00aa -> ASTERISK, right-left + u'+' # 0x00ab -> PLUS SIGN, right-left + u'\u060c' # 0x00ac -> ARABIC COMMA + u'-' # 0x00ad -> HYPHEN-MINUS, right-left + u'.' # 0x00ae -> FULL STOP, right-left + u'/' # 0x00af -> SOLIDUS, right-left + u'\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO, right-left (need override) + u'\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE, right-left (need override) + u'\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO, right-left (need override) + u'\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE, right-left (need override) + u'\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR, right-left (need override) + u'\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE, right-left (need override) + u'\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX, right-left (need override) + u'\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN, right-left (need override) + u'\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT, right-left (need override) + u'\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE, right-left (need override) + u':' # 0x00ba -> COLON, right-left + u'\u061b' # 0x00bb -> ARABIC SEMICOLON + u'<' # 0x00bc -> LESS-THAN SIGN, right-left + u'=' # 0x00bd -> EQUALS SIGN, right-left + u'>' # 0x00be -> GREATER-THAN SIGN, right-left + u'\u061f' # 0x00bf -> ARABIC QUESTION MARK + u'\u274a' # 0x00c0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + u'\u0621' # 0x00c1 -> ARABIC LETTER HAMZA + u'\u0622' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + u'\u0623' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + u'\u0624' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + u'\u0625' # 0x00c5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + u'\u0626' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + u'\u0627' # 0x00c7 -> ARABIC LETTER ALEF + u'\u0628' # 0x00c8 -> ARABIC LETTER BEH + u'\u0629' # 0x00c9 -> ARABIC LETTER TEH MARBUTA + u'\u062a' # 0x00ca -> ARABIC LETTER TEH + u'\u062b' # 0x00cb -> ARABIC LETTER THEH + u'\u062c' # 0x00cc -> ARABIC LETTER JEEM + u'\u062d' # 0x00cd -> ARABIC LETTER HAH + u'\u062e' # 0x00ce -> ARABIC LETTER KHAH + u'\u062f' # 0x00cf -> ARABIC LETTER DAL + u'\u0630' # 0x00d0 -> ARABIC LETTER THAL + u'\u0631' # 0x00d1 -> ARABIC LETTER REH + u'\u0632' # 0x00d2 -> ARABIC LETTER ZAIN + u'\u0633' # 0x00d3 -> ARABIC LETTER SEEN + u'\u0634' # 0x00d4 -> ARABIC LETTER SHEEN + u'\u0635' # 0x00d5 -> ARABIC LETTER SAD + u'\u0636' # 0x00d6 -> ARABIC LETTER DAD + u'\u0637' # 0x00d7 -> ARABIC LETTER TAH + u'\u0638' # 0x00d8 -> ARABIC LETTER ZAH + u'\u0639' # 0x00d9 -> ARABIC LETTER AIN + u'\u063a' # 0x00da -> ARABIC LETTER GHAIN + u'[' # 0x00db -> LEFT SQUARE BRACKET, right-left + u'\\' # 0x00dc -> REVERSE SOLIDUS, right-left + u']' # 0x00dd -> RIGHT SQUARE BRACKET, right-left + u'^' # 0x00de -> CIRCUMFLEX ACCENT, right-left + u'_' # 0x00df -> LOW LINE, right-left + u'\u0640' # 0x00e0 -> ARABIC TATWEEL + u'\u0641' # 0x00e1 -> ARABIC LETTER FEH + u'\u0642' # 0x00e2 -> ARABIC LETTER QAF + u'\u0643' # 0x00e3 -> ARABIC LETTER KAF + u'\u0644' # 0x00e4 -> ARABIC LETTER LAM + u'\u0645' # 0x00e5 -> ARABIC LETTER MEEM + u'\u0646' # 0x00e6 -> ARABIC LETTER NOON + u'\u0647' # 0x00e7 -> ARABIC LETTER HEH + u'\u0648' # 0x00e8 -> ARABIC LETTER WAW + u'\u0649' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA + u'\u064a' # 0x00ea -> ARABIC LETTER YEH + u'\u064b' # 0x00eb -> ARABIC FATHATAN + u'\u064c' # 0x00ec -> ARABIC DAMMATAN + u'\u064d' # 0x00ed -> ARABIC KASRATAN + u'\u064e' # 0x00ee -> ARABIC FATHA + u'\u064f' # 0x00ef -> ARABIC DAMMA + u'\u0650' # 0x00f0 -> ARABIC KASRA + u'\u0651' # 0x00f1 -> ARABIC SHADDA + u'\u0652' # 0x00f2 -> ARABIC SUKUN + u'\u067e' # 0x00f3 -> ARABIC LETTER PEH + u'\u0679' # 0x00f4 -> ARABIC LETTER TTEH + u'\u0686' # 0x00f5 -> ARABIC LETTER TCHEH + u'\u06d5' # 0x00f6 -> ARABIC LETTER AE + u'\u06a4' # 0x00f7 -> ARABIC LETTER VEH + u'\u06af' # 0x00f8 -> ARABIC LETTER GAF + u'\u0688' # 0x00f9 -> ARABIC LETTER DDAL + u'\u0691' # 0x00fa -> ARABIC LETTER RREH + u'{' # 0x00fb -> LEFT CURLY BRACKET, right-left + u'|' # 0x00fc -> VERTICAL LINE, right-left + u'}' # 0x00fd -> RIGHT CURLY BRACKET, right-left + u'\u0698' # 0x00fe -> ARABIC LETTER JEH + u'\u06d2' # 0x00ff -> ARABIC LETTER YEH BARREE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # CONTROL CHARACTER + 0x0001: 0x0001, # CONTROL CHARACTER + 0x0002: 0x0002, # CONTROL CHARACTER + 0x0003: 0x0003, # CONTROL CHARACTER + 0x0004: 0x0004, # CONTROL CHARACTER + 0x0005: 0x0005, # CONTROL CHARACTER + 0x0006: 0x0006, # CONTROL CHARACTER + 0x0007: 0x0007, # CONTROL CHARACTER + 0x0008: 0x0008, # CONTROL CHARACTER + 0x0009: 0x0009, # CONTROL CHARACTER + 0x000a: 0x000a, # CONTROL CHARACTER + 0x000b: 0x000b, # CONTROL CHARACTER + 0x000c: 0x000c, # CONTROL CHARACTER + 0x000d: 0x000d, # CONTROL CHARACTER + 0x000e: 0x000e, # CONTROL CHARACTER + 0x000f: 0x000f, # CONTROL CHARACTER + 0x0010: 0x0010, # CONTROL CHARACTER + 0x0011: 0x0011, # CONTROL CHARACTER + 0x0012: 0x0012, # CONTROL CHARACTER + 0x0013: 0x0013, # CONTROL CHARACTER + 0x0014: 0x0014, # CONTROL CHARACTER + 0x0015: 0x0015, # CONTROL CHARACTER + 0x0016: 0x0016, # CONTROL CHARACTER + 0x0017: 0x0017, # CONTROL CHARACTER + 0x0018: 0x0018, # CONTROL CHARACTER + 0x0019: 0x0019, # CONTROL CHARACTER + 0x001a: 0x001a, # CONTROL CHARACTER + 0x001b: 0x001b, # CONTROL CHARACTER + 0x001c: 0x001c, # CONTROL CHARACTER + 0x001d: 0x001d, # CONTROL CHARACTER + 0x001e: 0x001e, # CONTROL CHARACTER + 0x001f: 0x001f, # CONTROL CHARACTER + 0x0020: 0x0020, # SPACE, left-right + 0x0020: 0x00a0, # SPACE, right-left + 0x0021: 0x0021, # EXCLAMATION MARK, left-right + 0x0021: 0x00a1, # EXCLAMATION MARK, right-left + 0x0022: 0x0022, # QUOTATION MARK, left-right + 0x0022: 0x00a2, # QUOTATION MARK, right-left + 0x0023: 0x0023, # NUMBER SIGN, left-right + 0x0023: 0x00a3, # NUMBER SIGN, right-left + 0x0024: 0x0024, # DOLLAR SIGN, left-right + 0x0024: 0x00a4, # DOLLAR SIGN, right-left + 0x0025: 0x0025, # PERCENT SIGN, left-right + 0x0026: 0x0026, # AMPERSAND, left-right + 0x0026: 0x00a6, # AMPERSAND, right-left + 0x0027: 0x0027, # APOSTROPHE, left-right + 0x0027: 0x00a7, # APOSTROPHE, right-left + 0x0028: 0x0028, # LEFT PARENTHESIS, left-right + 0x0028: 0x00a8, # LEFT PARENTHESIS, right-left + 0x0029: 0x0029, # RIGHT PARENTHESIS, left-right + 0x0029: 0x00a9, # RIGHT PARENTHESIS, right-left + 0x002a: 0x002a, # ASTERISK, left-right + 0x002a: 0x00aa, # ASTERISK, right-left + 0x002b: 0x002b, # PLUS SIGN, left-right + 0x002b: 0x00ab, # PLUS SIGN, right-left + 0x002c: 0x002c, # COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + 0x002d: 0x002d, # HYPHEN-MINUS, left-right + 0x002d: 0x00ad, # HYPHEN-MINUS, right-left + 0x002e: 0x002e, # FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + 0x002e: 0x00ae, # FULL STOP, right-left + 0x002f: 0x002f, # SOLIDUS, left-right + 0x002f: 0x00af, # SOLIDUS, right-left + 0x0030: 0x0030, # DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE + 0x003a: 0x003a, # COLON, left-right + 0x003a: 0x00ba, # COLON, right-left + 0x003b: 0x003b, # SEMICOLON, left-right + 0x003c: 0x003c, # LESS-THAN SIGN, left-right + 0x003c: 0x00bc, # LESS-THAN SIGN, right-left + 0x003d: 0x003d, # EQUALS SIGN, left-right + 0x003d: 0x00bd, # EQUALS SIGN, right-left + 0x003e: 0x003e, # GREATER-THAN SIGN, left-right + 0x003e: 0x00be, # GREATER-THAN SIGN, right-left + 0x003f: 0x003f, # QUESTION MARK, left-right + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET, left-right + 0x005b: 0x00db, # LEFT SQUARE BRACKET, right-left + 0x005c: 0x005c, # REVERSE SOLIDUS, left-right + 0x005c: 0x00dc, # REVERSE SOLIDUS, right-left + 0x005d: 0x005d, # RIGHT SQUARE BRACKET, left-right + 0x005d: 0x00dd, # RIGHT SQUARE BRACKET, right-left + 0x005e: 0x005e, # CIRCUMFLEX ACCENT, left-right + 0x005e: 0x00de, # CIRCUMFLEX ACCENT, right-left + 0x005f: 0x005f, # LOW LINE, left-right + 0x005f: 0x00df, # LOW LINE, right-left + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET, left-right + 0x007b: 0x00fb, # LEFT CURLY BRACKET, right-left + 0x007c: 0x007c, # VERTICAL LINE, left-right + 0x007c: 0x00fc, # VERTICAL LINE, right-left + 0x007d: 0x007d, # RIGHT CURLY BRACKET, left-right + 0x007d: 0x00fd, # RIGHT CURLY BRACKET, right-left + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # CONTROL CHARACTER + 0x00a0: 0x0081, # NO-BREAK SPACE, right-left + 0x00ab: 0x008c, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x00bb: 0x0098, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x00c4: 0x0080, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c7: 0x0082, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0083, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x0084, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0085, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00dc: 0x0086, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00e0: 0x0088, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x0087, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0089, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x008a, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e7: 0x008d, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008f, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x008e, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0090, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0091, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x0092, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x0094, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x0095, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x0096, # LATIN SMALL LETTER N WITH TILDE + 0x00f3: 0x0097, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0099, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x009a, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x009b, # DIVISION SIGN, right-left + 0x00f9: 0x009d, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x009c, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x009e, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x009f, # LATIN SMALL LETTER U WITH DIAERESIS + 0x060c: 0x00ac, # ARABIC COMMA + 0x061b: 0x00bb, # ARABIC SEMICOLON + 0x061f: 0x00bf, # ARABIC QUESTION MARK + 0x0621: 0x00c1, # ARABIC LETTER HAMZA + 0x0622: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE + 0x0623: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE + 0x0624: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE + 0x0625: 0x00c5, # ARABIC LETTER ALEF WITH HAMZA BELOW + 0x0626: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE + 0x0627: 0x00c7, # ARABIC LETTER ALEF + 0x0628: 0x00c8, # ARABIC LETTER BEH + 0x0629: 0x00c9, # ARABIC LETTER TEH MARBUTA + 0x062a: 0x00ca, # ARABIC LETTER TEH + 0x062b: 0x00cb, # ARABIC LETTER THEH + 0x062c: 0x00cc, # ARABIC LETTER JEEM + 0x062d: 0x00cd, # ARABIC LETTER HAH + 0x062e: 0x00ce, # ARABIC LETTER KHAH + 0x062f: 0x00cf, # ARABIC LETTER DAL + 0x0630: 0x00d0, # ARABIC LETTER THAL + 0x0631: 0x00d1, # ARABIC LETTER REH + 0x0632: 0x00d2, # ARABIC LETTER ZAIN + 0x0633: 0x00d3, # ARABIC LETTER SEEN + 0x0634: 0x00d4, # ARABIC LETTER SHEEN + 0x0635: 0x00d5, # ARABIC LETTER SAD + 0x0636: 0x00d6, # ARABIC LETTER DAD + 0x0637: 0x00d7, # ARABIC LETTER TAH + 0x0638: 0x00d8, # ARABIC LETTER ZAH + 0x0639: 0x00d9, # ARABIC LETTER AIN + 0x063a: 0x00da, # ARABIC LETTER GHAIN + 0x0640: 0x00e0, # ARABIC TATWEEL + 0x0641: 0x00e1, # ARABIC LETTER FEH + 0x0642: 0x00e2, # ARABIC LETTER QAF + 0x0643: 0x00e3, # ARABIC LETTER KAF + 0x0644: 0x00e4, # ARABIC LETTER LAM + 0x0645: 0x00e5, # ARABIC LETTER MEEM + 0x0646: 0x00e6, # ARABIC LETTER NOON + 0x0647: 0x00e7, # ARABIC LETTER HEH + 0x0648: 0x00e8, # ARABIC LETTER WAW + 0x0649: 0x00e9, # ARABIC LETTER ALEF MAKSURA + 0x064a: 0x00ea, # ARABIC LETTER YEH + 0x064b: 0x00eb, # ARABIC FATHATAN + 0x064c: 0x00ec, # ARABIC DAMMATAN + 0x064d: 0x00ed, # ARABIC KASRATAN + 0x064e: 0x00ee, # ARABIC FATHA + 0x064f: 0x00ef, # ARABIC DAMMA + 0x0650: 0x00f0, # ARABIC KASRA + 0x0651: 0x00f1, # ARABIC SHADDA + 0x0652: 0x00f2, # ARABIC SUKUN + 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO, right-left (need override) + 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE, right-left (need override) + 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO, right-left (need override) + 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE, right-left (need override) + 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR, right-left (need override) + 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE, right-left (need override) + 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX, right-left (need override) + 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) + 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) + 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE, right-left (need override) + 0x066a: 0x00a5, # ARABIC PERCENT SIGN + 0x0679: 0x00f4, # ARABIC LETTER TTEH + 0x067e: 0x00f3, # ARABIC LETTER PEH + 0x0686: 0x00f5, # ARABIC LETTER TCHEH + 0x0688: 0x00f9, # ARABIC LETTER DDAL + 0x0691: 0x00fa, # ARABIC LETTER RREH + 0x0698: 0x00fe, # ARABIC LETTER JEH + 0x06a4: 0x00f7, # ARABIC LETTER VEH + 0x06af: 0x00f8, # ARABIC LETTER GAF + 0x06ba: 0x008b, # ARABIC LETTER NOON GHUNNA + 0x06d2: 0x00ff, # ARABIC LETTER YEH BARREE + 0x06d5: 0x00f6, # ARABIC LETTER AE + 0x2026: 0x0093, # HORIZONTAL ELLIPSIS, right-left + 0x274a: 0x00c0, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left +} diff --git a/src/main/resources/PythonLibs/encodings/mac_centeuro.py b/src/main/resources/PythonLibs/encodings/mac_centeuro.py new file mode 100644 index 0000000000000000000000000000000000000000..483c8212ace08f95502bee43c15ef4be268ad0e1 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_centeuro.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_centeuro generated from 'MAPPINGS/VENDORS/APPLE/CENTEURO.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-centeuro', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\u0100' # 0x81 -> LATIN CAPITAL LETTER A WITH MACRON + u'\u0101' # 0x82 -> LATIN SMALL LETTER A WITH MACRON + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\u0104' # 0x84 -> LATIN CAPITAL LETTER A WITH OGONEK + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + u'\u0105' # 0x88 -> LATIN SMALL LETTER A WITH OGONEK + u'\u010c' # 0x89 -> LATIN CAPITAL LETTER C WITH CARON + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u010d' # 0x8B -> LATIN SMALL LETTER C WITH CARON + u'\u0106' # 0x8C -> LATIN CAPITAL LETTER C WITH ACUTE + u'\u0107' # 0x8D -> LATIN SMALL LETTER C WITH ACUTE + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE + u'\u017a' # 0x90 -> LATIN SMALL LETTER Z WITH ACUTE + u'\u010e' # 0x91 -> LATIN CAPITAL LETTER D WITH CARON + u'\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + u'\u010f' # 0x93 -> LATIN SMALL LETTER D WITH CARON + u'\u0112' # 0x94 -> LATIN CAPITAL LETTER E WITH MACRON + u'\u0113' # 0x95 -> LATIN SMALL LETTER E WITH MACRON + u'\u0116' # 0x96 -> LATIN CAPITAL LETTER E WITH DOT ABOVE + u'\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + u'\u0117' # 0x98 -> LATIN SMALL LETTER E WITH DOT ABOVE + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + u'\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + u'\u011a' # 0x9D -> LATIN CAPITAL LETTER E WITH CARON + u'\u011b' # 0x9E -> LATIN SMALL LETTER E WITH CARON + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u2020' # 0xA0 -> DAGGER + u'\xb0' # 0xA1 -> DEGREE SIGN + u'\u0118' # 0xA2 -> LATIN CAPITAL LETTER E WITH OGONEK + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa7' # 0xA4 -> SECTION SIGN + u'\u2022' # 0xA5 -> BULLET + u'\xb6' # 0xA6 -> PILCROW SIGN + u'\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u2122' # 0xAA -> TRADE MARK SIGN + u'\u0119' # 0xAB -> LATIN SMALL LETTER E WITH OGONEK + u'\xa8' # 0xAC -> DIAERESIS + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\u0123' # 0xAE -> LATIN SMALL LETTER G WITH CEDILLA + u'\u012e' # 0xAF -> LATIN CAPITAL LETTER I WITH OGONEK + u'\u012f' # 0xB0 -> LATIN SMALL LETTER I WITH OGONEK + u'\u012a' # 0xB1 -> LATIN CAPITAL LETTER I WITH MACRON + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON + u'\u0136' # 0xB5 -> LATIN CAPITAL LETTER K WITH CEDILLA + u'\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + u'\u2211' # 0xB7 -> N-ARY SUMMATION + u'\u0142' # 0xB8 -> LATIN SMALL LETTER L WITH STROKE + u'\u013b' # 0xB9 -> LATIN CAPITAL LETTER L WITH CEDILLA + u'\u013c' # 0xBA -> LATIN SMALL LETTER L WITH CEDILLA + u'\u013d' # 0xBB -> LATIN CAPITAL LETTER L WITH CARON + u'\u013e' # 0xBC -> LATIN SMALL LETTER L WITH CARON + u'\u0139' # 0xBD -> LATIN CAPITAL LETTER L WITH ACUTE + u'\u013a' # 0xBE -> LATIN SMALL LETTER L WITH ACUTE + u'\u0145' # 0xBF -> LATIN CAPITAL LETTER N WITH CEDILLA + u'\u0146' # 0xC0 -> LATIN SMALL LETTER N WITH CEDILLA + u'\u0143' # 0xC1 -> LATIN CAPITAL LETTER N WITH ACUTE + u'\xac' # 0xC2 -> NOT SIGN + u'\u221a' # 0xC3 -> SQUARE ROOT + u'\u0144' # 0xC4 -> LATIN SMALL LETTER N WITH ACUTE + u'\u0147' # 0xC5 -> LATIN CAPITAL LETTER N WITH CARON + u'\u2206' # 0xC6 -> INCREMENT + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\u0148' # 0xCB -> LATIN SMALL LETTER N WITH CARON + u'\u0150' # 0xCC -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + u'\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + u'\u0151' # 0xCE -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + u'\u014c' # 0xCF -> LATIN CAPITAL LETTER O WITH MACRON + u'\u2013' # 0xD0 -> EN DASH + u'\u2014' # 0xD1 -> EM DASH + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u25ca' # 0xD7 -> LOZENGE + u'\u014d' # 0xD8 -> LATIN SMALL LETTER O WITH MACRON + u'\u0154' # 0xD9 -> LATIN CAPITAL LETTER R WITH ACUTE + u'\u0155' # 0xDA -> LATIN SMALL LETTER R WITH ACUTE + u'\u0158' # 0xDB -> LATIN CAPITAL LETTER R WITH CARON + u'\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u0159' # 0xDE -> LATIN SMALL LETTER R WITH CARON + u'\u0156' # 0xDF -> LATIN CAPITAL LETTER R WITH CEDILLA + u'\u0157' # 0xE0 -> LATIN SMALL LETTER R WITH CEDILLA + u'\u0160' # 0xE1 -> LATIN CAPITAL LETTER S WITH CARON + u'\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + u'\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + u'\u0161' # 0xE4 -> LATIN SMALL LETTER S WITH CARON + u'\u015a' # 0xE5 -> LATIN CAPITAL LETTER S WITH ACUTE + u'\u015b' # 0xE6 -> LATIN SMALL LETTER S WITH ACUTE + u'\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\u0164' # 0xE8 -> LATIN CAPITAL LETTER T WITH CARON + u'\u0165' # 0xE9 -> LATIN SMALL LETTER T WITH CARON + u'\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + u'\u017d' # 0xEB -> LATIN CAPITAL LETTER Z WITH CARON + u'\u017e' # 0xEC -> LATIN SMALL LETTER Z WITH CARON + u'\u016a' # 0xED -> LATIN CAPITAL LETTER U WITH MACRON + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u016b' # 0xF0 -> LATIN SMALL LETTER U WITH MACRON + u'\u016e' # 0xF1 -> LATIN CAPITAL LETTER U WITH RING ABOVE + u'\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\u016f' # 0xF3 -> LATIN SMALL LETTER U WITH RING ABOVE + u'\u0170' # 0xF4 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + u'\u0171' # 0xF5 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + u'\u0172' # 0xF6 -> LATIN CAPITAL LETTER U WITH OGONEK + u'\u0173' # 0xF7 -> LATIN SMALL LETTER U WITH OGONEK + u'\xdd' # 0xF8 -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xfd' # 0xF9 -> LATIN SMALL LETTER Y WITH ACUTE + u'\u0137' # 0xFA -> LATIN SMALL LETTER K WITH CEDILLA + u'\u017b' # 0xFB -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + u'\u0141' # 0xFC -> LATIN CAPITAL LETTER L WITH STROKE + u'\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + u'\u0122' # 0xFE -> LATIN CAPITAL LETTER G WITH CEDILLA + u'\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_croatian.py b/src/main/resources/PythonLibs/encodings/mac_croatian.py new file mode 100644 index 0000000000000000000000000000000000000000..f57f7b4b33fe6a6f90b5069783a523e2804908f8 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_croatian.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_croatian generated from 'MAPPINGS/VENDORS/APPLE/CROATIAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-croatian', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + u'\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + u'\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + u'\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + u'\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + u'\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u2020' # 0xA0 -> DAGGER + u'\xb0' # 0xA1 -> DEGREE SIGN + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa7' # 0xA4 -> SECTION SIGN + u'\u2022' # 0xA5 -> BULLET + u'\xb6' # 0xA6 -> PILCROW SIGN + u'\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + u'\u2122' # 0xAA -> TRADE MARK SIGN + u'\xb4' # 0xAB -> ACUTE ACCENT + u'\xa8' # 0xAC -> DIAERESIS + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + u'\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + u'\u221e' # 0xB0 -> INFINITY + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\u2206' # 0xB4 -> INCREMENT + u'\xb5' # 0xB5 -> MICRO SIGN + u'\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + u'\u2211' # 0xB7 -> N-ARY SUMMATION + u'\u220f' # 0xB8 -> N-ARY PRODUCT + u'\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + u'\u222b' # 0xBA -> INTEGRAL + u'\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + u'\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + u'\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + u'\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + u'\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + u'\xbf' # 0xC0 -> INVERTED QUESTION MARK + u'\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + u'\xac' # 0xC2 -> NOT SIGN + u'\u221a' # 0xC3 -> SQUARE ROOT + u'\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + u'\u2248' # 0xC5 -> ALMOST EQUAL TO + u'\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + u'\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + u'\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + u'\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + u'\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + u'\u2014' # 0xD1 -> EM DASH + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u25ca' # 0xD7 -> LOZENGE + u'\uf8ff' # 0xD8 -> Apple logo + u'\xa9' # 0xD9 -> COPYRIGHT SIGN + u'\u2044' # 0xDA -> FRACTION SLASH + u'\u20ac' # 0xDB -> EURO SIGN + u'\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\xc6' # 0xDE -> LATIN CAPITAL LETTER AE + u'\xbb' # 0xDF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2013' # 0xE0 -> EN DASH + u'\xb7' # 0xE1 -> MIDDLE DOT + u'\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + u'\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2030' # 0xE4 -> PER MILLE SIGN + u'\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + u'\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + u'\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + u'\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + u'\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u02dc' # 0xF7 -> SMALL TILDE + u'\xaf' # 0xF8 -> MACRON + u'\u03c0' # 0xF9 -> GREEK SMALL LETTER PI + u'\xcb' # 0xFA -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\u02da' # 0xFB -> RING ABOVE + u'\xb8' # 0xFC -> CEDILLA + u'\xca' # 0xFD -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xe6' # 0xFE -> LATIN SMALL LETTER AE + u'\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_cyrillic.py b/src/main/resources/PythonLibs/encodings/mac_cyrillic.py new file mode 100644 index 0000000000000000000000000000000000000000..63324a14b86528fd32c0002a8417252a70ffbcd7 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_cyrillic.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_cyrillic generated from 'MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-cyrillic', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\u0410' # 0x80 -> CYRILLIC CAPITAL LETTER A + u'\u0411' # 0x81 -> CYRILLIC CAPITAL LETTER BE + u'\u0412' # 0x82 -> CYRILLIC CAPITAL LETTER VE + u'\u0413' # 0x83 -> CYRILLIC CAPITAL LETTER GHE + u'\u0414' # 0x84 -> CYRILLIC CAPITAL LETTER DE + u'\u0415' # 0x85 -> CYRILLIC CAPITAL LETTER IE + u'\u0416' # 0x86 -> CYRILLIC CAPITAL LETTER ZHE + u'\u0417' # 0x87 -> CYRILLIC CAPITAL LETTER ZE + u'\u0418' # 0x88 -> CYRILLIC CAPITAL LETTER I + u'\u0419' # 0x89 -> CYRILLIC CAPITAL LETTER SHORT I + u'\u041a' # 0x8A -> CYRILLIC CAPITAL LETTER KA + u'\u041b' # 0x8B -> CYRILLIC CAPITAL LETTER EL + u'\u041c' # 0x8C -> CYRILLIC CAPITAL LETTER EM + u'\u041d' # 0x8D -> CYRILLIC CAPITAL LETTER EN + u'\u041e' # 0x8E -> CYRILLIC CAPITAL LETTER O + u'\u041f' # 0x8F -> CYRILLIC CAPITAL LETTER PE + u'\u0420' # 0x90 -> CYRILLIC CAPITAL LETTER ER + u'\u0421' # 0x91 -> CYRILLIC CAPITAL LETTER ES + u'\u0422' # 0x92 -> CYRILLIC CAPITAL LETTER TE + u'\u0423' # 0x93 -> CYRILLIC CAPITAL LETTER U + u'\u0424' # 0x94 -> CYRILLIC CAPITAL LETTER EF + u'\u0425' # 0x95 -> CYRILLIC CAPITAL LETTER HA + u'\u0426' # 0x96 -> CYRILLIC CAPITAL LETTER TSE + u'\u0427' # 0x97 -> CYRILLIC CAPITAL LETTER CHE + u'\u0428' # 0x98 -> CYRILLIC CAPITAL LETTER SHA + u'\u0429' # 0x99 -> CYRILLIC CAPITAL LETTER SHCHA + u'\u042a' # 0x9A -> CYRILLIC CAPITAL LETTER HARD SIGN + u'\u042b' # 0x9B -> CYRILLIC CAPITAL LETTER YERU + u'\u042c' # 0x9C -> CYRILLIC CAPITAL LETTER SOFT SIGN + u'\u042d' # 0x9D -> CYRILLIC CAPITAL LETTER E + u'\u042e' # 0x9E -> CYRILLIC CAPITAL LETTER YU + u'\u042f' # 0x9F -> CYRILLIC CAPITAL LETTER YA + u'\u2020' # 0xA0 -> DAGGER + u'\xb0' # 0xA1 -> DEGREE SIGN + u'\u0490' # 0xA2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa7' # 0xA4 -> SECTION SIGN + u'\u2022' # 0xA5 -> BULLET + u'\xb6' # 0xA6 -> PILCROW SIGN + u'\u0406' # 0xA7 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u2122' # 0xAA -> TRADE MARK SIGN + u'\u0402' # 0xAB -> CYRILLIC CAPITAL LETTER DJE + u'\u0452' # 0xAC -> CYRILLIC SMALL LETTER DJE + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\u0403' # 0xAE -> CYRILLIC CAPITAL LETTER GJE + u'\u0453' # 0xAF -> CYRILLIC SMALL LETTER GJE + u'\u221e' # 0xB0 -> INFINITY + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\u0456' # 0xB4 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + u'\xb5' # 0xB5 -> MICRO SIGN + u'\u0491' # 0xB6 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + u'\u0408' # 0xB7 -> CYRILLIC CAPITAL LETTER JE + u'\u0404' # 0xB8 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + u'\u0454' # 0xB9 -> CYRILLIC SMALL LETTER UKRAINIAN IE + u'\u0407' # 0xBA -> CYRILLIC CAPITAL LETTER YI + u'\u0457' # 0xBB -> CYRILLIC SMALL LETTER YI + u'\u0409' # 0xBC -> CYRILLIC CAPITAL LETTER LJE + u'\u0459' # 0xBD -> CYRILLIC SMALL LETTER LJE + u'\u040a' # 0xBE -> CYRILLIC CAPITAL LETTER NJE + u'\u045a' # 0xBF -> CYRILLIC SMALL LETTER NJE + u'\u0458' # 0xC0 -> CYRILLIC SMALL LETTER JE + u'\u0405' # 0xC1 -> CYRILLIC CAPITAL LETTER DZE + u'\xac' # 0xC2 -> NOT SIGN + u'\u221a' # 0xC3 -> SQUARE ROOT + u'\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + u'\u2248' # 0xC5 -> ALMOST EQUAL TO + u'\u2206' # 0xC6 -> INCREMENT + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\u040b' # 0xCB -> CYRILLIC CAPITAL LETTER TSHE + u'\u045b' # 0xCC -> CYRILLIC SMALL LETTER TSHE + u'\u040c' # 0xCD -> CYRILLIC CAPITAL LETTER KJE + u'\u045c' # 0xCE -> CYRILLIC SMALL LETTER KJE + u'\u0455' # 0xCF -> CYRILLIC SMALL LETTER DZE + u'\u2013' # 0xD0 -> EN DASH + u'\u2014' # 0xD1 -> EM DASH + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u201e' # 0xD7 -> DOUBLE LOW-9 QUOTATION MARK + u'\u040e' # 0xD8 -> CYRILLIC CAPITAL LETTER SHORT U + u'\u045e' # 0xD9 -> CYRILLIC SMALL LETTER SHORT U + u'\u040f' # 0xDA -> CYRILLIC CAPITAL LETTER DZHE + u'\u045f' # 0xDB -> CYRILLIC SMALL LETTER DZHE + u'\u2116' # 0xDC -> NUMERO SIGN + u'\u0401' # 0xDD -> CYRILLIC CAPITAL LETTER IO + u'\u0451' # 0xDE -> CYRILLIC SMALL LETTER IO + u'\u044f' # 0xDF -> CYRILLIC SMALL LETTER YA + u'\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + u'\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + u'\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + u'\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + u'\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + u'\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + u'\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + u'\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + u'\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + u'\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + u'\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + u'\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + u'\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + u'\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + u'\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + u'\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + u'\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + u'\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + u'\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + u'\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + u'\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + u'\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + u'\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + u'\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + u'\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + u'\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + u'\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + u'\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + u'\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + u'\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + u'\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + u'\u20ac' # 0xFF -> EURO SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_farsi.py b/src/main/resources/PythonLibs/encodings/mac_farsi.py new file mode 100644 index 0000000000000000000000000000000000000000..9dbd76a2323324c468e8c0a7cf76a3139eeb449f --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_farsi.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_farsi generated from 'MAPPINGS/VENDORS/APPLE/FARSI.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-farsi', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE, left-right + u'!' # 0x21 -> EXCLAMATION MARK, left-right + u'"' # 0x22 -> QUOTATION MARK, left-right + u'#' # 0x23 -> NUMBER SIGN, left-right + u'$' # 0x24 -> DOLLAR SIGN, left-right + u'%' # 0x25 -> PERCENT SIGN, left-right + u'&' # 0x26 -> AMPERSAND, left-right + u"'" # 0x27 -> APOSTROPHE, left-right + u'(' # 0x28 -> LEFT PARENTHESIS, left-right + u')' # 0x29 -> RIGHT PARENTHESIS, left-right + u'*' # 0x2A -> ASTERISK, left-right + u'+' # 0x2B -> PLUS SIGN, left-right + u',' # 0x2C -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + u'-' # 0x2D -> HYPHEN-MINUS, left-right + u'.' # 0x2E -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + u'/' # 0x2F -> SOLIDUS, left-right + u'0' # 0x30 -> DIGIT ZERO; in Arabic-script context, displayed as 0x06F0 EXTENDED ARABIC-INDIC DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE; in Arabic-script context, displayed as 0x06F1 EXTENDED ARABIC-INDIC DIGIT ONE + u'2' # 0x32 -> DIGIT TWO; in Arabic-script context, displayed as 0x06F2 EXTENDED ARABIC-INDIC DIGIT TWO + u'3' # 0x33 -> DIGIT THREE; in Arabic-script context, displayed as 0x06F3 EXTENDED ARABIC-INDIC DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR; in Arabic-script context, displayed as 0x06F4 EXTENDED ARABIC-INDIC DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE; in Arabic-script context, displayed as 0x06F5 EXTENDED ARABIC-INDIC DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX; in Arabic-script context, displayed as 0x06F6 EXTENDED ARABIC-INDIC DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE; in Arabic-script context, displayed as 0x06F9 EXTENDED ARABIC-INDIC DIGIT NINE + u':' # 0x3A -> COLON, left-right + u';' # 0x3B -> SEMICOLON, left-right + u'<' # 0x3C -> LESS-THAN SIGN, left-right + u'=' # 0x3D -> EQUALS SIGN, left-right + u'>' # 0x3E -> GREATER-THAN SIGN, left-right + u'?' # 0x3F -> QUESTION MARK, left-right + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET, left-right + u'\\' # 0x5C -> REVERSE SOLIDUS, left-right + u']' # 0x5D -> RIGHT SQUARE BRACKET, left-right + u'^' # 0x5E -> CIRCUMFLEX ACCENT, left-right + u'_' # 0x5F -> LOW LINE, left-right + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET, left-right + u'|' # 0x7C -> VERTICAL LINE, left-right + u'}' # 0x7D -> RIGHT CURLY BRACKET, left-right + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xa0' # 0x81 -> NO-BREAK SPACE, right-left + u'\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u06ba' # 0x8B -> ARABIC LETTER NOON GHUNNA + u'\xab' # 0x8C -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + u'\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + u'\u2026' # 0x93 -> HORIZONTAL ELLIPSIS, right-left + u'\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + u'\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + u'\xbb' # 0x98 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf7' # 0x9B -> DIVISION SIGN, right-left + u'\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + u'\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u' ' # 0xA0 -> SPACE, right-left + u'!' # 0xA1 -> EXCLAMATION MARK, right-left + u'"' # 0xA2 -> QUOTATION MARK, right-left + u'#' # 0xA3 -> NUMBER SIGN, right-left + u'$' # 0xA4 -> DOLLAR SIGN, right-left + u'\u066a' # 0xA5 -> ARABIC PERCENT SIGN + u'&' # 0xA6 -> AMPERSAND, right-left + u"'" # 0xA7 -> APOSTROPHE, right-left + u'(' # 0xA8 -> LEFT PARENTHESIS, right-left + u')' # 0xA9 -> RIGHT PARENTHESIS, right-left + u'*' # 0xAA -> ASTERISK, right-left + u'+' # 0xAB -> PLUS SIGN, right-left + u'\u060c' # 0xAC -> ARABIC COMMA + u'-' # 0xAD -> HYPHEN-MINUS, right-left + u'.' # 0xAE -> FULL STOP, right-left + u'/' # 0xAF -> SOLIDUS, right-left + u'\u06f0' # 0xB0 -> EXTENDED ARABIC-INDIC DIGIT ZERO, right-left (need override) + u'\u06f1' # 0xB1 -> EXTENDED ARABIC-INDIC DIGIT ONE, right-left (need override) + u'\u06f2' # 0xB2 -> EXTENDED ARABIC-INDIC DIGIT TWO, right-left (need override) + u'\u06f3' # 0xB3 -> EXTENDED ARABIC-INDIC DIGIT THREE, right-left (need override) + u'\u06f4' # 0xB4 -> EXTENDED ARABIC-INDIC DIGIT FOUR, right-left (need override) + u'\u06f5' # 0xB5 -> EXTENDED ARABIC-INDIC DIGIT FIVE, right-left (need override) + u'\u06f6' # 0xB6 -> EXTENDED ARABIC-INDIC DIGIT SIX, right-left (need override) + u'\u06f7' # 0xB7 -> EXTENDED ARABIC-INDIC DIGIT SEVEN, right-left (need override) + u'\u06f8' # 0xB8 -> EXTENDED ARABIC-INDIC DIGIT EIGHT, right-left (need override) + u'\u06f9' # 0xB9 -> EXTENDED ARABIC-INDIC DIGIT NINE, right-left (need override) + u':' # 0xBA -> COLON, right-left + u'\u061b' # 0xBB -> ARABIC SEMICOLON + u'<' # 0xBC -> LESS-THAN SIGN, right-left + u'=' # 0xBD -> EQUALS SIGN, right-left + u'>' # 0xBE -> GREATER-THAN SIGN, right-left + u'\u061f' # 0xBF -> ARABIC QUESTION MARK + u'\u274a' # 0xC0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + u'\u0621' # 0xC1 -> ARABIC LETTER HAMZA + u'\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + u'\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + u'\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + u'\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + u'\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + u'\u0627' # 0xC7 -> ARABIC LETTER ALEF + u'\u0628' # 0xC8 -> ARABIC LETTER BEH + u'\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + u'\u062a' # 0xCA -> ARABIC LETTER TEH + u'\u062b' # 0xCB -> ARABIC LETTER THEH + u'\u062c' # 0xCC -> ARABIC LETTER JEEM + u'\u062d' # 0xCD -> ARABIC LETTER HAH + u'\u062e' # 0xCE -> ARABIC LETTER KHAH + u'\u062f' # 0xCF -> ARABIC LETTER DAL + u'\u0630' # 0xD0 -> ARABIC LETTER THAL + u'\u0631' # 0xD1 -> ARABIC LETTER REH + u'\u0632' # 0xD2 -> ARABIC LETTER ZAIN + u'\u0633' # 0xD3 -> ARABIC LETTER SEEN + u'\u0634' # 0xD4 -> ARABIC LETTER SHEEN + u'\u0635' # 0xD5 -> ARABIC LETTER SAD + u'\u0636' # 0xD6 -> ARABIC LETTER DAD + u'\u0637' # 0xD7 -> ARABIC LETTER TAH + u'\u0638' # 0xD8 -> ARABIC LETTER ZAH + u'\u0639' # 0xD9 -> ARABIC LETTER AIN + u'\u063a' # 0xDA -> ARABIC LETTER GHAIN + u'[' # 0xDB -> LEFT SQUARE BRACKET, right-left + u'\\' # 0xDC -> REVERSE SOLIDUS, right-left + u']' # 0xDD -> RIGHT SQUARE BRACKET, right-left + u'^' # 0xDE -> CIRCUMFLEX ACCENT, right-left + u'_' # 0xDF -> LOW LINE, right-left + u'\u0640' # 0xE0 -> ARABIC TATWEEL + u'\u0641' # 0xE1 -> ARABIC LETTER FEH + u'\u0642' # 0xE2 -> ARABIC LETTER QAF + u'\u0643' # 0xE3 -> ARABIC LETTER KAF + u'\u0644' # 0xE4 -> ARABIC LETTER LAM + u'\u0645' # 0xE5 -> ARABIC LETTER MEEM + u'\u0646' # 0xE6 -> ARABIC LETTER NOON + u'\u0647' # 0xE7 -> ARABIC LETTER HEH + u'\u0648' # 0xE8 -> ARABIC LETTER WAW + u'\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA + u'\u064a' # 0xEA -> ARABIC LETTER YEH + u'\u064b' # 0xEB -> ARABIC FATHATAN + u'\u064c' # 0xEC -> ARABIC DAMMATAN + u'\u064d' # 0xED -> ARABIC KASRATAN + u'\u064e' # 0xEE -> ARABIC FATHA + u'\u064f' # 0xEF -> ARABIC DAMMA + u'\u0650' # 0xF0 -> ARABIC KASRA + u'\u0651' # 0xF1 -> ARABIC SHADDA + u'\u0652' # 0xF2 -> ARABIC SUKUN + u'\u067e' # 0xF3 -> ARABIC LETTER PEH + u'\u0679' # 0xF4 -> ARABIC LETTER TTEH + u'\u0686' # 0xF5 -> ARABIC LETTER TCHEH + u'\u06d5' # 0xF6 -> ARABIC LETTER AE + u'\u06a4' # 0xF7 -> ARABIC LETTER VEH + u'\u06af' # 0xF8 -> ARABIC LETTER GAF + u'\u0688' # 0xF9 -> ARABIC LETTER DDAL + u'\u0691' # 0xFA -> ARABIC LETTER RREH + u'{' # 0xFB -> LEFT CURLY BRACKET, right-left + u'|' # 0xFC -> VERTICAL LINE, right-left + u'}' # 0xFD -> RIGHT CURLY BRACKET, right-left + u'\u0698' # 0xFE -> ARABIC LETTER JEH + u'\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_greek.py b/src/main/resources/PythonLibs/encodings/mac_greek.py new file mode 100644 index 0000000000000000000000000000000000000000..68f4fff0dba9bcc75be2afe31a9001f6bd64d132 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_greek.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_greek generated from 'MAPPINGS/VENDORS/APPLE/GREEK.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-greek', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xb9' # 0x81 -> SUPERSCRIPT ONE + u'\xb2' # 0x82 -> SUPERSCRIPT TWO + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xb3' # 0x84 -> SUPERSCRIPT THREE + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\u0385' # 0x87 -> GREEK DIALYTIKA TONOS + u'\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\u0384' # 0x8B -> GREEK TONOS + u'\xa8' # 0x8C -> DIAERESIS + u'\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xa3' # 0x92 -> POUND SIGN + u'\u2122' # 0x93 -> TRADE MARK SIGN + u'\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\u2022' # 0x96 -> BULLET + u'\xbd' # 0x97 -> VULGAR FRACTION ONE HALF + u'\u2030' # 0x98 -> PER MILLE SIGN + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xa6' # 0x9B -> BROKEN BAR + u'\u20ac' # 0x9C -> EURO SIGN # before Mac OS 9.2.2, was SOFT HYPHEN + u'\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u2020' # 0xA0 -> DAGGER + u'\u0393' # 0xA1 -> GREEK CAPITAL LETTER GAMMA + u'\u0394' # 0xA2 -> GREEK CAPITAL LETTER DELTA + u'\u0398' # 0xA3 -> GREEK CAPITAL LETTER THETA + u'\u039b' # 0xA4 -> GREEK CAPITAL LETTER LAMDA + u'\u039e' # 0xA5 -> GREEK CAPITAL LETTER XI + u'\u03a0' # 0xA6 -> GREEK CAPITAL LETTER PI + u'\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u03a3' # 0xAA -> GREEK CAPITAL LETTER SIGMA + u'\u03aa' # 0xAB -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + u'\xa7' # 0xAC -> SECTION SIGN + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\xb0' # 0xAE -> DEGREE SIGN + u'\xb7' # 0xAF -> MIDDLE DOT + u'\u0391' # 0xB0 -> GREEK CAPITAL LETTER ALPHA + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\xa5' # 0xB4 -> YEN SIGN + u'\u0392' # 0xB5 -> GREEK CAPITAL LETTER BETA + u'\u0395' # 0xB6 -> GREEK CAPITAL LETTER EPSILON + u'\u0396' # 0xB7 -> GREEK CAPITAL LETTER ZETA + u'\u0397' # 0xB8 -> GREEK CAPITAL LETTER ETA + u'\u0399' # 0xB9 -> GREEK CAPITAL LETTER IOTA + u'\u039a' # 0xBA -> GREEK CAPITAL LETTER KAPPA + u'\u039c' # 0xBB -> GREEK CAPITAL LETTER MU + u'\u03a6' # 0xBC -> GREEK CAPITAL LETTER PHI + u'\u03ab' # 0xBD -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + u'\u03a8' # 0xBE -> GREEK CAPITAL LETTER PSI + u'\u03a9' # 0xBF -> GREEK CAPITAL LETTER OMEGA + u'\u03ac' # 0xC0 -> GREEK SMALL LETTER ALPHA WITH TONOS + u'\u039d' # 0xC1 -> GREEK CAPITAL LETTER NU + u'\xac' # 0xC2 -> NOT SIGN + u'\u039f' # 0xC3 -> GREEK CAPITAL LETTER OMICRON + u'\u03a1' # 0xC4 -> GREEK CAPITAL LETTER RHO + u'\u2248' # 0xC5 -> ALMOST EQUAL TO + u'\u03a4' # 0xC6 -> GREEK CAPITAL LETTER TAU + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\u03a5' # 0xCB -> GREEK CAPITAL LETTER UPSILON + u'\u03a7' # 0xCC -> GREEK CAPITAL LETTER CHI + u'\u0386' # 0xCD -> GREEK CAPITAL LETTER ALPHA WITH TONOS + u'\u0388' # 0xCE -> GREEK CAPITAL LETTER EPSILON WITH TONOS + u'\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + u'\u2013' # 0xD0 -> EN DASH + u'\u2015' # 0xD1 -> HORIZONTAL BAR + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u0389' # 0xD7 -> GREEK CAPITAL LETTER ETA WITH TONOS + u'\u038a' # 0xD8 -> GREEK CAPITAL LETTER IOTA WITH TONOS + u'\u038c' # 0xD9 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + u'\u038e' # 0xDA -> GREEK CAPITAL LETTER UPSILON WITH TONOS + u'\u03ad' # 0xDB -> GREEK SMALL LETTER EPSILON WITH TONOS + u'\u03ae' # 0xDC -> GREEK SMALL LETTER ETA WITH TONOS + u'\u03af' # 0xDD -> GREEK SMALL LETTER IOTA WITH TONOS + u'\u03cc' # 0xDE -> GREEK SMALL LETTER OMICRON WITH TONOS + u'\u038f' # 0xDF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + u'\u03cd' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH TONOS + u'\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + u'\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + u'\u03c8' # 0xE3 -> GREEK SMALL LETTER PSI + u'\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + u'\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + u'\u03c6' # 0xE6 -> GREEK SMALL LETTER PHI + u'\u03b3' # 0xE7 -> GREEK SMALL LETTER GAMMA + u'\u03b7' # 0xE8 -> GREEK SMALL LETTER ETA + u'\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + u'\u03be' # 0xEA -> GREEK SMALL LETTER XI + u'\u03ba' # 0xEB -> GREEK SMALL LETTER KAPPA + u'\u03bb' # 0xEC -> GREEK SMALL LETTER LAMDA + u'\u03bc' # 0xED -> GREEK SMALL LETTER MU + u'\u03bd' # 0xEE -> GREEK SMALL LETTER NU + u'\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + u'\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + u'\u03ce' # 0xF1 -> GREEK SMALL LETTER OMEGA WITH TONOS + u'\u03c1' # 0xF2 -> GREEK SMALL LETTER RHO + u'\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + u'\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + u'\u03b8' # 0xF5 -> GREEK SMALL LETTER THETA + u'\u03c9' # 0xF6 -> GREEK SMALL LETTER OMEGA + u'\u03c2' # 0xF7 -> GREEK SMALL LETTER FINAL SIGMA + u'\u03c7' # 0xF8 -> GREEK SMALL LETTER CHI + u'\u03c5' # 0xF9 -> GREEK SMALL LETTER UPSILON + u'\u03b6' # 0xFA -> GREEK SMALL LETTER ZETA + u'\u03ca' # 0xFB -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + u'\u03cb' # 0xFC -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + u'\u0390' # 0xFD -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + u'\u03b0' # 0xFE -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + u'\xad' # 0xFF -> SOFT HYPHEN # before Mac OS 9.2.2, was undefined +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_iceland.py b/src/main/resources/PythonLibs/encodings/mac_iceland.py new file mode 100644 index 0000000000000000000000000000000000000000..c24add2ad0d58b6e64cee86ff7941010b45bf44d --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_iceland.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_iceland generated from 'MAPPINGS/VENDORS/APPLE/ICELAND.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-iceland', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + u'\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + u'\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + u'\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + u'\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + u'\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u'\xdd' # 0xA0 -> LATIN CAPITAL LETTER Y WITH ACUTE + u'\xb0' # 0xA1 -> DEGREE SIGN + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa7' # 0xA4 -> SECTION SIGN + u'\u2022' # 0xA5 -> BULLET + u'\xb6' # 0xA6 -> PILCROW SIGN + u'\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u2122' # 0xAA -> TRADE MARK SIGN + u'\xb4' # 0xAB -> ACUTE ACCENT + u'\xa8' # 0xAC -> DIAERESIS + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + u'\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + u'\u221e' # 0xB0 -> INFINITY + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\xa5' # 0xB4 -> YEN SIGN + u'\xb5' # 0xB5 -> MICRO SIGN + u'\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + u'\u2211' # 0xB7 -> N-ARY SUMMATION + u'\u220f' # 0xB8 -> N-ARY PRODUCT + u'\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + u'\u222b' # 0xBA -> INTEGRAL + u'\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + u'\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + u'\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + u'\xe6' # 0xBE -> LATIN SMALL LETTER AE + u'\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + u'\xbf' # 0xC0 -> INVERTED QUESTION MARK + u'\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + u'\xac' # 0xC2 -> NOT SIGN + u'\u221a' # 0xC3 -> SQUARE ROOT + u'\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + u'\u2248' # 0xC5 -> ALMOST EQUAL TO + u'\u2206' # 0xC6 -> INCREMENT + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + u'\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + u'\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + u'\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + u'\u2013' # 0xD0 -> EN DASH + u'\u2014' # 0xD1 -> EM DASH + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u25ca' # 0xD7 -> LOZENGE + u'\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\u2044' # 0xDA -> FRACTION SLASH + u'\u20ac' # 0xDB -> EURO SIGN + u'\xd0' # 0xDC -> LATIN CAPITAL LETTER ETH + u'\xf0' # 0xDD -> LATIN SMALL LETTER ETH + u'\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + u'\xfe' # 0xDF -> LATIN SMALL LETTER THORN + u'\xfd' # 0xE0 -> LATIN SMALL LETTER Y WITH ACUTE + u'\xb7' # 0xE1 -> MIDDLE DOT + u'\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + u'\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2030' # 0xE4 -> PER MILLE SIGN + u'\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\uf8ff' # 0xF0 -> Apple logo + u'\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + u'\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u02dc' # 0xF7 -> SMALL TILDE + u'\xaf' # 0xF8 -> MACRON + u'\u02d8' # 0xF9 -> BREVE + u'\u02d9' # 0xFA -> DOT ABOVE + u'\u02da' # 0xFB -> RING ABOVE + u'\xb8' # 0xFC -> CEDILLA + u'\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + u'\u02db' # 0xFE -> OGONEK + u'\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_latin2.py b/src/main/resources/PythonLibs/encodings/mac_latin2.py new file mode 100644 index 0000000000000000000000000000000000000000..e322be236c3efdd66af473d753a049140b83a3bc --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_latin2.py @@ -0,0 +1,183 @@ +""" Python Character Mapping Codec generated from 'LATIN2.TXT' with gencodec.py. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. +(c) Copyright 2000 Guido van Rossum. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_map) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_map)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-latin2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x0081: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON + 0x0082: 0x0101, # LATIN SMALL LETTER A WITH MACRON + 0x0083: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0084: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK + 0x0085: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x0086: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x0087: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x0088: 0x0105, # LATIN SMALL LETTER A WITH OGONEK + 0x0089: 0x010c, # LATIN CAPITAL LETTER C WITH CARON + 0x008a: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x008b: 0x010d, # LATIN SMALL LETTER C WITH CARON + 0x008c: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE + 0x008d: 0x0107, # LATIN SMALL LETTER C WITH ACUTE + 0x008e: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x008f: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x0090: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE + 0x0091: 0x010e, # LATIN CAPITAL LETTER D WITH CARON + 0x0092: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x0093: 0x010f, # LATIN SMALL LETTER D WITH CARON + 0x0094: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON + 0x0095: 0x0113, # LATIN SMALL LETTER E WITH MACRON + 0x0096: 0x0116, # LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x0097: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x0098: 0x0117, # LATIN SMALL LETTER E WITH DOT ABOVE + 0x0099: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x009a: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x009b: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x009c: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x009d: 0x011a, # LATIN CAPITAL LETTER E WITH CARON + 0x009e: 0x011b, # LATIN SMALL LETTER E WITH CARON + 0x009f: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00a0: 0x2020, # DAGGER + 0x00a1: 0x00b0, # DEGREE SIGN + 0x00a2: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK + 0x00a4: 0x00a7, # SECTION SIGN + 0x00a5: 0x2022, # BULLET + 0x00a6: 0x00b6, # PILCROW SIGN + 0x00a7: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00a8: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x2122, # TRADE MARK SIGN + 0x00ab: 0x0119, # LATIN SMALL LETTER E WITH OGONEK + 0x00ac: 0x00a8, # DIAERESIS + 0x00ad: 0x2260, # NOT EQUAL TO + 0x00ae: 0x0123, # LATIN SMALL LETTER G WITH CEDILLA + 0x00af: 0x012e, # LATIN CAPITAL LETTER I WITH OGONEK + 0x00b0: 0x012f, # LATIN SMALL LETTER I WITH OGONEK + 0x00b1: 0x012a, # LATIN CAPITAL LETTER I WITH MACRON + 0x00b2: 0x2264, # LESS-THAN OR EQUAL TO + 0x00b3: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00b4: 0x012b, # LATIN SMALL LETTER I WITH MACRON + 0x00b5: 0x0136, # LATIN CAPITAL LETTER K WITH CEDILLA + 0x00b6: 0x2202, # PARTIAL DIFFERENTIAL + 0x00b7: 0x2211, # N-ARY SUMMATION + 0x00b8: 0x0142, # LATIN SMALL LETTER L WITH STROKE + 0x00b9: 0x013b, # LATIN CAPITAL LETTER L WITH CEDILLA + 0x00ba: 0x013c, # LATIN SMALL LETTER L WITH CEDILLA + 0x00bb: 0x013d, # LATIN CAPITAL LETTER L WITH CARON + 0x00bc: 0x013e, # LATIN SMALL LETTER L WITH CARON + 0x00bd: 0x0139, # LATIN CAPITAL LETTER L WITH ACUTE + 0x00be: 0x013a, # LATIN SMALL LETTER L WITH ACUTE + 0x00bf: 0x0145, # LATIN CAPITAL LETTER N WITH CEDILLA + 0x00c0: 0x0146, # LATIN SMALL LETTER N WITH CEDILLA + 0x00c1: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE + 0x00c2: 0x00ac, # NOT SIGN + 0x00c3: 0x221a, # SQUARE ROOT + 0x00c4: 0x0144, # LATIN SMALL LETTER N WITH ACUTE + 0x00c5: 0x0147, # LATIN CAPITAL LETTER N WITH CARON + 0x00c6: 0x2206, # INCREMENT + 0x00c7: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00c8: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00c9: 0x2026, # HORIZONTAL ELLIPSIS + 0x00ca: 0x00a0, # NO-BREAK SPACE + 0x00cb: 0x0148, # LATIN SMALL LETTER N WITH CARON + 0x00cc: 0x0150, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + 0x00cd: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00ce: 0x0151, # LATIN SMALL LETTER O WITH DOUBLE ACUTE + 0x00cf: 0x014c, # LATIN CAPITAL LETTER O WITH MACRON + 0x00d0: 0x2013, # EN DASH + 0x00d1: 0x2014, # EM DASH + 0x00d2: 0x201c, # LEFT DOUBLE QUOTATION MARK + 0x00d3: 0x201d, # RIGHT DOUBLE QUOTATION MARK + 0x00d4: 0x2018, # LEFT SINGLE QUOTATION MARK + 0x00d5: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x00d6: 0x00f7, # DIVISION SIGN + 0x00d7: 0x25ca, # LOZENGE + 0x00d8: 0x014d, # LATIN SMALL LETTER O WITH MACRON + 0x00d9: 0x0154, # LATIN CAPITAL LETTER R WITH ACUTE + 0x00da: 0x0155, # LATIN SMALL LETTER R WITH ACUTE + 0x00db: 0x0158, # LATIN CAPITAL LETTER R WITH CARON + 0x00dc: 0x2039, # SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x00dd: 0x203a, # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x00de: 0x0159, # LATIN SMALL LETTER R WITH CARON + 0x00df: 0x0156, # LATIN CAPITAL LETTER R WITH CEDILLA + 0x00e0: 0x0157, # LATIN SMALL LETTER R WITH CEDILLA + 0x00e1: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00e2: 0x201a, # SINGLE LOW-9 QUOTATION MARK + 0x00e3: 0x201e, # DOUBLE LOW-9 QUOTATION MARK + 0x00e4: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00e5: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE + 0x00e6: 0x015b, # LATIN SMALL LETTER S WITH ACUTE + 0x00e7: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00e8: 0x0164, # LATIN CAPITAL LETTER T WITH CARON + 0x00e9: 0x0165, # LATIN SMALL LETTER T WITH CARON + 0x00ea: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00eb: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON + 0x00ec: 0x017e, # LATIN SMALL LETTER Z WITH CARON + 0x00ed: 0x016a, # LATIN CAPITAL LETTER U WITH MACRON + 0x00ee: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00ef: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00f0: 0x016b, # LATIN SMALL LETTER U WITH MACRON + 0x00f1: 0x016e, # LATIN CAPITAL LETTER U WITH RING ABOVE + 0x00f2: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00f3: 0x016f, # LATIN SMALL LETTER U WITH RING ABOVE + 0x00f4: 0x0170, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + 0x00f5: 0x0171, # LATIN SMALL LETTER U WITH DOUBLE ACUTE + 0x00f6: 0x0172, # LATIN CAPITAL LETTER U WITH OGONEK + 0x00f7: 0x0173, # LATIN SMALL LETTER U WITH OGONEK + 0x00f8: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00f9: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fa: 0x0137, # LATIN SMALL LETTER K WITH CEDILLA + 0x00fb: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x00fc: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE + 0x00fd: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00fe: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA + 0x00ff: 0x02c7, # CARON +}) + +### Encoding Map + +encoding_map = codecs.make_encoding_map(decoding_map) diff --git a/src/main/resources/PythonLibs/encodings/mac_roman.py b/src/main/resources/PythonLibs/encodings/mac_roman.py new file mode 100644 index 0000000000000000000000000000000000000000..62605ec634f8e30814174b6a19b11196761faf90 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_roman.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_roman generated from 'MAPPINGS/VENDORS/APPLE/ROMAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-roman', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + u'\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + u'\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + u'\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + u'\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + u'\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u2020' # 0xA0 -> DAGGER + u'\xb0' # 0xA1 -> DEGREE SIGN + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa7' # 0xA4 -> SECTION SIGN + u'\u2022' # 0xA5 -> BULLET + u'\xb6' # 0xA6 -> PILCROW SIGN + u'\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u2122' # 0xAA -> TRADE MARK SIGN + u'\xb4' # 0xAB -> ACUTE ACCENT + u'\xa8' # 0xAC -> DIAERESIS + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + u'\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + u'\u221e' # 0xB0 -> INFINITY + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\xa5' # 0xB4 -> YEN SIGN + u'\xb5' # 0xB5 -> MICRO SIGN + u'\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + u'\u2211' # 0xB7 -> N-ARY SUMMATION + u'\u220f' # 0xB8 -> N-ARY PRODUCT + u'\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + u'\u222b' # 0xBA -> INTEGRAL + u'\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + u'\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + u'\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + u'\xe6' # 0xBE -> LATIN SMALL LETTER AE + u'\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + u'\xbf' # 0xC0 -> INVERTED QUESTION MARK + u'\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + u'\xac' # 0xC2 -> NOT SIGN + u'\u221a' # 0xC3 -> SQUARE ROOT + u'\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + u'\u2248' # 0xC5 -> ALMOST EQUAL TO + u'\u2206' # 0xC6 -> INCREMENT + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + u'\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + u'\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + u'\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + u'\u2013' # 0xD0 -> EN DASH + u'\u2014' # 0xD1 -> EM DASH + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u25ca' # 0xD7 -> LOZENGE + u'\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\u2044' # 0xDA -> FRACTION SLASH + u'\u20ac' # 0xDB -> EURO SIGN + u'\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\ufb01' # 0xDE -> LATIN SMALL LIGATURE FI + u'\ufb02' # 0xDF -> LATIN SMALL LIGATURE FL + u'\u2021' # 0xE0 -> DOUBLE DAGGER + u'\xb7' # 0xE1 -> MIDDLE DOT + u'\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + u'\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2030' # 0xE4 -> PER MILLE SIGN + u'\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\uf8ff' # 0xF0 -> Apple logo + u'\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + u'\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u02dc' # 0xF7 -> SMALL TILDE + u'\xaf' # 0xF8 -> MACRON + u'\u02d8' # 0xF9 -> BREVE + u'\u02d9' # 0xFA -> DOT ABOVE + u'\u02da' # 0xFB -> RING ABOVE + u'\xb8' # 0xFC -> CEDILLA + u'\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + u'\u02db' # 0xFE -> OGONEK + u'\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_romanian.py b/src/main/resources/PythonLibs/encodings/mac_romanian.py new file mode 100644 index 0000000000000000000000000000000000000000..5bd5ae862531f060f4910ad7de4c3c5b2895be9f --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_romanian.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_romanian generated from 'MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-romanian', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + u'\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + u'\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + u'\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + u'\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + u'\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u2020' # 0xA0 -> DAGGER + u'\xb0' # 0xA1 -> DEGREE SIGN + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa7' # 0xA4 -> SECTION SIGN + u'\u2022' # 0xA5 -> BULLET + u'\xb6' # 0xA6 -> PILCROW SIGN + u'\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u2122' # 0xAA -> TRADE MARK SIGN + u'\xb4' # 0xAB -> ACUTE ACCENT + u'\xa8' # 0xAC -> DIAERESIS + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\u0102' # 0xAE -> LATIN CAPITAL LETTER A WITH BREVE + u'\u0218' # 0xAF -> LATIN CAPITAL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later + u'\u221e' # 0xB0 -> INFINITY + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\xa5' # 0xB4 -> YEN SIGN + u'\xb5' # 0xB5 -> MICRO SIGN + u'\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + u'\u2211' # 0xB7 -> N-ARY SUMMATION + u'\u220f' # 0xB8 -> N-ARY PRODUCT + u'\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + u'\u222b' # 0xBA -> INTEGRAL + u'\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + u'\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + u'\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + u'\u0103' # 0xBE -> LATIN SMALL LETTER A WITH BREVE + u'\u0219' # 0xBF -> LATIN SMALL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later + u'\xbf' # 0xC0 -> INVERTED QUESTION MARK + u'\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + u'\xac' # 0xC2 -> NOT SIGN + u'\u221a' # 0xC3 -> SQUARE ROOT + u'\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + u'\u2248' # 0xC5 -> ALMOST EQUAL TO + u'\u2206' # 0xC6 -> INCREMENT + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + u'\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + u'\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + u'\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + u'\u2013' # 0xD0 -> EN DASH + u'\u2014' # 0xD1 -> EM DASH + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u25ca' # 0xD7 -> LOZENGE + u'\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\u2044' # 0xDA -> FRACTION SLASH + u'\u20ac' # 0xDB -> EURO SIGN + u'\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + u'\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + u'\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later + u'\u021b' # 0xDF -> LATIN SMALL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later + u'\u2021' # 0xE0 -> DOUBLE DAGGER + u'\xb7' # 0xE1 -> MIDDLE DOT + u'\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + u'\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2030' # 0xE4 -> PER MILLE SIGN + u'\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\uf8ff' # 0xF0 -> Apple logo + u'\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + u'\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u02dc' # 0xF7 -> SMALL TILDE + u'\xaf' # 0xF8 -> MACRON + u'\u02d8' # 0xF9 -> BREVE + u'\u02d9' # 0xFA -> DOT ABOVE + u'\u02da' # 0xFB -> RING ABOVE + u'\xb8' # 0xFC -> CEDILLA + u'\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + u'\u02db' # 0xFE -> OGONEK + u'\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mac_turkish.py b/src/main/resources/PythonLibs/encodings/mac_turkish.py new file mode 100644 index 0000000000000000000000000000000000000000..0787f4990b4b077d69a6858187ef7ba296d39a82 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mac_turkish.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_turkish generated from 'MAPPINGS/VENDORS/APPLE/TURKISH.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-turkish', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> CONTROL CHARACTER + u'\x01' # 0x01 -> CONTROL CHARACTER + u'\x02' # 0x02 -> CONTROL CHARACTER + u'\x03' # 0x03 -> CONTROL CHARACTER + u'\x04' # 0x04 -> CONTROL CHARACTER + u'\x05' # 0x05 -> CONTROL CHARACTER + u'\x06' # 0x06 -> CONTROL CHARACTER + u'\x07' # 0x07 -> CONTROL CHARACTER + u'\x08' # 0x08 -> CONTROL CHARACTER + u'\t' # 0x09 -> CONTROL CHARACTER + u'\n' # 0x0A -> CONTROL CHARACTER + u'\x0b' # 0x0B -> CONTROL CHARACTER + u'\x0c' # 0x0C -> CONTROL CHARACTER + u'\r' # 0x0D -> CONTROL CHARACTER + u'\x0e' # 0x0E -> CONTROL CHARACTER + u'\x0f' # 0x0F -> CONTROL CHARACTER + u'\x10' # 0x10 -> CONTROL CHARACTER + u'\x11' # 0x11 -> CONTROL CHARACTER + u'\x12' # 0x12 -> CONTROL CHARACTER + u'\x13' # 0x13 -> CONTROL CHARACTER + u'\x14' # 0x14 -> CONTROL CHARACTER + u'\x15' # 0x15 -> CONTROL CHARACTER + u'\x16' # 0x16 -> CONTROL CHARACTER + u'\x17' # 0x17 -> CONTROL CHARACTER + u'\x18' # 0x18 -> CONTROL CHARACTER + u'\x19' # 0x19 -> CONTROL CHARACTER + u'\x1a' # 0x1A -> CONTROL CHARACTER + u'\x1b' # 0x1B -> CONTROL CHARACTER + u'\x1c' # 0x1C -> CONTROL CHARACTER + u'\x1d' # 0x1D -> CONTROL CHARACTER + u'\x1e' # 0x1E -> CONTROL CHARACTER + u'\x1f' # 0x1F -> CONTROL CHARACTER + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> CONTROL CHARACTER + u'\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + u'\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + u'\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + u'\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + u'\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + u'\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + u'\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + u'\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + u'\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + u'\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + u'\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + u'\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + u'\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + u'\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + u'\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + u'\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + u'\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + u'\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + u'\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + u'\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + u'\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + u'\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + u'\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + u'\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + u'\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + u'\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + u'\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + u'\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + u'\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + u'\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + u'\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + u'\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + u'\u2020' # 0xA0 -> DAGGER + u'\xb0' # 0xA1 -> DEGREE SIGN + u'\xa2' # 0xA2 -> CENT SIGN + u'\xa3' # 0xA3 -> POUND SIGN + u'\xa7' # 0xA4 -> SECTION SIGN + u'\u2022' # 0xA5 -> BULLET + u'\xb6' # 0xA6 -> PILCROW SIGN + u'\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + u'\xae' # 0xA8 -> REGISTERED SIGN + u'\xa9' # 0xA9 -> COPYRIGHT SIGN + u'\u2122' # 0xAA -> TRADE MARK SIGN + u'\xb4' # 0xAB -> ACUTE ACCENT + u'\xa8' # 0xAC -> DIAERESIS + u'\u2260' # 0xAD -> NOT EQUAL TO + u'\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + u'\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + u'\u221e' # 0xB0 -> INFINITY + u'\xb1' # 0xB1 -> PLUS-MINUS SIGN + u'\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + u'\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + u'\xa5' # 0xB4 -> YEN SIGN + u'\xb5' # 0xB5 -> MICRO SIGN + u'\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + u'\u2211' # 0xB7 -> N-ARY SUMMATION + u'\u220f' # 0xB8 -> N-ARY PRODUCT + u'\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + u'\u222b' # 0xBA -> INTEGRAL + u'\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + u'\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + u'\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + u'\xe6' # 0xBE -> LATIN SMALL LETTER AE + u'\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + u'\xbf' # 0xC0 -> INVERTED QUESTION MARK + u'\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + u'\xac' # 0xC2 -> NOT SIGN + u'\u221a' # 0xC3 -> SQUARE ROOT + u'\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + u'\u2248' # 0xC5 -> ALMOST EQUAL TO + u'\u2206' # 0xC6 -> INCREMENT + u'\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + u'\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + u'\xa0' # 0xCA -> NO-BREAK SPACE + u'\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + u'\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + u'\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + u'\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + u'\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + u'\u2013' # 0xD0 -> EN DASH + u'\u2014' # 0xD1 -> EM DASH + u'\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + u'\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + u'\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + u'\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + u'\xf7' # 0xD6 -> DIVISION SIGN + u'\u25ca' # 0xD7 -> LOZENGE + u'\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + u'\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + u'\u011e' # 0xDA -> LATIN CAPITAL LETTER G WITH BREVE + u'\u011f' # 0xDB -> LATIN SMALL LETTER G WITH BREVE + u'\u0130' # 0xDC -> LATIN CAPITAL LETTER I WITH DOT ABOVE + u'\u0131' # 0xDD -> LATIN SMALL LETTER DOTLESS I + u'\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + u'\u015f' # 0xDF -> LATIN SMALL LETTER S WITH CEDILLA + u'\u2021' # 0xE0 -> DOUBLE DAGGER + u'\xb7' # 0xE1 -> MIDDLE DOT + u'\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + u'\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + u'\u2030' # 0xE4 -> PER MILLE SIGN + u'\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + u'\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + u'\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + u'\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + u'\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + u'\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + u'\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + u'\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + u'\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + u'\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + u'\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + u'\uf8ff' # 0xF0 -> Apple logo + u'\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + u'\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + u'\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + u'\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + u'\uf8a0' # 0xF5 -> undefined1 + u'\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + u'\u02dc' # 0xF7 -> SMALL TILDE + u'\xaf' # 0xF8 -> MACRON + u'\u02d8' # 0xF9 -> BREVE + u'\u02d9' # 0xFA -> DOT ABOVE + u'\u02da' # 0xFB -> RING ABOVE + u'\xb8' # 0xFC -> CEDILLA + u'\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + u'\u02db' # 0xFE -> OGONEK + u'\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/mbcs.py b/src/main/resources/PythonLibs/encodings/mbcs.py new file mode 100644 index 0000000000000000000000000000000000000000..baf46cbd4836bda6bb8ddccff7c282048383e0a2 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/mbcs.py @@ -0,0 +1,47 @@ +""" Python 'mbcs' Codec for Windows + + +Cloned by Mark Hammond (mhammond@skippinet.com.au) from ascii.py, +which was written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +# Import them explicitly to cause an ImportError +# on non-Windows systems +from codecs import mbcs_encode, mbcs_decode +# for IncrementalDecoder, IncrementalEncoder, ... +import codecs + +### Codec APIs + +encode = mbcs_encode + +def decode(input, errors='strict'): + return mbcs_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return mbcs_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = mbcs_decode + +class StreamWriter(codecs.StreamWriter): + encode = mbcs_encode + +class StreamReader(codecs.StreamReader): + decode = mbcs_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mbcs', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/palmos.py b/src/main/resources/PythonLibs/encodings/palmos.py new file mode 100644 index 0000000000000000000000000000000000000000..4b77e2ba9142ebc3f8a9f4a3dc2df89e39b5c50a --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/palmos.py @@ -0,0 +1,83 @@ +""" Python Character Mapping Codec for PalmOS 3.5. + +Written by Sjoerd Mullender (sjoerd@acm.org); based on iso8859_15.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_map) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_map)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='palmos', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) + +# The PalmOS character set is mostly iso-8859-1 with some differences. +decoding_map.update({ + 0x0080: 0x20ac, # EURO SIGN + 0x0082: 0x201a, # SINGLE LOW-9 QUOTATION MARK + 0x0083: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x0084: 0x201e, # DOUBLE LOW-9 QUOTATION MARK + 0x0085: 0x2026, # HORIZONTAL ELLIPSIS + 0x0086: 0x2020, # DAGGER + 0x0087: 0x2021, # DOUBLE DAGGER + 0x0088: 0x02c6, # MODIFIER LETTER CIRCUMFLEX ACCENT + 0x0089: 0x2030, # PER MILLE SIGN + 0x008a: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x008b: 0x2039, # SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x008c: 0x0152, # LATIN CAPITAL LIGATURE OE + 0x008d: 0x2666, # BLACK DIAMOND SUIT + 0x008e: 0x2663, # BLACK CLUB SUIT + 0x008f: 0x2665, # BLACK HEART SUIT + 0x0090: 0x2660, # BLACK SPADE SUIT + 0x0091: 0x2018, # LEFT SINGLE QUOTATION MARK + 0x0092: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x0093: 0x201c, # LEFT DOUBLE QUOTATION MARK + 0x0094: 0x201d, # RIGHT DOUBLE QUOTATION MARK + 0x0095: 0x2022, # BULLET + 0x0096: 0x2013, # EN DASH + 0x0097: 0x2014, # EM DASH + 0x0098: 0x02dc, # SMALL TILDE + 0x0099: 0x2122, # TRADE MARK SIGN + 0x009a: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x009c: 0x0153, # LATIN SMALL LIGATURE OE + 0x009f: 0x0178, # LATIN CAPITAL LETTER Y WITH DIAERESIS +}) + +### Encoding Map + +encoding_map = codecs.make_encoding_map(decoding_map) diff --git a/src/main/resources/PythonLibs/encodings/ptcp154.py b/src/main/resources/PythonLibs/encodings/ptcp154.py new file mode 100644 index 0000000000000000000000000000000000000000..aef897538f5e3542229e661f1679d39c21912c6b --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/ptcp154.py @@ -0,0 +1,175 @@ +""" Python Character Mapping Codec generated from 'PTCP154.txt' with gencodec.py. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. +(c) Copyright 2000 Guido van Rossum. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_map) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_map)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='ptcp154', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0496, # CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER + 0x0081: 0x0492, # CYRILLIC CAPITAL LETTER GHE WITH STROKE + 0x0082: 0x04ee, # CYRILLIC CAPITAL LETTER U WITH MACRON + 0x0083: 0x0493, # CYRILLIC SMALL LETTER GHE WITH STROKE + 0x0084: 0x201e, # DOUBLE LOW-9 QUOTATION MARK + 0x0085: 0x2026, # HORIZONTAL ELLIPSIS + 0x0086: 0x04b6, # CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + 0x0087: 0x04ae, # CYRILLIC CAPITAL LETTER STRAIGHT U + 0x0088: 0x04b2, # CYRILLIC CAPITAL LETTER HA WITH DESCENDER + 0x0089: 0x04af, # CYRILLIC SMALL LETTER STRAIGHT U + 0x008a: 0x04a0, # CYRILLIC CAPITAL LETTER BASHKIR KA + 0x008b: 0x04e2, # CYRILLIC CAPITAL LETTER I WITH MACRON + 0x008c: 0x04a2, # CYRILLIC CAPITAL LETTER EN WITH DESCENDER + 0x008d: 0x049a, # CYRILLIC CAPITAL LETTER KA WITH DESCENDER + 0x008e: 0x04ba, # CYRILLIC CAPITAL LETTER SHHA + 0x008f: 0x04b8, # CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE + 0x0090: 0x0497, # CYRILLIC SMALL LETTER ZHE WITH DESCENDER + 0x0091: 0x2018, # LEFT SINGLE QUOTATION MARK + 0x0092: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x0093: 0x201c, # LEFT DOUBLE QUOTATION MARK + 0x0094: 0x201d, # RIGHT DOUBLE QUOTATION MARK + 0x0095: 0x2022, # BULLET + 0x0096: 0x2013, # EN DASH + 0x0097: 0x2014, # EM DASH + 0x0098: 0x04b3, # CYRILLIC SMALL LETTER HA WITH DESCENDER + 0x0099: 0x04b7, # CYRILLIC SMALL LETTER CHE WITH DESCENDER + 0x009a: 0x04a1, # CYRILLIC SMALL LETTER BASHKIR KA + 0x009b: 0x04e3, # CYRILLIC SMALL LETTER I WITH MACRON + 0x009c: 0x04a3, # CYRILLIC SMALL LETTER EN WITH DESCENDER + 0x009d: 0x049b, # CYRILLIC SMALL LETTER KA WITH DESCENDER + 0x009e: 0x04bb, # CYRILLIC SMALL LETTER SHHA + 0x009f: 0x04b9, # CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE + 0x00a1: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U (Byelorussian) + 0x00a2: 0x045e, # CYRILLIC SMALL LETTER SHORT U (Byelorussian) + 0x00a3: 0x0408, # CYRILLIC CAPITAL LETTER JE + 0x00a4: 0x04e8, # CYRILLIC CAPITAL LETTER BARRED O + 0x00a5: 0x0498, # CYRILLIC CAPITAL LETTER ZE WITH DESCENDER + 0x00a6: 0x04b0, # CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + 0x00a8: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x00aa: 0x04d8, # CYRILLIC CAPITAL LETTER SCHWA + 0x00ad: 0x04ef, # CYRILLIC SMALL LETTER U WITH MACRON + 0x00af: 0x049c, # CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE + 0x00b1: 0x04b1, # CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + 0x00b2: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x00b3: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x00b4: 0x0499, # CYRILLIC SMALL LETTER ZE WITH DESCENDER + 0x00b5: 0x04e9, # CYRILLIC SMALL LETTER BARRED O + 0x00b8: 0x0451, # CYRILLIC SMALL LETTER IO + 0x00b9: 0x2116, # NUMERO SIGN + 0x00ba: 0x04d9, # CYRILLIC SMALL LETTER SCHWA + 0x00bc: 0x0458, # CYRILLIC SMALL LETTER JE + 0x00bd: 0x04aa, # CYRILLIC CAPITAL LETTER ES WITH DESCENDER + 0x00be: 0x04ab, # CYRILLIC SMALL LETTER ES WITH DESCENDER + 0x00bf: 0x049d, # CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE + 0x00c0: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x00c1: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x00c2: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x00c3: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x00c4: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x00c5: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x00c6: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x00c7: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x00c8: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x00c9: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x00ca: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x00cb: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x00cc: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x00cd: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x00ce: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x00cf: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x00d0: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x00d1: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x00d2: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x00d3: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x00d4: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x00d5: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x00d6: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x00d7: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x00d8: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x00d9: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x00da: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x00db: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x00dc: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x00dd: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x00de: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x00df: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00e0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00e1: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00e2: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00e3: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00e4: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00e5: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00e6: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00e7: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00e8: 0x0438, # CYRILLIC SMALL LETTER I + 0x00e9: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00ea: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00eb: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00ec: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00ed: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00ee: 0x043e, # CYRILLIC SMALL LETTER O + 0x00ef: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00f0: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00f1: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00f2: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00f3: 0x0443, # CYRILLIC SMALL LETTER U + 0x00f4: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00f5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00f6: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00f7: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00f8: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00f9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00fa: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x00fb: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00fc: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00fd: 0x044d, # CYRILLIC SMALL LETTER E + 0x00fe: 0x044e, # CYRILLIC SMALL LETTER YU + 0x00ff: 0x044f, # CYRILLIC SMALL LETTER YA +}) + +### Encoding Map + +encoding_map = codecs.make_encoding_map(decoding_map) diff --git a/src/main/resources/PythonLibs/encodings/punycode.py b/src/main/resources/PythonLibs/encodings/punycode.py new file mode 100644 index 0000000000000000000000000000000000000000..d97200fd35b11fa5a0bc68af79904e5b11751494 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/punycode.py @@ -0,0 +1,238 @@ +# -*- coding: iso-8859-1 -*- +""" Codec for the Punicode encoding, as specified in RFC 3492 + +Written by Martin v. Löwis. +""" + +import codecs + +##################### Encoding ##################################### + +def segregate(str): + """3.1 Basic code point segregation""" + base = [] + extended = {} + for c in str: + if ord(c) < 128: + base.append(c) + else: + extended[c] = 1 + extended = extended.keys() + extended.sort() + return "".join(base).encode("ascii"),extended + +def selective_len(str, max): + """Return the length of str, considering only characters below max.""" + res = 0 + for c in str: + if ord(c) < max: + res += 1 + return res + +def selective_find(str, char, index, pos): + """Return a pair (index, pos), indicating the next occurrence of + char in str. index is the position of the character considering + only ordinals up to and including char, and pos is the position in + the full string. index/pos is the starting position in the full + string.""" + + l = len(str) + while 1: + pos += 1 + if pos == l: + return (-1, -1) + c = str[pos] + if c == char: + return index+1, pos + elif c < char: + index += 1 + +def insertion_unsort(str, extended): + """3.2 Insertion unsort coding""" + oldchar = 0x80 + result = [] + oldindex = -1 + for c in extended: + index = pos = -1 + char = ord(c) + curlen = selective_len(str, char) + delta = (curlen+1) * (char - oldchar) + while 1: + index,pos = selective_find(str,c,index,pos) + if index == -1: + break + delta += index - oldindex + result.append(delta-1) + oldindex = index + delta = 0 + oldchar = char + + return result + +def T(j, bias): + # Punycode parameters: tmin = 1, tmax = 26, base = 36 + res = 36 * (j + 1) - bias + if res < 1: return 1 + if res > 26: return 26 + return res + +digits = "abcdefghijklmnopqrstuvwxyz0123456789" +def generate_generalized_integer(N, bias): + """3.3 Generalized variable-length integers""" + result = [] + j = 0 + while 1: + t = T(j, bias) + if N < t: + result.append(digits[N]) + return result + result.append(digits[t + ((N - t) % (36 - t))]) + N = (N - t) // (36 - t) + j += 1 + +def adapt(delta, first, numchars): + if first: + delta //= 700 + else: + delta //= 2 + delta += delta // numchars + # ((base - tmin) * tmax) // 2 == 455 + divisions = 0 + while delta > 455: + delta = delta // 35 # base - tmin + divisions += 36 + bias = divisions + (36 * delta // (delta + 38)) + return bias + + +def generate_integers(baselen, deltas): + """3.4 Bias adaptation""" + # Punycode parameters: initial bias = 72, damp = 700, skew = 38 + result = [] + bias = 72 + for points, delta in enumerate(deltas): + s = generate_generalized_integer(delta, bias) + result.extend(s) + bias = adapt(delta, points==0, baselen+points+1) + return "".join(result) + +def punycode_encode(text): + base, extended = segregate(text) + base = base.encode("ascii") + deltas = insertion_unsort(text, extended) + extended = generate_integers(len(base), deltas) + if base: + return base + "-" + extended + return extended + +##################### Decoding ##################################### + +def decode_generalized_number(extended, extpos, bias, errors): + """3.3 Generalized variable-length integers""" + result = 0 + w = 1 + j = 0 + while 1: + try: + char = ord(extended[extpos]) + except IndexError: + if errors == "strict": + raise UnicodeError, "incomplete punicode string" + return extpos + 1, None + extpos += 1 + if 0x41 <= char <= 0x5A: # A-Z + digit = char - 0x41 + elif 0x30 <= char <= 0x39: + digit = char - 22 # 0x30-26 + elif errors == "strict": + raise UnicodeError("Invalid extended code point '%s'" + % extended[extpos]) + else: + return extpos, None + t = T(j, bias) + result += digit * w + if digit < t: + return extpos, result + w = w * (36 - t) + j += 1 + + +def insertion_sort(base, extended, errors): + """3.2 Insertion unsort coding""" + char = 0x80 + pos = -1 + bias = 72 + extpos = 0 + while extpos < len(extended): + newpos, delta = decode_generalized_number(extended, extpos, + bias, errors) + if delta is None: + # There was an error in decoding. We can't continue because + # synchronization is lost. + return base + pos += delta+1 + char += pos // (len(base) + 1) + if char > 0x10FFFF: + if errors == "strict": + raise UnicodeError, ("Invalid character U+%x" % char) + char = ord('?') + pos = pos % (len(base) + 1) + base = base[:pos] + unichr(char) + base[pos:] + bias = adapt(delta, (extpos == 0), len(base)) + extpos = newpos + return base + +def punycode_decode(text, errors): + pos = text.rfind("-") + if pos == -1: + base = "" + extended = text + else: + base = text[:pos] + extended = text[pos+1:] + base = unicode(base, "ascii", errors) + extended = extended.upper() + return insertion_sort(base, extended, errors) + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + res = punycode_encode(input) + return res, len(input) + + def decode(self,input,errors='strict'): + if errors not in ('strict', 'replace', 'ignore'): + raise UnicodeError, "Unsupported error handling "+errors + res = punycode_decode(input, errors) + return res, len(input) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return punycode_encode(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + if self.errors not in ('strict', 'replace', 'ignore'): + raise UnicodeError, "Unsupported error handling "+self.errors + return punycode_decode(input, self.errors) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='punycode', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/quopri_codec.py b/src/main/resources/PythonLibs/encodings/quopri_codec.py new file mode 100644 index 0000000000000000000000000000000000000000..d8683fd56d325415a25116c129ab41ae45126016 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/quopri_codec.py @@ -0,0 +1,75 @@ +"""Codec for quoted-printable encoding. + +Like base64 and rot13, this returns Python strings, not Unicode. +""" + +import codecs, quopri +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +def quopri_encode(input, errors='strict'): + """Encode the input, returning a tuple (output object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + # using str() because of cStringIO's Unicode undesired Unicode behavior. + f = StringIO(str(input)) + g = StringIO() + quopri.encode(f, g, 1) + output = g.getvalue() + return (output, len(input)) + +def quopri_decode(input, errors='strict'): + """Decode the input, returning a tuple (output object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + f = StringIO(str(input)) + g = StringIO() + quopri.decode(f, g) + output = g.getvalue() + return (output, len(input)) + +class Codec(codecs.Codec): + + def encode(self, input,errors='strict'): + return quopri_encode(input,errors) + def decode(self, input,errors='strict'): + return quopri_decode(input,errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return quopri_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return quopri_decode(input, self.errors)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +# encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='quopri', + encode=quopri_encode, + decode=quopri_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/raw_unicode_escape.py b/src/main/resources/PythonLibs/encodings/raw_unicode_escape.py new file mode 100644 index 0000000000000000000000000000000000000000..2b919b40d3788a7bd7dab3a983af091deb48a235 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/raw_unicode_escape.py @@ -0,0 +1,45 @@ +""" Python 'raw-unicode-escape' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.raw_unicode_escape_encode + decode = codecs.raw_unicode_escape_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.raw_unicode_escape_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.raw_unicode_escape_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='raw-unicode-escape', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/rot_13.py b/src/main/resources/PythonLibs/encodings/rot_13.py new file mode 100644 index 0000000000000000000000000000000000000000..52b6431cf30d5edcc7454352cce4a8f7fe2581fe --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/rot_13.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +""" Python Character Mapping Codec for ROT13. + + See http://ucsub.colorado.edu/~kominek/rot13/ for details. + + Written by Marc-Andre Lemburg (mal@lemburg.com). + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_map) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_map)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='rot-13', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0041: 0x004e, + 0x0042: 0x004f, + 0x0043: 0x0050, + 0x0044: 0x0051, + 0x0045: 0x0052, + 0x0046: 0x0053, + 0x0047: 0x0054, + 0x0048: 0x0055, + 0x0049: 0x0056, + 0x004a: 0x0057, + 0x004b: 0x0058, + 0x004c: 0x0059, + 0x004d: 0x005a, + 0x004e: 0x0041, + 0x004f: 0x0042, + 0x0050: 0x0043, + 0x0051: 0x0044, + 0x0052: 0x0045, + 0x0053: 0x0046, + 0x0054: 0x0047, + 0x0055: 0x0048, + 0x0056: 0x0049, + 0x0057: 0x004a, + 0x0058: 0x004b, + 0x0059: 0x004c, + 0x005a: 0x004d, + 0x0061: 0x006e, + 0x0062: 0x006f, + 0x0063: 0x0070, + 0x0064: 0x0071, + 0x0065: 0x0072, + 0x0066: 0x0073, + 0x0067: 0x0074, + 0x0068: 0x0075, + 0x0069: 0x0076, + 0x006a: 0x0077, + 0x006b: 0x0078, + 0x006c: 0x0079, + 0x006d: 0x007a, + 0x006e: 0x0061, + 0x006f: 0x0062, + 0x0070: 0x0063, + 0x0071: 0x0064, + 0x0072: 0x0065, + 0x0073: 0x0066, + 0x0074: 0x0067, + 0x0075: 0x0068, + 0x0076: 0x0069, + 0x0077: 0x006a, + 0x0078: 0x006b, + 0x0079: 0x006c, + 0x007a: 0x006d, +}) + +### Encoding Map + +encoding_map = codecs.make_encoding_map(decoding_map) + +### Filter API + +def rot13(infile, outfile): + outfile.write(infile.read().encode('rot-13')) + +if __name__ == '__main__': + import sys + rot13(sys.stdin, sys.stdout) diff --git a/src/main/resources/PythonLibs/encodings/shift_jis.py b/src/main/resources/PythonLibs/encodings/shift_jis.py new file mode 100644 index 0000000000000000000000000000000000000000..83381172764dea0f76874716cda28852a5906f7f --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/shift_jis.py @@ -0,0 +1,39 @@ +# +# shift_jis.py: Python Unicode Codec for SHIFT_JIS +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('shift_jis') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='shift_jis', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/shift_jis_2004.py b/src/main/resources/PythonLibs/encodings/shift_jis_2004.py new file mode 100644 index 0000000000000000000000000000000000000000..161b1e86f9918a4df5c3290505a98d5de4566e0e --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/shift_jis_2004.py @@ -0,0 +1,39 @@ +# +# shift_jis_2004.py: Python Unicode Codec for SHIFT_JIS_2004 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('shift_jis_2004') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='shift_jis_2004', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/shift_jisx0213.py b/src/main/resources/PythonLibs/encodings/shift_jisx0213.py new file mode 100644 index 0000000000000000000000000000000000000000..cb653f53055e679c513218b0102ffa9d1b4ca82c --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/shift_jisx0213.py @@ -0,0 +1,39 @@ +# +# shift_jisx0213.py: Python Unicode Codec for SHIFT_JISX0213 +# +# Written by Hye-Shik Chang <perky@FreeBSD.org> +# + +import _codecs_jp, codecs +import _multibytecodec as mbc + +codec = _codecs_jp.getcodec('shift_jisx0213') + +class Codec(codecs.Codec): + encode = codec.encode + decode = codec.decode + +class IncrementalEncoder(mbc.MultibyteIncrementalEncoder, + codecs.IncrementalEncoder): + codec = codec + +class IncrementalDecoder(mbc.MultibyteIncrementalDecoder, + codecs.IncrementalDecoder): + codec = codec + +class StreamReader(Codec, mbc.MultibyteStreamReader, codecs.StreamReader): + codec = codec + +class StreamWriter(Codec, mbc.MultibyteStreamWriter, codecs.StreamWriter): + codec = codec + +def getregentry(): + return codecs.CodecInfo( + name='shift_jisx0213', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/string_escape.py b/src/main/resources/PythonLibs/encodings/string_escape.py new file mode 100644 index 0000000000000000000000000000000000000000..e329a2607de4d59fa014de61b5949db862e3112c --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/string_escape.py @@ -0,0 +1,38 @@ +# -*- coding: iso-8859-1 -*- +""" Python 'escape' Codec + + +Written by Martin v. Löwis (martin@v.loewis.de). + +""" +import codecs + +class Codec(codecs.Codec): + + encode = codecs.escape_encode + decode = codecs.escape_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.escape_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.escape_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +def getregentry(): + return codecs.CodecInfo( + name='string-escape', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/tis_620.py b/src/main/resources/PythonLibs/encodings/tis_620.py new file mode 100644 index 0000000000000000000000000000000000000000..b2cd22b23dcb0cf1e0c7ef6494246f05f6e7956d --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/tis_620.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec tis_620 generated from 'python-mappings/TIS-620.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='tis-620', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + u'\x00' # 0x00 -> NULL + u'\x01' # 0x01 -> START OF HEADING + u'\x02' # 0x02 -> START OF TEXT + u'\x03' # 0x03 -> END OF TEXT + u'\x04' # 0x04 -> END OF TRANSMISSION + u'\x05' # 0x05 -> ENQUIRY + u'\x06' # 0x06 -> ACKNOWLEDGE + u'\x07' # 0x07 -> BELL + u'\x08' # 0x08 -> BACKSPACE + u'\t' # 0x09 -> HORIZONTAL TABULATION + u'\n' # 0x0A -> LINE FEED + u'\x0b' # 0x0B -> VERTICAL TABULATION + u'\x0c' # 0x0C -> FORM FEED + u'\r' # 0x0D -> CARRIAGE RETURN + u'\x0e' # 0x0E -> SHIFT OUT + u'\x0f' # 0x0F -> SHIFT IN + u'\x10' # 0x10 -> DATA LINK ESCAPE + u'\x11' # 0x11 -> DEVICE CONTROL ONE + u'\x12' # 0x12 -> DEVICE CONTROL TWO + u'\x13' # 0x13 -> DEVICE CONTROL THREE + u'\x14' # 0x14 -> DEVICE CONTROL FOUR + u'\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + u'\x16' # 0x16 -> SYNCHRONOUS IDLE + u'\x17' # 0x17 -> END OF TRANSMISSION BLOCK + u'\x18' # 0x18 -> CANCEL + u'\x19' # 0x19 -> END OF MEDIUM + u'\x1a' # 0x1A -> SUBSTITUTE + u'\x1b' # 0x1B -> ESCAPE + u'\x1c' # 0x1C -> FILE SEPARATOR + u'\x1d' # 0x1D -> GROUP SEPARATOR + u'\x1e' # 0x1E -> RECORD SEPARATOR + u'\x1f' # 0x1F -> UNIT SEPARATOR + u' ' # 0x20 -> SPACE + u'!' # 0x21 -> EXCLAMATION MARK + u'"' # 0x22 -> QUOTATION MARK + u'#' # 0x23 -> NUMBER SIGN + u'$' # 0x24 -> DOLLAR SIGN + u'%' # 0x25 -> PERCENT SIGN + u'&' # 0x26 -> AMPERSAND + u"'" # 0x27 -> APOSTROPHE + u'(' # 0x28 -> LEFT PARENTHESIS + u')' # 0x29 -> RIGHT PARENTHESIS + u'*' # 0x2A -> ASTERISK + u'+' # 0x2B -> PLUS SIGN + u',' # 0x2C -> COMMA + u'-' # 0x2D -> HYPHEN-MINUS + u'.' # 0x2E -> FULL STOP + u'/' # 0x2F -> SOLIDUS + u'0' # 0x30 -> DIGIT ZERO + u'1' # 0x31 -> DIGIT ONE + u'2' # 0x32 -> DIGIT TWO + u'3' # 0x33 -> DIGIT THREE + u'4' # 0x34 -> DIGIT FOUR + u'5' # 0x35 -> DIGIT FIVE + u'6' # 0x36 -> DIGIT SIX + u'7' # 0x37 -> DIGIT SEVEN + u'8' # 0x38 -> DIGIT EIGHT + u'9' # 0x39 -> DIGIT NINE + u':' # 0x3A -> COLON + u';' # 0x3B -> SEMICOLON + u'<' # 0x3C -> LESS-THAN SIGN + u'=' # 0x3D -> EQUALS SIGN + u'>' # 0x3E -> GREATER-THAN SIGN + u'?' # 0x3F -> QUESTION MARK + u'@' # 0x40 -> COMMERCIAL AT + u'A' # 0x41 -> LATIN CAPITAL LETTER A + u'B' # 0x42 -> LATIN CAPITAL LETTER B + u'C' # 0x43 -> LATIN CAPITAL LETTER C + u'D' # 0x44 -> LATIN CAPITAL LETTER D + u'E' # 0x45 -> LATIN CAPITAL LETTER E + u'F' # 0x46 -> LATIN CAPITAL LETTER F + u'G' # 0x47 -> LATIN CAPITAL LETTER G + u'H' # 0x48 -> LATIN CAPITAL LETTER H + u'I' # 0x49 -> LATIN CAPITAL LETTER I + u'J' # 0x4A -> LATIN CAPITAL LETTER J + u'K' # 0x4B -> LATIN CAPITAL LETTER K + u'L' # 0x4C -> LATIN CAPITAL LETTER L + u'M' # 0x4D -> LATIN CAPITAL LETTER M + u'N' # 0x4E -> LATIN CAPITAL LETTER N + u'O' # 0x4F -> LATIN CAPITAL LETTER O + u'P' # 0x50 -> LATIN CAPITAL LETTER P + u'Q' # 0x51 -> LATIN CAPITAL LETTER Q + u'R' # 0x52 -> LATIN CAPITAL LETTER R + u'S' # 0x53 -> LATIN CAPITAL LETTER S + u'T' # 0x54 -> LATIN CAPITAL LETTER T + u'U' # 0x55 -> LATIN CAPITAL LETTER U + u'V' # 0x56 -> LATIN CAPITAL LETTER V + u'W' # 0x57 -> LATIN CAPITAL LETTER W + u'X' # 0x58 -> LATIN CAPITAL LETTER X + u'Y' # 0x59 -> LATIN CAPITAL LETTER Y + u'Z' # 0x5A -> LATIN CAPITAL LETTER Z + u'[' # 0x5B -> LEFT SQUARE BRACKET + u'\\' # 0x5C -> REVERSE SOLIDUS + u']' # 0x5D -> RIGHT SQUARE BRACKET + u'^' # 0x5E -> CIRCUMFLEX ACCENT + u'_' # 0x5F -> LOW LINE + u'`' # 0x60 -> GRAVE ACCENT + u'a' # 0x61 -> LATIN SMALL LETTER A + u'b' # 0x62 -> LATIN SMALL LETTER B + u'c' # 0x63 -> LATIN SMALL LETTER C + u'd' # 0x64 -> LATIN SMALL LETTER D + u'e' # 0x65 -> LATIN SMALL LETTER E + u'f' # 0x66 -> LATIN SMALL LETTER F + u'g' # 0x67 -> LATIN SMALL LETTER G + u'h' # 0x68 -> LATIN SMALL LETTER H + u'i' # 0x69 -> LATIN SMALL LETTER I + u'j' # 0x6A -> LATIN SMALL LETTER J + u'k' # 0x6B -> LATIN SMALL LETTER K + u'l' # 0x6C -> LATIN SMALL LETTER L + u'm' # 0x6D -> LATIN SMALL LETTER M + u'n' # 0x6E -> LATIN SMALL LETTER N + u'o' # 0x6F -> LATIN SMALL LETTER O + u'p' # 0x70 -> LATIN SMALL LETTER P + u'q' # 0x71 -> LATIN SMALL LETTER Q + u'r' # 0x72 -> LATIN SMALL LETTER R + u's' # 0x73 -> LATIN SMALL LETTER S + u't' # 0x74 -> LATIN SMALL LETTER T + u'u' # 0x75 -> LATIN SMALL LETTER U + u'v' # 0x76 -> LATIN SMALL LETTER V + u'w' # 0x77 -> LATIN SMALL LETTER W + u'x' # 0x78 -> LATIN SMALL LETTER X + u'y' # 0x79 -> LATIN SMALL LETTER Y + u'z' # 0x7A -> LATIN SMALL LETTER Z + u'{' # 0x7B -> LEFT CURLY BRACKET + u'|' # 0x7C -> VERTICAL LINE + u'}' # 0x7D -> RIGHT CURLY BRACKET + u'~' # 0x7E -> TILDE + u'\x7f' # 0x7F -> DELETE + u'\x80' # 0x80 -> <control> + u'\x81' # 0x81 -> <control> + u'\x82' # 0x82 -> <control> + u'\x83' # 0x83 -> <control> + u'\x84' # 0x84 -> <control> + u'\x85' # 0x85 -> <control> + u'\x86' # 0x86 -> <control> + u'\x87' # 0x87 -> <control> + u'\x88' # 0x88 -> <control> + u'\x89' # 0x89 -> <control> + u'\x8a' # 0x8A -> <control> + u'\x8b' # 0x8B -> <control> + u'\x8c' # 0x8C -> <control> + u'\x8d' # 0x8D -> <control> + u'\x8e' # 0x8E -> <control> + u'\x8f' # 0x8F -> <control> + u'\x90' # 0x90 -> <control> + u'\x91' # 0x91 -> <control> + u'\x92' # 0x92 -> <control> + u'\x93' # 0x93 -> <control> + u'\x94' # 0x94 -> <control> + u'\x95' # 0x95 -> <control> + u'\x96' # 0x96 -> <control> + u'\x97' # 0x97 -> <control> + u'\x98' # 0x98 -> <control> + u'\x99' # 0x99 -> <control> + u'\x9a' # 0x9A -> <control> + u'\x9b' # 0x9B -> <control> + u'\x9c' # 0x9C -> <control> + u'\x9d' # 0x9D -> <control> + u'\x9e' # 0x9E -> <control> + u'\x9f' # 0x9F -> <control> + u'\ufffe' + u'\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + u'\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + u'\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + u'\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + u'\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + u'\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + u'\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + u'\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + u'\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + u'\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + u'\u0e0b' # 0xAB -> THAI CHARACTER SO SO + u'\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + u'\u0e0d' # 0xAD -> THAI CHARACTER YO YING + u'\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + u'\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + u'\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + u'\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + u'\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + u'\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + u'\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + u'\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + u'\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + u'\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + u'\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + u'\u0e19' # 0xB9 -> THAI CHARACTER NO NU + u'\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + u'\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + u'\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + u'\u0e1d' # 0xBD -> THAI CHARACTER FO FA + u'\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + u'\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + u'\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + u'\u0e21' # 0xC1 -> THAI CHARACTER MO MA + u'\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + u'\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + u'\u0e24' # 0xC4 -> THAI CHARACTER RU + u'\u0e25' # 0xC5 -> THAI CHARACTER LO LING + u'\u0e26' # 0xC6 -> THAI CHARACTER LU + u'\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + u'\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + u'\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + u'\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + u'\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + u'\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + u'\u0e2d' # 0xCD -> THAI CHARACTER O ANG + u'\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + u'\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + u'\u0e30' # 0xD0 -> THAI CHARACTER SARA A + u'\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + u'\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + u'\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + u'\u0e34' # 0xD4 -> THAI CHARACTER SARA I + u'\u0e35' # 0xD5 -> THAI CHARACTER SARA II + u'\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + u'\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + u'\u0e38' # 0xD8 -> THAI CHARACTER SARA U + u'\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + u'\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + u'\u0e40' # 0xE0 -> THAI CHARACTER SARA E + u'\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + u'\u0e42' # 0xE2 -> THAI CHARACTER SARA O + u'\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + u'\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + u'\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + u'\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + u'\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + u'\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + u'\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + u'\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + u'\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + u'\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + u'\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + u'\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + u'\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + u'\u0e50' # 0xF0 -> THAI DIGIT ZERO + u'\u0e51' # 0xF1 -> THAI DIGIT ONE + u'\u0e52' # 0xF2 -> THAI DIGIT TWO + u'\u0e53' # 0xF3 -> THAI DIGIT THREE + u'\u0e54' # 0xF4 -> THAI DIGIT FOUR + u'\u0e55' # 0xF5 -> THAI DIGIT FIVE + u'\u0e56' # 0xF6 -> THAI DIGIT SIX + u'\u0e57' # 0xF7 -> THAI DIGIT SEVEN + u'\u0e58' # 0xF8 -> THAI DIGIT EIGHT + u'\u0e59' # 0xF9 -> THAI DIGIT NINE + u'\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + u'\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + u'\ufffe' + u'\ufffe' + u'\ufffe' + u'\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/src/main/resources/PythonLibs/encodings/undefined.py b/src/main/resources/PythonLibs/encodings/undefined.py new file mode 100644 index 0000000000000000000000000000000000000000..4690288355c710bc227c0990fb37f36e23186ea1 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/undefined.py @@ -0,0 +1,49 @@ +""" Python 'undefined' Codec + + This codec will always raise a ValueError exception when being + used. It is intended for use by the site.py file to switch off + automatic string to Unicode coercion. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + raise UnicodeError("undefined encoding") + + def decode(self,input,errors='strict'): + raise UnicodeError("undefined encoding") + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + raise UnicodeError("undefined encoding") + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + raise UnicodeError("undefined encoding") + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='undefined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/unicode_escape.py b/src/main/resources/PythonLibs/encodings/unicode_escape.py new file mode 100644 index 0000000000000000000000000000000000000000..817f93265a4634c9907b591b645a09cda73dcbf2 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/unicode_escape.py @@ -0,0 +1,45 @@ +""" Python 'unicode-escape' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.unicode_escape_encode + decode = codecs.unicode_escape_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.unicode_escape_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.unicode_escape_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='unicode-escape', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/unicode_internal.py b/src/main/resources/PythonLibs/encodings/unicode_internal.py new file mode 100644 index 0000000000000000000000000000000000000000..df3e7752d20a8e15c985742f11265b0ec7b3277b --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/unicode_internal.py @@ -0,0 +1,45 @@ +""" Python 'unicode-internal' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.unicode_internal_encode + decode = codecs.unicode_internal_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.unicode_internal_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.unicode_internal_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='unicode-internal', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_16.py b/src/main/resources/PythonLibs/encodings/utf_16.py new file mode 100644 index 0000000000000000000000000000000000000000..f3fadff6153bb96f8afeceef0952c7b9b7958805 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_16.py @@ -0,0 +1,126 @@ +""" Python 'utf-16' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs, sys + +### Codec APIs + +encode = codecs.utf_16_encode + +def decode(input, errors='strict'): + return codecs.utf_16_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + codecs.IncrementalEncoder.__init__(self, errors) + self.encoder = None + + def encode(self, input, final=False): + if self.encoder is None: + result = codecs.utf_16_encode(input, self.errors)[0] + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_le_encode + else: + self.encoder = codecs.utf_16_be_encode + return result + return self.encoder(input, self.errors)[0] + + def reset(self): + codecs.IncrementalEncoder.reset(self) + self.encoder = None + + def getstate(self): + # state info we return to the caller: + # 0: stream is in natural order for this platform + # 2: endianness hasn't been determined yet + # (we're never writing in unnatural order) + return (2 if self.encoder is None else 0) + + def setstate(self, state): + if state: + self.encoder = None + else: + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_le_encode + else: + self.encoder = codecs.utf_16_be_encode + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def __init__(self, errors='strict'): + codecs.BufferedIncrementalDecoder.__init__(self, errors) + self.decoder = None + + def _buffer_decode(self, input, errors, final): + if self.decoder is None: + (output, consumed, byteorder) = \ + codecs.utf_16_ex_decode(input, errors, 0, final) + if byteorder == -1: + self.decoder = codecs.utf_16_le_decode + elif byteorder == 1: + self.decoder = codecs.utf_16_be_decode + elif consumed >= 2: + raise UnicodeError("UTF-16 stream does not start with BOM") + return (output, consumed) + return self.decoder(input, self.errors, final) + + def reset(self): + codecs.BufferedIncrementalDecoder.reset(self) + self.decoder = None + +class StreamWriter(codecs.StreamWriter): + def __init__(self, stream, errors='strict'): + codecs.StreamWriter.__init__(self, stream, errors) + self.encoder = None + + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None + + def encode(self, input, errors='strict'): + if self.encoder is None: + result = codecs.utf_16_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_16_le_encode + else: + self.encoder = codecs.utf_16_be_encode + return result + else: + return self.encoder(input, errors) + +class StreamReader(codecs.StreamReader): + + def reset(self): + codecs.StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + (object, consumed, byteorder) = \ + codecs.utf_16_ex_decode(input, errors, 0, False) + if byteorder == -1: + self.decode = codecs.utf_16_le_decode + elif byteorder == 1: + self.decode = codecs.utf_16_be_decode + elif consumed>=2: + raise UnicodeError,"UTF-16 stream does not start with BOM" + return (object, consumed) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-16', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_16_be.py b/src/main/resources/PythonLibs/encodings/utf_16_be.py new file mode 100644 index 0000000000000000000000000000000000000000..86b458eb9bcd96b50f128df1978a14f5d1e41835 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_16_be.py @@ -0,0 +1,42 @@ +""" Python 'utf-16-be' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +encode = codecs.utf_16_be_encode + +def decode(input, errors='strict'): + return codecs.utf_16_be_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_16_be_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_16_be_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_16_be_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_16_be_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-16-be', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_16_le.py b/src/main/resources/PythonLibs/encodings/utf_16_le.py new file mode 100644 index 0000000000000000000000000000000000000000..ec454142eedf251e31eab481a1cbea6424273a0a --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_16_le.py @@ -0,0 +1,42 @@ +""" Python 'utf-16-le' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +encode = codecs.utf_16_le_encode + +def decode(input, errors='strict'): + return codecs.utf_16_le_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_16_le_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_16_le_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_16_le_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_16_le_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-16-le', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_32.py b/src/main/resources/PythonLibs/encodings/utf_32.py new file mode 100644 index 0000000000000000000000000000000000000000..6c8016fe1b3fd066db5e51ad9ad5d97042016fd6 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_32.py @@ -0,0 +1,150 @@ +""" +Python 'utf-32' Codec +""" +import codecs, sys + +### Codec APIs + +encode = codecs.utf_32_encode + +def decode(input, errors='strict'): + return codecs.utf_32_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + codecs.IncrementalEncoder.__init__(self, errors) + self.encoder = None + + def encode(self, input, final=False): + if self.encoder is None: + result = codecs.utf_32_encode(input, self.errors)[0] + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_le_encode + else: + self.encoder = codecs.utf_32_be_encode + return result + return self.encoder(input, self.errors)[0] + + def reset(self): + codecs.IncrementalEncoder.reset(self) + self.encoder = None + + def getstate(self): + # state info we return to the caller: + # 0: stream is in natural order for this platform + # 2: endianness hasn't been determined yet + # (we're never writing in unnatural order) + return (2 if self.encoder is None else 0) + + def setstate(self, state): + if state: + self.encoder = None + else: + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_le_encode + else: + self.encoder = codecs.utf_32_be_encode + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def __init__(self, errors='strict'): + codecs.BufferedIncrementalDecoder.__init__(self, errors) + self.decoder = None + + def _buffer_decode(self, input, errors, final): + if self.decoder is None: + (output, consumed, byteorder) = \ + codecs.utf_32_ex_decode(input, errors, 0, final) + if byteorder == -1: + self.decoder = codecs.utf_32_le_decode + elif byteorder == 1: + self.decoder = codecs.utf_32_be_decode + elif consumed >= 4: + raise UnicodeError("UTF-32 stream does not start with BOM") + return (output, consumed) + return self.decoder(input, self.errors, final) + + def reset(self): + codecs.BufferedIncrementalDecoder.reset(self) + self.decoder = None + + def getstate(self): + # additonal state info from the base class must be None here, + # as it isn't passed along to the caller + state = codecs.BufferedIncrementalDecoder.getstate(self)[0] + # additional state info we pass to the caller: + # 0: stream is in natural order for this platform + # 1: stream is in unnatural order + # 2: endianness hasn't been determined yet + if self.decoder is None: + return (state, 2) + addstate = int((sys.byteorder == "big") != + (self.decoder is codecs.utf_32_be_decode)) + return (state, addstate) + + def setstate(self, state): + # state[1] will be ignored by BufferedIncrementalDecoder.setstate() + codecs.BufferedIncrementalDecoder.setstate(self, state) + state = state[1] + if state == 0: + self.decoder = (codecs.utf_32_be_decode + if sys.byteorder == "big" + else codecs.utf_32_le_decode) + elif state == 1: + self.decoder = (codecs.utf_32_le_decode + if sys.byteorder == "big" + else codecs.utf_32_be_decode) + else: + self.decoder = None + +class StreamWriter(codecs.StreamWriter): + def __init__(self, stream, errors='strict'): + self.encoder = None + codecs.StreamWriter.__init__(self, stream, errors) + + def reset(self): + codecs.StreamWriter.reset(self) + self.encoder = None + + def encode(self, input, errors='strict'): + if self.encoder is None: + result = codecs.utf_32_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = codecs.utf_32_le_encode + else: + self.encoder = codecs.utf_32_be_encode + return result + else: + return self.encoder(input, errors) + +class StreamReader(codecs.StreamReader): + + def reset(self): + codecs.StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + (object, consumed, byteorder) = \ + codecs.utf_32_ex_decode(input, errors, 0, False) + if byteorder == -1: + self.decode = codecs.utf_32_le_decode + elif byteorder == 1: + self.decode = codecs.utf_32_be_decode + elif consumed>=4: + raise UnicodeError,"UTF-32 stream does not start with BOM" + return (object, consumed) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-32', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_32_be.py b/src/main/resources/PythonLibs/encodings/utf_32_be.py new file mode 100644 index 0000000000000000000000000000000000000000..fe272b5fafec69e506c7cb398712d7b6dd9e6145 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_32_be.py @@ -0,0 +1,37 @@ +""" +Python 'utf-32-be' Codec +""" +import codecs + +### Codec APIs + +encode = codecs.utf_32_be_encode + +def decode(input, errors='strict'): + return codecs.utf_32_be_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_32_be_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_32_be_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_32_be_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_32_be_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-32-be', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_32_le.py b/src/main/resources/PythonLibs/encodings/utf_32_le.py new file mode 100644 index 0000000000000000000000000000000000000000..9e48210928ee652b17fe797785a20267b1d12a6e --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_32_le.py @@ -0,0 +1,37 @@ +""" +Python 'utf-32-le' Codec +""" +import codecs + +### Codec APIs + +encode = codecs.utf_32_le_encode + +def decode(input, errors='strict'): + return codecs.utf_32_le_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_32_le_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_32_le_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_32_le_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_32_le_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-32-le', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_7.py b/src/main/resources/PythonLibs/encodings/utf_7.py new file mode 100644 index 0000000000000000000000000000000000000000..8e0567f2087d65e33b3152b8240bcaf703d855fb --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_7.py @@ -0,0 +1,38 @@ +""" Python 'utf-7' Codec + +Written by Brian Quinlan (brian@sweetapp.com). +""" +import codecs + +### Codec APIs + +encode = codecs.utf_7_encode + +def decode(input, errors='strict'): + return codecs.utf_7_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_7_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_7_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_7_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_7_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-7', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_8.py b/src/main/resources/PythonLibs/encodings/utf_8.py new file mode 100644 index 0000000000000000000000000000000000000000..1bf6336571547bcec3f5aa7978ff1c7f247490ce --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_8.py @@ -0,0 +1,42 @@ +""" Python 'utf-8' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +encode = codecs.utf_8_encode + +def decode(input, errors='strict'): + return codecs.utf_8_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_8_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_8_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_8_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_8_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-8', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/utf_8_sig.py b/src/main/resources/PythonLibs/encodings/utf_8_sig.py new file mode 100644 index 0000000000000000000000000000000000000000..8784694f02663451bd9196c03039ea8f4a7738e4 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/utf_8_sig.py @@ -0,0 +1,117 @@ +""" Python 'utf-8-sig' Codec +This work similar to UTF-8 with the following changes: + +* On encoding/writing a UTF-8 encoded BOM will be prepended/written as the + first three bytes. + +* On decoding/reading if the first three bytes are a UTF-8 encoded BOM, these + bytes will be skipped. +""" +import codecs + +### Codec APIs + +def encode(input, errors='strict'): + return (codecs.BOM_UTF8 + codecs.utf_8_encode(input, errors)[0], len(input)) + +def decode(input, errors='strict'): + prefix = 0 + if input[:3] == codecs.BOM_UTF8: + input = input[3:] + prefix = 3 + (output, consumed) = codecs.utf_8_decode(input, errors, True) + return (output, consumed+prefix) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + codecs.IncrementalEncoder.__init__(self, errors) + self.first = 1 + + def encode(self, input, final=False): + if self.first: + self.first = 0 + return codecs.BOM_UTF8 + codecs.utf_8_encode(input, self.errors)[0] + else: + return codecs.utf_8_encode(input, self.errors)[0] + + def reset(self): + codecs.IncrementalEncoder.reset(self) + self.first = 1 + + def getstate(self): + return self.first + + def setstate(self, state): + self.first = state + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def __init__(self, errors='strict'): + codecs.BufferedIncrementalDecoder.__init__(self, errors) + self.first = True + + def _buffer_decode(self, input, errors, final): + if self.first: + if len(input) < 3: + if codecs.BOM_UTF8.startswith(input): + # not enough data to decide if this really is a BOM + # => try again on the next call + return (u"", 0) + else: + self.first = None + else: + self.first = None + if input[:3] == codecs.BOM_UTF8: + (output, consumed) = codecs.utf_8_decode(input[3:], errors, final) + return (output, consumed+3) + return codecs.utf_8_decode(input, errors, final) + + def reset(self): + codecs.BufferedIncrementalDecoder.reset(self) + self.first = True + +class StreamWriter(codecs.StreamWriter): + def reset(self): + codecs.StreamWriter.reset(self) + try: + del self.encode + except AttributeError: + pass + + def encode(self, input, errors='strict'): + self.encode = codecs.utf_8_encode + return encode(input, errors) + +class StreamReader(codecs.StreamReader): + def reset(self): + codecs.StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + if len(input) < 3: + if codecs.BOM_UTF8.startswith(input): + # not enough data to decide if this is a BOM + # => try again on the next call + return (u"", 0) + elif input[:3] == codecs.BOM_UTF8: + self.decode = codecs.utf_8_decode + (output, consumed) = codecs.utf_8_decode(input[3:],errors) + return (output, consumed+3) + # (else) no BOM present + self.decode = codecs.utf_8_decode + return codecs.utf_8_decode(input, errors) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-8-sig', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/uu_codec.py b/src/main/resources/PythonLibs/encodings/uu_codec.py new file mode 100644 index 0000000000000000000000000000000000000000..fb03758171d1218ad023f7a092584baa28111883 --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/uu_codec.py @@ -0,0 +1,129 @@ +""" Python 'uu_codec' Codec - UU content transfer encoding + + Unlike most of the other codecs which target Unicode, this codec + will return Python string objects for both encode and decode. + + Written by Marc-Andre Lemburg (mal@lemburg.com). Some details were + adapted from uu.py which was written by Lance Ellinghouse and + modified by Jack Jansen and Fredrik Lundh. + +""" +import codecs, binascii + +### Codec APIs + +def uu_encode(input,errors='strict',filename='<data>',mode=0666): + + """ Encodes the object input and returns a tuple (output + object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + from cStringIO import StringIO + from binascii import b2a_uu + # using str() because of cStringIO's Unicode undesired Unicode behavior. + infile = StringIO(str(input)) + outfile = StringIO() + read = infile.read + write = outfile.write + + # Encode + write('begin %o %s\n' % (mode & 0777, filename)) + chunk = read(45) + while chunk: + write(b2a_uu(chunk)) + chunk = read(45) + write(' \nend\n') + + return (outfile.getvalue(), len(input)) + +def uu_decode(input,errors='strict'): + + """ Decodes the object input and returns a tuple (output + object, length consumed). + + input must be an object which provides the bf_getreadbuf + buffer slot. Python strings, buffer objects and memory + mapped files are examples of objects providing this slot. + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + Note: filename and file mode information in the input data is + ignored. + + """ + assert errors == 'strict' + from cStringIO import StringIO + from binascii import a2b_uu + infile = StringIO(str(input)) + outfile = StringIO() + readline = infile.readline + write = outfile.write + + # Find start of encoded data + while 1: + s = readline() + if not s: + raise ValueError, 'Missing "begin" line in input data' + if s[:5] == 'begin': + break + + # Decode + while 1: + s = readline() + if not s or \ + s == 'end\n': + break + try: + data = a2b_uu(s) + except binascii.Error, v: + # Workaround for broken uuencoders by /Fredrik Lundh + nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3 + data = a2b_uu(s[:nbytes]) + #sys.stderr.write("Warning: %s\n" % str(v)) + write(data) + if not s: + raise ValueError, 'Truncated input data' + + return (outfile.getvalue(), len(input)) + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return uu_encode(input,errors) + + def decode(self,input,errors='strict'): + return uu_decode(input,errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return uu_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return uu_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='uu', + encode=uu_encode, + decode=uu_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/encodings/zlib_codec.py b/src/main/resources/PythonLibs/encodings/zlib_codec.py new file mode 100644 index 0000000000000000000000000000000000000000..3419f9f48f5efbf1be4802f562536ca235e2748e --- /dev/null +++ b/src/main/resources/PythonLibs/encodings/zlib_codec.py @@ -0,0 +1,102 @@ +""" Python 'zlib_codec' Codec - zlib compression encoding + + Unlike most of the other codecs which target Unicode, this codec + will return Python string objects for both encode and decode. + + Written by Marc-Andre Lemburg (mal@lemburg.com). + +""" +import codecs +import zlib # this codec needs the optional zlib module ! + +### Codec APIs + +def zlib_encode(input,errors='strict'): + + """ Encodes the object input and returns a tuple (output + object, length consumed). + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = zlib.compress(input) + return (output, len(input)) + +def zlib_decode(input,errors='strict'): + + """ Decodes the object input and returns a tuple (output + object, length consumed). + + input must be an object which provides the bf_getreadbuf + buffer slot. Python strings, buffer objects and memory + mapped files are examples of objects providing this slot. + + errors defines the error handling to apply. It defaults to + 'strict' handling which is the only currently supported + error handling for this codec. + + """ + assert errors == 'strict' + output = zlib.decompress(input) + return (output, len(input)) + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return zlib_encode(input, errors) + def decode(self, input, errors='strict'): + return zlib_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.compressobj = zlib.compressobj() + + def encode(self, input, final=False): + if final: + c = self.compressobj.compress(input) + return c + self.compressobj.flush() + else: + return self.compressobj.compress(input) + + def reset(self): + self.compressobj = zlib.compressobj() + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict'): + assert errors == 'strict' + self.errors = errors + self.decompressobj = zlib.decompressobj() + + def decode(self, input, final=False): + if final: + c = self.decompressobj.decompress(input) + return c + self.decompressobj.flush() + else: + return self.decompressobj.decompress(input) + + def reset(self): + self.decompressobj = zlib.decompressobj() + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='zlib', + encode=zlib_encode, + decode=zlib_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/src/main/resources/PythonLibs/filecmp.py b/src/main/resources/PythonLibs/filecmp.py new file mode 100644 index 0000000000000000000000000000000000000000..4728317fce9934b5ef7cbe7fb36b740c6d12bce0 --- /dev/null +++ b/src/main/resources/PythonLibs/filecmp.py @@ -0,0 +1,296 @@ +"""Utilities for comparing files and directories. + +Classes: + dircmp + +Functions: + cmp(f1, f2, shallow=1) -> int + cmpfiles(a, b, common) -> ([], [], []) + +""" + +import os +import stat +from itertools import ifilter, ifilterfalse, imap, izip + +__all__ = ["cmp","dircmp","cmpfiles"] + +_cache = {} +BUFSIZE=8*1024 + +def cmp(f1, f2, shallow=1): + """Compare two files. + + Arguments: + + f1 -- First file name + + f2 -- Second file name + + shallow -- Just check stat signature (do not read the files). + defaults to 1. + + Return value: + + True if the files are the same, False otherwise. + + This function uses a cache for past comparisons and the results, + with a cache invalidation mechanism relying on stale signatures. + + """ + + s1 = _sig(os.stat(f1)) + s2 = _sig(os.stat(f2)) + if s1[0] != stat.S_IFREG or s2[0] != stat.S_IFREG: + return False + if shallow and s1 == s2: + return True + if s1[1] != s2[1]: + return False + + outcome = _cache.get((f1, f2, s1, s2)) + if outcome is None: + outcome = _do_cmp(f1, f2) + if len(_cache) > 100: # limit the maximum size of the cache + _cache.clear() + _cache[f1, f2, s1, s2] = outcome + return outcome + +def _sig(st): + return (stat.S_IFMT(st.st_mode), + st.st_size, + st.st_mtime) + +def _do_cmp(f1, f2): + bufsize = BUFSIZE + with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2: + while True: + b1 = fp1.read(bufsize) + b2 = fp2.read(bufsize) + if b1 != b2: + return False + if not b1: + return True + +# Directory comparison class. +# +class dircmp: + """A class that manages the comparison of 2 directories. + + dircmp(a,b,ignore=None,hide=None) + A and B are directories. + IGNORE is a list of names to ignore, + defaults to ['RCS', 'CVS', 'tags']. + HIDE is a list of names to hide, + defaults to [os.curdir, os.pardir]. + + High level usage: + x = dircmp(dir1, dir2) + x.report() -> prints a report on the differences between dir1 and dir2 + or + x.report_partial_closure() -> prints report on differences between dir1 + and dir2, and reports on common immediate subdirectories. + x.report_full_closure() -> like report_partial_closure, + but fully recursive. + + Attributes: + left_list, right_list: The files in dir1 and dir2, + filtered by hide and ignore. + common: a list of names in both dir1 and dir2. + left_only, right_only: names only in dir1, dir2. + common_dirs: subdirectories in both dir1 and dir2. + common_files: files in both dir1 and dir2. + common_funny: names in both dir1 and dir2 where the type differs between + dir1 and dir2, or the name is not stat-able. + same_files: list of identical files. + diff_files: list of filenames which differ. + funny_files: list of files which could not be compared. + subdirs: a dictionary of dircmp objects, keyed by names in common_dirs. + """ + + def __init__(self, a, b, ignore=None, hide=None): # Initialize + self.left = a + self.right = b + if hide is None: + self.hide = [os.curdir, os.pardir] # Names never to be shown + else: + self.hide = hide + if ignore is None: + self.ignore = ['RCS', 'CVS', 'tags'] # Names ignored in comparison + else: + self.ignore = ignore + + def phase0(self): # Compare everything except common subdirectories + self.left_list = _filter(os.listdir(self.left), + self.hide+self.ignore) + self.right_list = _filter(os.listdir(self.right), + self.hide+self.ignore) + self.left_list.sort() + self.right_list.sort() + + def phase1(self): # Compute common names + a = dict(izip(imap(os.path.normcase, self.left_list), self.left_list)) + b = dict(izip(imap(os.path.normcase, self.right_list), self.right_list)) + self.common = map(a.__getitem__, ifilter(b.__contains__, a)) + self.left_only = map(a.__getitem__, ifilterfalse(b.__contains__, a)) + self.right_only = map(b.__getitem__, ifilterfalse(a.__contains__, b)) + + def phase2(self): # Distinguish files, directories, funnies + self.common_dirs = [] + self.common_files = [] + self.common_funny = [] + + for x in self.common: + a_path = os.path.join(self.left, x) + b_path = os.path.join(self.right, x) + + ok = 1 + try: + a_stat = os.stat(a_path) + except os.error, why: + # print 'Can\'t stat', a_path, ':', why[1] + ok = 0 + try: + b_stat = os.stat(b_path) + except os.error, why: + # print 'Can\'t stat', b_path, ':', why[1] + ok = 0 + + if ok: + a_type = stat.S_IFMT(a_stat.st_mode) + b_type = stat.S_IFMT(b_stat.st_mode) + if a_type != b_type: + self.common_funny.append(x) + elif stat.S_ISDIR(a_type): + self.common_dirs.append(x) + elif stat.S_ISREG(a_type): + self.common_files.append(x) + else: + self.common_funny.append(x) + else: + self.common_funny.append(x) + + def phase3(self): # Find out differences between common files + xx = cmpfiles(self.left, self.right, self.common_files) + self.same_files, self.diff_files, self.funny_files = xx + + def phase4(self): # Find out differences between common subdirectories + # A new dircmp object is created for each common subdirectory, + # these are stored in a dictionary indexed by filename. + # The hide and ignore properties are inherited from the parent + self.subdirs = {} + for x in self.common_dirs: + a_x = os.path.join(self.left, x) + b_x = os.path.join(self.right, x) + self.subdirs[x] = dircmp(a_x, b_x, self.ignore, self.hide) + + def phase4_closure(self): # Recursively call phase4() on subdirectories + self.phase4() + for sd in self.subdirs.itervalues(): + sd.phase4_closure() + + def report(self): # Print a report on the differences between a and b + # Output format is purposely lousy + print 'diff', self.left, self.right + if self.left_only: + self.left_only.sort() + print 'Only in', self.left, ':', self.left_only + if self.right_only: + self.right_only.sort() + print 'Only in', self.right, ':', self.right_only + if self.same_files: + self.same_files.sort() + print 'Identical files :', self.same_files + if self.diff_files: + self.diff_files.sort() + print 'Differing files :', self.diff_files + if self.funny_files: + self.funny_files.sort() + print 'Trouble with common files :', self.funny_files + if self.common_dirs: + self.common_dirs.sort() + print 'Common subdirectories :', self.common_dirs + if self.common_funny: + self.common_funny.sort() + print 'Common funny cases :', self.common_funny + + def report_partial_closure(self): # Print reports on self and on subdirs + self.report() + for sd in self.subdirs.itervalues(): + print + sd.report() + + def report_full_closure(self): # Report on self and subdirs recursively + self.report() + for sd in self.subdirs.itervalues(): + print + sd.report_full_closure() + + methodmap = dict(subdirs=phase4, + same_files=phase3, diff_files=phase3, funny_files=phase3, + common_dirs = phase2, common_files=phase2, common_funny=phase2, + common=phase1, left_only=phase1, right_only=phase1, + left_list=phase0, right_list=phase0) + + def __getattr__(self, attr): + if attr not in self.methodmap: + raise AttributeError, attr + self.methodmap[attr](self) + return getattr(self, attr) + +def cmpfiles(a, b, common, shallow=1): + """Compare common files in two directories. + + a, b -- directory names + common -- list of file names found in both directories + shallow -- if true, do comparison based solely on stat() information + + Returns a tuple of three lists: + files that compare equal + files that are different + filenames that aren't regular files. + + """ + res = ([], [], []) + for x in common: + ax = os.path.join(a, x) + bx = os.path.join(b, x) + res[_cmp(ax, bx, shallow)].append(x) + return res + + +# Compare two files. +# Return: +# 0 for equal +# 1 for different +# 2 for funny cases (can't stat, etc.) +# +def _cmp(a, b, sh, abs=abs, cmp=cmp): + try: + return not abs(cmp(a, b, sh)) + except os.error: + return 2 + + +# Return a copy with items that occur in skip removed. +# +def _filter(flist, skip): + return list(ifilterfalse(skip.__contains__, flist)) + + +# Demonstration and testing. +# +def demo(): + import sys + import getopt + options, args = getopt.getopt(sys.argv[1:], 'r') + if len(args) != 2: + raise getopt.GetoptError('need exactly two args', None) + dd = dircmp(args[0], args[1]) + if ('-r', '') in options: + dd.report_full_closure() + else: + dd.report() + +if __name__ == '__main__': + demo() diff --git a/src/main/resources/PythonLibs/fileinput.py b/src/main/resources/PythonLibs/fileinput.py new file mode 100644 index 0000000000000000000000000000000000000000..5257711d224754fb2eeb07b20a5ab22bcd2fd843 --- /dev/null +++ b/src/main/resources/PythonLibs/fileinput.py @@ -0,0 +1,415 @@ +"""Helper class to quickly write a loop over all standard input files. + +Typical use is: + + import fileinput + for line in fileinput.input(): + process(line) + +This iterates over the lines of all files listed in sys.argv[1:], +defaulting to sys.stdin if the list is empty. If a filename is '-' it +is also replaced by sys.stdin. To specify an alternative list of +filenames, pass it as the argument to input(). A single file name is +also allowed. + +Functions filename(), lineno() return the filename and cumulative line +number of the line that has just been read; filelineno() returns its +line number in the current file; isfirstline() returns true iff the +line just read is the first line of its file; isstdin() returns true +iff the line was read from sys.stdin. Function nextfile() closes the +current file so that the next iteration will read the first line from +the next file (if any); lines not read from the file will not count +towards the cumulative line count; the filename is not changed until +after the first line of the next file has been read. Function close() +closes the sequence. + +Before any lines have been read, filename() returns None and both line +numbers are zero; nextfile() has no effect. After all lines have been +read, filename() and the line number functions return the values +pertaining to the last line read; nextfile() has no effect. + +All files are opened in text mode by default, you can override this by +setting the mode parameter to input() or FileInput.__init__(). +If an I/O error occurs during opening or reading a file, the IOError +exception is raised. + +If sys.stdin is used more than once, the second and further use will +return no lines, except perhaps for interactive use, or if it has been +explicitly reset (e.g. using sys.stdin.seek(0)). + +Empty files are opened and immediately closed; the only time their +presence in the list of filenames is noticeable at all is when the +last file opened is empty. + +It is possible that the last line of a file doesn't end in a newline +character; otherwise lines are returned including the trailing +newline. + +Class FileInput is the implementation; its methods filename(), +lineno(), fileline(), isfirstline(), isstdin(), nextfile() and close() +correspond to the functions in the module. In addition it has a +readline() method which returns the next input line, and a +__getitem__() method which implements the sequence behavior. The +sequence must be accessed in strictly sequential order; sequence +access and readline() cannot be mixed. + +Optional in-place filtering: if the keyword argument inplace=1 is +passed to input() or to the FileInput constructor, the file is moved +to a backup file and standard output is directed to the input file. +This makes it possible to write a filter that rewrites its input file +in place. If the keyword argument backup=".<some extension>" is also +given, it specifies the extension for the backup file, and the backup +file remains around; by default, the extension is ".bak" and it is +deleted when the output file is closed. In-place filtering is +disabled when standard input is read. XXX The current implementation +does not work for MS-DOS 8+3 filesystems. + +Performance: this module is unfortunately one of the slower ways of +processing large numbers of input lines. Nevertheless, a significant +speed-up has been obtained by using readlines(bufsize) instead of +readline(). A new keyword argument, bufsize=N, is present on the +input() function and the FileInput() class to override the default +buffer size. + +XXX Possible additions: + +- optional getopt argument processing +- isatty() +- read(), read(size), even readlines() + +""" + +import sys, os + +__all__ = ["input","close","nextfile","filename","lineno","filelineno", + "isfirstline","isstdin","FileInput"] + +_state = None + +DEFAULT_BUFSIZE = 8*1024 + +def input(files=None, inplace=0, backup="", bufsize=0, + mode="r", openhook=None): + """input([files[, inplace[, backup[, mode[, openhook]]]]]) + + Create an instance of the FileInput class. The instance will be used + as global state for the functions of this module, and is also returned + to use during iteration. The parameters to this function will be passed + along to the constructor of the FileInput class. + """ + global _state + if _state and _state._file: + raise RuntimeError, "input() already active" + _state = FileInput(files, inplace, backup, bufsize, mode, openhook) + return _state + +def close(): + """Close the sequence.""" + global _state + state = _state + _state = None + if state: + state.close() + +def nextfile(): + """ + Close the current file so that the next iteration will read the first + line from the next file (if any); lines not read from the file will + not count towards the cumulative line count. The filename is not + changed until after the first line of the next file has been read. + Before the first line has been read, this function has no effect; + it cannot be used to skip the first file. After the last line of the + last file has been read, this function has no effect. + """ + if not _state: + raise RuntimeError, "no active input()" + return _state.nextfile() + +def filename(): + """ + Return the name of the file currently being read. + Before the first line has been read, returns None. + """ + if not _state: + raise RuntimeError, "no active input()" + return _state.filename() + +def lineno(): + """ + Return the cumulative line number of the line that has just been read. + Before the first line has been read, returns 0. After the last line + of the last file has been read, returns the line number of that line. + """ + if not _state: + raise RuntimeError, "no active input()" + return _state.lineno() + +def filelineno(): + """ + Return the line number in the current file. Before the first line + has been read, returns 0. After the last line of the last file has + been read, returns the line number of that line within the file. + """ + if not _state: + raise RuntimeError, "no active input()" + return _state.filelineno() + +def fileno(): + """ + Return the file number of the current file. When no file is currently + opened, returns -1. + """ + if not _state: + raise RuntimeError, "no active input()" + return _state.fileno() + +def isfirstline(): + """ + Returns true the line just read is the first line of its file, + otherwise returns false. + """ + if not _state: + raise RuntimeError, "no active input()" + return _state.isfirstline() + +def isstdin(): + """ + Returns true if the last line was read from sys.stdin, + otherwise returns false. + """ + if not _state: + raise RuntimeError, "no active input()" + return _state.isstdin() + +class FileInput: + """class FileInput([files[, inplace[, backup[, mode[, openhook]]]]]) + + Class FileInput is the implementation of the module; its methods + filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(), + nextfile() and close() correspond to the functions of the same name + in the module. + In addition it has a readline() method which returns the next + input line, and a __getitem__() method which implements the + sequence behavior. The sequence must be accessed in strictly + sequential order; random access and readline() cannot be mixed. + """ + + def __init__(self, files=None, inplace=0, backup="", bufsize=0, + mode="r", openhook=None): + if isinstance(files, basestring): + files = (files,) + else: + if files is None: + files = sys.argv[1:] + if not files: + files = ('-',) + else: + files = tuple(files) + self._files = files + self._inplace = inplace + self._backup = backup + self._bufsize = bufsize or DEFAULT_BUFSIZE + self._savestdout = None + self._output = None + self._filename = None + self._lineno = 0 + self._filelineno = 0 + self._file = None + self._isstdin = False + self._backupfilename = None + self._buffer = [] + self._bufindex = 0 + # restrict mode argument to reading modes + if mode not in ('r', 'rU', 'U', 'rb'): + raise ValueError("FileInput opening mode must be one of " + "'r', 'rU', 'U' and 'rb'") + self._mode = mode + if inplace and openhook: + raise ValueError("FileInput cannot use an opening hook in inplace mode") + elif openhook and not hasattr(openhook, '__call__'): + raise ValueError("FileInput openhook must be callable") + self._openhook = openhook + + def __del__(self): + self.close() + + def close(self): + self.nextfile() + self._files = () + + def __iter__(self): + return self + + def next(self): + try: + line = self._buffer[self._bufindex] + except IndexError: + pass + else: + self._bufindex += 1 + self._lineno += 1 + self._filelineno += 1 + return line + line = self.readline() + if not line: + raise StopIteration + return line + + def __getitem__(self, i): + if i != self._lineno: + raise RuntimeError, "accessing lines out of order" + try: + return self.next() + except StopIteration: + raise IndexError, "end of input reached" + + def nextfile(self): + savestdout = self._savestdout + self._savestdout = 0 + if savestdout: + sys.stdout = savestdout + + output = self._output + self._output = 0 + if output: + output.close() + + file = self._file + self._file = 0 + if file and not self._isstdin: + file.close() + + backupfilename = self._backupfilename + self._backupfilename = 0 + if backupfilename and not self._backup: + try: os.unlink(backupfilename) + except OSError: pass + + self._isstdin = False + self._buffer = [] + self._bufindex = 0 + + def readline(self): + try: + line = self._buffer[self._bufindex] + except IndexError: + pass + else: + self._bufindex += 1 + self._lineno += 1 + self._filelineno += 1 + return line + if not self._file: + if not self._files: + return "" + self._filename = self._files[0] + self._files = self._files[1:] + self._filelineno = 0 + self._file = None + self._isstdin = False + self._backupfilename = 0 + if self._filename == '-': + self._filename = '<stdin>' + self._file = sys.stdin + self._isstdin = True + else: + if self._inplace: + self._backupfilename = ( + self._filename + (self._backup or os.extsep+"bak")) + try: os.unlink(self._backupfilename) + except os.error: pass + # The next few lines may raise IOError + os.rename(self._filename, self._backupfilename) + self._file = open(self._backupfilename, self._mode) + try: + perm = os.fstat(self._file.fileno()).st_mode + except (AttributeError, OSError): + # AttributeError occurs in Jython, where there's no + # os.fstat. + self._output = open(self._filename, "w") + else: + fd = os.open(self._filename, + os.O_CREAT | os.O_WRONLY | os.O_TRUNC, + perm) + self._output = os.fdopen(fd, "w") + try: + if hasattr(os, 'chmod'): + os.chmod(self._filename, perm) + except OSError: + pass + self._savestdout = sys.stdout + sys.stdout = self._output + else: + # This may raise IOError + if self._openhook: + self._file = self._openhook(self._filename, self._mode) + else: + self._file = open(self._filename, self._mode) + self._buffer = self._file.readlines(self._bufsize) + self._bufindex = 0 + if not self._buffer: + self.nextfile() + # Recursive call + return self.readline() + + def filename(self): + return self._filename + + def lineno(self): + return self._lineno + + def filelineno(self): + return self._filelineno + + def fileno(self): + if self._file: + try: + return self._file.fileno() + except ValueError: + return -1 + else: + return -1 + + def isfirstline(self): + return self._filelineno == 1 + + def isstdin(self): + return self._isstdin + + +def hook_compressed(filename, mode): + ext = os.path.splitext(filename)[1] + if ext == '.gz': + import gzip + return gzip.open(filename, mode) + elif ext == '.bz2': + import bz2 + return bz2.BZ2File(filename, mode) + else: + return open(filename, mode) + + +def hook_encoded(encoding): + import codecs + def openhook(filename, mode): + return codecs.open(filename, mode, encoding) + return openhook + + +def _test(): + import getopt + inplace = 0 + backup = 0 + opts, args = getopt.getopt(sys.argv[1:], "ib:") + for o, a in opts: + if o == '-i': inplace = 1 + if o == '-b': backup = a + for line in input(args, inplace=inplace, backup=backup): + if line[-1:] == '\n': line = line[:-1] + if line[-1:] == '\r': line = line[:-1] + print "%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(), + isfirstline() and "*" or "", line) + print "%d: %s[%d]" % (lineno(), filename(), filelineno()) + +if __name__ == '__main__': + _test() diff --git a/src/main/resources/PythonLibs/fnmatch.py b/src/main/resources/PythonLibs/fnmatch.py new file mode 100644 index 0000000000000000000000000000000000000000..ffe99b5762db0116b23f3008c7de54d49681a84c --- /dev/null +++ b/src/main/resources/PythonLibs/fnmatch.py @@ -0,0 +1,116 @@ +"""Filename matching with shell patterns. + +fnmatch(FILENAME, PATTERN) matches according to the local convention. +fnmatchcase(FILENAME, PATTERN) always takes case in account. + +The functions operate by translating the pattern into a regular +expression. They cache the compiled regular expressions for speed. + +The function translate(PATTERN) returns a regular expression +corresponding to PATTERN. (It does not compile it.) +""" + +import re + +__all__ = ["filter", "fnmatch", "fnmatchcase", "translate"] + +_cache = {} +_MAXCACHE = 100 + +def _purge(): + """Clear the pattern cache""" + _cache.clear() + +def fnmatch(name, pat): + """Test whether FILENAME matches PATTERN. + + Patterns are Unix shell style: + + * matches everything + ? matches any single character + [seq] matches any character in seq + [!seq] matches any char not in seq + + An initial period in FILENAME is not special. + Both FILENAME and PATTERN are first case-normalized + if the operating system requires it. + If you don't want this, use fnmatchcase(FILENAME, PATTERN). + """ + + import os + name = os.path.normcase(name) + pat = os.path.normcase(pat) + return fnmatchcase(name, pat) + +def filter(names, pat): + """Return the subset of the list NAMES that match PAT""" + import os,posixpath + result=[] + pat=os.path.normcase(pat) + if not pat in _cache: + res = translate(pat) + if len(_cache) >= _MAXCACHE: + _cache.clear() + _cache[pat] = re.compile(res) + match=_cache[pat].match + if os.path is posixpath: + # normcase on posix is NOP. Optimize it away from the loop. + for name in names: + if match(name): + result.append(name) + else: + for name in names: + if match(os.path.normcase(name)): + result.append(name) + return result + +def fnmatchcase(name, pat): + """Test whether FILENAME matches PATTERN, including case. + + This is a version of fnmatch() which doesn't case-normalize + its arguments. + """ + + if not pat in _cache: + res = translate(pat) + if len(_cache) >= _MAXCACHE: + _cache.clear() + _cache[pat] = re.compile(res) + return _cache[pat].match(name) is not None + +def translate(pat): + """Translate a shell PATTERN to a regular expression. + + There is no way to quote meta-characters. + """ + + i, n = 0, len(pat) + res = '' + while i < n: + c = pat[i] + i = i+1 + if c == '*': + res = res + '.*' + elif c == '?': + res = res + '.' + elif c == '[': + j = i + if j < n and pat[j] == '!': + j = j+1 + if j < n and pat[j] == ']': + j = j+1 + while j < n and pat[j] != ']': + j = j+1 + if j >= n: + res = res + '\\[' + else: + stuff = pat[i:j].replace('\\','\\\\') + i = j+1 + if stuff[0] == '!': + stuff = '^' + stuff[1:] + elif stuff[0] == '^': + stuff = '\\' + stuff + res = '%s[%s]' % (res, stuff) + else: + res = res + re.escape(c) + return res + '\Z(?ms)' diff --git a/src/main/resources/PythonLibs/formatter.py b/src/main/resources/PythonLibs/formatter.py new file mode 100644 index 0000000000000000000000000000000000000000..e0a8fe10b22323618ca030d984ba0230c18e8593 --- /dev/null +++ b/src/main/resources/PythonLibs/formatter.py @@ -0,0 +1,445 @@ +"""Generic output formatting. + +Formatter objects transform an abstract flow of formatting events into +specific output events on writer objects. Formatters manage several stack +structures to allow various properties of a writer object to be changed and +restored; writers need not be able to handle relative changes nor any sort +of ``change back'' operation. Specific writer properties which may be +controlled via formatter objects are horizontal alignment, font, and left +margin indentations. A mechanism is provided which supports providing +arbitrary, non-exclusive style settings to a writer as well. Additional +interfaces facilitate formatting events which are not reversible, such as +paragraph separation. + +Writer objects encapsulate device interfaces. Abstract devices, such as +file formats, are supported as well as physical devices. The provided +implementations all work with abstract devices. The interface makes +available mechanisms for setting the properties which formatter objects +manage and inserting data into the output. +""" + +import sys + + +AS_IS = None + + +class NullFormatter: + """A formatter which does nothing. + + If the writer parameter is omitted, a NullWriter instance is created. + No methods of the writer are called by NullFormatter instances. + + Implementations should inherit from this class if implementing a writer + interface but don't need to inherit any implementation. + + """ + + def __init__(self, writer=None): + if writer is None: + writer = NullWriter() + self.writer = writer + def end_paragraph(self, blankline): pass + def add_line_break(self): pass + def add_hor_rule(self, *args, **kw): pass + def add_label_data(self, format, counter, blankline=None): pass + def add_flowing_data(self, data): pass + def add_literal_data(self, data): pass + def flush_softspace(self): pass + def push_alignment(self, align): pass + def pop_alignment(self): pass + def push_font(self, x): pass + def pop_font(self): pass + def push_margin(self, margin): pass + def pop_margin(self): pass + def set_spacing(self, spacing): pass + def push_style(self, *styles): pass + def pop_style(self, n=1): pass + def assert_line_data(self, flag=1): pass + + +class AbstractFormatter: + """The standard formatter. + + This implementation has demonstrated wide applicability to many writers, + and may be used directly in most circumstances. It has been used to + implement a full-featured World Wide Web browser. + + """ + + # Space handling policy: blank spaces at the boundary between elements + # are handled by the outermost context. "Literal" data is not checked + # to determine context, so spaces in literal data are handled directly + # in all circumstances. + + def __init__(self, writer): + self.writer = writer # Output device + self.align = None # Current alignment + self.align_stack = [] # Alignment stack + self.font_stack = [] # Font state + self.margin_stack = [] # Margin state + self.spacing = None # Vertical spacing state + self.style_stack = [] # Other state, e.g. color + self.nospace = 1 # Should leading space be suppressed + self.softspace = 0 # Should a space be inserted + self.para_end = 1 # Just ended a paragraph + self.parskip = 0 # Skipped space between paragraphs? + self.hard_break = 1 # Have a hard break + self.have_label = 0 + + def end_paragraph(self, blankline): + if not self.hard_break: + self.writer.send_line_break() + self.have_label = 0 + if self.parskip < blankline and not self.have_label: + self.writer.send_paragraph(blankline - self.parskip) + self.parskip = blankline + self.have_label = 0 + self.hard_break = self.nospace = self.para_end = 1 + self.softspace = 0 + + def add_line_break(self): + if not (self.hard_break or self.para_end): + self.writer.send_line_break() + self.have_label = self.parskip = 0 + self.hard_break = self.nospace = 1 + self.softspace = 0 + + def add_hor_rule(self, *args, **kw): + if not self.hard_break: + self.writer.send_line_break() + self.writer.send_hor_rule(*args, **kw) + self.hard_break = self.nospace = 1 + self.have_label = self.para_end = self.softspace = self.parskip = 0 + + def add_label_data(self, format, counter, blankline = None): + if self.have_label or not self.hard_break: + self.writer.send_line_break() + if not self.para_end: + self.writer.send_paragraph((blankline and 1) or 0) + if isinstance(format, str): + self.writer.send_label_data(self.format_counter(format, counter)) + else: + self.writer.send_label_data(format) + self.nospace = self.have_label = self.hard_break = self.para_end = 1 + self.softspace = self.parskip = 0 + + def format_counter(self, format, counter): + label = '' + for c in format: + if c == '1': + label = label + ('%d' % counter) + elif c in 'aA': + if counter > 0: + label = label + self.format_letter(c, counter) + elif c in 'iI': + if counter > 0: + label = label + self.format_roman(c, counter) + else: + label = label + c + return label + + def format_letter(self, case, counter): + label = '' + while counter > 0: + counter, x = divmod(counter-1, 26) + # This makes a strong assumption that lowercase letters + # and uppercase letters form two contiguous blocks, with + # letters in order! + s = chr(ord(case) + x) + label = s + label + return label + + def format_roman(self, case, counter): + ones = ['i', 'x', 'c', 'm'] + fives = ['v', 'l', 'd'] + label, index = '', 0 + # This will die of IndexError when counter is too big + while counter > 0: + counter, x = divmod(counter, 10) + if x == 9: + label = ones[index] + ones[index+1] + label + elif x == 4: + label = ones[index] + fives[index] + label + else: + if x >= 5: + s = fives[index] + x = x-5 + else: + s = '' + s = s + ones[index]*x + label = s + label + index = index + 1 + if case == 'I': + return label.upper() + return label + + def add_flowing_data(self, data): + if not data: return + prespace = data[:1].isspace() + postspace = data[-1:].isspace() + data = " ".join(data.split()) + if self.nospace and not data: + return + elif prespace or self.softspace: + if not data: + if not self.nospace: + self.softspace = 1 + self.parskip = 0 + return + if not self.nospace: + data = ' ' + data + self.hard_break = self.nospace = self.para_end = \ + self.parskip = self.have_label = 0 + self.softspace = postspace + self.writer.send_flowing_data(data) + + def add_literal_data(self, data): + if not data: return + if self.softspace: + self.writer.send_flowing_data(" ") + self.hard_break = data[-1:] == '\n' + self.nospace = self.para_end = self.softspace = \ + self.parskip = self.have_label = 0 + self.writer.send_literal_data(data) + + def flush_softspace(self): + if self.softspace: + self.hard_break = self.para_end = self.parskip = \ + self.have_label = self.softspace = 0 + self.nospace = 1 + self.writer.send_flowing_data(' ') + + def push_alignment(self, align): + if align and align != self.align: + self.writer.new_alignment(align) + self.align = align + self.align_stack.append(align) + else: + self.align_stack.append(self.align) + + def pop_alignment(self): + if self.align_stack: + del self.align_stack[-1] + if self.align_stack: + self.align = align = self.align_stack[-1] + self.writer.new_alignment(align) + else: + self.align = None + self.writer.new_alignment(None) + + def push_font(self, font): + size, i, b, tt = font + if self.softspace: + self.hard_break = self.para_end = self.softspace = 0 + self.nospace = 1 + self.writer.send_flowing_data(' ') + if self.font_stack: + csize, ci, cb, ctt = self.font_stack[-1] + if size is AS_IS: size = csize + if i is AS_IS: i = ci + if b is AS_IS: b = cb + if tt is AS_IS: tt = ctt + font = (size, i, b, tt) + self.font_stack.append(font) + self.writer.new_font(font) + + def pop_font(self): + if self.font_stack: + del self.font_stack[-1] + if self.font_stack: + font = self.font_stack[-1] + else: + font = None + self.writer.new_font(font) + + def push_margin(self, margin): + self.margin_stack.append(margin) + fstack = filter(None, self.margin_stack) + if not margin and fstack: + margin = fstack[-1] + self.writer.new_margin(margin, len(fstack)) + + def pop_margin(self): + if self.margin_stack: + del self.margin_stack[-1] + fstack = filter(None, self.margin_stack) + if fstack: + margin = fstack[-1] + else: + margin = None + self.writer.new_margin(margin, len(fstack)) + + def set_spacing(self, spacing): + self.spacing = spacing + self.writer.new_spacing(spacing) + + def push_style(self, *styles): + if self.softspace: + self.hard_break = self.para_end = self.softspace = 0 + self.nospace = 1 + self.writer.send_flowing_data(' ') + for style in styles: + self.style_stack.append(style) + self.writer.new_styles(tuple(self.style_stack)) + + def pop_style(self, n=1): + del self.style_stack[-n:] + self.writer.new_styles(tuple(self.style_stack)) + + def assert_line_data(self, flag=1): + self.nospace = self.hard_break = not flag + self.para_end = self.parskip = self.have_label = 0 + + +class NullWriter: + """Minimal writer interface to use in testing & inheritance. + + A writer which only provides the interface definition; no actions are + taken on any methods. This should be the base class for all writers + which do not need to inherit any implementation methods. + + """ + def __init__(self): pass + def flush(self): pass + def new_alignment(self, align): pass + def new_font(self, font): pass + def new_margin(self, margin, level): pass + def new_spacing(self, spacing): pass + def new_styles(self, styles): pass + def send_paragraph(self, blankline): pass + def send_line_break(self): pass + def send_hor_rule(self, *args, **kw): pass + def send_label_data(self, data): pass + def send_flowing_data(self, data): pass + def send_literal_data(self, data): pass + + +class AbstractWriter(NullWriter): + """A writer which can be used in debugging formatters, but not much else. + + Each method simply announces itself by printing its name and + arguments on standard output. + + """ + + def new_alignment(self, align): + print "new_alignment(%r)" % (align,) + + def new_font(self, font): + print "new_font(%r)" % (font,) + + def new_margin(self, margin, level): + print "new_margin(%r, %d)" % (margin, level) + + def new_spacing(self, spacing): + print "new_spacing(%r)" % (spacing,) + + def new_styles(self, styles): + print "new_styles(%r)" % (styles,) + + def send_paragraph(self, blankline): + print "send_paragraph(%r)" % (blankline,) + + def send_line_break(self): + print "send_line_break()" + + def send_hor_rule(self, *args, **kw): + print "send_hor_rule()" + + def send_label_data(self, data): + print "send_label_data(%r)" % (data,) + + def send_flowing_data(self, data): + print "send_flowing_data(%r)" % (data,) + + def send_literal_data(self, data): + print "send_literal_data(%r)" % (data,) + + +class DumbWriter(NullWriter): + """Simple writer class which writes output on the file object passed in + as the file parameter or, if file is omitted, on standard output. The + output is simply word-wrapped to the number of columns specified by + the maxcol parameter. This class is suitable for reflowing a sequence + of paragraphs. + + """ + + def __init__(self, file=None, maxcol=72): + self.file = file or sys.stdout + self.maxcol = maxcol + NullWriter.__init__(self) + self.reset() + + def reset(self): + self.col = 0 + self.atbreak = 0 + + def send_paragraph(self, blankline): + self.file.write('\n'*blankline) + self.col = 0 + self.atbreak = 0 + + def send_line_break(self): + self.file.write('\n') + self.col = 0 + self.atbreak = 0 + + def send_hor_rule(self, *args, **kw): + self.file.write('\n') + self.file.write('-'*self.maxcol) + self.file.write('\n') + self.col = 0 + self.atbreak = 0 + + def send_literal_data(self, data): + self.file.write(data) + i = data.rfind('\n') + if i >= 0: + self.col = 0 + data = data[i+1:] + data = data.expandtabs() + self.col = self.col + len(data) + self.atbreak = 0 + + def send_flowing_data(self, data): + if not data: return + atbreak = self.atbreak or data[0].isspace() + col = self.col + maxcol = self.maxcol + write = self.file.write + for word in data.split(): + if atbreak: + if col + len(word) >= maxcol: + write('\n') + col = 0 + else: + write(' ') + col = col + 1 + write(word) + col = col + len(word) + atbreak = 1 + self.col = col + self.atbreak = data[-1].isspace() + + +def test(file = None): + w = DumbWriter() + f = AbstractFormatter(w) + if file is not None: + fp = open(file) + elif sys.argv[1:]: + fp = open(sys.argv[1]) + else: + fp = sys.stdin + for line in fp: + if line == '\n': + f.end_paragraph(1) + else: + f.add_flowing_data(line) + f.end_paragraph(0) + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/fpformat.py b/src/main/resources/PythonLibs/fpformat.py new file mode 100644 index 0000000000000000000000000000000000000000..71cbb25f3c8b9eb861415eca88358aeb049202ff --- /dev/null +++ b/src/main/resources/PythonLibs/fpformat.py @@ -0,0 +1,145 @@ +"""General floating point formatting functions. + +Functions: +fix(x, digits_behind) +sci(x, digits_behind) + +Each takes a number or a string and a number of digits as arguments. + +Parameters: +x: number to be formatted; or a string resembling a number +digits_behind: number of digits behind the decimal point +""" +from warnings import warnpy3k +warnpy3k("the fpformat module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +import re + +__all__ = ["fix","sci","NotANumber"] + +# Compiled regular expression to "decode" a number +decoder = re.compile(r'^([-+]?)0*(\d*)((?:\.\d*)?)(([eE][-+]?\d+)?)$') +# \0 the whole thing +# \1 leading sign or empty +# \2 digits left of decimal point +# \3 fraction (empty or begins with point) +# \4 exponent part (empty or begins with 'e' or 'E') + +try: + class NotANumber(ValueError): + pass +except TypeError: + NotANumber = 'fpformat.NotANumber' + +def extract(s): + """Return (sign, intpart, fraction, expo) or raise an exception: + sign is '+' or '-' + intpart is 0 or more digits beginning with a nonzero + fraction is 0 or more digits + expo is an integer""" + res = decoder.match(s) + if res is None: raise NotANumber, s + sign, intpart, fraction, exppart = res.group(1,2,3,4) + if sign == '+': sign = '' + if fraction: fraction = fraction[1:] + if exppart: expo = int(exppart[1:]) + else: expo = 0 + return sign, intpart, fraction, expo + +def unexpo(intpart, fraction, expo): + """Remove the exponent by changing intpart and fraction.""" + if expo > 0: # Move the point left + f = len(fraction) + intpart, fraction = intpart + fraction[:expo], fraction[expo:] + if expo > f: + intpart = intpart + '0'*(expo-f) + elif expo < 0: # Move the point right + i = len(intpart) + intpart, fraction = intpart[:expo], intpart[expo:] + fraction + if expo < -i: + fraction = '0'*(-expo-i) + fraction + return intpart, fraction + +def roundfrac(intpart, fraction, digs): + """Round or extend the fraction to size digs.""" + f = len(fraction) + if f <= digs: + return intpart, fraction + '0'*(digs-f) + i = len(intpart) + if i+digs < 0: + return '0'*-digs, '' + total = intpart + fraction + nextdigit = total[i+digs] + if nextdigit >= '5': # Hard case: increment last digit, may have carry! + n = i + digs - 1 + while n >= 0: + if total[n] != '9': break + n = n-1 + else: + total = '0' + total + i = i+1 + n = 0 + total = total[:n] + chr(ord(total[n]) + 1) + '0'*(len(total)-n-1) + intpart, fraction = total[:i], total[i:] + if digs >= 0: + return intpart, fraction[:digs] + else: + return intpart[:digs] + '0'*-digs, '' + +def fix(x, digs): + """Format x as [-]ddd.ddd with 'digs' digits after the point + and at least one digit before. + If digs <= 0, the point is suppressed.""" + if type(x) != type(''): x = repr(x) + try: + sign, intpart, fraction, expo = extract(x) + except NotANumber: + return x + intpart, fraction = unexpo(intpart, fraction, expo) + intpart, fraction = roundfrac(intpart, fraction, digs) + while intpart and intpart[0] == '0': intpart = intpart[1:] + if intpart == '': intpart = '0' + if digs > 0: return sign + intpart + '.' + fraction + else: return sign + intpart + +def sci(x, digs): + """Format x as [-]d.dddE[+-]ddd with 'digs' digits after the point + and exactly one digit before. + If digs is <= 0, one digit is kept and the point is suppressed.""" + if type(x) != type(''): x = repr(x) + sign, intpart, fraction, expo = extract(x) + if not intpart: + while fraction and fraction[0] == '0': + fraction = fraction[1:] + expo = expo - 1 + if fraction: + intpart, fraction = fraction[0], fraction[1:] + expo = expo - 1 + else: + intpart = '0' + else: + expo = expo + len(intpart) - 1 + intpart, fraction = intpart[0], intpart[1:] + fraction + digs = max(0, digs) + intpart, fraction = roundfrac(intpart, fraction, digs) + if len(intpart) > 1: + intpart, fraction, expo = \ + intpart[0], intpart[1:] + fraction[:-1], \ + expo + len(intpart) - 1 + s = sign + intpart + if digs > 0: s = s + '.' + fraction + e = repr(abs(expo)) + e = '0'*(3-len(e)) + e + if expo < 0: e = '-' + e + else: e = '+' + e + return s + 'e' + e + +def test(): + """Interactive test run.""" + try: + while 1: + x, digs = input('Enter (x, digs): ') + print x, fix(x, digs), sci(x, digs) + except (EOFError, KeyboardInterrupt): + pass diff --git a/src/main/resources/PythonLibs/fractions.py b/src/main/resources/PythonLibs/fractions.py new file mode 100644 index 0000000000000000000000000000000000000000..a0d86a4393684c0f96a2ddd3249b37b2b57b87e2 --- /dev/null +++ b/src/main/resources/PythonLibs/fractions.py @@ -0,0 +1,605 @@ +# Originally contributed by Sjoerd Mullender. +# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>. + +"""Rational, infinite-precision, real numbers.""" + +from __future__ import division +from decimal import Decimal +import math +import numbers +import operator +import re + +__all__ = ['Fraction', 'gcd'] + +Rational = numbers.Rational + + +def gcd(a, b): + """Calculate the Greatest Common Divisor of a and b. + + Unless b==0, the result will have the same sign as b (so that when + b is divided by it, the result comes out positive). + """ + while b: + a, b = b, a%b + return a + + +_RATIONAL_FORMAT = re.compile(r""" + \A\s* # optional whitespace at the start, then + (?P<sign>[-+]?) # an optional sign, then + (?=\d|\.\d) # lookahead for digit or .digit + (?P<num>\d*) # numerator (possibly empty) + (?: # followed by + (?:/(?P<denom>\d+))? # an optional denominator + | # or + (?:\.(?P<decimal>\d*))? # an optional fractional part + (?:E(?P<exp>[-+]?\d+))? # and optional exponent + ) + \s*\Z # and optional whitespace to finish +""", re.VERBOSE | re.IGNORECASE) + + +class Fraction(Rational): + """This class implements rational numbers. + + In the two-argument form of the constructor, Fraction(8, 6) will + produce a rational number equivalent to 4/3. Both arguments must + be Rational. The numerator defaults to 0 and the denominator + defaults to 1 so that Fraction(3) == 3 and Fraction() == 0. + + Fractions can also be constructed from: + + - numeric strings similar to those accepted by the + float constructor (for example, '-2.3' or '1e10') + + - strings of the form '123/456' + + - float and Decimal instances + + - other Rational instances (including integers) + + """ + + __slots__ = ('_numerator', '_denominator') + + # We're immutable, so use __new__ not __init__ + def __new__(cls, numerator=0, denominator=None): + """Constructs a Fraction. + + Takes a string like '3/2' or '1.5', another Rational instance, a + numerator/denominator pair, or a float. + + Examples + -------- + + >>> Fraction(10, -8) + Fraction(-5, 4) + >>> Fraction(Fraction(1, 7), 5) + Fraction(1, 35) + >>> Fraction(Fraction(1, 7), Fraction(2, 3)) + Fraction(3, 14) + >>> Fraction('314') + Fraction(314, 1) + >>> Fraction('-35/4') + Fraction(-35, 4) + >>> Fraction('3.1415') # conversion from numeric string + Fraction(6283, 2000) + >>> Fraction('-47e-2') # string may include a decimal exponent + Fraction(-47, 100) + >>> Fraction(1.47) # direct construction from float (exact conversion) + Fraction(6620291452234629, 4503599627370496) + >>> Fraction(2.25) + Fraction(9, 4) + >>> Fraction(Decimal('1.47')) + Fraction(147, 100) + + """ + self = super(Fraction, cls).__new__(cls) + + if denominator is None: + if isinstance(numerator, Rational): + self._numerator = numerator.numerator + self._denominator = numerator.denominator + return self + + elif isinstance(numerator, float): + # Exact conversion from float + value = Fraction.from_float(numerator) + self._numerator = value._numerator + self._denominator = value._denominator + return self + + elif isinstance(numerator, Decimal): + value = Fraction.from_decimal(numerator) + self._numerator = value._numerator + self._denominator = value._denominator + return self + + elif isinstance(numerator, basestring): + # Handle construction from strings. + m = _RATIONAL_FORMAT.match(numerator) + if m is None: + raise ValueError('Invalid literal for Fraction: %r' % + numerator) + numerator = int(m.group('num') or '0') + denom = m.group('denom') + if denom: + denominator = int(denom) + else: + denominator = 1 + decimal = m.group('decimal') + if decimal: + scale = 10**len(decimal) + numerator = numerator * scale + int(decimal) + denominator *= scale + exp = m.group('exp') + if exp: + exp = int(exp) + if exp >= 0: + numerator *= 10**exp + else: + denominator *= 10**-exp + if m.group('sign') == '-': + numerator = -numerator + + else: + raise TypeError("argument should be a string " + "or a Rational instance") + + elif (isinstance(numerator, Rational) and + isinstance(denominator, Rational)): + numerator, denominator = ( + numerator.numerator * denominator.denominator, + denominator.numerator * numerator.denominator + ) + else: + raise TypeError("both arguments should be " + "Rational instances") + + if denominator == 0: + raise ZeroDivisionError('Fraction(%s, 0)' % numerator) + g = gcd(numerator, denominator) + self._numerator = numerator // g + self._denominator = denominator // g + return self + + @classmethod + def from_float(cls, f): + """Converts a finite float to a rational number, exactly. + + Beware that Fraction.from_float(0.3) != Fraction(3, 10). + + """ + if isinstance(f, numbers.Integral): + return cls(f) + elif not isinstance(f, float): + raise TypeError("%s.from_float() only takes floats, not %r (%s)" % + (cls.__name__, f, type(f).__name__)) + if math.isnan(f) or math.isinf(f): + raise TypeError("Cannot convert %r to %s." % (f, cls.__name__)) + return cls(*f.as_integer_ratio()) + + @classmethod + def from_decimal(cls, dec): + """Converts a finite Decimal instance to a rational number, exactly.""" + from decimal import Decimal + if isinstance(dec, numbers.Integral): + dec = Decimal(int(dec)) + elif not isinstance(dec, Decimal): + raise TypeError( + "%s.from_decimal() only takes Decimals, not %r (%s)" % + (cls.__name__, dec, type(dec).__name__)) + if not dec.is_finite(): + # Catches infinities and nans. + raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__)) + sign, digits, exp = dec.as_tuple() + digits = int(''.join(map(str, digits))) + if sign: + digits = -digits + if exp >= 0: + return cls(digits * 10 ** exp) + else: + return cls(digits, 10 ** -exp) + + def limit_denominator(self, max_denominator=1000000): + """Closest Fraction to self with denominator at most max_denominator. + + >>> Fraction('3.141592653589793').limit_denominator(10) + Fraction(22, 7) + >>> Fraction('3.141592653589793').limit_denominator(100) + Fraction(311, 99) + >>> Fraction(4321, 8765).limit_denominator(10000) + Fraction(4321, 8765) + + """ + # Algorithm notes: For any real number x, define a *best upper + # approximation* to x to be a rational number p/q such that: + # + # (1) p/q >= x, and + # (2) if p/q > r/s >= x then s > q, for any rational r/s. + # + # Define *best lower approximation* similarly. Then it can be + # proved that a rational number is a best upper or lower + # approximation to x if, and only if, it is a convergent or + # semiconvergent of the (unique shortest) continued fraction + # associated to x. + # + # To find a best rational approximation with denominator <= M, + # we find the best upper and lower approximations with + # denominator <= M and take whichever of these is closer to x. + # In the event of a tie, the bound with smaller denominator is + # chosen. If both denominators are equal (which can happen + # only when max_denominator == 1 and self is midway between + # two integers) the lower bound---i.e., the floor of self, is + # taken. + + if max_denominator < 1: + raise ValueError("max_denominator should be at least 1") + if self._denominator <= max_denominator: + return Fraction(self) + + p0, q0, p1, q1 = 0, 1, 1, 0 + n, d = self._numerator, self._denominator + while True: + a = n//d + q2 = q0+a*q1 + if q2 > max_denominator: + break + p0, q0, p1, q1 = p1, q1, p0+a*p1, q2 + n, d = d, n-a*d + + k = (max_denominator-q0)//q1 + bound1 = Fraction(p0+k*p1, q0+k*q1) + bound2 = Fraction(p1, q1) + if abs(bound2 - self) <= abs(bound1-self): + return bound2 + else: + return bound1 + + @property + def numerator(a): + return a._numerator + + @property + def denominator(a): + return a._denominator + + def __repr__(self): + """repr(self)""" + return ('Fraction(%s, %s)' % (self._numerator, self._denominator)) + + def __str__(self): + """str(self)""" + if self._denominator == 1: + return str(self._numerator) + else: + return '%s/%s' % (self._numerator, self._denominator) + + def _operator_fallbacks(monomorphic_operator, fallback_operator): + """Generates forward and reverse operators given a purely-rational + operator and a function from the operator module. + + Use this like: + __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op) + + In general, we want to implement the arithmetic operations so + that mixed-mode operations either call an implementation whose + author knew about the types of both arguments, or convert both + to the nearest built in type and do the operation there. In + Fraction, that means that we define __add__ and __radd__ as: + + def __add__(self, other): + # Both types have numerators/denominator attributes, + # so do the operation directly + if isinstance(other, (int, long, Fraction)): + return Fraction(self.numerator * other.denominator + + other.numerator * self.denominator, + self.denominator * other.denominator) + # float and complex don't have those operations, but we + # know about those types, so special case them. + elif isinstance(other, float): + return float(self) + other + elif isinstance(other, complex): + return complex(self) + other + # Let the other type take over. + return NotImplemented + + def __radd__(self, other): + # radd handles more types than add because there's + # nothing left to fall back to. + if isinstance(other, Rational): + return Fraction(self.numerator * other.denominator + + other.numerator * self.denominator, + self.denominator * other.denominator) + elif isinstance(other, Real): + return float(other) + float(self) + elif isinstance(other, Complex): + return complex(other) + complex(self) + return NotImplemented + + + There are 5 different cases for a mixed-type addition on + Fraction. I'll refer to all of the above code that doesn't + refer to Fraction, float, or complex as "boilerplate". 'r' + will be an instance of Fraction, which is a subtype of + Rational (r : Fraction <: Rational), and b : B <: + Complex. The first three involve 'r + b': + + 1. If B <: Fraction, int, float, or complex, we handle + that specially, and all is well. + 2. If Fraction falls back to the boilerplate code, and it + were to return a value from __add__, we'd miss the + possibility that B defines a more intelligent __radd__, + so the boilerplate should return NotImplemented from + __add__. In particular, we don't handle Rational + here, even though we could get an exact answer, in case + the other type wants to do something special. + 3. If B <: Fraction, Python tries B.__radd__ before + Fraction.__add__. This is ok, because it was + implemented with knowledge of Fraction, so it can + handle those instances before delegating to Real or + Complex. + + The next two situations describe 'b + r'. We assume that b + didn't know about Fraction in its implementation, and that it + uses similar boilerplate code: + + 4. If B <: Rational, then __radd_ converts both to the + builtin rational type (hey look, that's us) and + proceeds. + 5. Otherwise, __radd__ tries to find the nearest common + base ABC, and fall back to its builtin type. Since this + class doesn't subclass a concrete type, there's no + implementation to fall back to, so we need to try as + hard as possible to return an actual value, or the user + will get a TypeError. + + """ + def forward(a, b): + if isinstance(b, (int, long, Fraction)): + return monomorphic_operator(a, b) + elif isinstance(b, float): + return fallback_operator(float(a), b) + elif isinstance(b, complex): + return fallback_operator(complex(a), b) + else: + return NotImplemented + forward.__name__ = '__' + fallback_operator.__name__ + '__' + forward.__doc__ = monomorphic_operator.__doc__ + + def reverse(b, a): + if isinstance(a, Rational): + # Includes ints. + return monomorphic_operator(a, b) + elif isinstance(a, numbers.Real): + return fallback_operator(float(a), float(b)) + elif isinstance(a, numbers.Complex): + return fallback_operator(complex(a), complex(b)) + else: + return NotImplemented + reverse.__name__ = '__r' + fallback_operator.__name__ + '__' + reverse.__doc__ = monomorphic_operator.__doc__ + + return forward, reverse + + def _add(a, b): + """a + b""" + return Fraction(a.numerator * b.denominator + + b.numerator * a.denominator, + a.denominator * b.denominator) + + __add__, __radd__ = _operator_fallbacks(_add, operator.add) + + def _sub(a, b): + """a - b""" + return Fraction(a.numerator * b.denominator - + b.numerator * a.denominator, + a.denominator * b.denominator) + + __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) + + def _mul(a, b): + """a * b""" + return Fraction(a.numerator * b.numerator, a.denominator * b.denominator) + + __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul) + + def _div(a, b): + """a / b""" + return Fraction(a.numerator * b.denominator, + a.denominator * b.numerator) + + __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) + __div__, __rdiv__ = _operator_fallbacks(_div, operator.div) + + def __floordiv__(a, b): + """a // b""" + # Will be math.floor(a / b) in 3.0. + div = a / b + if isinstance(div, Rational): + # trunc(math.floor(div)) doesn't work if the rational is + # more precise than a float because the intermediate + # rounding may cross an integer boundary. + return div.numerator // div.denominator + else: + return math.floor(div) + + def __rfloordiv__(b, a): + """a // b""" + # Will be math.floor(a / b) in 3.0. + div = a / b + if isinstance(div, Rational): + # trunc(math.floor(div)) doesn't work if the rational is + # more precise than a float because the intermediate + # rounding may cross an integer boundary. + return div.numerator // div.denominator + else: + return math.floor(div) + + def __mod__(a, b): + """a % b""" + div = a // b + return a - b * div + + def __rmod__(b, a): + """a % b""" + div = a // b + return a - b * div + + def __pow__(a, b): + """a ** b + + If b is not an integer, the result will be a float or complex + since roots are generally irrational. If b is an integer, the + result will be rational. + + """ + if isinstance(b, Rational): + if b.denominator == 1: + power = b.numerator + if power >= 0: + return Fraction(a._numerator ** power, + a._denominator ** power) + else: + return Fraction(a._denominator ** -power, + a._numerator ** -power) + else: + # A fractional power will generally produce an + # irrational number. + return float(a) ** float(b) + else: + return float(a) ** b + + def __rpow__(b, a): + """a ** b""" + if b._denominator == 1 and b._numerator >= 0: + # If a is an int, keep it that way if possible. + return a ** b._numerator + + if isinstance(a, Rational): + return Fraction(a.numerator, a.denominator) ** b + + if b._denominator == 1: + return a ** b._numerator + + return a ** float(b) + + def __pos__(a): + """+a: Coerces a subclass instance to Fraction""" + return Fraction(a._numerator, a._denominator) + + def __neg__(a): + """-a""" + return Fraction(-a._numerator, a._denominator) + + def __abs__(a): + """abs(a)""" + return Fraction(abs(a._numerator), a._denominator) + + def __trunc__(a): + """trunc(a)""" + if a._numerator < 0: + return -(-a._numerator // a._denominator) + else: + return a._numerator // a._denominator + + def __hash__(self): + """hash(self) + + Tricky because values that are exactly representable as a + float must have the same hash as that float. + + """ + # XXX since this method is expensive, consider caching the result + if self._denominator == 1: + # Get integers right. + return hash(self._numerator) + # Expensive check, but definitely correct. + if self == float(self): + return hash(float(self)) + else: + # Use tuple's hash to avoid a high collision rate on + # simple fractions. + return hash((self._numerator, self._denominator)) + + def __eq__(a, b): + """a == b""" + if isinstance(b, Rational): + return (a._numerator == b.numerator and + a._denominator == b.denominator) + if isinstance(b, numbers.Complex) and b.imag == 0: + b = b.real + if isinstance(b, float): + if math.isnan(b) or math.isinf(b): + # comparisons with an infinity or nan should behave in + # the same way for any finite a, so treat a as zero. + return 0.0 == b + else: + return a == a.from_float(b) + else: + # Since a doesn't know how to compare with b, let's give b + # a chance to compare itself with a. + return NotImplemented + + def _richcmp(self, other, op): + """Helper for comparison operators, for internal use only. + + Implement comparison between a Rational instance `self`, and + either another Rational instance or a float `other`. If + `other` is not a Rational instance or a float, return + NotImplemented. `op` should be one of the six standard + comparison operators. + + """ + # convert other to a Rational instance where reasonable. + if isinstance(other, Rational): + return op(self._numerator * other.denominator, + self._denominator * other.numerator) + # comparisons with complex should raise a TypeError, for consistency + # with int<->complex, float<->complex, and complex<->complex comparisons. + if isinstance(other, complex): + raise TypeError("no ordering relation is defined for complex numbers") + if isinstance(other, float): + if math.isnan(other) or math.isinf(other): + return op(0.0, other) + else: + return op(self, self.from_float(other)) + else: + return NotImplemented + + def __lt__(a, b): + """a < b""" + return a._richcmp(b, operator.lt) + + def __gt__(a, b): + """a > b""" + return a._richcmp(b, operator.gt) + + def __le__(a, b): + """a <= b""" + return a._richcmp(b, operator.le) + + def __ge__(a, b): + """a >= b""" + return a._richcmp(b, operator.ge) + + def __nonzero__(a): + """a != 0""" + return a._numerator != 0 + + # support for pickling, copy, and deepcopy + + def __reduce__(self): + return (self.__class__, (str(self),)) + + def __copy__(self): + if type(self) == Fraction: + return self # I'm immutable; therefore I am my own clone + return self.__class__(self._numerator, self._denominator) + + def __deepcopy__(self, memo): + if type(self) == Fraction: + return self # My components are also immutable + return self.__class__(self._numerator, self._denominator) diff --git a/src/main/resources/PythonLibs/ftplib.py b/src/main/resources/PythonLibs/ftplib.py new file mode 100644 index 0000000000000000000000000000000000000000..2305cf8aeb1e3e899220230ebe38b15b22a5ff4d --- /dev/null +++ b/src/main/resources/PythonLibs/ftplib.py @@ -0,0 +1,1047 @@ +"""An FTP client class and some helper functions. + +Based on RFC 959: File Transfer Protocol (FTP), by J. Postel and J. Reynolds + +Example: + +>>> from ftplib import FTP +>>> ftp = FTP('ftp.python.org') # connect to host, default port +>>> ftp.login() # default, i.e.: user anonymous, passwd anonymous@ +'230 Guest login ok, access restrictions apply.' +>>> ftp.retrlines('LIST') # list directory contents +total 9 +drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . +drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. +drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin +drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc +d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming +drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib +drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub +drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr +-rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg +'226 Transfer complete.' +>>> ftp.quit() +'221 Goodbye.' +>>> + +A nice test that reveals some of the network dialogue would be: +python ftplib.py -d localhost -l -p -l +""" + +# +# Changes and improvements suggested by Steve Majewski. +# Modified by Jack to work on the mac. +# Modified by Siebren to support docstrings and PASV. +# Modified by Phil Schwartz to add storbinary and storlines callbacks. +# Modified by Giampaolo Rodola' to add TLS support. +# + +import os +import sys + +# Import SOCKS module if it exists, else standard socket module socket +try: + import SOCKS; socket = SOCKS; del SOCKS # import SOCKS as socket + from socket import getfqdn; socket.getfqdn = getfqdn; del getfqdn +except ImportError: + import socket +from socket import _GLOBAL_DEFAULT_TIMEOUT + +__all__ = ["FTP","Netrc"] + +# Magic number from <socket.h> +MSG_OOB = 0x1 # Process data out of band + + +# The standard FTP server control port +FTP_PORT = 21 + + +# Exception raised when an error or invalid response is received +class Error(Exception): pass +class error_reply(Error): pass # unexpected [123]xx reply +class error_temp(Error): pass # 4xx errors +class error_perm(Error): pass # 5xx errors +class error_proto(Error): pass # response does not begin with [1-5] + + +# All exceptions (hopefully) that may be raised here and that aren't +# (always) programming errors on our side +all_errors = (Error, IOError, EOFError) + + +# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF) +CRLF = '\r\n' + +# The class itself +class FTP: + + '''An FTP client class. + + To create a connection, call the class using these arguments: + host, user, passwd, acct, timeout + + The first four arguments are all strings, and have default value ''. + timeout must be numeric and defaults to None if not passed, + meaning that no timeout will be set on any ftp socket(s) + If a timeout is passed, then this is now the default timeout for all ftp + socket operations for this instance. + + Then use self.connect() with optional host and port argument. + + To download a file, use ftp.retrlines('RETR ' + filename), + or ftp.retrbinary() with slightly different arguments. + To upload a file, use ftp.storlines() or ftp.storbinary(), + which have an open file as argument (see their definitions + below for details). + The download/upload functions first issue appropriate TYPE + and PORT or PASV commands. +''' + + debugging = 0 + host = '' + port = FTP_PORT + sock = None + file = None + welcome = None + passiveserver = 1 + + # Initialization method (called by class instantiation). + # Initialize host to localhost, port to standard ftp port + # Optional arguments are host (for connect()), + # and user, passwd, acct (for login()) + def __init__(self, host='', user='', passwd='', acct='', + timeout=_GLOBAL_DEFAULT_TIMEOUT): + self.timeout = timeout + if host: + self.connect(host) + if user: + self.login(user, passwd, acct) + + def connect(self, host='', port=0, timeout=-999): + '''Connect to host. Arguments are: + - host: hostname to connect to (string, default previous host) + - port: port to connect to (integer, default previous port) + ''' + if host != '': + self.host = host + if port > 0: + self.port = port + if timeout != -999: + self.timeout = timeout + self.sock = socket.create_connection((self.host, self.port), self.timeout) + self.af = self.sock.family + self.file = self.sock.makefile('rb') + self.welcome = self.getresp() + return self.welcome + + def getwelcome(self): + '''Get the welcome message from the server. + (this is read and squirreled away by connect())''' + if self.debugging: + print '*welcome*', self.sanitize(self.welcome) + return self.welcome + + def set_debuglevel(self, level): + '''Set the debugging level. + The required argument level means: + 0: no debugging output (default) + 1: print commands and responses but not body text etc. + 2: also print raw lines read and sent before stripping CR/LF''' + self.debugging = level + debug = set_debuglevel + + def set_pasv(self, val): + '''Use passive or active mode for data transfers. + With a false argument, use the normal PORT mode, + With a true argument, use the PASV command.''' + self.passiveserver = val + + # Internal: "sanitize" a string for printing + def sanitize(self, s): + if s[:5] == 'pass ' or s[:5] == 'PASS ': + i = len(s) + while i > 5 and s[i-1] in '\r\n': + i = i-1 + s = s[:5] + '*'*(i-5) + s[i:] + return repr(s) + + # Internal: send one line to the server, appending CRLF + def putline(self, line): + line = line + CRLF + if self.debugging > 1: print '*put*', self.sanitize(line) + self.sock.sendall(line) + + # Internal: send one command to the server (through putline()) + def putcmd(self, line): + if self.debugging: print '*cmd*', self.sanitize(line) + self.putline(line) + + # Internal: return one line from the server, stripping CRLF. + # Raise EOFError if the connection is closed + def getline(self): + line = self.file.readline() + if self.debugging > 1: + print '*get*', self.sanitize(line) + if not line: raise EOFError + if line[-2:] == CRLF: line = line[:-2] + elif line[-1:] in CRLF: line = line[:-1] + return line + + # Internal: get a response from the server, which may possibly + # consist of multiple lines. Return a single string with no + # trailing CRLF. If the response consists of multiple lines, + # these are separated by '\n' characters in the string + def getmultiline(self): + line = self.getline() + if line[3:4] == '-': + code = line[:3] + while 1: + nextline = self.getline() + line = line + ('\n' + nextline) + if nextline[:3] == code and \ + nextline[3:4] != '-': + break + return line + + # Internal: get a response from the server. + # Raise various errors if the response indicates an error + def getresp(self): + resp = self.getmultiline() + if self.debugging: print '*resp*', self.sanitize(resp) + self.lastresp = resp[:3] + c = resp[:1] + if c in ('1', '2', '3'): + return resp + if c == '4': + raise error_temp, resp + if c == '5': + raise error_perm, resp + raise error_proto, resp + + def voidresp(self): + """Expect a response beginning with '2'.""" + resp = self.getresp() + if resp[:1] != '2': + raise error_reply, resp + return resp + + def abort(self): + '''Abort a file transfer. Uses out-of-band data. + This does not follow the procedure from the RFC to send Telnet + IP and Synch; that doesn't seem to work with the servers I've + tried. Instead, just send the ABOR command as OOB data.''' + line = 'ABOR' + CRLF + if self.debugging > 1: print '*put urgent*', self.sanitize(line) + self.sock.sendall(line, MSG_OOB) + resp = self.getmultiline() + if resp[:3] not in ('426', '225', '226'): + raise error_proto, resp + + def sendcmd(self, cmd): + '''Send a command and return the response.''' + self.putcmd(cmd) + return self.getresp() + + def voidcmd(self, cmd): + """Send a command and expect a response beginning with '2'.""" + self.putcmd(cmd) + return self.voidresp() + + def sendport(self, host, port): + '''Send a PORT command with the current host and the given + port number. + ''' + hbytes = host.split('.') + pbytes = [repr(port//256), repr(port%256)] + bytes = hbytes + pbytes + cmd = 'PORT ' + ','.join(bytes) + return self.voidcmd(cmd) + + def sendeprt(self, host, port): + '''Send a EPRT command with the current host and the given port number.''' + af = 0 + if self.af == socket.AF_INET: + af = 1 + if self.af == socket.AF_INET6: + af = 2 + if af == 0: + raise error_proto, 'unsupported address family' + fields = ['', repr(af), host, repr(port), ''] + cmd = 'EPRT ' + '|'.join(fields) + return self.voidcmd(cmd) + + def makeport(self): + '''Create a new socket and send a PORT command for it.''' + err = None + sock = None + for res in socket.getaddrinfo(None, 0, self.af, socket.SOCK_STREAM, 0, socket.AI_PASSIVE): + af, socktype, proto, canonname, sa = res + try: + sock = socket.socket(af, socktype, proto) + sock.bind(sa) + except socket.error, err: + if sock: + sock.close() + sock = None + continue + break + if sock is None: + if err is not None: + raise err + else: + raise socket.error("getaddrinfo returns an empty list") + sock.listen(1) + port = sock.getsockname()[1] # Get proper port + host = self.sock.getsockname()[0] # Get proper host + if self.af == socket.AF_INET: + resp = self.sendport(host, port) + else: + resp = self.sendeprt(host, port) + if self.timeout is not _GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(self.timeout) + return sock + + def makepasv(self): + if self.af == socket.AF_INET: + host, port = parse227(self.sendcmd('PASV')) + else: + host, port = parse229(self.sendcmd('EPSV'), self.sock.getpeername()) + return host, port + + def ntransfercmd(self, cmd, rest=None): + """Initiate a transfer over the data connection. + + If the transfer is active, send a port command and the + transfer command, and accept the connection. If the server is + passive, send a pasv command, connect to it, and start the + transfer command. Either way, return the socket for the + connection and the expected size of the transfer. The + expected size may be None if it could not be determined. + + Optional `rest' argument can be a string that is sent as the + argument to a REST command. This is essentially a server + marker used to tell the server to skip over any data up to the + given marker. + """ + size = None + if self.passiveserver: + host, port = self.makepasv() + conn = socket.create_connection((host, port), self.timeout) + try: + if rest is not None: + self.sendcmd("REST %s" % rest) + resp = self.sendcmd(cmd) + # Some servers apparently send a 200 reply to + # a LIST or STOR command, before the 150 reply + # (and way before the 226 reply). This seems to + # be in violation of the protocol (which only allows + # 1xx or error messages for LIST), so we just discard + # this response. + if resp[0] == '2': + resp = self.getresp() + if resp[0] != '1': + raise error_reply, resp + except: + conn.close() + raise + else: + sock = self.makeport() + try: + if rest is not None: + self.sendcmd("REST %s" % rest) + resp = self.sendcmd(cmd) + # See above. + if resp[0] == '2': + resp = self.getresp() + if resp[0] != '1': + raise error_reply, resp + conn, sockaddr = sock.accept() + if self.timeout is not _GLOBAL_DEFAULT_TIMEOUT: + conn.settimeout(self.timeout) + finally: + sock.close() + if resp[:3] == '150': + # this is conditional in case we received a 125 + size = parse150(resp) + return conn, size + + def transfercmd(self, cmd, rest=None): + """Like ntransfercmd() but returns only the socket.""" + return self.ntransfercmd(cmd, rest)[0] + + def login(self, user = '', passwd = '', acct = ''): + '''Login, default anonymous.''' + if not user: user = 'anonymous' + if not passwd: passwd = '' + if not acct: acct = '' + if user == 'anonymous' and passwd in ('', '-'): + # If there is no anonymous ftp password specified + # then we'll just use anonymous@ + # We don't send any other thing because: + # - We want to remain anonymous + # - We want to stop SPAM + # - We don't want to let ftp sites to discriminate by the user, + # host or country. + passwd = passwd + 'anonymous@' + resp = self.sendcmd('USER ' + user) + if resp[0] == '3': resp = self.sendcmd('PASS ' + passwd) + if resp[0] == '3': resp = self.sendcmd('ACCT ' + acct) + if resp[0] != '2': + raise error_reply, resp + return resp + + def retrbinary(self, cmd, callback, blocksize=8192, rest=None): + """Retrieve data in binary mode. A new port is created for you. + + Args: + cmd: A RETR command. + callback: A single parameter callable to be called on each + block of data read. + blocksize: The maximum number of bytes to read from the + socket at one time. [default: 8192] + rest: Passed to transfercmd(). [default: None] + + Returns: + The response code. + """ + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd, rest) + while 1: + data = conn.recv(blocksize) + if not data: + break + callback(data) + conn.close() + return self.voidresp() + + def retrlines(self, cmd, callback = None): + """Retrieve data in line mode. A new port is created for you. + + Args: + cmd: A RETR, LIST, NLST, or MLSD command. + callback: An optional single parameter callable that is called + for each line with the trailing CRLF stripped. + [default: print_line()] + + Returns: + The response code. + """ + if callback is None: callback = print_line + resp = self.sendcmd('TYPE A') + conn = self.transfercmd(cmd) + fp = conn.makefile('rb') + while 1: + line = fp.readline() + if self.debugging > 2: print '*retr*', repr(line) + if not line: + break + if line[-2:] == CRLF: + line = line[:-2] + elif line[-1:] == '\n': + line = line[:-1] + callback(line) + fp.close() + conn.close() + return self.voidresp() + + def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None): + """Store a file in binary mode. A new port is created for you. + + Args: + cmd: A STOR command. + fp: A file-like object with a read(num_bytes) method. + blocksize: The maximum data size to read from fp and send over + the connection at once. [default: 8192] + callback: An optional single parameter callable that is called on + on each block of data after it is sent. [default: None] + rest: Passed to transfercmd(). [default: None] + + Returns: + The response code. + """ + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd, rest) + while 1: + buf = fp.read(blocksize) + if not buf: break + conn.sendall(buf) + if callback: callback(buf) + conn.close() + return self.voidresp() + + def storlines(self, cmd, fp, callback=None): + """Store a file in line mode. A new port is created for you. + + Args: + cmd: A STOR command. + fp: A file-like object with a readline() method. + callback: An optional single parameter callable that is called on + on each line after it is sent. [default: None] + + Returns: + The response code. + """ + self.voidcmd('TYPE A') + conn = self.transfercmd(cmd) + while 1: + buf = fp.readline() + if not buf: break + if buf[-2:] != CRLF: + if buf[-1] in CRLF: buf = buf[:-1] + buf = buf + CRLF + conn.sendall(buf) + if callback: callback(buf) + conn.close() + return self.voidresp() + + def acct(self, password): + '''Send new account name.''' + cmd = 'ACCT ' + password + return self.voidcmd(cmd) + + def nlst(self, *args): + '''Return a list of files in a given directory (default the current).''' + cmd = 'NLST' + for arg in args: + cmd = cmd + (' ' + arg) + files = [] + self.retrlines(cmd, files.append) + return files + + def dir(self, *args): + '''List a directory in long form. + By default list current directory to stdout. + Optional last argument is callback function; all + non-empty arguments before it are concatenated to the + LIST command. (This *should* only be used for a pathname.)''' + cmd = 'LIST' + func = None + if args[-1:] and type(args[-1]) != type(''): + args, func = args[:-1], args[-1] + for arg in args: + if arg: + cmd = cmd + (' ' + arg) + self.retrlines(cmd, func) + + def rename(self, fromname, toname): + '''Rename a file.''' + resp = self.sendcmd('RNFR ' + fromname) + if resp[0] != '3': + raise error_reply, resp + return self.voidcmd('RNTO ' + toname) + + def delete(self, filename): + '''Delete a file.''' + resp = self.sendcmd('DELE ' + filename) + if resp[:3] in ('250', '200'): + return resp + else: + raise error_reply, resp + + def cwd(self, dirname): + '''Change to a directory.''' + if dirname == '..': + try: + return self.voidcmd('CDUP') + except error_perm, msg: + if msg.args[0][:3] != '500': + raise + elif dirname == '': + dirname = '.' # does nothing, but could return error + cmd = 'CWD ' + dirname + return self.voidcmd(cmd) + + def size(self, filename): + '''Retrieve the size of a file.''' + # The SIZE command is defined in RFC-3659 + resp = self.sendcmd('SIZE ' + filename) + if resp[:3] == '213': + s = resp[3:].strip() + try: + return int(s) + except (OverflowError, ValueError): + return long(s) + + def mkd(self, dirname): + '''Make a directory, return its full pathname.''' + resp = self.sendcmd('MKD ' + dirname) + return parse257(resp) + + def rmd(self, dirname): + '''Remove a directory.''' + return self.voidcmd('RMD ' + dirname) + + def pwd(self): + '''Return current working directory.''' + resp = self.sendcmd('PWD') + return parse257(resp) + + def quit(self): + '''Quit, and close the connection.''' + resp = self.voidcmd('QUIT') + self.close() + return resp + + def close(self): + '''Close the connection without assuming anything about it.''' + if self.file is not None: + self.file.close() + if self.sock is not None: + self.sock.close() + self.file = self.sock = None + +try: + import ssl + ssl.PROTOCOL_TLSv1 +except (ImportError, AttributeError): + pass +else: + class FTP_TLS(FTP): + '''A FTP subclass which adds TLS support to FTP as described + in RFC-4217. + + Connect as usual to port 21 implicitly securing the FTP control + connection before authenticating. + + Securing the data connection requires user to explicitly ask + for it by calling prot_p() method. + + Usage example: + >>> from ftplib import FTP_TLS + >>> ftps = FTP_TLS('ftp.python.org') + >>> ftps.login() # login anonymously previously securing control channel + '230 Guest login ok, access restrictions apply.' + >>> ftps.prot_p() # switch to secure data connection + '200 Protection level set to P' + >>> ftps.retrlines('LIST') # list directory content securely + total 9 + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . + drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin + drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc + d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming + drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib + drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub + drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr + -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg + '226 Transfer complete.' + >>> ftps.quit() + '221 Goodbye.' + >>> + ''' + ssl_version = ssl.PROTOCOL_TLSv1 + + def __init__(self, host='', user='', passwd='', acct='', keyfile=None, + certfile=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): + self.keyfile = keyfile + self.certfile = certfile + self._prot_p = False + FTP.__init__(self, host, user, passwd, acct, timeout) + + def login(self, user='', passwd='', acct='', secure=True): + if secure and not isinstance(self.sock, ssl.SSLSocket): + self.auth() + return FTP.login(self, user, passwd, acct) + + def auth(self): + '''Set up secure control connection by using TLS/SSL.''' + if isinstance(self.sock, ssl.SSLSocket): + raise ValueError("Already using TLS") + if self.ssl_version == ssl.PROTOCOL_TLSv1: + resp = self.voidcmd('AUTH TLS') + else: + resp = self.voidcmd('AUTH SSL') + self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + self.file = self.sock.makefile(mode='rb') + return resp + + def prot_p(self): + '''Set up secure data connection.''' + # PROT defines whether or not the data channel is to be protected. + # Though RFC-2228 defines four possible protection levels, + # RFC-4217 only recommends two, Clear and Private. + # Clear (PROT C) means that no security is to be used on the + # data-channel, Private (PROT P) means that the data-channel + # should be protected by TLS. + # PBSZ command MUST still be issued, but must have a parameter of + # '0' to indicate that no buffering is taking place and the data + # connection should not be encapsulated. + self.voidcmd('PBSZ 0') + resp = self.voidcmd('PROT P') + self._prot_p = True + return resp + + def prot_c(self): + '''Set up clear text data connection.''' + resp = self.voidcmd('PROT C') + self._prot_p = False + return resp + + # --- Overridden FTP methods + + def ntransfercmd(self, cmd, rest=None): + conn, size = FTP.ntransfercmd(self, cmd, rest) + if self._prot_p: + conn = ssl.wrap_socket(conn, self.keyfile, self.certfile, + ssl_version=self.ssl_version) + return conn, size + + def retrbinary(self, cmd, callback, blocksize=8192, rest=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd, rest) + try: + while 1: + data = conn.recv(blocksize) + if not data: + break + callback(data) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def retrlines(self, cmd, callback = None): + if callback is None: callback = print_line + resp = self.sendcmd('TYPE A') + conn = self.transfercmd(cmd) + fp = conn.makefile('rb') + try: + while 1: + line = fp.readline() + if self.debugging > 2: print '*retr*', repr(line) + if not line: + break + if line[-2:] == CRLF: + line = line[:-2] + elif line[-1:] == '\n': + line = line[:-1] + callback(line) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + fp.close() + conn.close() + return self.voidresp() + + def storbinary(self, cmd, fp, blocksize=8192, callback=None, rest=None): + self.voidcmd('TYPE I') + conn = self.transfercmd(cmd, rest) + try: + while 1: + buf = fp.read(blocksize) + if not buf: break + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + def storlines(self, cmd, fp, callback=None): + self.voidcmd('TYPE A') + conn = self.transfercmd(cmd) + try: + while 1: + buf = fp.readline() + if not buf: break + if buf[-2:] != CRLF: + if buf[-1] in CRLF: buf = buf[:-1] + buf = buf + CRLF + conn.sendall(buf) + if callback: callback(buf) + # shutdown ssl layer + if isinstance(conn, ssl.SSLSocket): + conn.unwrap() + finally: + conn.close() + return self.voidresp() + + __all__.append('FTP_TLS') + all_errors = (Error, IOError, EOFError, ssl.SSLError) + + +_150_re = None + +def parse150(resp): + '''Parse the '150' response for a RETR request. + Returns the expected transfer size or None; size is not guaranteed to + be present in the 150 message. + ''' + if resp[:3] != '150': + raise error_reply, resp + global _150_re + if _150_re is None: + import re + _150_re = re.compile("150 .* \((\d+) bytes\)", re.IGNORECASE) + m = _150_re.match(resp) + if not m: + return None + s = m.group(1) + try: + return int(s) + except (OverflowError, ValueError): + return long(s) + + +_227_re = None + +def parse227(resp): + '''Parse the '227' response for a PASV request. + Raises error_proto if it does not contain '(h1,h2,h3,h4,p1,p2)' + Return ('host.addr.as.numbers', port#) tuple.''' + + if resp[:3] != '227': + raise error_reply, resp + global _227_re + if _227_re is None: + import re + _227_re = re.compile(r'(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)') + m = _227_re.search(resp) + if not m: + raise error_proto, resp + numbers = m.groups() + host = '.'.join(numbers[:4]) + port = (int(numbers[4]) << 8) + int(numbers[5]) + return host, port + + +def parse229(resp, peer): + '''Parse the '229' response for a EPSV request. + Raises error_proto if it does not contain '(|||port|)' + Return ('host.addr.as.numbers', port#) tuple.''' + + if resp[:3] != '229': + raise error_reply, resp + left = resp.find('(') + if left < 0: raise error_proto, resp + right = resp.find(')', left + 1) + if right < 0: + raise error_proto, resp # should contain '(|||port|)' + if resp[left + 1] != resp[right - 1]: + raise error_proto, resp + parts = resp[left + 1:right].split(resp[left+1]) + if len(parts) != 5: + raise error_proto, resp + host = peer[0] + port = int(parts[3]) + return host, port + + +def parse257(resp): + '''Parse the '257' response for a MKD or PWD request. + This is a response to a MKD or PWD request: a directory name. + Returns the directoryname in the 257 reply.''' + + if resp[:3] != '257': + raise error_reply, resp + if resp[3:5] != ' "': + return '' # Not compliant to RFC 959, but UNIX ftpd does this + dirname = '' + i = 5 + n = len(resp) + while i < n: + c = resp[i] + i = i+1 + if c == '"': + if i >= n or resp[i] != '"': + break + i = i+1 + dirname = dirname + c + return dirname + + +def print_line(line): + '''Default retrlines callback to print a line.''' + print line + + +def ftpcp(source, sourcename, target, targetname = '', type = 'I'): + '''Copy file from one FTP-instance to another.''' + if not targetname: targetname = sourcename + type = 'TYPE ' + type + source.voidcmd(type) + target.voidcmd(type) + sourcehost, sourceport = parse227(source.sendcmd('PASV')) + target.sendport(sourcehost, sourceport) + # RFC 959: the user must "listen" [...] BEFORE sending the + # transfer request. + # So: STOR before RETR, because here the target is a "user". + treply = target.sendcmd('STOR ' + targetname) + if treply[:3] not in ('125', '150'): raise error_proto # RFC 959 + sreply = source.sendcmd('RETR ' + sourcename) + if sreply[:3] not in ('125', '150'): raise error_proto # RFC 959 + source.voidresp() + target.voidresp() + + +class Netrc: + """Class to parse & provide access to 'netrc' format files. + + See the netrc(4) man page for information on the file format. + + WARNING: This class is obsolete -- use module netrc instead. + + """ + __defuser = None + __defpasswd = None + __defacct = None + + def __init__(self, filename=None): + if filename is None: + if "HOME" in os.environ: + filename = os.path.join(os.environ["HOME"], + ".netrc") + else: + raise IOError, \ + "specify file to load or set $HOME" + self.__hosts = {} + self.__macros = {} + fp = open(filename, "r") + in_macro = 0 + while 1: + line = fp.readline() + if not line: break + if in_macro and line.strip(): + macro_lines.append(line) + continue + elif in_macro: + self.__macros[macro_name] = tuple(macro_lines) + in_macro = 0 + words = line.split() + host = user = passwd = acct = None + default = 0 + i = 0 + while i < len(words): + w1 = words[i] + if i+1 < len(words): + w2 = words[i + 1] + else: + w2 = None + if w1 == 'default': + default = 1 + elif w1 == 'machine' and w2: + host = w2.lower() + i = i + 1 + elif w1 == 'login' and w2: + user = w2 + i = i + 1 + elif w1 == 'password' and w2: + passwd = w2 + i = i + 1 + elif w1 == 'account' and w2: + acct = w2 + i = i + 1 + elif w1 == 'macdef' and w2: + macro_name = w2 + macro_lines = [] + in_macro = 1 + break + i = i + 1 + if default: + self.__defuser = user or self.__defuser + self.__defpasswd = passwd or self.__defpasswd + self.__defacct = acct or self.__defacct + if host: + if host in self.__hosts: + ouser, opasswd, oacct = \ + self.__hosts[host] + user = user or ouser + passwd = passwd or opasswd + acct = acct or oacct + self.__hosts[host] = user, passwd, acct + fp.close() + + def get_hosts(self): + """Return a list of hosts mentioned in the .netrc file.""" + return self.__hosts.keys() + + def get_account(self, host): + """Returns login information for the named host. + + The return value is a triple containing userid, + password, and the accounting field. + + """ + host = host.lower() + user = passwd = acct = None + if host in self.__hosts: + user, passwd, acct = self.__hosts[host] + user = user or self.__defuser + passwd = passwd or self.__defpasswd + acct = acct or self.__defacct + return user, passwd, acct + + def get_macros(self): + """Return a list of all defined macro names.""" + return self.__macros.keys() + + def get_macro(self, macro): + """Return a sequence of lines which define a named macro.""" + return self.__macros[macro] + + + +def test(): + '''Test program. + Usage: ftp [-d] [-r[file]] host [-l[dir]] [-d[dir]] [-p] [file] ... + + -d dir + -l list + -p password + ''' + + if len(sys.argv) < 2: + print test.__doc__ + sys.exit(0) + + debugging = 0 + rcfile = None + while sys.argv[1] == '-d': + debugging = debugging+1 + del sys.argv[1] + if sys.argv[1][:2] == '-r': + # get name of alternate ~/.netrc file: + rcfile = sys.argv[1][2:] + del sys.argv[1] + host = sys.argv[1] + ftp = FTP(host) + ftp.set_debuglevel(debugging) + userid = passwd = acct = '' + try: + netrc = Netrc(rcfile) + except IOError: + if rcfile is not None: + sys.stderr.write("Could not open account file" + " -- using anonymous login.") + else: + try: + userid, passwd, acct = netrc.get_account(host) + except KeyError: + # no account for host + sys.stderr.write( + "No account -- using anonymous login.") + ftp.login(userid, passwd, acct) + for file in sys.argv[2:]: + if file[:2] == '-l': + ftp.dir(file[2:]) + elif file[:2] == '-d': + cmd = 'CWD' + if file[2:]: cmd = cmd + ' ' + file[2:] + resp = ftp.sendcmd(cmd) + elif file == '-p': + ftp.set_pasv(not ftp.passiveserver) + else: + ftp.retrbinary('RETR ' + file, \ + sys.stdout.write, 1024) + ftp.quit() + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/functools.py b/src/main/resources/PythonLibs/functools.py new file mode 100644 index 0000000000000000000000000000000000000000..53680b894660774d5c460c0198221d9444d23923 --- /dev/null +++ b/src/main/resources/PythonLibs/functools.py @@ -0,0 +1,100 @@ +"""functools.py - Tools for working with functions and callable objects +""" +# Python module wrapper for _functools C module +# to allow utilities written in Python to be added +# to the functools module. +# Written by Nick Coghlan <ncoghlan at gmail.com> +# Copyright (C) 2006 Python Software Foundation. +# See C source code for _functools credits/copyright + +from _functools import partial, reduce + +# update_wrapper() and wraps() are tools to help write +# wrapper functions that can handle naive introspection + +WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__') +WRAPPER_UPDATES = ('__dict__',) +def update_wrapper(wrapper, + wrapped, + assigned = WRAPPER_ASSIGNMENTS, + updated = WRAPPER_UPDATES): + """Update a wrapper function to look like the wrapped function + + wrapper is the function to be updated + wrapped is the original function + assigned is a tuple naming the attributes assigned directly + from the wrapped function to the wrapper function (defaults to + functools.WRAPPER_ASSIGNMENTS) + updated is a tuple naming the attributes of the wrapper that + are updated with the corresponding attribute from the wrapped + function (defaults to functools.WRAPPER_UPDATES) + """ + for attr in assigned: + setattr(wrapper, attr, getattr(wrapped, attr)) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + # Return the wrapper so this can be used as a decorator via partial() + return wrapper + +def wraps(wrapped, + assigned = WRAPPER_ASSIGNMENTS, + updated = WRAPPER_UPDATES): + """Decorator factory to apply update_wrapper() to a wrapper function + + Returns a decorator that invokes update_wrapper() with the decorated + function as the wrapper argument and the arguments to wraps() as the + remaining arguments. Default arguments are as for update_wrapper(). + This is a convenience function to simplify applying partial() to + update_wrapper(). + """ + return partial(update_wrapper, wrapped=wrapped, + assigned=assigned, updated=updated) + +def total_ordering(cls): + """Class decorator that fills in missing ordering methods""" + convert = { + '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)), + ('__le__', lambda self, other: self < other or self == other), + ('__ge__', lambda self, other: not self < other)], + '__le__': [('__ge__', lambda self, other: not self <= other or self == other), + ('__lt__', lambda self, other: self <= other and not self == other), + ('__gt__', lambda self, other: not self <= other)], + '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)), + ('__ge__', lambda self, other: self > other or self == other), + ('__le__', lambda self, other: not self > other)], + '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other), + ('__gt__', lambda self, other: self >= other and not self == other), + ('__lt__', lambda self, other: not self >= other)] + } + roots = set(dir(cls)) & set(convert) + if not roots: + raise ValueError('must define at least one ordering operation: < > <= >=') + root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__ + for opname, opfunc in convert[root]: + if opname not in roots: + opfunc.__name__ = opname + opfunc.__doc__ = getattr(int, opname).__doc__ + setattr(cls, opname, opfunc) + return cls + +def cmp_to_key(mycmp): + """Convert a cmp= function into a key= function""" + class K(object): + __slots__ = ['obj'] + def __init__(self, obj, *args): + self.obj = obj + def __lt__(self, other): + return mycmp(self.obj, other.obj) < 0 + def __gt__(self, other): + return mycmp(self.obj, other.obj) > 0 + def __eq__(self, other): + return mycmp(self.obj, other.obj) == 0 + def __le__(self, other): + return mycmp(self.obj, other.obj) <= 0 + def __ge__(self, other): + return mycmp(self.obj, other.obj) >= 0 + def __ne__(self, other): + return mycmp(self.obj, other.obj) != 0 + def __hash__(self): + raise TypeError('hash not implemented') + return K diff --git a/src/main/resources/PythonLibs/future_builtins.py b/src/main/resources/PythonLibs/future_builtins.py new file mode 100644 index 0000000000000000000000000000000000000000..9a90591f962ce6ee19c69c17b30ed077fb2fd48b --- /dev/null +++ b/src/main/resources/PythonLibs/future_builtins.py @@ -0,0 +1,33 @@ +"""This module provides functions that will be builtins in Python 3.0, +but that conflict with builtins that already exist in Python 2.x. + +Functions: + +hex(arg) -- Returns the hexadecimal representation of an integer +oct(arg) -- Returns the octal representation of an integer +ascii(arg) -- Same as repr(arg) +map, filter, zip -- Same as itertools.imap, ifilter, izip + +The typical usage of this module is to replace existing builtins in a +module's namespace: + +from future_builtins import hex, oct +""" + +__all__ = ['hex', 'oct', 'ascii', 'map', 'filter', 'zip'] + +from itertools import imap as map, ifilter as filter, izip as zip + +ascii = repr +_builtin_hex = hex +_builtin_oct = oct + +def hex(arg): + return _builtin_hex(arg).rstrip('L') + +def oct(arg): + result = _builtin_oct(arg).rstrip('L') + if result == '0': + return '0o0' + i = result.index('0') + 1 + return result[:i] + 'o' + result[i:] diff --git a/src/main/resources/PythonLibs/genericpath.py b/src/main/resources/PythonLibs/genericpath.py new file mode 100644 index 0000000000000000000000000000000000000000..a0bf6013e93763ab87895a561117f25cf641af72 --- /dev/null +++ b/src/main/resources/PythonLibs/genericpath.py @@ -0,0 +1,105 @@ +""" +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 + +__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime', + 'getsize', 'isdir', 'isfile'] + + +# 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 os.error: + return False + return True + + +# This follows symbolic links, so both islink() and isdir() can be true +# for the same path ono systems that support symlinks +def isfile(path): + """Test whether a path is a regular file""" + try: + st = os.stat(path) + except os.error: + 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 os.error: + 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 '' + s1 = min(m) + s2 = max(m) + for i, c in enumerate(s1): + if c != s2[i]: + return s1[:i] + return s1 + +# 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.""" + + 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] != extsep: + return p[:dotIndex], p[dotIndex:] + filenameIndex += 1 + + return p, '' diff --git a/src/main/resources/PythonLibs/getopt.py b/src/main/resources/PythonLibs/getopt.py new file mode 100644 index 0000000000000000000000000000000000000000..251d89c5cfe9ad9c11768377c86140243d9f92ee --- /dev/null +++ b/src/main/resources/PythonLibs/getopt.py @@ -0,0 +1,210 @@ +"""Parser for command line options. + +This module helps scripts to parse the command line arguments in +sys.argv. It supports the same conventions as the Unix getopt() +function (including the special meanings of arguments of the form `-' +and `--'). Long options similar to those supported by GNU software +may be used as well via an optional third argument. This module +provides two functions and an exception: + +getopt() -- Parse command line options +gnu_getopt() -- Like getopt(), but allow option and non-option arguments +to be intermixed. +GetoptError -- exception (class) raised with 'opt' attribute, which is the +option involved with the exception. +""" + +# Long option support added by Lars Wirzenius <liw@iki.fi>. +# +# Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions +# to class-based exceptions. +# +# Peter Astrand <astrand@lysator.liu.se> added gnu_getopt(). +# +# TODO for gnu_getopt(): +# +# - GNU getopt_long_only mechanism +# - allow the caller to specify ordering +# - RETURN_IN_ORDER option +# - GNU extension with '-' as first character of option string +# - optional arguments, specified by double colons +# - a option string with a W followed by semicolon should +# treat "-W foo" as "--foo" + +__all__ = ["GetoptError","error","getopt","gnu_getopt"] + +import os + +class GetoptError(Exception): + opt = '' + msg = '' + def __init__(self, msg, opt=''): + self.msg = msg + self.opt = opt + Exception.__init__(self, msg, opt) + + def __str__(self): + return self.msg + +error = GetoptError # backward compatibility + +def getopt(args, shortopts, longopts = []): + """getopt(args, options[, long_options]) -> opts, args + + Parses command line options and parameter list. args is the + argument list to be parsed, without the leading reference to the + running program. Typically, this means "sys.argv[1:]". shortopts + is the string of option letters that the script wants to + recognize, with options that require an argument followed by a + colon (i.e., the same format that Unix getopt() uses). If + specified, longopts is a list of strings with the names of the + long options which should be supported. The leading '--' + characters should not be included in the option name. Options + which require an argument should be followed by an equal sign + ('='). + + The return value consists of two elements: the first is a list of + (option, value) pairs; the second is the list of program arguments + left after the option list was stripped (this is a trailing slice + of the first argument). Each option-and-value pair returned has + the option as its first element, prefixed with a hyphen (e.g., + '-x'), and the option argument as its second element, or an empty + string if the option has no argument. The options occur in the + list in the same order in which they were found, thus allowing + multiple occurrences. Long and short options may be mixed. + + """ + + opts = [] + if type(longopts) == type(""): + longopts = [longopts] + else: + longopts = list(longopts) + while args and args[0].startswith('-') and args[0] != '-': + if args[0] == '--': + args = args[1:] + break + if args[0].startswith('--'): + opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) + else: + opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) + + return opts, args + +def gnu_getopt(args, shortopts, longopts = []): + """getopt(args, options[, long_options]) -> opts, args + + This function works like getopt(), except that GNU style scanning + mode is used by default. This means that option and non-option + arguments may be intermixed. The getopt() function stops + processing options as soon as a non-option argument is + encountered. + + If the first character of the option string is `+', or if the + environment variable POSIXLY_CORRECT is set, then option + processing stops as soon as a non-option argument is encountered. + + """ + + opts = [] + prog_args = [] + if isinstance(longopts, str): + longopts = [longopts] + else: + longopts = list(longopts) + + # Allow options after non-option arguments? + if shortopts.startswith('+'): + shortopts = shortopts[1:] + all_options_first = True + elif os.environ.get("POSIXLY_CORRECT"): + all_options_first = True + else: + all_options_first = False + + while args: + if args[0] == '--': + prog_args += args[1:] + break + + if args[0][:2] == '--': + opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) + elif args[0][:1] == '-' and args[0] != '-': + opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) + else: + if all_options_first: + prog_args += args + break + else: + prog_args.append(args[0]) + args = args[1:] + + return opts, prog_args + +def do_longs(opts, opt, longopts, args): + try: + i = opt.index('=') + except ValueError: + optarg = None + else: + opt, optarg = opt[:i], opt[i+1:] + + has_arg, opt = long_has_args(opt, longopts) + if has_arg: + if optarg is None: + if not args: + raise GetoptError('option --%s requires argument' % opt, opt) + optarg, args = args[0], args[1:] + elif optarg is not None: + raise GetoptError('option --%s must not have an argument' % opt, opt) + opts.append(('--' + opt, optarg or '')) + return opts, args + +# Return: +# has_arg? +# full option name +def long_has_args(opt, longopts): + possibilities = [o for o in longopts if o.startswith(opt)] + if not possibilities: + raise GetoptError('option --%s not recognized' % opt, opt) + # Is there an exact match? + if opt in possibilities: + return False, opt + elif opt + '=' in possibilities: + return True, opt + # No exact match, so better be unique. + if len(possibilities) > 1: + # XXX since possibilities contains all valid continuations, might be + # nice to work them into the error msg + raise GetoptError('option --%s not a unique prefix' % opt, opt) + assert len(possibilities) == 1 + unique_match = possibilities[0] + has_arg = unique_match.endswith('=') + if has_arg: + unique_match = unique_match[:-1] + return has_arg, unique_match + +def do_shorts(opts, optstring, shortopts, args): + while optstring != '': + opt, optstring = optstring[0], optstring[1:] + if short_has_arg(opt, shortopts): + if optstring == '': + if not args: + raise GetoptError('option -%s requires argument' % opt, + opt) + optstring, args = args[0], args[1:] + optarg, optstring = optstring, '' + else: + optarg = '' + opts.append(('-' + opt, optarg)) + return opts, args + +def short_has_arg(opt, shortopts): + for i in range(len(shortopts)): + if opt == shortopts[i] != ':': + return shortopts.startswith(':', i+1) + raise GetoptError('option -%s not recognized' % opt, opt) + +if __name__ == '__main__': + import sys + print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"]) diff --git a/src/main/resources/PythonLibs/getpass.py b/src/main/resources/PythonLibs/getpass.py new file mode 100644 index 0000000000000000000000000000000000000000..012a233de00cda42c503afb992374a48d9c7cd3d --- /dev/null +++ b/src/main/resources/PythonLibs/getpass.py @@ -0,0 +1,160 @@ +"""Utilities to get a password and/or the current user name. + +getpass(prompt) - prompt for a password, with echo turned off +getuser() - get the user name from the environment or password database + +On Windows, the msvcrt module will be used. +On the Mac EasyDialogs.AskPassword is used, if available. + +""" + +# From CPython 2.5.1 with a fix to _raw_input (see +# http://bugs.python.org/issue1703 ) + +# Authors: Piers Lauder (original) +# Guido van Rossum (Windows support and cleanup) + +import os +import sys + +__all__ = ["getpass","getuser"] + +def jython_getpass(prompt='Password: ', stream=None): + """Prompt for a password, with echo turned off. + The prompt is written on stream, by default stdout. + + Restore terminal settings at end. + """ + if stream is None: + stream = sys.stdout + + try: + terminal = sys._jy_interpreter.reader.terminal + except: + return default_getpass(prompt) + + echoed = terminal.getEcho() + terminal.disableEcho() + try: + passwd = _raw_input(prompt, stream) + finally: + if echoed: + terminal.enableEcho() + + stream.write('\n') + return passwd + + +def unix_getpass(prompt='Password: ', stream=None): + """Prompt for a password, with echo turned off. + The prompt is written on stream, by default stdout. + + Restore terminal settings at end. + """ + if stream is None: + stream = sys.stdout + + try: + fd = sys.stdin.fileno() + except: + return default_getpass(prompt) + + old = termios.tcgetattr(fd) # a copy to save + new = old[:] + + new[3] = new[3] & ~termios.ECHO # 3 == 'lflags' + try: + termios.tcsetattr(fd, termios.TCSADRAIN, new) + passwd = _raw_input(prompt, stream) + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old) + + stream.write('\n') + return passwd + + +def win_getpass(prompt='Password: ', stream=None): + """Prompt for password with echo off, using Windows getch().""" + if sys.stdin is not sys.__stdin__: + return default_getpass(prompt, stream) + import msvcrt + for c in prompt: + msvcrt.putch(c) + pw = "" + while 1: + c = msvcrt.getch() + if c == '\r' or c == '\n': + break + if c == '\003': + raise KeyboardInterrupt + if c == '\b': + pw = pw[:-1] + else: + pw = pw + c + msvcrt.putch('\r') + msvcrt.putch('\n') + return pw + + +def default_getpass(prompt='Password: ', stream=None): + print >>sys.stderr, "Warning: Problem with getpass. Passwords may be echoed." + return _raw_input(prompt, stream) + + +def _raw_input(prompt="", stream=None): + # A raw_input() replacement that doesn't save the string in the + # GNU readline history. + if stream is None: + stream = sys.stdout + prompt = str(prompt) + if prompt: + stream.write(prompt) + stream.flush() + line = sys.stdin.readline() + if not line: + raise EOFError + if line[-1] == '\n': + line = line[:-1] + return line + + +def getuser(): + """Get the username from the environment or password database. + + First try various environment variables, then the password + database. This works on Windows as long as USERNAME is set. + + """ + + for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): + user = os.environ.get(name) + if user: + return user + + # If this fails, the exception will "explain" why + import pwd + return pwd.getpwuid(os.getuid())[0] + +# Bind the name getpass to the appropriate function +try: + import termios + # it's possible there is an incompatible termios from the + # McMillan Installer, make sure we have a UNIX-compatible termios + termios.tcgetattr, termios.tcsetattr +except (ImportError, AttributeError): + try: + import msvcrt + except ImportError: + try: + from EasyDialogs import AskPassword + except ImportError: + if os.name == 'java': + getpass = jython_getpass + else: + getpass = default_getpass + else: + getpass = AskPassword + else: + getpass = win_getpass +else: + getpass = unix_getpass diff --git a/src/main/resources/PythonLibs/gettext.py b/src/main/resources/PythonLibs/gettext.py new file mode 100644 index 0000000000000000000000000000000000000000..7698bdd57d2f1b9c0d6e74503b8098d523f87b5e --- /dev/null +++ b/src/main/resources/PythonLibs/gettext.py @@ -0,0 +1,592 @@ +"""Internationalization and localization support. + +This module provides internationalization (I18N) and localization (L10N) +support for your Python programs by providing an interface to the GNU gettext +message catalog library. + +I18N refers to the operation by which a program is made aware of multiple +languages. L10N refers to the adaptation of your program, once +internationalized, to the local language and cultural habits. + +""" + +# This module represents the integration of work, contributions, feedback, and +# suggestions from the following people: +# +# Martin von Loewis, who wrote the initial implementation of the underlying +# C-based libintlmodule (later renamed _gettext), along with a skeletal +# gettext.py implementation. +# +# Peter Funk, who wrote fintl.py, a fairly complete wrapper around intlmodule, +# which also included a pure-Python implementation to read .mo files if +# intlmodule wasn't available. +# +# James Henstridge, who also wrote a gettext.py module, which has some +# interesting, but currently unsupported experimental features: the notion of +# a Catalog class and instances, and the ability to add to a catalog file via +# a Python API. +# +# Barry Warsaw integrated these modules, wrote the .install() API and code, +# and conformed all C and Python code to Python's coding standards. +# +# Francois Pinard and Marc-Andre Lemburg also contributed valuably to this +# module. +# +# J. David Ibanez implemented plural forms. Bruno Haible fixed some bugs. +# +# TODO: +# - Lazy loading of .mo files. Currently the entire catalog is loaded into +# memory, but that's probably bad for large translated programs. Instead, +# the lexical sort of original strings in GNU .mo files should be exploited +# to do binary searches and lazy initializations. Or you might want to use +# the undocumented double-hash algorithm for .mo files with hash tables, but +# you'll need to study the GNU gettext code to do this. +# +# - Support Solaris .mo file formats. Unfortunately, we've been unable to +# find this format documented anywhere. + + +from __future__ import with_statement +import locale, copy, os, re, struct, sys +from errno import ENOENT + + +__all__ = ['NullTranslations', 'GNUTranslations', 'Catalog', + 'find', 'translation', 'install', 'textdomain', 'bindtextdomain', + 'dgettext', 'dngettext', 'gettext', 'ngettext', + ] + +_default_localedir = os.path.join(sys.prefix, 'share', 'locale') + + +def test(condition, true, false): + """ + Implements the C expression: + + condition ? true : false + + Required to correctly interpret plural forms. + """ + if condition: + return true + else: + return false + + +def c2py(plural): + """Gets a C expression as used in PO files for plural forms and returns a + Python lambda function that implements an equivalent expression. + """ + # Security check, allow only the "n" identifier + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + import token, tokenize + tokens = tokenize.generate_tokens(StringIO(plural).readline) + try: + danger = [x for x in tokens if x[0] == token.NAME and x[1] != 'n'] + except tokenize.TokenError: + raise ValueError, \ + 'plural forms expression error, maybe unbalanced parenthesis' + else: + if danger: + raise ValueError, 'plural forms expression could be dangerous' + + # Replace some C operators by their Python equivalents + plural = plural.replace('&&', ' and ') + plural = plural.replace('||', ' or ') + + expr = re.compile(r'\!([^=])') + plural = expr.sub(' not \\1', plural) + + # Regular expression and replacement function used to transform + # "a?b:c" to "test(a,b,c)". + expr = re.compile(r'(.*?)\?(.*?):(.*)') + def repl(x): + return "test(%s, %s, %s)" % (x.group(1), x.group(2), + expr.sub(repl, x.group(3))) + + # Code to transform the plural expression, taking care of parentheses + stack = [''] + for c in plural: + if c == '(': + stack.append('') + elif c == ')': + if len(stack) == 1: + # Actually, we never reach this code, because unbalanced + # parentheses get caught in the security check at the + # beginning. + raise ValueError, 'unbalanced parenthesis in plural form' + s = expr.sub(repl, stack.pop()) + stack[-1] += '(%s)' % s + else: + stack[-1] += c + plural = expr.sub(repl, stack.pop()) + + return eval('lambda n: int(%s)' % plural) + + + +def _expand_lang(locale): + from locale import normalize + locale = normalize(locale) + COMPONENT_CODESET = 1 << 0 + COMPONENT_TERRITORY = 1 << 1 + COMPONENT_MODIFIER = 1 << 2 + # split up the locale into its base components + mask = 0 + pos = locale.find('@') + if pos >= 0: + modifier = locale[pos:] + locale = locale[:pos] + mask |= COMPONENT_MODIFIER + else: + modifier = '' + pos = locale.find('.') + if pos >= 0: + codeset = locale[pos:] + locale = locale[:pos] + mask |= COMPONENT_CODESET + else: + codeset = '' + pos = locale.find('_') + if pos >= 0: + territory = locale[pos:] + locale = locale[:pos] + mask |= COMPONENT_TERRITORY + else: + territory = '' + language = locale + ret = [] + for i in range(mask+1): + if not (i & ~mask): # if all components for this combo exist ... + val = language + if i & COMPONENT_TERRITORY: val += territory + if i & COMPONENT_CODESET: val += codeset + if i & COMPONENT_MODIFIER: val += modifier + ret.append(val) + ret.reverse() + return ret + + + +class NullTranslations: + def __init__(self, fp=None): + self._info = {} + self._charset = None + self._output_charset = None + self._fallback = None + if fp is not None: + self._parse(fp) + + def _parse(self, fp): + pass + + def add_fallback(self, fallback): + if self._fallback: + self._fallback.add_fallback(fallback) + else: + self._fallback = fallback + + def gettext(self, message): + if self._fallback: + return self._fallback.gettext(message) + return message + + def lgettext(self, message): + if self._fallback: + return self._fallback.lgettext(message) + return message + + def ngettext(self, msgid1, msgid2, n): + if self._fallback: + return self._fallback.ngettext(msgid1, msgid2, n) + if n == 1: + return msgid1 + else: + return msgid2 + + def lngettext(self, msgid1, msgid2, n): + if self._fallback: + return self._fallback.lngettext(msgid1, msgid2, n) + if n == 1: + return msgid1 + else: + return msgid2 + + def ugettext(self, message): + if self._fallback: + return self._fallback.ugettext(message) + return unicode(message) + + def ungettext(self, msgid1, msgid2, n): + if self._fallback: + return self._fallback.ungettext(msgid1, msgid2, n) + if n == 1: + return unicode(msgid1) + else: + return unicode(msgid2) + + def info(self): + return self._info + + def charset(self): + return self._charset + + def output_charset(self): + return self._output_charset + + def set_output_charset(self, charset): + self._output_charset = charset + + def install(self, unicode=False, names=None): + import __builtin__ + __builtin__.__dict__['_'] = unicode and self.ugettext or self.gettext + if hasattr(names, "__contains__"): + if "gettext" in names: + __builtin__.__dict__['gettext'] = __builtin__.__dict__['_'] + if "ngettext" in names: + __builtin__.__dict__['ngettext'] = (unicode and self.ungettext + or self.ngettext) + if "lgettext" in names: + __builtin__.__dict__['lgettext'] = self.lgettext + if "lngettext" in names: + __builtin__.__dict__['lngettext'] = self.lngettext + + +class GNUTranslations(NullTranslations): + # Magic number of .mo files + LE_MAGIC = 0x950412deL + BE_MAGIC = 0xde120495L + + def _parse(self, fp): + """Override this method to support alternative .mo formats.""" + unpack = struct.unpack + filename = getattr(fp, 'name', '') + # Parse the .mo file header, which consists of 5 little endian 32 + # bit words. + self._catalog = catalog = {} + self.plural = lambda n: int(n != 1) # germanic plural by default + buf = fp.read() + buflen = len(buf) + # Are we big endian or little endian? + magic = unpack('<I', buf[:4])[0] + if magic == self.LE_MAGIC: + version, msgcount, masteridx, transidx = unpack('<4I', buf[4:20]) + ii = '<II' + elif magic == self.BE_MAGIC: + version, msgcount, masteridx, transidx = unpack('>4I', buf[4:20]) + ii = '>II' + else: + raise IOError(0, 'Bad magic number', filename) + # Now put all messages from the .mo file buffer into the catalog + # dictionary. + for i in xrange(0, msgcount): + mlen, moff = unpack(ii, buf[masteridx:masteridx+8]) + mend = moff + mlen + tlen, toff = unpack(ii, buf[transidx:transidx+8]) + tend = toff + tlen + if mend < buflen and tend < buflen: + msg = buf[moff:mend] + tmsg = buf[toff:tend] + else: + raise IOError(0, 'File is corrupt', filename) + # See if we're looking at GNU .mo conventions for metadata + if mlen == 0: + # Catalog description + lastk = k = None + for item in tmsg.splitlines(): + item = item.strip() + if not item: + continue + if ':' in item: + k, v = item.split(':', 1) + k = k.strip().lower() + v = v.strip() + self._info[k] = v + lastk = k + elif lastk: + self._info[lastk] += '\n' + item + if k == 'content-type': + self._charset = v.split('charset=')[1] + elif k == 'plural-forms': + v = v.split(';') + plural = v[1].split('plural=')[1] + self.plural = c2py(plural) + # Note: we unconditionally convert both msgids and msgstrs to + # Unicode using the character encoding specified in the charset + # parameter of the Content-Type header. The gettext documentation + # strongly encourages msgids to be us-ascii, but some appliations + # require alternative encodings (e.g. Zope's ZCML and ZPT). For + # traditional gettext applications, the msgid conversion will + # cause no problems since us-ascii should always be a subset of + # the charset encoding. We may want to fall back to 8-bit msgids + # if the Unicode conversion fails. + if '\x00' in msg: + # Plural forms + msgid1, msgid2 = msg.split('\x00') + tmsg = tmsg.split('\x00') + if self._charset: + msgid1 = unicode(msgid1, self._charset) + tmsg = [unicode(x, self._charset) for x in tmsg] + for i in range(len(tmsg)): + catalog[(msgid1, i)] = tmsg[i] + else: + if self._charset: + msg = unicode(msg, self._charset) + tmsg = unicode(tmsg, self._charset) + catalog[msg] = tmsg + # advance to next entry in the seek tables + masteridx += 8 + transidx += 8 + + def gettext(self, message): + missing = object() + tmsg = self._catalog.get(message, missing) + if tmsg is missing: + if self._fallback: + return self._fallback.gettext(message) + return message + # Encode the Unicode tmsg back to an 8-bit string, if possible + if self._output_charset: + return tmsg.encode(self._output_charset) + elif self._charset: + return tmsg.encode(self._charset) + return tmsg + + def lgettext(self, message): + missing = object() + tmsg = self._catalog.get(message, missing) + if tmsg is missing: + if self._fallback: + return self._fallback.lgettext(message) + return message + if self._output_charset: + return tmsg.encode(self._output_charset) + return tmsg.encode(locale.getpreferredencoding()) + + def ngettext(self, msgid1, msgid2, n): + try: + tmsg = self._catalog[(msgid1, self.plural(n))] + if self._output_charset: + return tmsg.encode(self._output_charset) + elif self._charset: + return tmsg.encode(self._charset) + return tmsg + except KeyError: + if self._fallback: + return self._fallback.ngettext(msgid1, msgid2, n) + if n == 1: + return msgid1 + else: + return msgid2 + + def lngettext(self, msgid1, msgid2, n): + try: + tmsg = self._catalog[(msgid1, self.plural(n))] + if self._output_charset: + return tmsg.encode(self._output_charset) + return tmsg.encode(locale.getpreferredencoding()) + except KeyError: + if self._fallback: + return self._fallback.lngettext(msgid1, msgid2, n) + if n == 1: + return msgid1 + else: + return msgid2 + + def ugettext(self, message): + missing = object() + tmsg = self._catalog.get(message, missing) + if tmsg is missing: + if self._fallback: + return self._fallback.ugettext(message) + return unicode(message) + return tmsg + + def ungettext(self, msgid1, msgid2, n): + try: + tmsg = self._catalog[(msgid1, self.plural(n))] + except KeyError: + if self._fallback: + return self._fallback.ungettext(msgid1, msgid2, n) + if n == 1: + tmsg = unicode(msgid1) + else: + tmsg = unicode(msgid2) + return tmsg + + +# Locate a .mo file using the gettext strategy +def find(domain, localedir=None, languages=None, all=0): + # Get some reasonable defaults for arguments that were not supplied + if localedir is None: + localedir = _default_localedir + if languages is None: + languages = [] + for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'): + val = os.environ.get(envar) + if val: + languages = val.split(':') + break + if 'C' not in languages: + languages.append('C') + # now normalize and expand the languages + nelangs = [] + for lang in languages: + for nelang in _expand_lang(lang): + if nelang not in nelangs: + nelangs.append(nelang) + # select a language + if all: + result = [] + else: + result = None + for lang in nelangs: + if lang == 'C': + break + mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain) + if os.path.exists(mofile): + if all: + result.append(mofile) + else: + return mofile + return result + + + +# a mapping between absolute .mo file path and Translation object +_translations = {} + +def translation(domain, localedir=None, languages=None, + class_=None, fallback=False, codeset=None): + if class_ is None: + class_ = GNUTranslations + mofiles = find(domain, localedir, languages, all=1) + if not mofiles: + if fallback: + return NullTranslations() + raise IOError(ENOENT, 'No translation file found for domain', domain) + # Avoid opening, reading, and parsing the .mo file after it's been done + # once. + result = None + for mofile in mofiles: + key = (class_, os.path.abspath(mofile)) + t = _translations.get(key) + if t is None: + with open(mofile, 'rb') as fp: + t = _translations.setdefault(key, class_(fp)) + # Copy the translation object to allow setting fallbacks and + # output charset. All other instance data is shared with the + # cached object. + t = copy.copy(t) + if codeset: + t.set_output_charset(codeset) + if result is None: + result = t + else: + result.add_fallback(t) + return result + + +def install(domain, localedir=None, unicode=False, codeset=None, names=None): + t = translation(domain, localedir, fallback=True, codeset=codeset) + t.install(unicode, names) + + + +# a mapping b/w domains and locale directories +_localedirs = {} +# a mapping b/w domains and codesets +_localecodesets = {} +# current global domain, `messages' used for compatibility w/ GNU gettext +_current_domain = 'messages' + + +def textdomain(domain=None): + global _current_domain + if domain is not None: + _current_domain = domain + return _current_domain + + +def bindtextdomain(domain, localedir=None): + global _localedirs + if localedir is not None: + _localedirs[domain] = localedir + return _localedirs.get(domain, _default_localedir) + + +def bind_textdomain_codeset(domain, codeset=None): + global _localecodesets + if codeset is not None: + _localecodesets[domain] = codeset + return _localecodesets.get(domain) + + +def dgettext(domain, message): + try: + t = translation(domain, _localedirs.get(domain, None), + codeset=_localecodesets.get(domain)) + except IOError: + return message + return t.gettext(message) + +def ldgettext(domain, message): + try: + t = translation(domain, _localedirs.get(domain, None), + codeset=_localecodesets.get(domain)) + except IOError: + return message + return t.lgettext(message) + +def dngettext(domain, msgid1, msgid2, n): + try: + t = translation(domain, _localedirs.get(domain, None), + codeset=_localecodesets.get(domain)) + except IOError: + if n == 1: + return msgid1 + else: + return msgid2 + return t.ngettext(msgid1, msgid2, n) + +def ldngettext(domain, msgid1, msgid2, n): + try: + t = translation(domain, _localedirs.get(domain, None), + codeset=_localecodesets.get(domain)) + except IOError: + if n == 1: + return msgid1 + else: + return msgid2 + return t.lngettext(msgid1, msgid2, n) + +def gettext(message): + return dgettext(_current_domain, message) + +def lgettext(message): + return ldgettext(_current_domain, message) + +def ngettext(msgid1, msgid2, n): + return dngettext(_current_domain, msgid1, msgid2, n) + +def lngettext(msgid1, msgid2, n): + return ldngettext(_current_domain, msgid1, msgid2, n) + +# dcgettext() has been deemed unnecessary and is not implemented. + +# James Henstridge's Catalog constructor from GNOME gettext. Documented usage +# was: +# +# import gettext +# cat = gettext.Catalog(PACKAGE, localedir=LOCALEDIR) +# _ = cat.gettext +# print _('Hello World') + +# The resulting catalog object currently don't support access through a +# dictionary API, which was supported (but apparently unused) in GNOME +# gettext. + +Catalog = translation diff --git a/src/main/resources/PythonLibs/glob.py b/src/main/resources/PythonLibs/glob.py new file mode 100644 index 0000000000000000000000000000000000000000..f34534b53c44825f010fd757aaf68cd93132cd5a --- /dev/null +++ b/src/main/resources/PythonLibs/glob.py @@ -0,0 +1,95 @@ +"""Filename globbing utility.""" + +import sys +import os +import re +import fnmatch + +try: + _unicode = unicode +except NameError: + # If Python is built without Unicode support, the unicode type + # will not exist. Fake one. + class _unicode(object): + pass + +__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. + + """ + if not has_magic(pathname): + if os.path.lexists(pathname): + yield pathname + return + dirname, basename = os.path.split(pathname) + if not dirname: + for name in glob1(os.curdir, basename): + yield name + 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: + dirname = os.curdir + if isinstance(pattern, _unicode) and not isinstance(dirname, unicode): + dirname = unicode(dirname, sys.getfilesystemencoding() or + sys.getdefaultencoding()) + try: + names = os.listdir(dirname) + except os.error: + return [] + if pattern[0] != '.': + names = filter(lambda x: x[0] != '.', names) + return fnmatch.filter(names, pattern) + +def glob0(dirname, basename): + if 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('[*?[]') + +def has_magic(s): + return magic_check.search(s) is not None diff --git a/src/main/resources/PythonLibs/grp.py b/src/main/resources/PythonLibs/grp.py new file mode 100644 index 0000000000000000000000000000000000000000..50f3bd005449dd82205e7fb22c36d515cd277d6b --- /dev/null +++ b/src/main/resources/PythonLibs/grp.py @@ -0,0 +1,85 @@ +""" +Access to the Unix group database. + +Group entries are reported as 4-tuples containing the following fields +from the group database, in order: + + name - name of the group + passwd - group password (encrypted); often empty + gid - numeric ID of the group + mem - list of members + +The gid is an integer, name and password are strings. (Note that most +users are not explicitly listed as members of the groups they are in +according to the password database. Check both databases to get +complete membership information.) +""" + +__all__ = ['getgrgid', 'getgrnam', 'getgrall'] + +from os import _name, _posix_impl +from org.python.core.Py import newString + +if _name == 'nt': + raise ImportError, 'grp module not supported on Windows' + +class struct_group(tuple): + """ + grp.struct_group: Results from getgr*() routines. + + This object may be accessed either as a tuple of + (gr_name,gr_passwd,gr_gid,gr_mem) + or via the object attributes as named in the above tuple. + """ + + attrs = ['gr_name', 'gr_passwd', 'gr_gid', 'gr_mem'] + + def __new__(cls, grp): + grp = (newString(grp.name), newString(grp.password), int(grp.GID), + [newString(member) for member in grp.members]) + return tuple.__new__(cls, grp) + + def __getattr__(self, attr): + try: + return self[self.attrs.index(attr)] + except ValueError: + raise AttributeError + + +def getgrgid(uid): + """ + getgrgid(id) -> tuple + Return the group database entry for the given numeric group ID. If + id is not valid, raise KeyError. + """ + entry = _posix_impl.getgrgid(uid) + if not entry: + raise KeyError(uid) + return struct_group(entry) + + +def getgrnam(name): + """ + getgrnam(name) -> tuple + Return the group database entry for the given group name. If + name is not valid, raise KeyError. + """ + entry = _posix_impl.getgrnam(name) + if not entry: + raise KeyError(name) + return struct_group(entry) + + +def getgrall(): + """ + getgrall() -> list of tuples + Return a list of all available group database entries, + in arbitrary order. + """ + groups = [] + while True: + group = _posix_impl.getgrent() + if not group: + break + groups.append(struct_group(group)) + return groups diff --git a/src/main/resources/PythonLibs/gzip.py b/src/main/resources/PythonLibs/gzip.py new file mode 100644 index 0000000000000000000000000000000000000000..0f50c3c0a16d1909d3775950c353ecdf2a456464 --- /dev/null +++ b/src/main/resources/PythonLibs/gzip.py @@ -0,0 +1,520 @@ +"""Functions that read and write gzipped files. + +The user of the file doesn't have to worry about the compression, +but random access is not allowed.""" + +# based on Andrew Kuchling's minigzip.py distributed with the zlib module + +import struct, sys, time, os +import zlib +import io +import __builtin__ + +__all__ = ["GzipFile","open"] + +FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT = 1, 2, 4, 8, 16 + +READ, WRITE = 1, 2 + +def write32u(output, value): + # The L format writes the bit pattern correctly whether signed + # or unsigned. + output.write(struct.pack("<L", value)) + +def read32(input): + return struct.unpack("<I", input.read(4))[0] + +def open(filename, mode="rb", compresslevel=9): + """Shorthand for GzipFile(filename, mode, compresslevel). + + The filename argument is required; mode defaults to 'rb' + and compresslevel defaults to 9. + + """ + return GzipFile(filename, mode, compresslevel) + +class GzipFile(io.BufferedIOBase): + """The GzipFile class simulates most of the methods of a file object with + the exception of the readinto() and truncate() methods. + + """ + + myfileobj = None + # XXX: repeated 10mb chunk reads hurt test_gzip.test_many_append's + # performance on Jython (maybe CPython's allocator recycles the same + # 10mb buffer whereas Java's doesn't) + #max_read_chunk = 10 * 1024 * 1024 # 10Mb + max_read_chunk = 256 * 1024 # 256kb + + def __init__(self, filename=None, mode=None, + compresslevel=9, fileobj=None, mtime=None): + """Constructor for the GzipFile class. + + At least one of fileobj and filename must be given a + non-trivial value. + + The new class instance is based on fileobj, which can be a regular + file, a StringIO object, or any other object which simulates a file. + It defaults to None, in which case filename is opened to provide + a file object. + + When fileobj is not None, the filename argument is only used to be + included in the gzip file header, which may includes the original + filename of the uncompressed file. It defaults to the filename of + fileobj, if discernible; otherwise, it defaults to the empty string, + and in this case the original filename is not included in the header. + + The mode argument can be any of 'r', 'rb', 'a', 'ab', 'w', or 'wb', + depending on whether the file will be read or written. The default + is the mode of fileobj if discernible; otherwise, the default is 'rb'. + Be aware that only the 'rb', 'ab', and 'wb' values should be used + for cross-platform portability. + + The compresslevel argument is an integer from 1 to 9 controlling the + level of compression; 1 is fastest and produces the least compression, + and 9 is slowest and produces the most compression. The default is 9. + + The mtime argument is an optional numeric timestamp to be written + to the stream when compressing. All gzip compressed streams + are required to contain a timestamp. If omitted or None, the + current time is used. This module ignores the timestamp when + decompressing; however, some programs, such as gunzip, make use + of it. The format of the timestamp is the same as that of the + return value of time.time() and of the st_mtime member of the + object returned by os.stat(). + + """ + + # guarantee the file is opened in binary mode on platforms + # that care about that sort of thing + if mode and 'b' not in mode: + mode += 'b' + if fileobj is None: + fileobj = self.myfileobj = __builtin__.open(filename, mode or 'rb') + if filename is None: + if hasattr(fileobj, 'name'): filename = fileobj.name + else: filename = '' + if mode is None: + if hasattr(fileobj, 'mode'): mode = fileobj.mode + else: mode = 'rb' + + if mode[0:1] == 'r': + self.mode = READ + # Set flag indicating start of a new member + self._new_member = True + # Buffer data read from gzip file. extrastart is offset in + # stream where buffer starts. extrasize is number of + # bytes remaining in buffer from current stream position. + self.extrabuf = "" + self.extrasize = 0 + self.extrastart = 0 + self.name = filename + # Starts small, scales exponentially + self.min_readsize = 100 + + elif mode[0:1] == 'w' or mode[0:1] == 'a': + self.mode = WRITE + self._init_write(filename) + self.compress = zlib.compressobj(compresslevel, + zlib.DEFLATED, + -zlib.MAX_WBITS, + zlib.DEF_MEM_LEVEL, + 0) + else: + raise IOError, "Mode " + mode + " not supported" + + self.fileobj = fileobj + self.offset = 0 + self.mtime = mtime + + if self.mode == WRITE: + self._write_gzip_header() + + @property + def filename(self): + import warnings + warnings.warn("use the name attribute", DeprecationWarning, 2) + if self.mode == WRITE and self.name[-3:] != ".gz": + return self.name + ".gz" + return self.name + + def __repr__(self): + s = repr(self.fileobj) + return '<gzip ' + s[1:-1] + ' ' + hex(id(self)) + '>' + + def _check_closed(self): + """Raises a ValueError if the underlying file object has been closed. + + """ + if self.closed: + raise ValueError('I/O operation on closed file.') + + def _init_write(self, filename): + self.name = filename + self.crc = zlib.crc32("") & 0xffffffffL + self.size = 0 + self.writebuf = [] + self.bufsize = 0 + + def _write_gzip_header(self): + self.fileobj.write('\037\213') # magic header + self.fileobj.write('\010') # compression method + fname = os.path.basename(self.name) + if fname.endswith(".gz"): + fname = fname[:-3] + flags = 0 + if fname: + flags = FNAME + self.fileobj.write(chr(flags)) + mtime = self.mtime + if mtime is None: + mtime = time.time() + write32u(self.fileobj, long(mtime)) + self.fileobj.write('\002') + self.fileobj.write('\377') + if fname: + self.fileobj.write(fname + '\000') + + def _init_read(self): + self.crc = zlib.crc32("") & 0xffffffffL + self.size = 0 + + def _read_gzip_header(self): + magic = self.fileobj.read(2) + if magic != '\037\213': + raise IOError, 'Not a gzipped file' + method = ord( self.fileobj.read(1) ) + if method != 8: + raise IOError, 'Unknown compression method' + flag = ord( self.fileobj.read(1) ) + self.mtime = read32(self.fileobj) + # extraflag = self.fileobj.read(1) + # os = self.fileobj.read(1) + self.fileobj.read(2) + + if flag & FEXTRA: + # Read & discard the extra field, if present + xlen = ord(self.fileobj.read(1)) + xlen = xlen + 256*ord(self.fileobj.read(1)) + self.fileobj.read(xlen) + if flag & FNAME: + # Read and discard a null-terminated string containing the filename + while True: + s = self.fileobj.read(1) + if not s or s=='\000': + break + if flag & FCOMMENT: + # Read and discard a null-terminated string containing a comment + while True: + s = self.fileobj.read(1) + if not s or s=='\000': + break + if flag & FHCRC: + self.fileobj.read(2) # Read & discard the 16-bit header CRC + + def write(self,data): + self._check_closed() + if self.mode != WRITE: + import errno + raise IOError(errno.EBADF, "write() on read-only GzipFile object") + + if self.fileobj is None: + raise ValueError, "write() on closed GzipFile object" + + # Convert data type if called by io.BufferedWriter. + if isinstance(data, memoryview): + data = data.tobytes() + + if len(data) > 0: + self.size = self.size + len(data) + self.crc = zlib.crc32(data, self.crc) & 0xffffffffL + self.fileobj.write( self.compress.compress(data) ) + self.offset += len(data) + + return len(data) + + def read(self, size=-1): + self._check_closed() + if self.mode != READ: + import errno + raise IOError(errno.EBADF, "read() on write-only GzipFile object") + + if self.extrasize <= 0 and self.fileobj is None: + return '' + + readsize = 1024 + if size < 0: # get the whole thing + try: + while True: + self._read(readsize) + readsize = min(self.max_read_chunk, readsize * 2) + except EOFError: + size = self.extrasize + else: # just get some more of it + try: + while size > self.extrasize: + self._read(readsize) + readsize = min(self.max_read_chunk, readsize * 2) + except EOFError: + if size > self.extrasize: + size = self.extrasize + + offset = self.offset - self.extrastart + chunk = self.extrabuf[offset: offset + size] + self.extrasize = self.extrasize - size + + self.offset += size + return chunk + + def _unread(self, buf): + self.extrasize = len(buf) + self.extrasize + self.offset -= len(buf) + + def _read(self, size=1024): + if self.fileobj is None: + raise EOFError, "Reached EOF" + + if self._new_member: + # If the _new_member flag is set, we have to + # jump to the next member, if there is one. + # + # First, check if we're at the end of the file; + # if so, it's time to stop; no more members to read. + pos = self.fileobj.tell() # Save current position + self.fileobj.seek(0, 2) # Seek to end of file + if pos == self.fileobj.tell(): + raise EOFError, "Reached EOF" + else: + self.fileobj.seek( pos ) # Return to original position + + self._init_read() + self._read_gzip_header() + self.decompress = zlib.decompressobj(-zlib.MAX_WBITS) + self._new_member = False + + # Read a chunk of data from the file + buf = self.fileobj.read(size) + + # If the EOF has been reached, flush the decompression object + # and mark this object as finished. + + if buf == "": + uncompress = self.decompress.flush() + self._read_eof() + self._add_read_data( uncompress ) + raise EOFError, 'Reached EOF' + + uncompress = self.decompress.decompress(buf) + self._add_read_data( uncompress ) + + if self.decompress.unused_data != "": + # Ending case: we've come to the end of a member in the file, + # so seek back to the start of the unused data, finish up + # this member, and read a new gzip header. + # (The number of bytes to seek back is the length of the unused + # data, minus 8 because _read_eof() will rewind a further 8 bytes) + self.fileobj.seek( -len(self.decompress.unused_data)+8, 1) + + # Check the CRC and file size, and set the flag so we read + # a new member on the next call + self._read_eof() + self._new_member = True + + def _add_read_data(self, data): + self.crc = zlib.crc32(data, self.crc) & 0xffffffffL + offset = self.offset - self.extrastart + self.extrabuf = self.extrabuf[offset:] + data + self.extrasize = self.extrasize + len(data) + self.extrastart = self.offset + self.size = self.size + len(data) + + def _read_eof(self): + # We've read to the end of the file, so we have to rewind in order + # to reread the 8 bytes containing the CRC and the file size. + # We check the that the computed CRC and size of the + # uncompressed data matches the stored values. Note that the size + # stored is the true file size mod 2**32. + self.fileobj.seek(-8, 1) + crc32 = read32(self.fileobj) + isize = read32(self.fileobj) # may exceed 2GB + if crc32 != self.crc: + raise IOError("CRC check failed %s != %s" % (hex(crc32), + hex(self.crc))) + elif isize != (self.size & 0xffffffffL): + raise IOError, "Incorrect length of data produced" + + # Gzip files can be padded with zeroes and still have archives. + # Consume all zero bytes and set the file position to the first + # non-zero byte. See http://www.gzip.org/#faq8 + c = "\x00" + while c == "\x00": + c = self.fileobj.read(1) + if c: + self.fileobj.seek(-1, 1) + + @property + def closed(self): + return self.fileobj is None + + def close(self): + if self.fileobj is None: + return + if self.mode == WRITE: + self.fileobj.write(self.compress.flush()) + write32u(self.fileobj, self.crc) + # self.size may exceed 2GB, or even 4GB + write32u(self.fileobj, self.size & 0xffffffffL) + self.fileobj = None + elif self.mode == READ: + self.fileobj = None + if self.myfileobj: + self.myfileobj.close() + self.myfileobj = None + + if not sys.platform.startswith('java'): + def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH): + self._check_closed() + if self.mode == WRITE: + # Ensure the compressor's buffer is flushed + self.fileobj.write(self.compress.flush(zlib_mode)) + self.fileobj.flush() + else: + # Java lacks Z_SYNC_FLUSH; thus Jython can't flush the + # compressobj until EOF + def flush(self,zlib_mode=None): + self._check_closed() + self.fileobj.flush() + + def fileno(self): + """Invoke the underlying file object's fileno() method. + + This will raise AttributeError if the underlying file object + doesn't support fileno(). + """ + return self.fileobj.fileno() + + def rewind(self): + '''Return the uncompressed stream file position indicator to the + beginning of the file''' + if self.mode != READ: + raise IOError("Can't rewind in write mode") + self.fileobj.seek(0) + self._new_member = True + self.extrabuf = "" + self.extrasize = 0 + self.extrastart = 0 + self.offset = 0 + + def readable(self): + return self.mode == READ + + def writable(self): + return self.mode == WRITE + + def seekable(self): + return True + + def seek(self, offset, whence=0): + if whence: + if whence == 1: + offset = self.offset + offset + else: + raise ValueError('Seek from end not supported') + if self.mode == WRITE: + if offset < self.offset: + raise IOError('Negative seek in write mode') + count = offset - self.offset + for i in range(count // 1024): + self.write(1024 * '\0') + self.write((count % 1024) * '\0') + elif self.mode == READ: + if offset < self.offset: + # for negative seek, rewind and do positive seek + self.rewind() + count = offset - self.offset + for i in range(count // 1024): + self.read(1024) + self.read(count % 1024) + + return self.offset + + def readline(self, size=-1): + if size < 0: + # Shortcut common case - newline found in buffer. + offset = self.offset - self.extrastart + i = self.extrabuf.find('\n', offset) + 1 + if i > 0: + self.extrasize -= i - offset + self.offset += i - offset + return self.extrabuf[offset: i] + + size = sys.maxint + readsize = self.min_readsize + else: + readsize = size + bufs = [] + while size != 0: + c = self.read(readsize) + i = c.find('\n') + + # We set i=size to break out of the loop under two + # conditions: 1) there's no newline, and the chunk is + # larger than size, or 2) there is a newline, but the + # resulting line would be longer than 'size'. + if (size <= i) or (i == -1 and len(c) > size): + i = size - 1 + + if i >= 0 or c == '': + bufs.append(c[:i + 1]) # Add portion of last chunk + self._unread(c[i + 1:]) # Push back rest of chunk + break + + # Append chunk to list, decrease 'size', + bufs.append(c) + size = size - len(c) + readsize = min(size, readsize * 2) + if readsize > self.min_readsize: + self.min_readsize = min(readsize, self.min_readsize * 2, 512) + return ''.join(bufs) # Return resulting line + + +def _test(): + # Act like gzip; with -d, act like gunzip. + # The input file is not deleted, however, nor are any other gzip + # options or features supported. + args = sys.argv[1:] + decompress = args and args[0] == "-d" + if decompress: + args = args[1:] + if not args: + args = ["-"] + for arg in args: + if decompress: + if arg == "-": + f = GzipFile(filename="", mode="rb", fileobj=sys.stdin) + g = sys.stdout + else: + if arg[-3:] != ".gz": + print "filename doesn't end in .gz:", repr(arg) + continue + f = open(arg, "rb") + g = __builtin__.open(arg[:-3], "wb") + else: + if arg == "-": + f = sys.stdin + g = GzipFile(filename="", mode="wb", fileobj=sys.stdout) + else: + f = __builtin__.open(arg, "rb") + g = open(arg + ".gz", "wb") + while True: + chunk = f.read(1024) + if not chunk: + break + g.write(chunk) + if g is not sys.stdout: + g.close() + if f is not sys.stdin: + f.close() + +if __name__ == '__main__': + _test() diff --git a/src/main/resources/PythonLibs/hashlib.py b/src/main/resources/PythonLibs/hashlib.py new file mode 100644 index 0000000000000000000000000000000000000000..d20e1f95a2afc8407ad6ea7b3602163f598e0896 --- /dev/null +++ b/src/main/resources/PythonLibs/hashlib.py @@ -0,0 +1,146 @@ +# $Id$ +# +# Copyright (C) 2005 Gregory P. Smith (greg@krypto.org) +# Licensed to PSF under a Contributor Agreement. +# + +__doc__ = """hashlib module - A common interface to many hash functions. + +new(name, string='') - returns a new hash object implementing the + given hash function; initializing the hash + using the given string data. + +Named constructor functions are also available, these are much faster +than using new(): + +md5(), sha1(), sha224(), sha256(), sha384(), and sha512() + +More algorithms may be available on your platform but the above are +guaranteed to exist. + +NOTE: If you want the adler32 or crc32 hash functions they are available in +the zlib module. + +Choose your hash function wisely. Some have known collision weaknesses. +sha384 and sha512 will be slow on 32 bit platforms. + +Hash objects have these methods: + - update(arg): Update the hash object with the string arg. Repeated calls + are equivalent to a single call with the concatenation of all + the arguments. + - digest(): Return the digest of the strings passed to the update() method + so far. This may contain non-ASCII characters, including + NUL bytes. + - hexdigest(): Like digest() except the digest is returned as a string of + double length, containing only hexadecimal digits. + - copy(): Return a copy (clone) of the hash object. This can be used to + efficiently compute the digests of strings that share a common + initial substring. + +For example, to obtain the digest of the string 'Nobody inspects the +spammish repetition': + + >>> import hashlib + >>> m = hashlib.md5() + >>> m.update("Nobody inspects") + >>> m.update(" the spammish repetition") + >>> m.digest() + '\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9' + +More condensed: + + >>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest() + 'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2' + +""" + +# This tuple and __get_builtin_constructor() must be modified if a new +# always available algorithm is added. +__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512') + +algorithms = __always_supported + +__all__ = __always_supported + ('new', 'algorithms') + + +def __get_builtin_constructor(name): + try: + if name in ('SHA1', 'sha1'): + import _sha + return _sha.new + elif name in ('MD5', 'md5'): + import _md5 + return _md5.new + elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'): + import _sha256 + bs = name[3:] + if bs == '256': + return _sha256.sha256 + elif bs == '224': + return _sha256.sha224 + elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'): + import _sha512 + bs = name[3:] + if bs == '512': + return _sha512.sha512 + elif bs == '384': + return _sha512.sha384 + except ImportError: + pass # no extension module, this hash is unsupported. + + raise ValueError('unsupported hash type ' + name) + + +def __get_openssl_constructor(name): + try: + f = getattr(_hashlib, 'openssl_' + name) + # Allow the C module to raise ValueError. The function will be + # defined but the hash not actually available thanks to OpenSSL. + f() + # Use the C function directly (very fast) + return f + except (AttributeError, ValueError): + return __get_builtin_constructor(name) + + +def __py_new(name, string=''): + """new(name, string='') - Return a new hashing object using the named algorithm; + optionally initialized with a string. + """ + return __get_builtin_constructor(name)(string) + + +def __hash_new(name, string=''): + """new(name, string='') - Return a new hashing object using the named algorithm; + optionally initialized with a string. + """ + try: + return _hashlib.new(name, string) + except ValueError: + # If the _hashlib module (OpenSSL) doesn't support the named + # hash, try using our builtin implementations. + # This allows for SHA224/256 and SHA384/512 support even though + # the OpenSSL library prior to 0.9.8 doesn't provide them. + return __get_builtin_constructor(name)(string) + + +try: + import _hashlib + new = __hash_new + __get_hash = __get_openssl_constructor +except ImportError: + new = __py_new + __get_hash = __get_builtin_constructor + +for __func_name in __always_supported: + # try them all, some may not work due to the OpenSSL + # version not supporting that algorithm. + try: + globals()[__func_name] = __get_hash(__func_name) + except ValueError: + import logging + logging.exception('code for hash %s was not found.', __func_name) + +# Cleanup locals() +del __always_supported, __func_name, __get_hash +del __py_new, __hash_new, __get_openssl_constructor diff --git a/src/main/resources/PythonLibs/heapq.py b/src/main/resources/PythonLibs/heapq.py new file mode 100644 index 0000000000000000000000000000000000000000..ca79db15295f49a62eda157937168a5c833dbcf5 --- /dev/null +++ b/src/main/resources/PythonLibs/heapq.py @@ -0,0 +1,480 @@ +# -*- coding: latin-1 -*- + +"""Heap queue algorithm (a.k.a. priority queue). + +Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for +all k, counting elements from 0. For the sake of comparison, +non-existing elements are considered to be infinite. The interesting +property of a heap is that a[0] is always its smallest element. + +Usage: + +heap = [] # creates an empty heap +heappush(heap, item) # pushes a new item on the heap +item = heappop(heap) # pops the smallest item from the heap +item = heap[0] # smallest item on the heap without popping it +heapify(x) # transforms list into a heap, in-place, in linear time +item = heapreplace(heap, item) # pops and returns smallest item, and adds + # new item; the heap size is unchanged + +Our API differs from textbook heap algorithms as follows: + +- We use 0-based indexing. This makes the relationship between the + index for a node and the indexes for its children slightly less + obvious, but is more suitable since Python uses 0-based indexing. + +- Our heappop() method returns the smallest item, not the largest. + +These two make it possible to view the heap as a regular Python list +without surprises: heap[0] is the smallest item, and heap.sort() +maintains the heap invariant! +""" + +# Original code by Kevin O'Connor, augmented by Tim Peters and Raymond Hettinger + +__about__ = """Heap queues + +[explanation by François Pinard] + +Heaps are arrays for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for +all k, counting elements from 0. For the sake of comparison, +non-existing elements are considered to be infinite. The interesting +property of a heap is that a[0] is always its smallest element. + +The strange invariant above is meant to be an efficient memory +representation for a tournament. The numbers below are `k', not a[k]: + + 0 + + 1 2 + + 3 4 5 6 + + 7 8 9 10 11 12 13 14 + + 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 + + +In the tree above, each cell `k' is topping `2*k+1' and `2*k+2'. In +an usual binary tournament we see in sports, each cell is the winner +over the two cells it tops, and we can trace the winner down the tree +to see all opponents s/he had. However, in many computer applications +of such tournaments, we do not need to trace the history of a winner. +To be more memory efficient, when a winner is promoted, we try to +replace it by something else at a lower level, and the rule becomes +that a cell and the two cells it tops contain three different items, +but the top cell "wins" over the two topped cells. + +If this heap invariant is protected at all time, index 0 is clearly +the overall winner. The simplest algorithmic way to remove it and +find the "next" winner is to move some loser (let's say cell 30 in the +diagram above) into the 0 position, and then percolate this new 0 down +the tree, exchanging values, until the invariant is re-established. +This is clearly logarithmic on the total number of items in the tree. +By iterating over all items, you get an O(n ln n) sort. + +A nice feature of this sort is that you can efficiently insert new +items while the sort is going on, provided that the inserted items are +not "better" than the last 0'th element you extracted. This is +especially useful in simulation contexts, where the tree holds all +incoming events, and the "win" condition means the smallest scheduled +time. When an event schedule other events for execution, they are +scheduled into the future, so they can easily go into the heap. So, a +heap is a good structure for implementing schedulers (this is what I +used for my MIDI sequencer :-). + +Various structures for implementing schedulers have been extensively +studied, and heaps are good for this, as they are reasonably speedy, +the speed is almost constant, and the worst case is not much different +than the average case. However, there are other representations which +are more efficient overall, yet the worst cases might be terrible. + +Heaps are also very useful in big disk sorts. You most probably all +know that a big sort implies producing "runs" (which are pre-sorted +sequences, which size is usually related to the amount of CPU memory), +followed by a merging passes for these runs, which merging is often +very cleverly organised[1]. It is very important that the initial +sort produces the longest runs possible. Tournaments are a good way +to that. If, using all the memory available to hold a tournament, you +replace and percolate items that happen to fit the current run, you'll +produce runs which are twice the size of the memory for random input, +and much better for input fuzzily ordered. + +Moreover, if you output the 0'th item on disk and get an input which +may not fit in the current tournament (because the value "wins" over +the last output value), it cannot fit in the heap, so the size of the +heap decreases. The freed memory could be cleverly reused immediately +for progressively building a second heap, which grows at exactly the +same rate the first heap is melting. When the first heap completely +vanishes, you switch heaps and start a new run. Clever and quite +effective! + +In a word, heaps are useful memory structures to know. I use them in +a few applications, and I think it is good to keep a `heap' module +around. :-) + +-------------------- +[1] The disk balancing algorithms which are current, nowadays, are +more annoying than clever, and this is a consequence of the seeking +capabilities of the disks. On devices which cannot seek, like big +tape drives, the story was quite different, and one had to be very +clever to ensure (far in advance) that each tape movement will be the +most effective possible (that is, will best participate at +"progressing" the merge). Some tapes were even able to read +backwards, and this was also used to avoid the rewinding time. +Believe me, real good tape sorts were quite spectacular to watch! +From all times, sorting has always been a Great Art! :-) +""" + +__all__ = ['heappush', 'heappop', 'heapify', 'heapreplace', 'merge', + 'nlargest', 'nsmallest', 'heappushpop'] + +from itertools import islice, count, imap, izip, tee, chain +from operator import itemgetter + +def cmp_lt(x, y): + # Use __lt__ if available; otherwise, try __le__. + # In Py3.x, only __lt__ will be called. + return (x < y) if hasattr(x, '__lt__') else (not y <= x) + +def heappush(heap, item): + """Push item onto heap, maintaining the heap invariant.""" + heap.append(item) + _siftdown(heap, 0, len(heap)-1) + +def heappop(heap): + """Pop the smallest item off the heap, maintaining the heap invariant.""" + lastelt = heap.pop() # raises appropriate IndexError if heap is empty + if heap: + returnitem = heap[0] + heap[0] = lastelt + _siftup(heap, 0) + else: + returnitem = lastelt + return returnitem + +def heapreplace(heap, item): + """Pop and return the current smallest value, and add the new item. + + This is more efficient than heappop() followed by heappush(), and can be + more appropriate when using a fixed-size heap. Note that the value + returned may be larger than item! That constrains reasonable uses of + this routine unless written as part of a conditional replacement: + + if item > heap[0]: + item = heapreplace(heap, item) + """ + returnitem = heap[0] # raises appropriate IndexError if heap is empty + heap[0] = item + _siftup(heap, 0) + return returnitem + +def heappushpop(heap, item): + """Fast version of a heappush followed by a heappop.""" + if heap and cmp_lt(heap[0], item): + item, heap[0] = heap[0], item + _siftup(heap, 0) + return item + +def heapify(x): + """Transform list into a heap, in-place, in O(len(x)) time.""" + n = len(x) + # Transform bottom-up. The largest index there's any point to looking at + # is the largest with a child index in-range, so must have 2*i + 1 < n, + # or i < (n-1)/2. If n is even = 2*j, this is (2*j-1)/2 = j-1/2 so + # j-1 is the largest, which is n//2 - 1. If n is odd = 2*j+1, this is + # (2*j+1-1)/2 = j so j-1 is the largest, and that's again n//2-1. + for i in reversed(xrange(n//2)): + _siftup(x, i) + +def _heappushpop_max(heap, item): + """Maxheap version of a heappush followed by a heappop.""" + if heap and cmp_lt(item, heap[0]): + item, heap[0] = heap[0], item + _siftup_max(heap, 0) + return item + +def _heapify_max(x): + """Transform list into a maxheap, in-place, in O(len(x)) time.""" + n = len(x) + for i in reversed(range(n//2)): + _siftup_max(x, i) + +def nlargest(n, iterable): + """Find the n largest elements in a dataset. + + Equivalent to: sorted(iterable, reverse=True)[:n] + """ + if n < 0: + return [] + it = iter(iterable) + result = list(islice(it, n)) + if not result: + return result + heapify(result) + _heappushpop = heappushpop + for elem in it: + _heappushpop(result, elem) + result.sort(reverse=True) + return result + +def nsmallest(n, iterable): + """Find the n smallest elements in a dataset. + + Equivalent to: sorted(iterable)[:n] + """ + if n < 0: + return [] + it = iter(iterable) + result = list(islice(it, n)) + if not result: + return result + _heapify_max(result) + _heappushpop = _heappushpop_max + for elem in it: + _heappushpop(result, elem) + result.sort() + return result + +# 'heap' is a heap at all indices >= startpos, except possibly for pos. pos +# is the index of a leaf with a possibly out-of-order value. Restore the +# heap invariant. +def _siftdown(heap, startpos, pos): + newitem = heap[pos] + # Follow the path to the root, moving parents down until finding a place + # newitem fits. + while pos > startpos: + parentpos = (pos - 1) >> 1 + parent = heap[parentpos] + if cmp_lt(newitem, parent): + heap[pos] = parent + pos = parentpos + continue + break + heap[pos] = newitem + +# The child indices of heap index pos are already heaps, and we want to make +# a heap at index pos too. We do this by bubbling the smaller child of +# pos up (and so on with that child's children, etc) until hitting a leaf, +# then using _siftdown to move the oddball originally at index pos into place. +# +# We *could* break out of the loop as soon as we find a pos where newitem <= +# both its children, but turns out that's not a good idea, and despite that +# many books write the algorithm that way. During a heap pop, the last array +# element is sifted in, and that tends to be large, so that comparing it +# against values starting from the root usually doesn't pay (= usually doesn't +# get us out of the loop early). See Knuth, Volume 3, where this is +# explained and quantified in an exercise. +# +# Cutting the # of comparisons is important, since these routines have no +# way to extract "the priority" from an array element, so that intelligence +# is likely to be hiding in custom __cmp__ methods, or in array elements +# storing (priority, record) tuples. Comparisons are thus potentially +# expensive. +# +# On random arrays of length 1000, making this change cut the number of +# comparisons made by heapify() a little, and those made by exhaustive +# heappop() a lot, in accord with theory. Here are typical results from 3 +# runs (3 just to demonstrate how small the variance is): +# +# Compares needed by heapify Compares needed by 1000 heappops +# -------------------------- -------------------------------- +# 1837 cut to 1663 14996 cut to 8680 +# 1855 cut to 1659 14966 cut to 8678 +# 1847 cut to 1660 15024 cut to 8703 +# +# Building the heap by using heappush() 1000 times instead required +# 2198, 2148, and 2219 compares: heapify() is more efficient, when +# you can use it. +# +# The total compares needed by list.sort() on the same lists were 8627, +# 8627, and 8632 (this should be compared to the sum of heapify() and +# heappop() compares): list.sort() is (unsurprisingly!) more efficient +# for sorting. + +def _siftup(heap, pos): + endpos = len(heap) + startpos = pos + newitem = heap[pos] + # Bubble up the smaller child until hitting a leaf. + childpos = 2*pos + 1 # leftmost child position + while childpos < endpos: + # Set childpos to index of smaller child. + rightpos = childpos + 1 + if rightpos < endpos and not cmp_lt(heap[childpos], heap[rightpos]): + childpos = rightpos + # Move the smaller child up. + heap[pos] = heap[childpos] + pos = childpos + childpos = 2*pos + 1 + # The leaf at pos is empty now. Put newitem there, and bubble it up + # to its final resting place (by sifting its parents down). + heap[pos] = newitem + _siftdown(heap, startpos, pos) + +def _siftdown_max(heap, startpos, pos): + 'Maxheap variant of _siftdown' + newitem = heap[pos] + # Follow the path to the root, moving parents down until finding a place + # newitem fits. + while pos > startpos: + parentpos = (pos - 1) >> 1 + parent = heap[parentpos] + if cmp_lt(parent, newitem): + heap[pos] = parent + pos = parentpos + continue + break + heap[pos] = newitem + +def _siftup_max(heap, pos): + 'Maxheap variant of _siftup' + endpos = len(heap) + startpos = pos + newitem = heap[pos] + # Bubble up the larger child until hitting a leaf. + childpos = 2*pos + 1 # leftmost child position + while childpos < endpos: + # Set childpos to index of larger child. + rightpos = childpos + 1 + if rightpos < endpos and not cmp_lt(heap[rightpos], heap[childpos]): + childpos = rightpos + # Move the larger child up. + heap[pos] = heap[childpos] + pos = childpos + childpos = 2*pos + 1 + # The leaf at pos is empty now. Put newitem there, and bubble it up + # to its final resting place (by sifting its parents down). + heap[pos] = newitem + _siftdown_max(heap, startpos, pos) + +# If available, use C implementation +try: + from _heapq import * +except ImportError: + pass + +def merge(*iterables): + '''Merge multiple sorted inputs into a single sorted output. + + Similar to sorted(itertools.chain(*iterables)) but returns a generator, + does not pull the data into memory all at once, and assumes that each of + the input streams is already sorted (smallest to largest). + + >>> list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) + [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] + + ''' + _heappop, _heapreplace, _StopIteration = heappop, heapreplace, StopIteration + + h = [] + h_append = h.append + for itnum, it in enumerate(map(iter, iterables)): + try: + next = it.next + h_append([next(), itnum, next]) + except _StopIteration: + pass + heapify(h) + + while 1: + try: + while 1: + v, itnum, next = s = h[0] # raises IndexError when h is empty + yield v + s[0] = next() # raises StopIteration when exhausted + _heapreplace(h, s) # restore heap condition + except _StopIteration: + _heappop(h) # remove empty iterator + except IndexError: + return + +# Extend the implementations of nsmallest and nlargest to use a key= argument +_nsmallest = nsmallest +def nsmallest(n, iterable, key=None): + """Find the n smallest elements in a dataset. + + Equivalent to: sorted(iterable, key=key)[:n] + """ + # Short-cut for n==1 is to use min() when len(iterable)>0 + if n == 1: + it = iter(iterable) + head = list(islice(it, 1)) + if not head: + return [] + if key is None: + return [min(chain(head, it))] + return [min(chain(head, it), key=key)] + + # When n>=size, it's faster to use sorted() + try: + size = len(iterable) + except (TypeError, AttributeError): + pass + else: + if n >= size: + return sorted(iterable, key=key)[:n] + + # When key is none, use simpler decoration + if key is None: + it = izip(iterable, count()) # decorate + result = _nsmallest(n, it) + return map(itemgetter(0), result) # undecorate + + # General case, slowest method + in1, in2 = tee(iterable) + it = izip(imap(key, in1), count(), in2) # decorate + result = _nsmallest(n, it) + return map(itemgetter(2), result) # undecorate + +_nlargest = nlargest +def nlargest(n, iterable, key=None): + """Find the n largest elements in a dataset. + + Equivalent to: sorted(iterable, key=key, reverse=True)[:n] + """ + + # Short-cut for n==1 is to use max() when len(iterable)>0 + if n == 1: + it = iter(iterable) + head = list(islice(it, 1)) + if not head: + return [] + if key is None: + return [max(chain(head, it))] + return [max(chain(head, it), key=key)] + + # When n>=size, it's faster to use sorted() + try: + size = len(iterable) + except (TypeError, AttributeError): + pass + else: + if n >= size: + return sorted(iterable, key=key, reverse=True)[:n] + + # When key is none, use simpler decoration + if key is None: + it = izip(iterable, count(0,-1)) # decorate + result = _nlargest(n, it) + return map(itemgetter(0), result) # undecorate + + # General case, slowest method + in1, in2 = tee(iterable) + it = izip(imap(key, in1), count(0,-1), in2) # decorate + result = _nlargest(n, it) + return map(itemgetter(2), result) # undecorate + +if __name__ == "__main__": + # Simple sanity test + heap = [] + data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] + for item in data: + heappush(heap, item) + sort = [] + while heap: + sort.append(heappop(heap)) + print sort + + import doctest + doctest.testmod() diff --git a/src/main/resources/PythonLibs/hmac.py b/src/main/resources/PythonLibs/hmac.py new file mode 100644 index 0000000000000000000000000000000000000000..538810630cf3ad5a471082e74f0a1e7d990b10c1 --- /dev/null +++ b/src/main/resources/PythonLibs/hmac.py @@ -0,0 +1,133 @@ +"""HMAC (Keyed-Hashing for Message Authentication) Python module. + +Implements the HMAC algorithm as described by RFC 2104. +""" + +import warnings as _warnings + +trans_5C = "".join ([chr (x ^ 0x5C) for x in xrange(256)]) +trans_36 = "".join ([chr (x ^ 0x36) for x in xrange(256)]) + +# The size of the digests returned by HMAC depends on the underlying +# hashing module used. Use digest_size from the instance of HMAC instead. +digest_size = None + +# A unique object passed by HMAC.copy() to the HMAC constructor, in order +# that the latter return very quickly. HMAC("") in contrast is quite +# expensive. +_secret_backdoor_key = [] + +class HMAC: + """RFC 2104 HMAC class. Also complies with RFC 4231. + + This supports the API for Cryptographic Hash Functions (PEP 247). + """ + blocksize = 64 # 512-bit HMAC; can be changed in subclasses. + + def __init__(self, key, msg = None, digestmod = None): + """Create a new HMAC object. + + key: key for the keyed hash object. + msg: Initial input for the hash, if provided. + digestmod: A module supporting PEP 247. *OR* + A hashlib constructor returning a new hash object. + Defaults to hashlib.md5. + """ + + if key is _secret_backdoor_key: # cheap + return + + if digestmod is None: + import hashlib + digestmod = hashlib.md5 + + if hasattr(digestmod, '__call__'): + self.digest_cons = digestmod + else: + self.digest_cons = lambda d='': digestmod.new(d) + + self.outer = self.digest_cons() + self.inner = self.digest_cons() + self.digest_size = self.inner.digest_size + + if hasattr(self.inner, 'block_size'): + blocksize = self.inner.block_size + if blocksize < 16: + # Very low blocksize, most likely a legacy value like + # Lib/sha.py and Lib/md5.py have. + _warnings.warn('block_size of %d seems too small; using our ' + 'default of %d.' % (blocksize, self.blocksize), + RuntimeWarning, 2) + blocksize = self.blocksize + else: + _warnings.warn('No block_size attribute on given digest object; ' + 'Assuming %d.' % (self.blocksize), + RuntimeWarning, 2) + blocksize = self.blocksize + + if len(key) > blocksize: + key = self.digest_cons(key).digest() + + key = key + chr(0) * (blocksize - len(key)) + self.outer.update(key.translate(trans_5C)) + self.inner.update(key.translate(trans_36)) + if msg is not None: + self.update(msg) + +## def clear(self): +## raise NotImplementedError, "clear() method not available in HMAC." + + def update(self, msg): + """Update this hashing object with the string msg. + """ + self.inner.update(msg) + + def copy(self): + """Return a separate copy of this hashing object. + + An update to this copy won't affect the original object. + """ + other = self.__class__(_secret_backdoor_key) + other.digest_cons = self.digest_cons + other.digest_size = self.digest_size + other.inner = self.inner.copy() + other.outer = self.outer.copy() + return other + + def _current(self): + """Return a hash object for the current state. + + To be used only internally with digest() and hexdigest(). + """ + h = self.outer.copy() + h.update(self.inner.digest()) + return h + + def digest(self): + """Return the hash value of this hashing object. + + This returns a string containing 8-bit data. The object is + not altered in any way by this function; you can continue + updating the object after calling this function. + """ + h = self._current() + return h.digest() + + def hexdigest(self): + """Like digest(), but returns a string of hexadecimal digits instead. + """ + h = self._current() + return h.hexdigest() + +def new(key, msg = None, digestmod = None): + """Create a new hashing object and return it. + + key: The starting key for the hash. + msg: if available, will immediately be hashed into the object's starting + state. + + You can now feed arbitrary strings into the object using its update() + method, and can ask for the hash value at any time by calling its digest() + method. + """ + return HMAC(key, msg, digestmod) diff --git a/src/main/resources/PythonLibs/htmlentitydefs.py b/src/main/resources/PythonLibs/htmlentitydefs.py new file mode 100644 index 0000000000000000000000000000000000000000..3dd14a79fab855c089b94d6d03902dfb61847c75 --- /dev/null +++ b/src/main/resources/PythonLibs/htmlentitydefs.py @@ -0,0 +1,273 @@ +"""HTML character entity references.""" + +# maps the HTML entity name to the Unicode codepoint +name2codepoint = { + 'AElig': 0x00c6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 + 'Aacute': 0x00c1, # latin capital letter A with acute, U+00C1 ISOlat1 + 'Acirc': 0x00c2, # latin capital letter A with circumflex, U+00C2 ISOlat1 + 'Agrave': 0x00c0, # latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 + 'Alpha': 0x0391, # greek capital letter alpha, U+0391 + 'Aring': 0x00c5, # latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 + 'Atilde': 0x00c3, # latin capital letter A with tilde, U+00C3 ISOlat1 + 'Auml': 0x00c4, # latin capital letter A with diaeresis, U+00C4 ISOlat1 + 'Beta': 0x0392, # greek capital letter beta, U+0392 + 'Ccedil': 0x00c7, # latin capital letter C with cedilla, U+00C7 ISOlat1 + 'Chi': 0x03a7, # greek capital letter chi, U+03A7 + 'Dagger': 0x2021, # double dagger, U+2021 ISOpub + 'Delta': 0x0394, # greek capital letter delta, U+0394 ISOgrk3 + 'ETH': 0x00d0, # latin capital letter ETH, U+00D0 ISOlat1 + 'Eacute': 0x00c9, # latin capital letter E with acute, U+00C9 ISOlat1 + 'Ecirc': 0x00ca, # latin capital letter E with circumflex, U+00CA ISOlat1 + 'Egrave': 0x00c8, # latin capital letter E with grave, U+00C8 ISOlat1 + 'Epsilon': 0x0395, # greek capital letter epsilon, U+0395 + 'Eta': 0x0397, # greek capital letter eta, U+0397 + 'Euml': 0x00cb, # latin capital letter E with diaeresis, U+00CB ISOlat1 + 'Gamma': 0x0393, # greek capital letter gamma, U+0393 ISOgrk3 + 'Iacute': 0x00cd, # latin capital letter I with acute, U+00CD ISOlat1 + 'Icirc': 0x00ce, # latin capital letter I with circumflex, U+00CE ISOlat1 + 'Igrave': 0x00cc, # latin capital letter I with grave, U+00CC ISOlat1 + 'Iota': 0x0399, # greek capital letter iota, U+0399 + 'Iuml': 0x00cf, # latin capital letter I with diaeresis, U+00CF ISOlat1 + 'Kappa': 0x039a, # greek capital letter kappa, U+039A + 'Lambda': 0x039b, # greek capital letter lambda, U+039B ISOgrk3 + 'Mu': 0x039c, # greek capital letter mu, U+039C + 'Ntilde': 0x00d1, # latin capital letter N with tilde, U+00D1 ISOlat1 + 'Nu': 0x039d, # greek capital letter nu, U+039D + 'OElig': 0x0152, # latin capital ligature OE, U+0152 ISOlat2 + 'Oacute': 0x00d3, # latin capital letter O with acute, U+00D3 ISOlat1 + 'Ocirc': 0x00d4, # latin capital letter O with circumflex, U+00D4 ISOlat1 + 'Ograve': 0x00d2, # latin capital letter O with grave, U+00D2 ISOlat1 + 'Omega': 0x03a9, # greek capital letter omega, U+03A9 ISOgrk3 + 'Omicron': 0x039f, # greek capital letter omicron, U+039F + 'Oslash': 0x00d8, # latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 + 'Otilde': 0x00d5, # latin capital letter O with tilde, U+00D5 ISOlat1 + 'Ouml': 0x00d6, # latin capital letter O with diaeresis, U+00D6 ISOlat1 + 'Phi': 0x03a6, # greek capital letter phi, U+03A6 ISOgrk3 + 'Pi': 0x03a0, # greek capital letter pi, U+03A0 ISOgrk3 + 'Prime': 0x2033, # double prime = seconds = inches, U+2033 ISOtech + 'Psi': 0x03a8, # greek capital letter psi, U+03A8 ISOgrk3 + 'Rho': 0x03a1, # greek capital letter rho, U+03A1 + 'Scaron': 0x0160, # latin capital letter S with caron, U+0160 ISOlat2 + 'Sigma': 0x03a3, # greek capital letter sigma, U+03A3 ISOgrk3 + 'THORN': 0x00de, # latin capital letter THORN, U+00DE ISOlat1 + 'Tau': 0x03a4, # greek capital letter tau, U+03A4 + 'Theta': 0x0398, # greek capital letter theta, U+0398 ISOgrk3 + 'Uacute': 0x00da, # latin capital letter U with acute, U+00DA ISOlat1 + 'Ucirc': 0x00db, # latin capital letter U with circumflex, U+00DB ISOlat1 + 'Ugrave': 0x00d9, # latin capital letter U with grave, U+00D9 ISOlat1 + 'Upsilon': 0x03a5, # greek capital letter upsilon, U+03A5 ISOgrk3 + 'Uuml': 0x00dc, # latin capital letter U with diaeresis, U+00DC ISOlat1 + 'Xi': 0x039e, # greek capital letter xi, U+039E ISOgrk3 + 'Yacute': 0x00dd, # latin capital letter Y with acute, U+00DD ISOlat1 + 'Yuml': 0x0178, # latin capital letter Y with diaeresis, U+0178 ISOlat2 + 'Zeta': 0x0396, # greek capital letter zeta, U+0396 + 'aacute': 0x00e1, # latin small letter a with acute, U+00E1 ISOlat1 + 'acirc': 0x00e2, # latin small letter a with circumflex, U+00E2 ISOlat1 + 'acute': 0x00b4, # acute accent = spacing acute, U+00B4 ISOdia + 'aelig': 0x00e6, # latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 + 'agrave': 0x00e0, # latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 + 'alefsym': 0x2135, # alef symbol = first transfinite cardinal, U+2135 NEW + 'alpha': 0x03b1, # greek small letter alpha, U+03B1 ISOgrk3 + 'amp': 0x0026, # ampersand, U+0026 ISOnum + 'and': 0x2227, # logical and = wedge, U+2227 ISOtech + 'ang': 0x2220, # angle, U+2220 ISOamso + 'aring': 0x00e5, # latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 + 'asymp': 0x2248, # almost equal to = asymptotic to, U+2248 ISOamsr + 'atilde': 0x00e3, # latin small letter a with tilde, U+00E3 ISOlat1 + 'auml': 0x00e4, # latin small letter a with diaeresis, U+00E4 ISOlat1 + 'bdquo': 0x201e, # double low-9 quotation mark, U+201E NEW + 'beta': 0x03b2, # greek small letter beta, U+03B2 ISOgrk3 + 'brvbar': 0x00a6, # broken bar = broken vertical bar, U+00A6 ISOnum + 'bull': 0x2022, # bullet = black small circle, U+2022 ISOpub + 'cap': 0x2229, # intersection = cap, U+2229 ISOtech + 'ccedil': 0x00e7, # latin small letter c with cedilla, U+00E7 ISOlat1 + 'cedil': 0x00b8, # cedilla = spacing cedilla, U+00B8 ISOdia + 'cent': 0x00a2, # cent sign, U+00A2 ISOnum + 'chi': 0x03c7, # greek small letter chi, U+03C7 ISOgrk3 + 'circ': 0x02c6, # modifier letter circumflex accent, U+02C6 ISOpub + 'clubs': 0x2663, # black club suit = shamrock, U+2663 ISOpub + 'cong': 0x2245, # approximately equal to, U+2245 ISOtech + 'copy': 0x00a9, # copyright sign, U+00A9 ISOnum + 'crarr': 0x21b5, # downwards arrow with corner leftwards = carriage return, U+21B5 NEW + 'cup': 0x222a, # union = cup, U+222A ISOtech + 'curren': 0x00a4, # currency sign, U+00A4 ISOnum + 'dArr': 0x21d3, # downwards double arrow, U+21D3 ISOamsa + 'dagger': 0x2020, # dagger, U+2020 ISOpub + 'darr': 0x2193, # downwards arrow, U+2193 ISOnum + 'deg': 0x00b0, # degree sign, U+00B0 ISOnum + 'delta': 0x03b4, # greek small letter delta, U+03B4 ISOgrk3 + 'diams': 0x2666, # black diamond suit, U+2666 ISOpub + 'divide': 0x00f7, # division sign, U+00F7 ISOnum + 'eacute': 0x00e9, # latin small letter e with acute, U+00E9 ISOlat1 + 'ecirc': 0x00ea, # latin small letter e with circumflex, U+00EA ISOlat1 + 'egrave': 0x00e8, # latin small letter e with grave, U+00E8 ISOlat1 + 'empty': 0x2205, # empty set = null set = diameter, U+2205 ISOamso + 'emsp': 0x2003, # em space, U+2003 ISOpub + 'ensp': 0x2002, # en space, U+2002 ISOpub + 'epsilon': 0x03b5, # greek small letter epsilon, U+03B5 ISOgrk3 + 'equiv': 0x2261, # identical to, U+2261 ISOtech + 'eta': 0x03b7, # greek small letter eta, U+03B7 ISOgrk3 + 'eth': 0x00f0, # latin small letter eth, U+00F0 ISOlat1 + 'euml': 0x00eb, # latin small letter e with diaeresis, U+00EB ISOlat1 + 'euro': 0x20ac, # euro sign, U+20AC NEW + 'exist': 0x2203, # there exists, U+2203 ISOtech + 'fnof': 0x0192, # latin small f with hook = function = florin, U+0192 ISOtech + 'forall': 0x2200, # for all, U+2200 ISOtech + 'frac12': 0x00bd, # vulgar fraction one half = fraction one half, U+00BD ISOnum + 'frac14': 0x00bc, # vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum + 'frac34': 0x00be, # vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum + 'frasl': 0x2044, # fraction slash, U+2044 NEW + 'gamma': 0x03b3, # greek small letter gamma, U+03B3 ISOgrk3 + 'ge': 0x2265, # greater-than or equal to, U+2265 ISOtech + 'gt': 0x003e, # greater-than sign, U+003E ISOnum + 'hArr': 0x21d4, # left right double arrow, U+21D4 ISOamsa + 'harr': 0x2194, # left right arrow, U+2194 ISOamsa + 'hearts': 0x2665, # black heart suit = valentine, U+2665 ISOpub + 'hellip': 0x2026, # horizontal ellipsis = three dot leader, U+2026 ISOpub + 'iacute': 0x00ed, # latin small letter i with acute, U+00ED ISOlat1 + 'icirc': 0x00ee, # latin small letter i with circumflex, U+00EE ISOlat1 + 'iexcl': 0x00a1, # inverted exclamation mark, U+00A1 ISOnum + 'igrave': 0x00ec, # latin small letter i with grave, U+00EC ISOlat1 + 'image': 0x2111, # blackletter capital I = imaginary part, U+2111 ISOamso + 'infin': 0x221e, # infinity, U+221E ISOtech + 'int': 0x222b, # integral, U+222B ISOtech + 'iota': 0x03b9, # greek small letter iota, U+03B9 ISOgrk3 + 'iquest': 0x00bf, # inverted question mark = turned question mark, U+00BF ISOnum + 'isin': 0x2208, # element of, U+2208 ISOtech + 'iuml': 0x00ef, # latin small letter i with diaeresis, U+00EF ISOlat1 + 'kappa': 0x03ba, # greek small letter kappa, U+03BA ISOgrk3 + 'lArr': 0x21d0, # leftwards double arrow, U+21D0 ISOtech + 'lambda': 0x03bb, # greek small letter lambda, U+03BB ISOgrk3 + 'lang': 0x2329, # left-pointing angle bracket = bra, U+2329 ISOtech + 'laquo': 0x00ab, # left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum + 'larr': 0x2190, # leftwards arrow, U+2190 ISOnum + 'lceil': 0x2308, # left ceiling = apl upstile, U+2308 ISOamsc + 'ldquo': 0x201c, # left double quotation mark, U+201C ISOnum + 'le': 0x2264, # less-than or equal to, U+2264 ISOtech + 'lfloor': 0x230a, # left floor = apl downstile, U+230A ISOamsc + 'lowast': 0x2217, # asterisk operator, U+2217 ISOtech + 'loz': 0x25ca, # lozenge, U+25CA ISOpub + 'lrm': 0x200e, # left-to-right mark, U+200E NEW RFC 2070 + 'lsaquo': 0x2039, # single left-pointing angle quotation mark, U+2039 ISO proposed + 'lsquo': 0x2018, # left single quotation mark, U+2018 ISOnum + 'lt': 0x003c, # less-than sign, U+003C ISOnum + 'macr': 0x00af, # macron = spacing macron = overline = APL overbar, U+00AF ISOdia + 'mdash': 0x2014, # em dash, U+2014 ISOpub + 'micro': 0x00b5, # micro sign, U+00B5 ISOnum + 'middot': 0x00b7, # middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum + 'minus': 0x2212, # minus sign, U+2212 ISOtech + 'mu': 0x03bc, # greek small letter mu, U+03BC ISOgrk3 + 'nabla': 0x2207, # nabla = backward difference, U+2207 ISOtech + 'nbsp': 0x00a0, # no-break space = non-breaking space, U+00A0 ISOnum + 'ndash': 0x2013, # en dash, U+2013 ISOpub + 'ne': 0x2260, # not equal to, U+2260 ISOtech + 'ni': 0x220b, # contains as member, U+220B ISOtech + 'not': 0x00ac, # not sign, U+00AC ISOnum + 'notin': 0x2209, # not an element of, U+2209 ISOtech + 'nsub': 0x2284, # not a subset of, U+2284 ISOamsn + 'ntilde': 0x00f1, # latin small letter n with tilde, U+00F1 ISOlat1 + 'nu': 0x03bd, # greek small letter nu, U+03BD ISOgrk3 + 'oacute': 0x00f3, # latin small letter o with acute, U+00F3 ISOlat1 + 'ocirc': 0x00f4, # latin small letter o with circumflex, U+00F4 ISOlat1 + 'oelig': 0x0153, # latin small ligature oe, U+0153 ISOlat2 + 'ograve': 0x00f2, # latin small letter o with grave, U+00F2 ISOlat1 + 'oline': 0x203e, # overline = spacing overscore, U+203E NEW + 'omega': 0x03c9, # greek small letter omega, U+03C9 ISOgrk3 + 'omicron': 0x03bf, # greek small letter omicron, U+03BF NEW + 'oplus': 0x2295, # circled plus = direct sum, U+2295 ISOamsb + 'or': 0x2228, # logical or = vee, U+2228 ISOtech + 'ordf': 0x00aa, # feminine ordinal indicator, U+00AA ISOnum + 'ordm': 0x00ba, # masculine ordinal indicator, U+00BA ISOnum + 'oslash': 0x00f8, # latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 + 'otilde': 0x00f5, # latin small letter o with tilde, U+00F5 ISOlat1 + 'otimes': 0x2297, # circled times = vector product, U+2297 ISOamsb + 'ouml': 0x00f6, # latin small letter o with diaeresis, U+00F6 ISOlat1 + 'para': 0x00b6, # pilcrow sign = paragraph sign, U+00B6 ISOnum + 'part': 0x2202, # partial differential, U+2202 ISOtech + 'permil': 0x2030, # per mille sign, U+2030 ISOtech + 'perp': 0x22a5, # up tack = orthogonal to = perpendicular, U+22A5 ISOtech + 'phi': 0x03c6, # greek small letter phi, U+03C6 ISOgrk3 + 'pi': 0x03c0, # greek small letter pi, U+03C0 ISOgrk3 + 'piv': 0x03d6, # greek pi symbol, U+03D6 ISOgrk3 + 'plusmn': 0x00b1, # plus-minus sign = plus-or-minus sign, U+00B1 ISOnum + 'pound': 0x00a3, # pound sign, U+00A3 ISOnum + 'prime': 0x2032, # prime = minutes = feet, U+2032 ISOtech + 'prod': 0x220f, # n-ary product = product sign, U+220F ISOamsb + 'prop': 0x221d, # proportional to, U+221D ISOtech + 'psi': 0x03c8, # greek small letter psi, U+03C8 ISOgrk3 + 'quot': 0x0022, # quotation mark = APL quote, U+0022 ISOnum + 'rArr': 0x21d2, # rightwards double arrow, U+21D2 ISOtech + 'radic': 0x221a, # square root = radical sign, U+221A ISOtech + 'rang': 0x232a, # right-pointing angle bracket = ket, U+232A ISOtech + 'raquo': 0x00bb, # right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum + 'rarr': 0x2192, # rightwards arrow, U+2192 ISOnum + 'rceil': 0x2309, # right ceiling, U+2309 ISOamsc + 'rdquo': 0x201d, # right double quotation mark, U+201D ISOnum + 'real': 0x211c, # blackletter capital R = real part symbol, U+211C ISOamso + 'reg': 0x00ae, # registered sign = registered trade mark sign, U+00AE ISOnum + 'rfloor': 0x230b, # right floor, U+230B ISOamsc + 'rho': 0x03c1, # greek small letter rho, U+03C1 ISOgrk3 + 'rlm': 0x200f, # right-to-left mark, U+200F NEW RFC 2070 + 'rsaquo': 0x203a, # single right-pointing angle quotation mark, U+203A ISO proposed + 'rsquo': 0x2019, # right single quotation mark, U+2019 ISOnum + 'sbquo': 0x201a, # single low-9 quotation mark, U+201A NEW + 'scaron': 0x0161, # latin small letter s with caron, U+0161 ISOlat2 + 'sdot': 0x22c5, # dot operator, U+22C5 ISOamsb + 'sect': 0x00a7, # section sign, U+00A7 ISOnum + 'shy': 0x00ad, # soft hyphen = discretionary hyphen, U+00AD ISOnum + 'sigma': 0x03c3, # greek small letter sigma, U+03C3 ISOgrk3 + 'sigmaf': 0x03c2, # greek small letter final sigma, U+03C2 ISOgrk3 + 'sim': 0x223c, # tilde operator = varies with = similar to, U+223C ISOtech + 'spades': 0x2660, # black spade suit, U+2660 ISOpub + 'sub': 0x2282, # subset of, U+2282 ISOtech + 'sube': 0x2286, # subset of or equal to, U+2286 ISOtech + 'sum': 0x2211, # n-ary sumation, U+2211 ISOamsb + 'sup': 0x2283, # superset of, U+2283 ISOtech + 'sup1': 0x00b9, # superscript one = superscript digit one, U+00B9 ISOnum + 'sup2': 0x00b2, # superscript two = superscript digit two = squared, U+00B2 ISOnum + 'sup3': 0x00b3, # superscript three = superscript digit three = cubed, U+00B3 ISOnum + 'supe': 0x2287, # superset of or equal to, U+2287 ISOtech + 'szlig': 0x00df, # latin small letter sharp s = ess-zed, U+00DF ISOlat1 + 'tau': 0x03c4, # greek small letter tau, U+03C4 ISOgrk3 + 'there4': 0x2234, # therefore, U+2234 ISOtech + 'theta': 0x03b8, # greek small letter theta, U+03B8 ISOgrk3 + 'thetasym': 0x03d1, # greek small letter theta symbol, U+03D1 NEW + 'thinsp': 0x2009, # thin space, U+2009 ISOpub + 'thorn': 0x00fe, # latin small letter thorn with, U+00FE ISOlat1 + 'tilde': 0x02dc, # small tilde, U+02DC ISOdia + 'times': 0x00d7, # multiplication sign, U+00D7 ISOnum + 'trade': 0x2122, # trade mark sign, U+2122 ISOnum + 'uArr': 0x21d1, # upwards double arrow, U+21D1 ISOamsa + 'uacute': 0x00fa, # latin small letter u with acute, U+00FA ISOlat1 + 'uarr': 0x2191, # upwards arrow, U+2191 ISOnum + 'ucirc': 0x00fb, # latin small letter u with circumflex, U+00FB ISOlat1 + 'ugrave': 0x00f9, # latin small letter u with grave, U+00F9 ISOlat1 + 'uml': 0x00a8, # diaeresis = spacing diaeresis, U+00A8 ISOdia + 'upsih': 0x03d2, # greek upsilon with hook symbol, U+03D2 NEW + 'upsilon': 0x03c5, # greek small letter upsilon, U+03C5 ISOgrk3 + 'uuml': 0x00fc, # latin small letter u with diaeresis, U+00FC ISOlat1 + 'weierp': 0x2118, # script capital P = power set = Weierstrass p, U+2118 ISOamso + 'xi': 0x03be, # greek small letter xi, U+03BE ISOgrk3 + 'yacute': 0x00fd, # latin small letter y with acute, U+00FD ISOlat1 + 'yen': 0x00a5, # yen sign = yuan sign, U+00A5 ISOnum + 'yuml': 0x00ff, # latin small letter y with diaeresis, U+00FF ISOlat1 + 'zeta': 0x03b6, # greek small letter zeta, U+03B6 ISOgrk3 + 'zwj': 0x200d, # zero width joiner, U+200D NEW RFC 2070 + 'zwnj': 0x200c, # zero width non-joiner, U+200C NEW RFC 2070 +} + +# maps the Unicode codepoint to the HTML entity name +codepoint2name = {} + +# maps the HTML entity name to the character +# (or a character reference if the character is outside the Latin-1 range) +entitydefs = {} + +for (name, codepoint) in name2codepoint.iteritems(): + codepoint2name[codepoint] = name + if codepoint <= 0xff: + entitydefs[name] = chr(codepoint) + else: + entitydefs[name] = '&#%d;' % codepoint + +del name, codepoint diff --git a/src/main/resources/PythonLibs/htmllib.py b/src/main/resources/PythonLibs/htmllib.py new file mode 100644 index 0000000000000000000000000000000000000000..44647dbf026c054c563a78dee19020927cfd5d88 --- /dev/null +++ b/src/main/resources/PythonLibs/htmllib.py @@ -0,0 +1,491 @@ +"""HTML 2.0 parser. + +See the HTML 2.0 specification: +http://www.w3.org/hypertext/WWW/MarkUp/html-spec/html-spec_toc.html +""" + +from warnings import warnpy3k +warnpy3k("the htmllib module has been removed in Python 3.0", + stacklevel=2) +del warnpy3k + +import sgmllib + +from formatter import AS_IS + +__all__ = ["HTMLParser", "HTMLParseError"] + + +class HTMLParseError(sgmllib.SGMLParseError): + """Error raised when an HTML document can't be parsed.""" + + +class HTMLParser(sgmllib.SGMLParser): + """This is the basic HTML parser class. + + It supports all entity names required by the XHTML 1.0 Recommendation. + It also defines handlers for all HTML 2.0 and many HTML 3.0 and 3.2 + elements. + + """ + + from htmlentitydefs import entitydefs + + def __init__(self, formatter, verbose=0): + """Creates an instance of the HTMLParser class. + + The formatter parameter is the formatter instance associated with + the parser. + + """ + sgmllib.SGMLParser.__init__(self, verbose) + self.formatter = formatter + + def error(self, message): + raise HTMLParseError(message) + + def reset(self): + sgmllib.SGMLParser.reset(self) + self.savedata = None + self.isindex = 0 + self.title = None + self.base = None + self.anchor = None + self.anchorlist = [] + self.nofill = 0 + self.list_stack = [] + + # ------ Methods used internally; some may be overridden + + # --- Formatter interface, taking care of 'savedata' mode; + # shouldn't need to be overridden + + def handle_data(self, data): + if self.savedata is not None: + self.savedata = self.savedata + data + else: + if self.nofill: + self.formatter.add_literal_data(data) + else: + self.formatter.add_flowing_data(data) + + # --- Hooks to save data; shouldn't need to be overridden + + def save_bgn(self): + """Begins saving character data in a buffer instead of sending it + to the formatter object. + + Retrieve the stored data via the save_end() method. Use of the + save_bgn() / save_end() pair may not be nested. + + """ + self.savedata = '' + + def save_end(self): + """Ends buffering character data and returns all data saved since + the preceding call to the save_bgn() method. + + If the nofill flag is false, whitespace is collapsed to single + spaces. A call to this method without a preceding call to the + save_bgn() method will raise a TypeError exception. + + """ + data = self.savedata + self.savedata = None + if not self.nofill: + data = ' '.join(data.split()) + return data + + # --- Hooks for anchors; should probably be overridden + + def anchor_bgn(self, href, name, type): + """This method is called at the start of an anchor region. + + The arguments correspond to the attributes of the <A> tag with + the same names. The default implementation maintains a list of + hyperlinks (defined by the HREF attribute for <A> tags) within + the document. The list of hyperlinks is available as the data + attribute anchorlist. + + """ + self.anchor = href + if self.anchor: + self.anchorlist.append(href) + + def anchor_end(self): + """This method is called at the end of an anchor region. + + The default implementation adds a textual footnote marker using an + index into the list of hyperlinks created by the anchor_bgn()method. + + """ + if self.anchor: + self.handle_data("[%d]" % len(self.anchorlist)) + self.anchor = None + + # --- Hook for images; should probably be overridden + + def handle_image(self, src, alt, *args): + """This method is called to handle images. + + The default implementation simply passes the alt value to the + handle_data() method. + + """ + self.handle_data(alt) + + # --------- Top level elememts + + def start_html(self, attrs): pass + def end_html(self): pass + + def start_head(self, attrs): pass + def end_head(self): pass + + def start_body(self, attrs): pass + def end_body(self): pass + + # ------ Head elements + + def start_title(self, attrs): + self.save_bgn() + + def end_title(self): + self.title = self.save_end() + + def do_base(self, attrs): + for a, v in attrs: + if a == 'href': + self.base = v + + def do_isindex(self, attrs): + self.isindex = 1 + + def do_link(self, attrs): + pass + + def do_meta(self, attrs): + pass + + def do_nextid(self, attrs): # Deprecated + pass + + # ------ Body elements + + # --- Headings + + def start_h1(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_font(('h1', 0, 1, 0)) + + def end_h1(self): + self.formatter.end_paragraph(1) + self.formatter.pop_font() + + def start_h2(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_font(('h2', 0, 1, 0)) + + def end_h2(self): + self.formatter.end_paragraph(1) + self.formatter.pop_font() + + def start_h3(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_font(('h3', 0, 1, 0)) + + def end_h3(self): + self.formatter.end_paragraph(1) + self.formatter.pop_font() + + def start_h4(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_font(('h4', 0, 1, 0)) + + def end_h4(self): + self.formatter.end_paragraph(1) + self.formatter.pop_font() + + def start_h5(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_font(('h5', 0, 1, 0)) + + def end_h5(self): + self.formatter.end_paragraph(1) + self.formatter.pop_font() + + def start_h6(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_font(('h6', 0, 1, 0)) + + def end_h6(self): + self.formatter.end_paragraph(1) + self.formatter.pop_font() + + # --- Block Structuring Elements + + def do_p(self, attrs): + self.formatter.end_paragraph(1) + + def start_pre(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_font((AS_IS, AS_IS, AS_IS, 1)) + self.nofill = self.nofill + 1 + + def end_pre(self): + self.formatter.end_paragraph(1) + self.formatter.pop_font() + self.nofill = max(0, self.nofill - 1) + + def start_xmp(self, attrs): + self.start_pre(attrs) + self.setliteral('xmp') # Tell SGML parser + + def end_xmp(self): + self.end_pre() + + def start_listing(self, attrs): + self.start_pre(attrs) + self.setliteral('listing') # Tell SGML parser + + def end_listing(self): + self.end_pre() + + def start_address(self, attrs): + self.formatter.end_paragraph(0) + self.formatter.push_font((AS_IS, 1, AS_IS, AS_IS)) + + def end_address(self): + self.formatter.end_paragraph(0) + self.formatter.pop_font() + + def start_blockquote(self, attrs): + self.formatter.end_paragraph(1) + self.formatter.push_margin('blockquote') + + def end_blockquote(self): + self.formatter.end_paragraph(1) + self.formatter.pop_margin() + + # --- List Elements + + def start_ul(self, attrs): + self.formatter.end_paragraph(not self.list_stack) + self.formatter.push_margin('ul') + self.list_stack.append(['ul', '*', 0]) + + def end_ul(self): + if self.list_stack: del self.list_stack[-1] + self.formatter.end_paragraph(not self.list_stack) + self.formatter.pop_margin() + + def do_li(self, attrs): + self.formatter.end_paragraph(0) + if self.list_stack: + [dummy, label, counter] = top = self.list_stack[-1] + top[2] = counter = counter+1 + else: + label, counter = '*', 0 + self.formatter.add_label_data(label, counter) + + def start_ol(self, attrs): + self.formatter.end_paragraph(not self.list_stack) + self.formatter.push_margin('ol') + label = '1.' + for a, v in attrs: + if a == 'type': + if len(v) == 1: v = v + '.' + label = v + self.list_stack.append(['ol', label, 0]) + + def end_ol(self): + if self.list_stack: del self.list_stack[-1] + self.formatter.end_paragraph(not self.list_stack) + self.formatter.pop_margin() + + def start_menu(self, attrs): + self.start_ul(attrs) + + def end_menu(self): + self.end_ul() + + def start_dir(self, attrs): + self.start_ul(attrs) + + def end_dir(self): + self.end_ul() + + def start_dl(self, attrs): + self.formatter.end_paragraph(1) + self.list_stack.append(['dl', '', 0]) + + def end_dl(self): + self.ddpop(1) + if self.list_stack: del self.list_stack[-1] + + def do_dt(self, attrs): + self.ddpop() + + def do_dd(self, attrs): + self.ddpop() + self.formatter.push_margin('dd') + self.list_stack.append(['dd', '', 0]) + + def ddpop(self, bl=0): + self.formatter.end_paragraph(bl) + if self.list_stack: + if self.list_stack[-1][0] == 'dd': + del self.list_stack[-1] + self.formatter.pop_margin() + + # --- Phrase Markup + + # Idiomatic Elements + + def start_cite(self, attrs): self.start_i(attrs) + def end_cite(self): self.end_i() + + def start_code(self, attrs): self.start_tt(attrs) + def end_code(self): self.end_tt() + + def start_em(self, attrs): self.start_i(attrs) + def end_em(self): self.end_i() + + def start_kbd(self, attrs): self.start_tt(attrs) + def end_kbd(self): self.end_tt() + + def start_samp(self, attrs): self.start_tt(attrs) + def end_samp(self): self.end_tt() + + def start_strong(self, attrs): self.start_b(attrs) + def end_strong(self): self.end_b() + + def start_var(self, attrs): self.start_i(attrs) + def end_var(self): self.end_i() + + # Typographic Elements + + def start_i(self, attrs): + self.formatter.push_font((AS_IS, 1, AS_IS, AS_IS)) + def end_i(self): + self.formatter.pop_font() + + def start_b(self, attrs): + self.formatter.push_font((AS_IS, AS_IS, 1, AS_IS)) + def end_b(self): + self.formatter.pop_font() + + def start_tt(self, attrs): + self.formatter.push_font((AS_IS, AS_IS, AS_IS, 1)) + def end_tt(self): + self.formatter.pop_font() + + def start_a(self, attrs): + href = '' + name = '' + type = '' + for attrname, value in attrs: + value = value.strip() + if attrname == 'href': + href = value + if attrname == 'name': + name = value + if attrname == 'type': + type = value.lower() + self.anchor_bgn(href, name, type) + + def end_a(self): + self.anchor_end() + + # --- Line Break + + def do_br(self, attrs): + self.formatter.add_line_break() + + # --- Horizontal Rule + + def do_hr(self, attrs): + self.formatter.add_hor_rule() + + # --- Image + + def do_img(self, attrs): + align = '' + alt = '(image)' + ismap = '' + src = '' + width = 0 + height = 0 + for attrname, value in attrs: + if attrname == 'align': + align = value + if attrname == 'alt': + alt = value + if attrname == 'ismap': + ismap = value + if attrname == 'src': + src = value + if attrname == 'width': + try: width = int(value) + except ValueError: pass + if attrname == 'height': + try: height = int(value) + except ValueError: pass + self.handle_image(src, alt, ismap, align, width, height) + + # --- Really Old Unofficial Deprecated Stuff + + def do_plaintext(self, attrs): + self.start_pre(attrs) + self.setnomoretags() # Tell SGML parser + + # --- Unhandled tags + + def unknown_starttag(self, tag, attrs): + pass + + def unknown_endtag(self, tag): + pass + + +def test(args = None): + import sys, formatter + + if not args: + args = sys.argv[1:] + + silent = args and args[0] == '-s' + if silent: + del args[0] + + if args: + file = args[0] + else: + file = 'test.html' + + if file == '-': + f = sys.stdin + else: + try: + f = open(file, 'r') + except IOError, msg: + print file, ":", msg + sys.exit(1) + + data = f.read() + + if f is not sys.stdin: + f.close() + + if silent: + f = formatter.NullFormatter() + else: + f = formatter.AbstractFormatter(formatter.DumbWriter()) + + p = HTMLParser(f) + p.feed(data) + p.close() + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/httplib.py b/src/main/resources/PythonLibs/httplib.py new file mode 100644 index 0000000000000000000000000000000000000000..5c919d2b2fafb81b98b1b26a43e91538fda4ebc9 --- /dev/null +++ b/src/main/resources/PythonLibs/httplib.py @@ -0,0 +1,1342 @@ +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 + | + | response = getresponse() + v + Unread-response [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> +""" + +from array import array +import os +import socket +from sys import py3kwarning +from urlparse import urlsplit +import warnings +with warnings.catch_warnings(): + if py3kwarning: + warnings.filterwarnings("ignore", ".*mimetools has been removed", + DeprecationWarning) + import mimetools + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +__all__ = ["HTTP", "HTTPResponse", "HTTPConnection", + "HTTPException", "NotConnected", "UnknownProtocol", + "UnknownTransferEncoding", "UnimplementedFileMode", + "IncompleteRead", "InvalidURL", "ImproperConnectionState", + "CannotSendRequest", "CannotSendHeader", "ResponseNotReady", + "BadStatusLine", "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' + +# status codes +# informational +CONTINUE = 100 +SWITCHING_PROTOCOLS = 101 +PROCESSING = 102 + +# successful +OK = 200 +CREATED = 201 +ACCEPTED = 202 +NON_AUTHORITATIVE_INFORMATION = 203 +NO_CONTENT = 204 +RESET_CONTENT = 205 +PARTIAL_CONTENT = 206 +MULTI_STATUS = 207 +IM_USED = 226 + +# redirection +MULTIPLE_CHOICES = 300 +MOVED_PERMANENTLY = 301 +FOUND = 302 +SEE_OTHER = 303 +NOT_MODIFIED = 304 +USE_PROXY = 305 +TEMPORARY_REDIRECT = 307 + +# client error +BAD_REQUEST = 400 +UNAUTHORIZED = 401 +PAYMENT_REQUIRED = 402 +FORBIDDEN = 403 +NOT_FOUND = 404 +METHOD_NOT_ALLOWED = 405 +NOT_ACCEPTABLE = 406 +PROXY_AUTHENTICATION_REQUIRED = 407 +REQUEST_TIMEOUT = 408 +CONFLICT = 409 +GONE = 410 +LENGTH_REQUIRED = 411 +PRECONDITION_FAILED = 412 +REQUEST_ENTITY_TOO_LARGE = 413 +REQUEST_URI_TOO_LONG = 414 +UNSUPPORTED_MEDIA_TYPE = 415 +REQUESTED_RANGE_NOT_SATISFIABLE = 416 +EXPECTATION_FAILED = 417 +UNPROCESSABLE_ENTITY = 422 +LOCKED = 423 +FAILED_DEPENDENCY = 424 +UPGRADE_REQUIRED = 426 + +# server error +INTERNAL_SERVER_ERROR = 500 +NOT_IMPLEMENTED = 501 +BAD_GATEWAY = 502 +SERVICE_UNAVAILABLE = 503 +GATEWAY_TIMEOUT = 504 +HTTP_VERSION_NOT_SUPPORTED = 505 +INSUFFICIENT_STORAGE = 507 +NOT_EXTENDED = 510 + +# Mapping status codes to official W3C names +responses = { + 100: 'Continue', + 101: 'Switching Protocols', + + 200: 'OK', + 201: 'Created', + 202: 'Accepted', + 203: 'Non-Authoritative Information', + 204: 'No Content', + 205: 'Reset Content', + 206: 'Partial Content', + + 300: 'Multiple Choices', + 301: 'Moved Permanently', + 302: 'Found', + 303: 'See Other', + 304: 'Not Modified', + 305: 'Use Proxy', + 306: '(Unused)', + 307: 'Temporary Redirect', + + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Request Entity Too Large', + 414: 'Request-URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Requested Range Not Satisfiable', + 417: 'Expectation Failed', + + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', +} + +# maximal amount of data to read at one time in _safe_read +MAXAMOUNT = 1048576 + +# maximal line length when calling readline(). +_MAXLINE = 65536 + +class HTTPMessage(mimetools.Message): + + def addheader(self, key, value): + """Add header for field key handling repeats.""" + prev = self.dict.get(key) + if prev is None: + self.dict[key] = value + else: + combined = ", ".join((prev, value)) + self.dict[key] = combined + + def addcontinue(self, key, more): + """Add more field data from a continuation line.""" + prev = self.dict[key] + self.dict[key] = prev + "\n " + more + + def readheaders(self): + """Read header lines. + + Read header lines up to the entirely blank line that terminates them. + The (normally blank) line that ends the headers is skipped, but not + included in the returned list. If a non-header line ends the headers, + (which is an error), an attempt is made to backspace over it; it is + never included in the returned list. + + The variable self.status is set to the empty string if all went well, + otherwise it is an error message. The variable self.headers is a + completely uninterpreted list of lines contained in the header (so + printing them will reproduce the header exactly as it appears in the + file). + + If multiple header fields with the same name occur, they are combined + according to the rules in RFC 2616 sec 4.2: + + Appending each subsequent field-value to the first, each separated + by a comma. The order in which header fields with the same field-name + are received is significant to the interpretation of the combined + field value. + """ + # XXX The implementation overrides the readheaders() method of + # rfc822.Message. The base class design isn't amenable to + # customized behavior here so the method here is a copy of the + # base class code with a few small changes. + + self.dict = {} + self.unixfrom = '' + self.headers = hlist = [] + self.status = '' + headerseen = "" + firstline = 1 + startofline = unread = tell = None + if hasattr(self.fp, 'unread'): + unread = self.fp.unread + elif self.seekable: + tell = self.fp.tell + while True: + if tell: + try: + startofline = tell() + except IOError: + startofline = tell = None + self.seekable = 0 + line = self.fp.readline(_MAXLINE + 1) + if len(line) > _MAXLINE: + raise LineTooLong("header line") + if not line: + self.status = 'EOF in headers' + break + # Skip unix From name time lines + if firstline and line.startswith('From '): + self.unixfrom = self.unixfrom + line + continue + firstline = 0 + if headerseen and line[0] in ' \t': + # XXX Not sure if continuation lines are handled properly + # for http and/or for repeating headers + # It's a continuation line. + hlist.append(line) + self.addcontinue(headerseen, line.strip()) + continue + elif self.iscomment(line): + # It's a comment. Ignore it. + continue + elif self.islast(line): + # Note! No pushback here! The delimiter line gets eaten. + break + headerseen = self.isheader(line) + if headerseen: + # It's a legal header line, save it. + hlist.append(line) + self.addheader(headerseen, line[len(headerseen)+1:].strip()) + continue + else: + # It's not a header line; throw it back and stop here. + if not self.dict: + self.status = 'No headers' + else: + self.status = 'Non-header line where header expected' + # Try to undo the read. + if unread: + unread(line) + elif tell: + self.fp.seek(startofline) + else: + self.status = self.status + '; bad seek' + break + +class HTTPResponse: + + # strict: If true, raise BadStatusLine if the status line can't be + # parsed as a valid HTTP/1.0 or 1.1 status line. By default it is + # false because it prevents clients from talking to HTTP/0.9 + # servers. Note that a response with a sufficiently corrupted + # status line will look like an HTTP/0.9 response. + + # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details. + + def __init__(self, sock, debuglevel=0, strict=0, method=None, buffering=False): + if buffering: + # The caller won't be using any sock.recv() calls, so buffering + # is fine and recommended for performance. + self.fp = sock.makefile('rb') + else: + # The buffer size is specified as zero, because the headers of + # the response are read with readline(). If the reads were + # buffered the readline() calls could consume some of the + # response, which make be read via a recv() on the underlying + # socket. + self.fp = sock.makefile('rb', 0) + self.debuglevel = debuglevel + self.strict = strict + self._method = method + + 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): + # Initialize with Simple-Response defaults + line = self.fp.readline(_MAXLINE + 1) + if len(line) > _MAXLINE: + raise LineTooLong("header line") + if self.debuglevel > 0: + print "reply:", repr(line) + if not line: + # Presumably, the server closed the connection before + # sending a valid response. + raise BadStatusLine(line) + 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 and status + # will be treated as 0.9 response. + version = "" + if not version.startswith('HTTP/'): + if self.strict: + self.close() + raise BadStatusLine(line) + else: + # assume it's a Simple-Response from an 0.9 server + self.fp = LineAndFileWrapper(line, self.fp) + return "HTTP/0.9", 200, "" + + # 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.msg 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.status = status + self.reason = reason.strip() + if version == 'HTTP/1.0': + self.version = 10 + elif version.startswith('HTTP/1.'): + self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1 + elif version == 'HTTP/0.9': + self.version = 9 + else: + raise UnknownProtocol(version) + + if self.version == 9: + self.length = None + self.chunked = 0 + self.will_close = 1 + self.msg = HTTPMessage(StringIO()) + return + + self.msg = HTTPMessage(self.fp, 0) + if self.debuglevel > 0: + for hdr in self.msg.headers: + print "header:", hdr, + + # don't let the msg keep an fp + self.msg.fp = None + + # are we using the chunked-style of transfer encoding? + tr_enc = self.msg.getheader('transfer-encoding') + if tr_enc and tr_enc.lower() == "chunked": + self.chunked = 1 + self.chunk_left = None + else: + self.chunked = 0 + + # 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" + length = self.msg.getheader('content-length') + 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 = 1 + + def _check_close(self): + conn = self.msg.getheader('connection') + if self.version == 11: + # An HTTP/1.1 proxy is assumed to stay open unless + # explicitly closed. + conn = self.msg.getheader('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.msg.getheader('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.msg.getheader('proxy-connection') + if pconn and "keep-alive" in pconn.lower(): + return False + + # otherwise, assume it will close + return True + + def close(self): + if self.fp: + self.fp.close() + self.fp = None + + def isclosed(self): + # 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 + + # XXX It would be nice to have readline and __iter__ for this, too. + + def read(self, amt=None): + if self.fp is None: + return '' + + if self._method == 'HEAD': + self.close() + return '' + + if self.chunked: + return self._read_chunked(amt) + + if amt is None: + # unbounded read + if self.length is None: + s = self.fp.read() + else: + try: + s = self._safe_read(self.length) + except IncompleteRead: + self.close() + raise + self.length = 0 + self.close() # we read everything + return s + + if self.length is not None: + if amt > self.length: + # clip the read to the "end of response" + amt = 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) + s = self.fp.read(amt) + if not s: + # Ideally, we would raise IncompleteRead if the content-length + # wasn't satisfied, but it might break compatibility. + self.close() + if self.length is not None: + self.length -= len(s) + if not self.length: + self.close() + + return s + + def _read_chunked(self, amt): + assert self.chunked != _UNKNOWN + chunk_left = self.chunk_left + value = [] + while True: + if chunk_left is None: + line = self.fp.readline(_MAXLINE + 1) + if len(line) > _MAXLINE: + raise LineTooLong("chunk size") + i = line.find(';') + if i >= 0: + line = line[:i] # strip chunk-extensions + try: + chunk_left = int(line, 16) + except ValueError: + # close the connection as protocol synchronisation is + # probably lost + self.close() + raise IncompleteRead(''.join(value)) + if chunk_left == 0: + break + if amt is None: + value.append(self._safe_read(chunk_left)) + elif amt < chunk_left: + value.append(self._safe_read(amt)) + self.chunk_left = chunk_left - amt + return ''.join(value) + elif amt == chunk_left: + value.append(self._safe_read(amt)) + self._safe_read(2) # toss the CRLF at the end of the chunk + self.chunk_left = None + return ''.join(value) + else: + value.append(self._safe_read(chunk_left)) + amt -= chunk_left + + # we read the whole chunk, get another + self._safe_read(2) # toss the CRLF at the end of the chunk + chunk_left = None + + # 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 == '\r\n': + break + + # we read everything; close the "file" + self.close() + + return ''.join(value) + + 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. + """ + # NOTE(gps): As of svn r74426 socket._fileobject.read(x) will never + # return less than x bytes unless EOF is encountered. It now handles + # signal interruptions (socket.error EINTR) internally. This code + # never caught that exception anyways. It seems largely pointless. + # self.fp.read(amt) will work fine. + s = [] + while amt > 0: + chunk = self.fp.read(min(amt, MAXAMOUNT)) + if not chunk: + raise IncompleteRead(''.join(s), amt) + s.append(chunk) + amt -= len(chunk) + return ''.join(s) + + def fileno(self): + return self.fp.fileno() + + def getheader(self, name, default=None): + if self.msg is None: + raise ResponseNotReady() + return self.msg.getheader(name, default) + + def getheaders(self): + """Return list of (header, value) tuples.""" + if self.msg is None: + raise ResponseNotReady() + return self.msg.items() + + +class HTTPConnection: + + _http_vsn = 11 + _http_vsn_str = 'HTTP/1.1' + + response_class = HTTPResponse + default_port = HTTP_PORT + auto_open = 1 + debuglevel = 0 + strict = 0 + + def __init__(self, host, port=None, strict=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._set_hostport(host, port) + if strict is not None: + self.strict = strict + + def set_tunnel(self, host, port=None, headers=None): + """ Sets up the host and the port for the HTTP CONNECT Tunnelling. + + The headers argument should be a mapping of extra HTTP headers + to send with the CONNECT request. + """ + self._tunnel_host = host + self._tunnel_port = port + if headers: + self._tunnel_headers = headers + else: + self._tunnel_headers.clear() + + def _set_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] + self.host = host + self.port = port + + def set_debuglevel(self, level): + self.debuglevel = level + + def _tunnel(self): + self._set_hostport(self._tunnel_host, self._tunnel_port) + self.send("CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port)) + for header, value in self._tunnel_headers.iteritems(): + self.send("%s: %s\r\n" % (header, value)) + self.send("\r\n") + response = self.response_class(self.sock, strict = self.strict, + method = self._method) + (version, code, message) = response._read_status() + + if code != 200: + self.close() + raise socket.error("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 trailer + break + if line == '\r\n': + break + + + def connect(self): + """Connect to the host and port specified in __init__.""" + self.sock = socket.create_connection((self.host,self.port), + self.timeout, self.source_address) + + if self._tunnel_host: + self._tunnel() + + def close(self): + """Close the connection to the HTTP server.""" + if self.sock: + self.sock.close() # close it manually... there may be other refs + self.sock = None + if self.__response: + self.__response.close() + self.__response = None + self.__state = _CS_IDLE + + def send(self, data): + """Send `data' to the server.""" + 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') and not isinstance(data, array): + if self.debuglevel > 0: print "sendIng a read()able" + datablock = data.read(blocksize) + while datablock: + self.sock.sendall(datablock) + datablock = data.read(blocksize) + else: + self.sock.sendall(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 _send_output(self, message_body=None): + """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(("", "")) + msg = "\r\n".join(self._buffer) + del self._buffer[:] + # If msg and message_body are sent in a single send() call, + # it will avoid performance problems caused by the interaction + # between delayed ack and the Nagle algorithm. + if isinstance(message_body, str): + msg += message_body + message_body = None + self.send(msg) + if message_body is not None: + #message_body was not a string (i.e. it is a file) and + #we must run the risk of Nagle + self.send(message_body) + + def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0): + """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() + + # Save the method we use, we need it later in the response phase + self._method = method + if not url: + url = '/' + hdr = '%s %s %s' % (method, url, self._http_vsn_str) + + self._output(hdr) + + 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 url.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: + try: + host_enc = self.host.encode("ascii") + except UnicodeEncodeError: + host_enc = self.host.encode("idna") + # Wrap the IPv6 Host Header with [] (RFC 2732) + if host_enc.find(':') >= 0: + host_enc = "[" + host_enc + "]" + if self.port == self.default_port: + self.putheader('Host', host_enc) + else: + self.putheader('Host', "%s:%s" % (host_enc, self.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() + + hdr = '%s: %s' % (header, '\r\n\t'.join([str(v) for v in values])) + self._output(hdr) + + def endheaders(self, message_body=None): + """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. The message body will be sent in + the same packet as the message headers if it is string, otherwise it is + sent as a separate packet. + """ + if self.__state == _CS_REQ_STARTED: + self.__state = _CS_REQ_SENT + else: + raise CannotSendHeader() + self._send_output(message_body) + + def request(self, method, url, body=None, headers={}): + """Send a complete request to the server.""" + self._send_request(method, url, body, headers) + + def _set_content_length(self, body): + # Set the content-length based on the body. + thelen = None + try: + thelen = str(len(body)) + except TypeError, te: + # If this is a file-like object, try to + # fstat its file descriptor + try: + thelen = str(os.fstat(body.fileno()).st_size) + except (AttributeError, OSError): + # Don't send a length if this failed + if self.debuglevel > 0: print "Cannot stat!!" + + if thelen is not None: + self.putheader('Content-Length', thelen) + + def _send_request(self, method, url, body, headers): + # Honor explicitly requested Host: and Accept-Encoding: headers. + header_names = dict.fromkeys([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) + + if body is not None and 'content-length' not in header_names: + self._set_content_length(body) + for hdr, value in headers.iteritems(): + self.putheader(hdr, value) + self.endheaders(body) + + def getresponse(self, buffering=False): + "Get the response from the server." + + # 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() + + args = (self.sock,) + kwds = {"strict":self.strict, "method":self._method} + if self.debuglevel > 0: + args += (self.debuglevel,) + if buffering: + #only add this keyword if non-default, for compatibility with + #other response_classes. + kwds["buffering"] = True; + response = self.response_class(*args, **kwds) + + response.begin() + 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 + + +class HTTP: + "Compatibility class with httplib.py from 1.5." + + _http_vsn = 10 + _http_vsn_str = 'HTTP/1.0' + + debuglevel = 0 + + _connection_class = HTTPConnection + + def __init__(self, host='', port=None, strict=None): + "Provide a default host, since the superclass requires one." + + # some joker passed 0 explicitly, meaning default port + if port == 0: + port = None + + # Note that we may pass an empty string as the host; this will raise + # an error when we attempt to connect. Presumably, the client code + # will call connect before then, with a proper host. + self._setup(self._connection_class(host, port, strict)) + + def _setup(self, conn): + self._conn = conn + + # set up delegation to flesh out interface + self.send = conn.send + self.putrequest = conn.putrequest + self.putheader = conn.putheader + self.endheaders = conn.endheaders + self.set_debuglevel = conn.set_debuglevel + + conn._http_vsn = self._http_vsn + conn._http_vsn_str = self._http_vsn_str + + self.file = None + + def connect(self, host=None, port=None): + "Accept arguments to set the host/port, since the superclass doesn't." + + if host is not None: + self._conn._set_hostport(host, port) + self._conn.connect() + + def getfile(self): + "Provide a getfile, since the superclass' does not use this concept." + return self.file + + def getreply(self, buffering=False): + """Compat definition since superclass does not define it. + + Returns a tuple consisting of: + - server status code (e.g. '200' if all goes well) + - server "reason" corresponding to status code + - any RFC822 headers in the response from the server + """ + try: + if not buffering: + response = self._conn.getresponse() + else: + #only add this keyword if non-default for compatibility + #with other connection classes + response = self._conn.getresponse(buffering) + except BadStatusLine, e: + ### hmm. if getresponse() ever closes the socket on a bad request, + ### then we are going to have problems with self.sock + + ### should we keep this behavior? do people use it? + # keep the socket open (as a file), and return it + self.file = self._conn.sock.makefile('rb', 0) + + # close our socket -- we want to restart after any protocol error + self.close() + + self.headers = None + return -1, e.line, None + + self.headers = response.msg + self.file = response.fp + return response.status, response.reason, response.msg + + def close(self): + self._conn.close() + + # note that self.file == response.fp, which gets closed by the + # superclass. just clear the object ref here. + ### hmm. messy. if status==-1, then self.file is owned by us. + ### well... we aren't explicitly closing, but losing this ref will + ### do it + self.file = None + +try: + import ssl +except ImportError: + pass +else: + class HTTPSConnection(HTTPConnection): + "This class allows communication via SSL." + + default_port = HTTPS_PORT + + def __init__(self, host, port=None, key_file=None, cert_file=None, + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None): + HTTPConnection.__init__(self, host, port, strict, timeout, + source_address) + self.key_file = key_file + self.cert_file = cert_file + + def connect(self): + "Connect to a host on a given (SSL) port." + + sock = socket.create_connection((self.host, self.port), + self.timeout, self.source_address) + if self._tunnel_host: + self.sock = sock + self._tunnel() + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) + + __all__.append("HTTPSConnection") + + class HTTPS(HTTP): + """Compatibility with 1.5 httplib interface + + Python 1.5.2 did not have an HTTPS class, but it defined an + interface for sending http requests that is also useful for + https. + """ + + _connection_class = HTTPSConnection + + def __init__(self, host='', port=None, key_file=None, cert_file=None, + strict=None): + # provide a default host, pass the X509 cert info + + # urf. compensate for bad input. + if port == 0: + port = None + self._setup(self._connection_class(host, port, key_file, + cert_file, strict)) + + # we never actually use these for anything, but we keep them + # here for compatibility with post-1.5.2 CVS. + self.key_file = key_file + self.cert_file = cert_file + + + def FakeSocket (sock, sslobj): + warnings.warn("FakeSocket is deprecated, and won't be in 3.x. " + + "Use the result of ssl.wrap_socket() directly instead.", + DeprecationWarning, stacklevel=2) + return sslobj + + +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 'IncompleteRead(%i bytes read%s)' % (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)) + +# for backwards compatibility +error = HTTPException + +class LineAndFileWrapper: + """A limited file-like object for HTTP/0.9 responses.""" + + # The status-line parsing code calls readline(), which normally + # get the HTTP status line. For a 0.9 response, however, this is + # actually the first line of the body! Clients need to get a + # readable file object that contains that line. + + def __init__(self, line, file): + self._line = line + self._file = file + self._line_consumed = 0 + self._line_offset = 0 + self._line_left = len(line) + + def __getattr__(self, attr): + return getattr(self._file, attr) + + def _done(self): + # called when the last byte is read from the line. After the + # call, all read methods are delegated to the underlying file + # object. + self._line_consumed = 1 + self.read = self._file.read + self.readline = self._file.readline + self.readlines = self._file.readlines + + def read(self, amt=None): + if self._line_consumed: + return self._file.read(amt) + assert self._line_left + if amt is None or amt > self._line_left: + s = self._line[self._line_offset:] + self._done() + if amt is None: + return s + self._file.read() + else: + return s + self._file.read(amt - len(s)) + else: + assert amt <= self._line_left + i = self._line_offset + j = i + amt + s = self._line[i:j] + self._line_offset = j + self._line_left -= amt + if self._line_left == 0: + self._done() + return s + + def readline(self): + if self._line_consumed: + return self._file.readline() + assert self._line_left + s = self._line[self._line_offset:] + self._done() + return s + + def readlines(self, size=None): + if self._line_consumed: + return self._file.readlines(size) + assert self._line_left + L = [self._line[self._line_offset:]] + self._done() + if size is None: + return L + self._file.readlines() + else: + return L + self._file.readlines(size) diff --git a/src/main/resources/PythonLibs/ihooks.py b/src/main/resources/PythonLibs/ihooks.py new file mode 100644 index 0000000000000000000000000000000000000000..8761dac7cd05d0caace06cc1fbd115e046b20819 --- /dev/null +++ b/src/main/resources/PythonLibs/ihooks.py @@ -0,0 +1,554 @@ +"""Import hook support. + +Consistent use of this module will make it possible to change the +different mechanisms involved in loading modules independently. + +While the built-in module imp exports interfaces to the built-in +module searching and loading algorithm, and it is possible to replace +the built-in function __import__ in order to change the semantics of +the import statement, until now it has been difficult to combine the +effect of different __import__ hacks, like loading modules from URLs +by rimport.py, or restricted execution by rexec.py. + +This module defines three new concepts: + +1) A "file system hooks" class provides an interface to a filesystem. + +One hooks class is defined (Hooks), which uses the interface provided +by standard modules os and os.path. It should be used as the base +class for other hooks classes. + +2) A "module loader" class provides an interface to search for a +module in a search path and to load it. It defines a method which +searches for a module in a single directory; by overriding this method +one can redefine the details of the search. If the directory is None, +built-in and frozen modules are searched instead. + +Two module loader class are defined, both implementing the search +strategy used by the built-in __import__ function: ModuleLoader uses +the imp module's find_module interface, while HookableModuleLoader +uses a file system hooks class to interact with the file system. Both +use the imp module's load_* interfaces to actually load the module. + +3) A "module importer" class provides an interface to import a +module, as well as interfaces to reload and unload a module. It also +provides interfaces to install and uninstall itself instead of the +default __import__ and reload (and unload) functions. + +One module importer class is defined (ModuleImporter), which uses a +module loader instance passed in (by default HookableModuleLoader is +instantiated). + +The classes defined here should be used as base classes for extended +functionality along those lines. + +If a module importer class supports dotted names, its import_module() +must return a different value depending on whether it is called on +behalf of a "from ... import ..." statement or not. (This is caused +by the way the __import__ hook is used by the Python interpreter.) It +would also do wise to install a different version of reload(). + +""" +from warnings import warnpy3k, warn +warnpy3k("the ihooks module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +import __builtin__ +import imp +import os +import sys + +__all__ = ["BasicModuleLoader","Hooks","ModuleLoader","FancyModuleLoader", + "BasicModuleImporter","ModuleImporter","install","uninstall"] + +VERBOSE = 0 + + +from imp import C_EXTENSION, PY_SOURCE, PY_COMPILED +from imp import C_BUILTIN, PY_FROZEN, PKG_DIRECTORY +BUILTIN_MODULE = C_BUILTIN +FROZEN_MODULE = PY_FROZEN + + +class _Verbose: + + def __init__(self, verbose = VERBOSE): + self.verbose = verbose + + def get_verbose(self): + return self.verbose + + def set_verbose(self, verbose): + self.verbose = verbose + + # XXX The following is an experimental interface + + def note(self, *args): + if self.verbose: + self.message(*args) + + def message(self, format, *args): + if args: + print format%args + else: + print format + + +class BasicModuleLoader(_Verbose): + + """Basic module loader. + + This provides the same functionality as built-in import. It + doesn't deal with checking sys.modules -- all it provides is + find_module() and a load_module(), as well as find_module_in_dir() + which searches just one directory, and can be overridden by a + derived class to change the module search algorithm when the basic + dependency on sys.path is unchanged. + + The interface is a little more convenient than imp's: + find_module(name, [path]) returns None or 'stuff', and + load_module(name, stuff) loads the module. + + """ + + def find_module(self, name, path = None): + if path is None: + path = [None] + self.default_path() + for dir in path: + stuff = self.find_module_in_dir(name, dir) + if stuff: return stuff + return None + + def default_path(self): + return sys.path + + def find_module_in_dir(self, name, dir): + if dir is None: + return self.find_builtin_module(name) + else: + try: + return imp.find_module(name, [dir]) + except ImportError: + return None + + def find_builtin_module(self, name): + # XXX frozen packages? + if imp.is_builtin(name): + return None, '', ('', '', BUILTIN_MODULE) + if imp.is_frozen(name): + return None, '', ('', '', FROZEN_MODULE) + return None + + def load_module(self, name, stuff): + file, filename, info = stuff + try: + return imp.load_module(name, file, filename, info) + finally: + if file: file.close() + + +class Hooks(_Verbose): + + """Hooks into the filesystem and interpreter. + + By deriving a subclass you can redefine your filesystem interface, + e.g. to merge it with the URL space. + + This base class behaves just like the native filesystem. + + """ + + # imp interface + def get_suffixes(self): return imp.get_suffixes() + def new_module(self, name): return imp.new_module(name) + def is_builtin(self, name): return imp.is_builtin(name) + def init_builtin(self, name): return imp.init_builtin(name) + def is_frozen(self, name): return imp.is_frozen(name) + def init_frozen(self, name): return imp.init_frozen(name) + def get_frozen_object(self, name): return imp.get_frozen_object(name) + def load_source(self, name, filename, file=None): + return imp.load_source(name, filename, file) + def load_compiled(self, name, filename, file=None): + return imp.load_compiled(name, filename, file) + def load_dynamic(self, name, filename, file=None): + return imp.load_dynamic(name, filename, file) + def load_package(self, name, filename, file=None): + return imp.load_module(name, file, filename, ("", "", PKG_DIRECTORY)) + + def add_module(self, name): + d = self.modules_dict() + if name in d: return d[name] + d[name] = m = self.new_module(name) + return m + + # sys interface + def modules_dict(self): return sys.modules + def default_path(self): return sys.path + + def path_split(self, x): return os.path.split(x) + def path_join(self, x, y): return os.path.join(x, y) + def path_isabs(self, x): return os.path.isabs(x) + # etc. + + def path_exists(self, x): return os.path.exists(x) + def path_isdir(self, x): return os.path.isdir(x) + def path_isfile(self, x): return os.path.isfile(x) + def path_islink(self, x): return os.path.islink(x) + # etc. + + def openfile(self, *x): return open(*x) + openfile_error = IOError + def listdir(self, x): return os.listdir(x) + listdir_error = os.error + # etc. + + +class ModuleLoader(BasicModuleLoader): + + """Default module loader; uses file system hooks. + + By defining suitable hooks, you might be able to load modules from + other sources than the file system, e.g. from compressed or + encrypted files, tar files or (if you're brave!) URLs. + + """ + + def __init__(self, hooks = None, verbose = VERBOSE): + BasicModuleLoader.__init__(self, verbose) + self.hooks = hooks or Hooks(verbose) + + def default_path(self): + return self.hooks.default_path() + + def modules_dict(self): + return self.hooks.modules_dict() + + def get_hooks(self): + return self.hooks + + def set_hooks(self, hooks): + self.hooks = hooks + + def find_builtin_module(self, name): + # XXX frozen packages? + if self.hooks.is_builtin(name): + return None, '', ('', '', BUILTIN_MODULE) + if self.hooks.is_frozen(name): + return None, '', ('', '', FROZEN_MODULE) + return None + + def find_module_in_dir(self, name, dir, allow_packages=1): + if dir is None: + return self.find_builtin_module(name) + if allow_packages: + fullname = self.hooks.path_join(dir, name) + if self.hooks.path_isdir(fullname): + stuff = self.find_module_in_dir("__init__", fullname, 0) + if stuff: + file = stuff[0] + if file: file.close() + return None, fullname, ('', '', PKG_DIRECTORY) + for info in self.hooks.get_suffixes(): + suff, mode, type = info + fullname = self.hooks.path_join(dir, name+suff) + try: + fp = self.hooks.openfile(fullname, mode) + return fp, fullname, info + except self.hooks.openfile_error: + pass + return None + + def load_module(self, name, stuff): + file, filename, info = stuff + (suff, mode, type) = info + try: + if type == BUILTIN_MODULE: + return self.hooks.init_builtin(name) + if type == FROZEN_MODULE: + return self.hooks.init_frozen(name) + if type == C_EXTENSION: + m = self.hooks.load_dynamic(name, filename, file) + elif type == PY_SOURCE: + m = self.hooks.load_source(name, filename, file) + elif type == PY_COMPILED: + m = self.hooks.load_compiled(name, filename, file) + elif type == PKG_DIRECTORY: + m = self.hooks.load_package(name, filename, file) + else: + raise ImportError, "Unrecognized module type (%r) for %s" % \ + (type, name) + finally: + if file: file.close() + m.__file__ = filename + return m + + +class FancyModuleLoader(ModuleLoader): + + """Fancy module loader -- parses and execs the code itself.""" + + def load_module(self, name, stuff): + file, filename, (suff, mode, type) = stuff + realfilename = filename + path = None + + if type == PKG_DIRECTORY: + initstuff = self.find_module_in_dir("__init__", filename, 0) + if not initstuff: + raise ImportError, "No __init__ module in package %s" % name + initfile, initfilename, initinfo = initstuff + initsuff, initmode, inittype = initinfo + if inittype not in (PY_COMPILED, PY_SOURCE): + if initfile: initfile.close() + raise ImportError, \ + "Bad type (%r) for __init__ module in package %s" % ( + inittype, name) + path = [filename] + file = initfile + realfilename = initfilename + type = inittype + + if type == FROZEN_MODULE: + code = self.hooks.get_frozen_object(name) + elif type == PY_COMPILED: + import marshal + file.seek(8) + code = marshal.load(file) + elif type == PY_SOURCE: + data = file.read() + code = compile(data, realfilename, 'exec') + else: + return ModuleLoader.load_module(self, name, stuff) + + m = self.hooks.add_module(name) + if path: + m.__path__ = path + m.__file__ = filename + try: + exec code in m.__dict__ + except: + d = self.hooks.modules_dict() + if name in d: + del d[name] + raise + return m + + +class BasicModuleImporter(_Verbose): + + """Basic module importer; uses module loader. + + This provides basic import facilities but no package imports. + + """ + + def __init__(self, loader = None, verbose = VERBOSE): + _Verbose.__init__(self, verbose) + self.loader = loader or ModuleLoader(None, verbose) + self.modules = self.loader.modules_dict() + + def get_loader(self): + return self.loader + + def set_loader(self, loader): + self.loader = loader + + def get_hooks(self): + return self.loader.get_hooks() + + def set_hooks(self, hooks): + return self.loader.set_hooks(hooks) + + def import_module(self, name, globals={}, locals={}, fromlist=[]): + name = str(name) + if name in self.modules: + return self.modules[name] # Fast path + stuff = self.loader.find_module(name) + if not stuff: + raise ImportError, "No module named %s" % name + return self.loader.load_module(name, stuff) + + def reload(self, module, path = None): + name = str(module.__name__) + stuff = self.loader.find_module(name, path) + if not stuff: + raise ImportError, "Module %s not found for reload" % name + return self.loader.load_module(name, stuff) + + def unload(self, module): + del self.modules[str(module.__name__)] + # XXX Should this try to clear the module's namespace? + + def install(self): + self.save_import_module = __builtin__.__import__ + self.save_reload = __builtin__.reload + if not hasattr(__builtin__, 'unload'): + __builtin__.unload = None + self.save_unload = __builtin__.unload + __builtin__.__import__ = self.import_module + __builtin__.reload = self.reload + __builtin__.unload = self.unload + + def uninstall(self): + __builtin__.__import__ = self.save_import_module + __builtin__.reload = self.save_reload + __builtin__.unload = self.save_unload + if not __builtin__.unload: + del __builtin__.unload + + +class ModuleImporter(BasicModuleImporter): + + """A module importer that supports packages.""" + + def import_module(self, name, globals=None, locals=None, fromlist=None, + level=-1): + parent = self.determine_parent(globals, level) + q, tail = self.find_head_package(parent, str(name)) + m = self.load_tail(q, tail) + if not fromlist: + return q + if hasattr(m, "__path__"): + self.ensure_fromlist(m, fromlist) + return m + + def determine_parent(self, globals, level=-1): + if not globals or not level: + return None + pkgname = globals.get('__package__') + if pkgname is not None: + if not pkgname and level > 0: + raise ValueError, 'Attempted relative import in non-package' + else: + # __package__ not set, figure it out and set it + modname = globals.get('__name__') + if modname is None: + return None + if "__path__" in globals: + # __path__ is set so modname is already the package name + pkgname = modname + else: + # normal module, work out package name if any + if '.' not in modname: + if level > 0: + raise ValueError, ('Attempted relative import in ' + 'non-package') + globals['__package__'] = None + return None + pkgname = modname.rpartition('.')[0] + globals['__package__'] = pkgname + if level > 0: + dot = len(pkgname) + for x in range(level, 1, -1): + try: + dot = pkgname.rindex('.', 0, dot) + except ValueError: + raise ValueError('attempted relative import beyond ' + 'top-level package') + pkgname = pkgname[:dot] + try: + return sys.modules[pkgname] + except KeyError: + if level < 1: + warn("Parent module '%s' not found while handling " + "absolute import" % pkgname, RuntimeWarning, 1) + return None + else: + raise SystemError, ("Parent module '%s' not loaded, cannot " + "perform relative import" % pkgname) + + def find_head_package(self, parent, name): + if '.' in name: + i = name.find('.') + head = name[:i] + tail = name[i+1:] + else: + head = name + tail = "" + if parent: + qname = "%s.%s" % (parent.__name__, head) + else: + qname = head + q = self.import_it(head, qname, parent) + if q: return q, tail + if parent: + qname = head + parent = None + q = self.import_it(head, qname, parent) + if q: return q, tail + raise ImportError, "No module named '%s'" % qname + + def load_tail(self, q, tail): + m = q + while tail: + i = tail.find('.') + if i < 0: i = len(tail) + head, tail = tail[:i], tail[i+1:] + mname = "%s.%s" % (m.__name__, head) + m = self.import_it(head, mname, m) + if not m: + raise ImportError, "No module named '%s'" % mname + return m + + def ensure_fromlist(self, m, fromlist, recursive=0): + for sub in fromlist: + if sub == "*": + if not recursive: + try: + all = m.__all__ + except AttributeError: + pass + else: + self.ensure_fromlist(m, all, 1) + continue + if sub != "*" and not hasattr(m, sub): + subname = "%s.%s" % (m.__name__, sub) + submod = self.import_it(sub, subname, m) + if not submod: + raise ImportError, "No module named '%s'" % subname + + def import_it(self, partname, fqname, parent, force_load=0): + if not partname: + # completely empty module name should only happen in + # 'from . import' or __import__("") + return parent + if not force_load: + try: + return self.modules[fqname] + except KeyError: + pass + try: + path = parent and parent.__path__ + except AttributeError: + return None + partname = str(partname) + stuff = self.loader.find_module(partname, path) + if not stuff: + return None + fqname = str(fqname) + m = self.loader.load_module(fqname, stuff) + if parent: + setattr(parent, partname, m) + return m + + def reload(self, module): + name = str(module.__name__) + if '.' not in name: + return self.import_it(name, name, None, force_load=1) + i = name.rfind('.') + pname = name[:i] + parent = self.modules[pname] + return self.import_it(name[i+1:], name, parent, force_load=1) + + +default_importer = None +current_importer = None + +def install(importer = None): + global current_importer + current_importer = importer or default_importer or ModuleImporter() + current_importer.install() + +def uninstall(): + global current_importer + current_importer.uninstall() diff --git a/src/main/resources/PythonLibs/imaplib.py b/src/main/resources/PythonLibs/imaplib.py new file mode 100644 index 0000000000000000000000000000000000000000..c576927a8b0e4c92dd4ca9aad88baff4b3e1de19 --- /dev/null +++ b/src/main/resources/PythonLibs/imaplib.py @@ -0,0 +1,1518 @@ +"""IMAP4 client. + +Based on RFC 2060. + +Public class: IMAP4 +Public variable: Debug +Public functions: Internaldate2tuple + Int2AP + ParseFlags + Time2Internaldate +""" + +# Author: Piers Lauder <piers@cs.su.oz.au> December 1997. +# +# Authentication code contributed by Donn Cave <donn@u.washington.edu> June 1998. +# String method conversion by ESR, February 2001. +# GET/SETACL contributed by Anthony Baxter <anthony@interlink.com.au> April 2001. +# IMAP4_SSL contributed by Tino Lange <Tino.Lange@isg.de> March 2002. +# GET/SETQUOTA contributed by Andreas Zeidler <az@kreativkombinat.de> June 2002. +# PROXYAUTH contributed by Rick Holbert <holbert.13@osu.edu> November 2002. +# GET/SETANNOTATION contributed by Tomas Lindroos <skitta@abo.fi> June 2005. + +__version__ = "2.58" + +import binascii, errno, random, re, socket, subprocess, sys, time + +__all__ = ["IMAP4", "IMAP4_stream", "Internaldate2tuple", + "Int2AP", "ParseFlags", "Time2Internaldate"] + +# Globals + +CRLF = '\r\n' +Debug = 0 +IMAP4_PORT = 143 +IMAP4_SSL_PORT = 993 +AllowedVersions = ('IMAP4REV1', 'IMAP4') # Most recent first + +# Commands + +Commands = { + # name valid states + 'APPEND': ('AUTH', 'SELECTED'), + 'AUTHENTICATE': ('NONAUTH',), + 'CAPABILITY': ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'), + 'CHECK': ('SELECTED',), + 'CLOSE': ('SELECTED',), + 'COPY': ('SELECTED',), + 'CREATE': ('AUTH', 'SELECTED'), + 'DELETE': ('AUTH', 'SELECTED'), + 'DELETEACL': ('AUTH', 'SELECTED'), + 'EXAMINE': ('AUTH', 'SELECTED'), + 'EXPUNGE': ('SELECTED',), + 'FETCH': ('SELECTED',), + 'GETACL': ('AUTH', 'SELECTED'), + 'GETANNOTATION':('AUTH', 'SELECTED'), + 'GETQUOTA': ('AUTH', 'SELECTED'), + 'GETQUOTAROOT': ('AUTH', 'SELECTED'), + 'MYRIGHTS': ('AUTH', 'SELECTED'), + 'LIST': ('AUTH', 'SELECTED'), + 'LOGIN': ('NONAUTH',), + 'LOGOUT': ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'), + 'LSUB': ('AUTH', 'SELECTED'), + 'NAMESPACE': ('AUTH', 'SELECTED'), + 'NOOP': ('NONAUTH', 'AUTH', 'SELECTED', 'LOGOUT'), + 'PARTIAL': ('SELECTED',), # NB: obsolete + 'PROXYAUTH': ('AUTH',), + 'RENAME': ('AUTH', 'SELECTED'), + 'SEARCH': ('SELECTED',), + 'SELECT': ('AUTH', 'SELECTED'), + 'SETACL': ('AUTH', 'SELECTED'), + 'SETANNOTATION':('AUTH', 'SELECTED'), + 'SETQUOTA': ('AUTH', 'SELECTED'), + 'SORT': ('SELECTED',), + 'STATUS': ('AUTH', 'SELECTED'), + 'STORE': ('SELECTED',), + 'SUBSCRIBE': ('AUTH', 'SELECTED'), + 'THREAD': ('SELECTED',), + 'UID': ('SELECTED',), + 'UNSUBSCRIBE': ('AUTH', 'SELECTED'), + } + +# Patterns to match server responses + +Continuation = re.compile(r'\+( (?P<data>.*))?') +Flags = re.compile(r'.*FLAGS \((?P<flags>[^\)]*)\)') +InternalDate = re.compile(r'.*INTERNALDATE "' + r'(?P<day>[ 0123][0-9])-(?P<mon>[A-Z][a-z][a-z])-(?P<year>[0-9][0-9][0-9][0-9])' + r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])' + r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])' + r'"') +Literal = re.compile(r'.*{(?P<size>\d+)}$') +MapCRLF = re.compile(r'\r\n|\r|\n') +Response_code = re.compile(r'\[(?P<type>[A-Z-]+)( (?P<data>[^\]]*))?\]') +Untagged_response = re.compile(r'\* (?P<type>[A-Z-]+)( (?P<data>.*))?') +Untagged_status = re.compile(r'\* (?P<data>\d+) (?P<type>[A-Z-]+)( (?P<data2>.*))?') + + + +class IMAP4: + + """IMAP4 client class. + + Instantiate with: IMAP4([host[, port]]) + + host - host's name (default: localhost); + port - port number (default: standard IMAP4 port). + + All IMAP4rev1 commands are supported by methods of the same + name (in lower-case). + + All arguments to commands are converted to strings, except for + AUTHENTICATE, and the last argument to APPEND which is passed as + an IMAP4 literal. If necessary (the string contains any + non-printing characters or white-space and isn't enclosed with + either parentheses or double quotes) each string is quoted. + However, the 'password' argument to the LOGIN command is always + quoted. If you want to avoid having an argument string quoted + (eg: the 'flags' argument to STORE) then enclose the string in + parentheses (eg: "(\Deleted)"). + + Each command returns a tuple: (type, [data, ...]) where 'type' + is usually 'OK' or 'NO', and 'data' is either the text from the + tagged response, or untagged results from command. Each 'data' + is either a string, or a tuple. If a tuple, then the first part + is the header of the response, and the second part contains + the data (ie: 'literal' value). + + Errors raise the exception class <instance>.error("<reason>"). + IMAP4 server errors raise <instance>.abort("<reason>"), + which is a sub-class of 'error'. Mailbox status changes + from READ-WRITE to READ-ONLY raise the exception class + <instance>.readonly("<reason>"), which is a sub-class of 'abort'. + + "error" exceptions imply a program error. + "abort" exceptions imply the connection should be reset, and + the command re-tried. + "readonly" exceptions imply the command should be re-tried. + + Note: to use this module, you must read the RFCs pertaining to the + IMAP4 protocol, as the semantics of the arguments to each IMAP4 + command are left to the invoker, not to mention the results. Also, + most IMAP servers implement a sub-set of the commands available here. + """ + + class error(Exception): pass # Logical errors - debug required + class abort(error): pass # Service errors - close and retry + class readonly(abort): pass # Mailbox status changed to READ-ONLY + + mustquote = re.compile(r"[^\w!#$%&'*+,.:;<=>?^`|~-]") + + def __init__(self, host = '', port = IMAP4_PORT): + self.debug = Debug + self.state = 'LOGOUT' + self.literal = None # A literal argument to a command + self.tagged_commands = {} # Tagged commands awaiting response + self.untagged_responses = {} # {typ: [data, ...], ...} + self.continuation_response = '' # Last continuation response + self.is_readonly = False # READ-ONLY desired state + self.tagnum = 0 + + # Open socket to server. + + self.open(host, port) + + # Create unique tag for this session, + # and compile tagged response matcher. + + self.tagpre = Int2AP(random.randint(4096, 65535)) + self.tagre = re.compile(r'(?P<tag>' + + self.tagpre + + r'\d+) (?P<type>[A-Z]+) (?P<data>.*)') + + # Get server welcome message, + # request and store CAPABILITY response. + + if __debug__: + self._cmd_log_len = 10 + self._cmd_log_idx = 0 + self._cmd_log = {} # Last `_cmd_log_len' interactions + if self.debug >= 1: + self._mesg('imaplib version %s' % __version__) + self._mesg('new IMAP4 connection, tag=%s' % self.tagpre) + + self.welcome = self._get_response() + if 'PREAUTH' in self.untagged_responses: + self.state = 'AUTH' + elif 'OK' in self.untagged_responses: + self.state = 'NONAUTH' + else: + raise self.error(self.welcome) + + typ, dat = self.capability() + if dat == [None]: + raise self.error('no CAPABILITY response from server') + self.capabilities = tuple(dat[-1].upper().split()) + + if __debug__: + if self.debug >= 3: + self._mesg('CAPABILITIES: %r' % (self.capabilities,)) + + for version in AllowedVersions: + if not version in self.capabilities: + continue + self.PROTOCOL_VERSION = version + return + + raise self.error('server not IMAP4 compliant') + + + def __getattr__(self, attr): + # Allow UPPERCASE variants of IMAP4 command methods. + if attr in Commands: + return getattr(self, attr.lower()) + raise AttributeError("Unknown IMAP4 command: '%s'" % attr) + + + + # Overridable methods + + + def open(self, host = '', port = IMAP4_PORT): + """Setup connection to remote server on "host:port" + (default: localhost:standard IMAP4 port). + This connection will be used by the routines: + read, readline, send, shutdown. + """ + self.host = host + self.port = port + self.sock = socket.create_connection((host, port)) + self.file = self.sock.makefile('rb') + + + def read(self, size): + """Read 'size' bytes from remote.""" + return self.file.read(size) + + + def readline(self): + """Read line from remote.""" + return self.file.readline() + + + def send(self, data): + """Send data to remote.""" + self.sock.sendall(data) + + + def shutdown(self): + """Close I/O established in "open".""" + self.file.close() + try: + self.sock.shutdown(socket.SHUT_RDWR) + except socket.error as e: + # The server might already have closed the connection + if e.errno != errno.ENOTCONN: + raise + finally: + self.sock.close() + + + def socket(self): + """Return socket instance used to connect to IMAP4 server. + + socket = <instance>.socket() + """ + return self.sock + + + + # Utility methods + + + def recent(self): + """Return most recent 'RECENT' responses if any exist, + else prompt server for an update using the 'NOOP' command. + + (typ, [data]) = <instance>.recent() + + 'data' is None if no new messages, + else list of RECENT responses, most recent last. + """ + name = 'RECENT' + typ, dat = self._untagged_response('OK', [None], name) + if dat[-1]: + return typ, dat + typ, dat = self.noop() # Prod server for response + return self._untagged_response(typ, dat, name) + + + def response(self, code): + """Return data for response 'code' if received, or None. + + Old value for response 'code' is cleared. + + (code, [data]) = <instance>.response(code) + """ + return self._untagged_response(code, [None], code.upper()) + + + + # IMAP4 commands + + + def append(self, mailbox, flags, date_time, message): + """Append message to named mailbox. + + (typ, [data]) = <instance>.append(mailbox, flags, date_time, message) + + All args except `message' can be None. + """ + name = 'APPEND' + if not mailbox: + mailbox = 'INBOX' + if flags: + if (flags[0],flags[-1]) != ('(',')'): + flags = '(%s)' % flags + else: + flags = None + if date_time: + date_time = Time2Internaldate(date_time) + else: + date_time = None + self.literal = MapCRLF.sub(CRLF, message) + return self._simple_command(name, mailbox, flags, date_time) + + + def authenticate(self, mechanism, authobject): + """Authenticate command - requires response processing. + + 'mechanism' specifies which authentication mechanism is to + be used - it must appear in <instance>.capabilities in the + form AUTH=<mechanism>. + + 'authobject' must be a callable object: + + data = authobject(response) + + It will be called to process server continuation responses. + It should return data that will be encoded and sent to server. + It should return None if the client abort response '*' should + be sent instead. + """ + mech = mechanism.upper() + # XXX: shouldn't this code be removed, not commented out? + #cap = 'AUTH=%s' % mech + #if not cap in self.capabilities: # Let the server decide! + # raise self.error("Server doesn't allow %s authentication." % mech) + self.literal = _Authenticator(authobject).process + typ, dat = self._simple_command('AUTHENTICATE', mech) + if typ != 'OK': + raise self.error(dat[-1]) + self.state = 'AUTH' + return typ, dat + + + def capability(self): + """(typ, [data]) = <instance>.capability() + Fetch capabilities list from server.""" + + name = 'CAPABILITY' + typ, dat = self._simple_command(name) + return self._untagged_response(typ, dat, name) + + + def check(self): + """Checkpoint mailbox on server. + + (typ, [data]) = <instance>.check() + """ + return self._simple_command('CHECK') + + + def close(self): + """Close currently selected mailbox. + + Deleted messages are removed from writable mailbox. + This is the recommended command before 'LOGOUT'. + + (typ, [data]) = <instance>.close() + """ + try: + typ, dat = self._simple_command('CLOSE') + finally: + self.state = 'AUTH' + return typ, dat + + + def copy(self, message_set, new_mailbox): + """Copy 'message_set' messages onto end of 'new_mailbox'. + + (typ, [data]) = <instance>.copy(message_set, new_mailbox) + """ + return self._simple_command('COPY', message_set, new_mailbox) + + + def create(self, mailbox): + """Create new mailbox. + + (typ, [data]) = <instance>.create(mailbox) + """ + return self._simple_command('CREATE', mailbox) + + + def delete(self, mailbox): + """Delete old mailbox. + + (typ, [data]) = <instance>.delete(mailbox) + """ + return self._simple_command('DELETE', mailbox) + + def deleteacl(self, mailbox, who): + """Delete the ACLs (remove any rights) set for who on mailbox. + + (typ, [data]) = <instance>.deleteacl(mailbox, who) + """ + return self._simple_command('DELETEACL', mailbox, who) + + def expunge(self): + """Permanently remove deleted items from selected mailbox. + + Generates 'EXPUNGE' response for each deleted message. + + (typ, [data]) = <instance>.expunge() + + 'data' is list of 'EXPUNGE'd message numbers in order received. + """ + name = 'EXPUNGE' + typ, dat = self._simple_command(name) + return self._untagged_response(typ, dat, name) + + + def fetch(self, message_set, message_parts): + """Fetch (parts of) messages. + + (typ, [data, ...]) = <instance>.fetch(message_set, message_parts) + + 'message_parts' should be a string of selected parts + enclosed in parentheses, eg: "(UID BODY[TEXT])". + + 'data' are tuples of message part envelope and data. + """ + name = 'FETCH' + typ, dat = self._simple_command(name, message_set, message_parts) + return self._untagged_response(typ, dat, name) + + + def getacl(self, mailbox): + """Get the ACLs for a mailbox. + + (typ, [data]) = <instance>.getacl(mailbox) + """ + typ, dat = self._simple_command('GETACL', mailbox) + return self._untagged_response(typ, dat, 'ACL') + + + def getannotation(self, mailbox, entry, attribute): + """(typ, [data]) = <instance>.getannotation(mailbox, entry, attribute) + Retrieve ANNOTATIONs.""" + + typ, dat = self._simple_command('GETANNOTATION', mailbox, entry, attribute) + return self._untagged_response(typ, dat, 'ANNOTATION') + + + def getquota(self, root): + """Get the quota root's resource usage and limits. + + Part of the IMAP4 QUOTA extension defined in rfc2087. + + (typ, [data]) = <instance>.getquota(root) + """ + typ, dat = self._simple_command('GETQUOTA', root) + return self._untagged_response(typ, dat, 'QUOTA') + + + def getquotaroot(self, mailbox): + """Get the list of quota roots for the named mailbox. + + (typ, [[QUOTAROOT responses...], [QUOTA responses]]) = <instance>.getquotaroot(mailbox) + """ + typ, dat = self._simple_command('GETQUOTAROOT', mailbox) + typ, quota = self._untagged_response(typ, dat, 'QUOTA') + typ, quotaroot = self._untagged_response(typ, dat, 'QUOTAROOT') + return typ, [quotaroot, quota] + + + def list(self, directory='""', pattern='*'): + """List mailbox names in directory matching pattern. + + (typ, [data]) = <instance>.list(directory='""', pattern='*') + + 'data' is list of LIST responses. + """ + name = 'LIST' + typ, dat = self._simple_command(name, directory, pattern) + return self._untagged_response(typ, dat, name) + + + def login(self, user, password): + """Identify client using plaintext password. + + (typ, [data]) = <instance>.login(user, password) + + NB: 'password' will be quoted. + """ + typ, dat = self._simple_command('LOGIN', user, self._quote(password)) + if typ != 'OK': + raise self.error(dat[-1]) + self.state = 'AUTH' + return typ, dat + + + def login_cram_md5(self, user, password): + """ Force use of CRAM-MD5 authentication. + + (typ, [data]) = <instance>.login_cram_md5(user, password) + """ + self.user, self.password = user, password + return self.authenticate('CRAM-MD5', self._CRAM_MD5_AUTH) + + + def _CRAM_MD5_AUTH(self, challenge): + """ Authobject to use with CRAM-MD5 authentication. """ + import hmac + return self.user + " " + hmac.HMAC(self.password, challenge).hexdigest() + + + def logout(self): + """Shutdown connection to server. + + (typ, [data]) = <instance>.logout() + + Returns server 'BYE' response. + """ + self.state = 'LOGOUT' + try: typ, dat = self._simple_command('LOGOUT') + except: typ, dat = 'NO', ['%s: %s' % sys.exc_info()[:2]] + self.shutdown() + if 'BYE' in self.untagged_responses: + return 'BYE', self.untagged_responses['BYE'] + return typ, dat + + + def lsub(self, directory='""', pattern='*'): + """List 'subscribed' mailbox names in directory matching pattern. + + (typ, [data, ...]) = <instance>.lsub(directory='""', pattern='*') + + 'data' are tuples of message part envelope and data. + """ + name = 'LSUB' + typ, dat = self._simple_command(name, directory, pattern) + return self._untagged_response(typ, dat, name) + + def myrights(self, mailbox): + """Show my ACLs for a mailbox (i.e. the rights that I have on mailbox). + + (typ, [data]) = <instance>.myrights(mailbox) + """ + typ,dat = self._simple_command('MYRIGHTS', mailbox) + return self._untagged_response(typ, dat, 'MYRIGHTS') + + def namespace(self): + """ Returns IMAP namespaces ala rfc2342 + + (typ, [data, ...]) = <instance>.namespace() + """ + name = 'NAMESPACE' + typ, dat = self._simple_command(name) + return self._untagged_response(typ, dat, name) + + + def noop(self): + """Send NOOP command. + + (typ, [data]) = <instance>.noop() + """ + if __debug__: + if self.debug >= 3: + self._dump_ur(self.untagged_responses) + return self._simple_command('NOOP') + + + def partial(self, message_num, message_part, start, length): + """Fetch truncated part of a message. + + (typ, [data, ...]) = <instance>.partial(message_num, message_part, start, length) + + 'data' is tuple of message part envelope and data. + """ + name = 'PARTIAL' + typ, dat = self._simple_command(name, message_num, message_part, start, length) + return self._untagged_response(typ, dat, 'FETCH') + + + def proxyauth(self, user): + """Assume authentication as "user". + + Allows an authorised administrator to proxy into any user's + mailbox. + + (typ, [data]) = <instance>.proxyauth(user) + """ + + name = 'PROXYAUTH' + return self._simple_command('PROXYAUTH', user) + + + def rename(self, oldmailbox, newmailbox): + """Rename old mailbox name to new. + + (typ, [data]) = <instance>.rename(oldmailbox, newmailbox) + """ + return self._simple_command('RENAME', oldmailbox, newmailbox) + + + def search(self, charset, *criteria): + """Search mailbox for matching messages. + + (typ, [data]) = <instance>.search(charset, criterion, ...) + + 'data' is space separated list of matching message numbers. + """ + name = 'SEARCH' + if charset: + typ, dat = self._simple_command(name, 'CHARSET', charset, *criteria) + else: + typ, dat = self._simple_command(name, *criteria) + return self._untagged_response(typ, dat, name) + + + def select(self, mailbox='INBOX', readonly=False): + """Select a mailbox. + + Flush all untagged responses. + + (typ, [data]) = <instance>.select(mailbox='INBOX', readonly=False) + + 'data' is count of messages in mailbox ('EXISTS' response). + + Mandated responses are ('FLAGS', 'EXISTS', 'RECENT', 'UIDVALIDITY'), so + other responses should be obtained via <instance>.response('FLAGS') etc. + """ + self.untagged_responses = {} # Flush old responses. + self.is_readonly = readonly + if readonly: + name = 'EXAMINE' + else: + name = 'SELECT' + typ, dat = self._simple_command(name, mailbox) + if typ != 'OK': + self.state = 'AUTH' # Might have been 'SELECTED' + return typ, dat + self.state = 'SELECTED' + if 'READ-ONLY' in self.untagged_responses \ + and not readonly: + if __debug__: + if self.debug >= 1: + self._dump_ur(self.untagged_responses) + raise self.readonly('%s is not writable' % mailbox) + return typ, self.untagged_responses.get('EXISTS', [None]) + + + def setacl(self, mailbox, who, what): + """Set a mailbox acl. + + (typ, [data]) = <instance>.setacl(mailbox, who, what) + """ + return self._simple_command('SETACL', mailbox, who, what) + + + def setannotation(self, *args): + """(typ, [data]) = <instance>.setannotation(mailbox[, entry, attribute]+) + Set ANNOTATIONs.""" + + typ, dat = self._simple_command('SETANNOTATION', *args) + return self._untagged_response(typ, dat, 'ANNOTATION') + + + def setquota(self, root, limits): + """Set the quota root's resource limits. + + (typ, [data]) = <instance>.setquota(root, limits) + """ + typ, dat = self._simple_command('SETQUOTA', root, limits) + return self._untagged_response(typ, dat, 'QUOTA') + + + def sort(self, sort_criteria, charset, *search_criteria): + """IMAP4rev1 extension SORT command. + + (typ, [data]) = <instance>.sort(sort_criteria, charset, search_criteria, ...) + """ + name = 'SORT' + #if not name in self.capabilities: # Let the server decide! + # raise self.error('unimplemented extension command: %s' % name) + if (sort_criteria[0],sort_criteria[-1]) != ('(',')'): + sort_criteria = '(%s)' % sort_criteria + typ, dat = self._simple_command(name, sort_criteria, charset, *search_criteria) + return self._untagged_response(typ, dat, name) + + + def status(self, mailbox, names): + """Request named status conditions for mailbox. + + (typ, [data]) = <instance>.status(mailbox, names) + """ + name = 'STATUS' + #if self.PROTOCOL_VERSION == 'IMAP4': # Let the server decide! + # raise self.error('%s unimplemented in IMAP4 (obtain IMAP4rev1 server, or re-code)' % name) + typ, dat = self._simple_command(name, mailbox, names) + return self._untagged_response(typ, dat, name) + + + def store(self, message_set, command, flags): + """Alters flag dispositions for messages in mailbox. + + (typ, [data]) = <instance>.store(message_set, command, flags) + """ + if (flags[0],flags[-1]) != ('(',')'): + flags = '(%s)' % flags # Avoid quoting the flags + typ, dat = self._simple_command('STORE', message_set, command, flags) + return self._untagged_response(typ, dat, 'FETCH') + + + def subscribe(self, mailbox): + """Subscribe to new mailbox. + + (typ, [data]) = <instance>.subscribe(mailbox) + """ + return self._simple_command('SUBSCRIBE', mailbox) + + + def thread(self, threading_algorithm, charset, *search_criteria): + """IMAPrev1 extension THREAD command. + + (type, [data]) = <instance>.thread(threading_algorithm, charset, search_criteria, ...) + """ + name = 'THREAD' + typ, dat = self._simple_command(name, threading_algorithm, charset, *search_criteria) + return self._untagged_response(typ, dat, name) + + + def uid(self, command, *args): + """Execute "command arg ..." with messages identified by UID, + rather than message number. + + (typ, [data]) = <instance>.uid(command, arg1, arg2, ...) + + Returns response appropriate to 'command'. + """ + command = command.upper() + if not command in Commands: + raise self.error("Unknown IMAP4 UID command: %s" % command) + if self.state not in Commands[command]: + raise self.error("command %s illegal in state %s, " + "only allowed in states %s" % + (command, self.state, + ', '.join(Commands[command]))) + name = 'UID' + typ, dat = self._simple_command(name, command, *args) + if command in ('SEARCH', 'SORT', 'THREAD'): + name = command + else: + name = 'FETCH' + return self._untagged_response(typ, dat, name) + + + def unsubscribe(self, mailbox): + """Unsubscribe from old mailbox. + + (typ, [data]) = <instance>.unsubscribe(mailbox) + """ + return self._simple_command('UNSUBSCRIBE', mailbox) + + + def xatom(self, name, *args): + """Allow simple extension commands + notified by server in CAPABILITY response. + + Assumes command is legal in current state. + + (typ, [data]) = <instance>.xatom(name, arg, ...) + + Returns response appropriate to extension command `name'. + """ + name = name.upper() + #if not name in self.capabilities: # Let the server decide! + # raise self.error('unknown extension command: %s' % name) + if not name in Commands: + Commands[name] = (self.state,) + return self._simple_command(name, *args) + + + + # Private methods + + + def _append_untagged(self, typ, dat): + + if dat is None: dat = '' + ur = self.untagged_responses + if __debug__: + if self.debug >= 5: + self._mesg('untagged_responses[%s] %s += ["%s"]' % + (typ, len(ur.get(typ,'')), dat)) + if typ in ur: + ur[typ].append(dat) + else: + ur[typ] = [dat] + + + def _check_bye(self): + bye = self.untagged_responses.get('BYE') + if bye: + raise self.abort(bye[-1]) + + + def _command(self, name, *args): + + if self.state not in Commands[name]: + self.literal = None + raise self.error("command %s illegal in state %s, " + "only allowed in states %s" % + (name, self.state, + ', '.join(Commands[name]))) + + for typ in ('OK', 'NO', 'BAD'): + if typ in self.untagged_responses: + del self.untagged_responses[typ] + + if 'READ-ONLY' in self.untagged_responses \ + and not self.is_readonly: + raise self.readonly('mailbox status changed to READ-ONLY') + + tag = self._new_tag() + data = '%s %s' % (tag, name) + for arg in args: + if arg is None: continue + data = '%s %s' % (data, self._checkquote(arg)) + + literal = self.literal + if literal is not None: + self.literal = None + if type(literal) is type(self._command): + literator = literal + else: + literator = None + data = '%s {%s}' % (data, len(literal)) + + if __debug__: + if self.debug >= 4: + self._mesg('> %s' % data) + else: + self._log('> %s' % data) + + try: + self.send('%s%s' % (data, CRLF)) + except (socket.error, OSError), val: + raise self.abort('socket error: %s' % val) + + if literal is None: + return tag + + while 1: + # Wait for continuation response + + while self._get_response(): + if self.tagged_commands[tag]: # BAD/NO? + return tag + + # Send literal + + if literator: + literal = literator(self.continuation_response) + + if __debug__: + if self.debug >= 4: + self._mesg('write literal size %s' % len(literal)) + + try: + self.send(literal) + self.send(CRLF) + except (socket.error, OSError), val: + raise self.abort('socket error: %s' % val) + + if not literator: + break + + return tag + + + def _command_complete(self, name, tag): + # BYE is expected after LOGOUT + if name != 'LOGOUT': + self._check_bye() + try: + typ, data = self._get_tagged_response(tag) + except self.abort, val: + raise self.abort('command: %s => %s' % (name, val)) + except self.error, val: + raise self.error('command: %s => %s' % (name, val)) + if name != 'LOGOUT': + self._check_bye() + if typ == 'BAD': + raise self.error('%s command error: %s %s' % (name, typ, data)) + return typ, data + + + def _get_response(self): + + # Read response and store. + # + # Returns None for continuation responses, + # otherwise first response line received. + + resp = self._get_line() + + # Command completion response? + + if self._match(self.tagre, resp): + tag = self.mo.group('tag') + if not tag in self.tagged_commands: + raise self.abort('unexpected tagged response: %s' % resp) + + typ = self.mo.group('type') + dat = self.mo.group('data') + self.tagged_commands[tag] = (typ, [dat]) + else: + dat2 = None + + # '*' (untagged) responses? + + if not self._match(Untagged_response, resp): + if self._match(Untagged_status, resp): + dat2 = self.mo.group('data2') + + if self.mo is None: + # Only other possibility is '+' (continuation) response... + + if self._match(Continuation, resp): + self.continuation_response = self.mo.group('data') + return None # NB: indicates continuation + + raise self.abort("unexpected response: '%s'" % resp) + + typ = self.mo.group('type') + dat = self.mo.group('data') + if dat is None: dat = '' # Null untagged response + if dat2: dat = dat + ' ' + dat2 + + # Is there a literal to come? + + while self._match(Literal, dat): + + # Read literal direct from connection. + + size = int(self.mo.group('size')) + if __debug__: + if self.debug >= 4: + self._mesg('read literal size %s' % size) + data = self.read(size) + + # Store response with literal as tuple + + self._append_untagged(typ, (dat, data)) + + # Read trailer - possibly containing another literal + + dat = self._get_line() + + self._append_untagged(typ, dat) + + # Bracketed response information? + + if typ in ('OK', 'NO', 'BAD') and self._match(Response_code, dat): + self._append_untagged(self.mo.group('type'), self.mo.group('data')) + + if __debug__: + if self.debug >= 1 and typ in ('NO', 'BAD', 'BYE'): + self._mesg('%s response: %s' % (typ, dat)) + + return resp + + + def _get_tagged_response(self, tag): + + while 1: + result = self.tagged_commands[tag] + if result is not None: + del self.tagged_commands[tag] + return result + + # Some have reported "unexpected response" exceptions. + # Note that ignoring them here causes loops. + # Instead, send me details of the unexpected response and + # I'll update the code in `_get_response()'. + + try: + self._get_response() + except self.abort, val: + if __debug__: + if self.debug >= 1: + self.print_log() + raise + + + def _get_line(self): + + line = self.readline() + if not line: + raise self.abort('socket error: EOF') + + # Protocol mandates all lines terminated by CRLF + if not line.endswith('\r\n'): + raise self.abort('socket error: unterminated line') + + line = line[:-2] + if __debug__: + if self.debug >= 4: + self._mesg('< %s' % line) + else: + self._log('< %s' % line) + return line + + + def _match(self, cre, s): + + # Run compiled regular expression match method on 's'. + # Save result, return success. + + self.mo = cre.match(s) + if __debug__: + if self.mo is not None and self.debug >= 5: + self._mesg("\tmatched r'%s' => %r" % (cre.pattern, self.mo.groups())) + return self.mo is not None + + + def _new_tag(self): + + tag = '%s%s' % (self.tagpre, self.tagnum) + self.tagnum = self.tagnum + 1 + self.tagged_commands[tag] = None + return tag + + + def _checkquote(self, arg): + + # Must quote command args if non-alphanumeric chars present, + # and not already quoted. + + if type(arg) is not type(''): + return arg + if len(arg) >= 2 and (arg[0],arg[-1]) in (('(',')'),('"','"')): + return arg + if arg and self.mustquote.search(arg) is None: + return arg + return self._quote(arg) + + + def _quote(self, arg): + + arg = arg.replace('\\', '\\\\') + arg = arg.replace('"', '\\"') + + return '"%s"' % arg + + + def _simple_command(self, name, *args): + + return self._command_complete(name, self._command(name, *args)) + + + def _untagged_response(self, typ, dat, name): + + if typ == 'NO': + return typ, dat + if not name in self.untagged_responses: + return typ, [None] + data = self.untagged_responses.pop(name) + if __debug__: + if self.debug >= 5: + self._mesg('untagged_responses[%s] => %s' % (name, data)) + return typ, data + + + if __debug__: + + def _mesg(self, s, secs=None): + if secs is None: + secs = time.time() + tm = time.strftime('%M:%S', time.localtime(secs)) + sys.stderr.write(' %s.%02d %s\n' % (tm, (secs*100)%100, s)) + sys.stderr.flush() + + def _dump_ur(self, dict): + # Dump untagged responses (in `dict'). + l = dict.items() + if not l: return + t = '\n\t\t' + l = map(lambda x:'%s: "%s"' % (x[0], x[1][0] and '" "'.join(x[1]) or ''), l) + self._mesg('untagged responses dump:%s%s' % (t, t.join(l))) + + def _log(self, line): + # Keep log of last `_cmd_log_len' interactions for debugging. + self._cmd_log[self._cmd_log_idx] = (line, time.time()) + self._cmd_log_idx += 1 + if self._cmd_log_idx >= self._cmd_log_len: + self._cmd_log_idx = 0 + + def print_log(self): + self._mesg('last %d IMAP4 interactions:' % len(self._cmd_log)) + i, n = self._cmd_log_idx, self._cmd_log_len + while n: + try: + self._mesg(*self._cmd_log[i]) + except: + pass + i += 1 + if i >= self._cmd_log_len: + i = 0 + n -= 1 + + + +try: + import ssl +except ImportError: + pass +else: + class IMAP4_SSL(IMAP4): + + """IMAP4 client class over SSL connection + + Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile]]]]) + + host - host's name (default: localhost); + port - port number (default: standard IMAP4 SSL port). + keyfile - PEM formatted file that contains your private key (default: None); + certfile - PEM formatted certificate chain file (default: None); + + for more documentation see the docstring of the parent class IMAP4. + """ + + + def __init__(self, host = '', port = IMAP4_SSL_PORT, keyfile = None, certfile = None): + self.keyfile = keyfile + self.certfile = certfile + IMAP4.__init__(self, host, port) + + + def open(self, host = '', port = IMAP4_SSL_PORT): + """Setup connection to remote server on "host:port". + (default: localhost:standard IMAP4 SSL port). + This connection will be used by the routines: + read, readline, send, shutdown. + """ + self.host = host + self.port = port + self.sock = socket.create_connection((host, port)) + self.sslobj = ssl.wrap_socket(self.sock, self.keyfile, self.certfile) + self.file = self.sslobj.makefile('rb') + + + def read(self, size): + """Read 'size' bytes from remote.""" + return self.file.read(size) + + + def readline(self): + """Read line from remote.""" + return self.file.readline() + + + def send(self, data): + """Send data to remote.""" + bytes = len(data) + while bytes > 0: + sent = self.sslobj.write(data) + if sent == bytes: + break # avoid copy + data = data[sent:] + bytes = bytes - sent + + + def shutdown(self): + """Close I/O established in "open".""" + self.file.close() + self.sock.close() + + + def socket(self): + """Return socket instance used to connect to IMAP4 server. + + socket = <instance>.socket() + """ + return self.sock + + + def ssl(self): + """Return SSLObject instance used to communicate with the IMAP4 server. + + ssl = ssl.wrap_socket(<instance>.socket) + """ + return self.sslobj + + __all__.append("IMAP4_SSL") + + +class IMAP4_stream(IMAP4): + + """IMAP4 client class over a stream + + Instantiate with: IMAP4_stream(command) + + where "command" is a string that can be passed to subprocess.Popen() + + for more documentation see the docstring of the parent class IMAP4. + """ + + + def __init__(self, command): + self.command = command + IMAP4.__init__(self) + + + def open(self, host = None, port = None): + """Setup a stream connection. + This connection will be used by the routines: + read, readline, send, shutdown. + """ + self.host = None # For compatibility with parent class + self.port = None + self.sock = None + self.file = None + self.process = subprocess.Popen(self.command, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + shell=True, close_fds=True) + self.writefile = self.process.stdin + self.readfile = self.process.stdout + + + def read(self, size): + """Read 'size' bytes from remote.""" + return self.readfile.read(size) + + + def readline(self): + """Read line from remote.""" + return self.readfile.readline() + + + def send(self, data): + """Send data to remote.""" + self.writefile.write(data) + self.writefile.flush() + + + def shutdown(self): + """Close I/O established in "open".""" + self.readfile.close() + self.writefile.close() + self.process.wait() + + + +class _Authenticator: + + """Private class to provide en/decoding + for base64-based authentication conversation. + """ + + def __init__(self, mechinst): + self.mech = mechinst # Callable object to provide/process data + + def process(self, data): + ret = self.mech(self.decode(data)) + if ret is None: + return '*' # Abort conversation + return self.encode(ret) + + def encode(self, inp): + # + # Invoke binascii.b2a_base64 iteratively with + # short even length buffers, strip the trailing + # line feed from the result and append. "Even" + # means a number that factors to both 6 and 8, + # so when it gets to the end of the 8-bit input + # there's no partial 6-bit output. + # + oup = '' + while inp: + if len(inp) > 48: + t = inp[:48] + inp = inp[48:] + else: + t = inp + inp = '' + e = binascii.b2a_base64(t) + if e: + oup = oup + e[:-1] + return oup + + def decode(self, inp): + if not inp: + return '' + return binascii.a2b_base64(inp) + + + +Mon2num = {'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, + 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12} + +def Internaldate2tuple(resp): + """Parse an IMAP4 INTERNALDATE string. + + Return corresponding local time. The return value is a + time.struct_time instance or None if the string has wrong format. + """ + + mo = InternalDate.match(resp) + if not mo: + return None + + mon = Mon2num[mo.group('mon')] + zonen = mo.group('zonen') + + day = int(mo.group('day')) + year = int(mo.group('year')) + hour = int(mo.group('hour')) + min = int(mo.group('min')) + sec = int(mo.group('sec')) + zoneh = int(mo.group('zoneh')) + zonem = int(mo.group('zonem')) + + # INTERNALDATE timezone must be subtracted to get UT + + zone = (zoneh*60 + zonem)*60 + if zonen == '-': + zone = -zone + + tt = (year, mon, day, hour, min, sec, -1, -1, -1) + + utc = time.mktime(tt) + + # Following is necessary because the time module has no 'mkgmtime'. + # 'mktime' assumes arg in local timezone, so adds timezone/altzone. + + lt = time.localtime(utc) + if time.daylight and lt[-1]: + zone = zone + time.altzone + else: + zone = zone + time.timezone + + return time.localtime(utc - zone) + + + +def Int2AP(num): + + """Convert integer to A-P string representation.""" + + val = ''; AP = 'ABCDEFGHIJKLMNOP' + num = int(abs(num)) + while num: + num, mod = divmod(num, 16) + val = AP[mod] + val + return val + + + +def ParseFlags(resp): + + """Convert IMAP4 flags response to python tuple.""" + + mo = Flags.match(resp) + if not mo: + return () + + return tuple(mo.group('flags').split()) + + +def Time2Internaldate(date_time): + + """Convert date_time to IMAP4 INTERNALDATE representation. + + Return string in form: '"DD-Mmm-YYYY HH:MM:SS +HHMM"'. The + date_time argument can be a number (int or float) representing + seconds since epoch (as returned by time.time()), a 9-tuple + representing local time (as returned by time.localtime()), or a + double-quoted string. In the last case, it is assumed to already + be in the correct format. + """ + + if isinstance(date_time, (int, float)): + tt = time.localtime(date_time) + elif isinstance(date_time, (tuple, time.struct_time)): + tt = date_time + elif isinstance(date_time, str) and (date_time[0],date_time[-1]) == ('"','"'): + return date_time # Assume in correct format + else: + raise ValueError("date_time not of a known type") + + dt = time.strftime("%d-%b-%Y %H:%M:%S", tt) + if dt[0] == '0': + dt = ' ' + dt[1:] + if time.daylight and tt[-1]: + zone = -time.altzone + else: + zone = -time.timezone + return '"' + dt + " %+03d%02d" % divmod(zone//60, 60) + '"' + + + +if __name__ == '__main__': + + # To test: invoke either as 'python imaplib.py [IMAP4_server_hostname]' + # or 'python imaplib.py -s "rsh IMAP4_server_hostname exec /etc/rimapd"' + # to test the IMAP4_stream class + + import getopt, getpass + + try: + optlist, args = getopt.getopt(sys.argv[1:], 'd:s:') + except getopt.error, val: + optlist, args = (), () + + stream_command = None + for opt,val in optlist: + if opt == '-d': + Debug = int(val) + elif opt == '-s': + stream_command = val + if not args: args = (stream_command,) + + if not args: args = ('',) + + host = args[0] + + USER = getpass.getuser() + PASSWD = getpass.getpass("IMAP password for %s on %s: " % (USER, host or "localhost")) + + test_mesg = 'From: %(user)s@localhost%(lf)sSubject: IMAP4 test%(lf)s%(lf)sdata...%(lf)s' % {'user':USER, 'lf':'\n'} + test_seq1 = ( + ('login', (USER, PASSWD)), + ('create', ('/tmp/xxx 1',)), + ('rename', ('/tmp/xxx 1', '/tmp/yyy')), + ('CREATE', ('/tmp/yyz 2',)), + ('append', ('/tmp/yyz 2', None, None, test_mesg)), + ('list', ('/tmp', 'yy*')), + ('select', ('/tmp/yyz 2',)), + ('search', (None, 'SUBJECT', 'test')), + ('fetch', ('1', '(FLAGS INTERNALDATE RFC822)')), + ('store', ('1', 'FLAGS', '(\Deleted)')), + ('namespace', ()), + ('expunge', ()), + ('recent', ()), + ('close', ()), + ) + + test_seq2 = ( + ('select', ()), + ('response',('UIDVALIDITY',)), + ('uid', ('SEARCH', 'ALL')), + ('response', ('EXISTS',)), + ('append', (None, None, None, test_mesg)), + ('recent', ()), + ('logout', ()), + ) + + def run(cmd, args): + M._mesg('%s %s' % (cmd, args)) + typ, dat = getattr(M, cmd)(*args) + M._mesg('%s => %s %s' % (cmd, typ, dat)) + if typ == 'NO': raise dat[0] + return dat + + try: + if stream_command: + M = IMAP4_stream(stream_command) + else: + M = IMAP4(host) + if M.state == 'AUTH': + test_seq1 = test_seq1[1:] # Login not needed + M._mesg('PROTOCOL_VERSION = %s' % M.PROTOCOL_VERSION) + M._mesg('CAPABILITIES = %r' % (M.capabilities,)) + + for cmd,args in test_seq1: + run(cmd, args) + + for ml in run('list', ('/tmp/', 'yy%')): + mo = re.match(r'.*"([^"]+)"$', ml) + if mo: path = mo.group(1) + else: path = ml.split()[-1] + run('delete', (path,)) + + for cmd,args in test_seq2: + dat = run(cmd, args) + + if (cmd,args) != ('uid', ('SEARCH', 'ALL')): + continue + + uid = dat[-1].split() + if not uid: continue + run('uid', ('FETCH', '%s' % uid[-1], + '(FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822.TEXT)')) + + print '\nAll tests OK.' + + except: + print '\nTests failed.' + + if not Debug: + print ''' +If you would like to see debugging output, +try: %s -d5 +''' % sys.argv[0] + + raise diff --git a/src/main/resources/PythonLibs/imghdr.py b/src/main/resources/PythonLibs/imghdr.py new file mode 100644 index 0000000000000000000000000000000000000000..1683024cb72923d6a02bf50230ad9860aa69875c --- /dev/null +++ b/src/main/resources/PythonLibs/imghdr.py @@ -0,0 +1,161 @@ +"""Recognize image file formats based on their first few bytes.""" + +__all__ = ["what"] + +#-------------------------# +# Recognize image headers # +#-------------------------# + +def what(file, h=None): + if h is None: + if isinstance(file, basestring): + f = open(file, 'rb') + h = f.read(32) + else: + location = file.tell() + h = file.read(32) + file.seek(location) + f = None + else: + f = None + try: + for tf in tests: + res = tf(h, f) + if res: + return res + finally: + if f: f.close() + return None + + +#---------------------------------# +# Subroutines per image file type # +#---------------------------------# + +tests = [] + +def test_jpeg(h, f): + """JPEG data in JFIF format""" + if h[6:10] == 'JFIF': + return 'jpeg' + +tests.append(test_jpeg) + +def test_exif(h, f): + """JPEG data in Exif format""" + if h[6:10] == 'Exif': + return 'jpeg' + +tests.append(test_exif) + +def test_png(h, f): + if h[:8] == "\211PNG\r\n\032\n": + return 'png' + +tests.append(test_png) + +def test_gif(h, f): + """GIF ('87 and '89 variants)""" + if h[:6] in ('GIF87a', 'GIF89a'): + return 'gif' + +tests.append(test_gif) + +def test_tiff(h, f): + """TIFF (can be in Motorola or Intel byte order)""" + if h[:2] in ('MM', 'II'): + return 'tiff' + +tests.append(test_tiff) + +def test_rgb(h, f): + """SGI image library""" + if h[:2] == '\001\332': + return 'rgb' + +tests.append(test_rgb) + +def test_pbm(h, f): + """PBM (portable bitmap)""" + if len(h) >= 3 and \ + h[0] == 'P' and h[1] in '14' and h[2] in ' \t\n\r': + return 'pbm' + +tests.append(test_pbm) + +def test_pgm(h, f): + """PGM (portable graymap)""" + if len(h) >= 3 and \ + h[0] == 'P' and h[1] in '25' and h[2] in ' \t\n\r': + return 'pgm' + +tests.append(test_pgm) + +def test_ppm(h, f): + """PPM (portable pixmap)""" + if len(h) >= 3 and \ + h[0] == 'P' and h[1] in '36' and h[2] in ' \t\n\r': + return 'ppm' + +tests.append(test_ppm) + +def test_rast(h, f): + """Sun raster file""" + if h[:4] == '\x59\xA6\x6A\x95': + return 'rast' + +tests.append(test_rast) + +def test_xbm(h, f): + """X bitmap (X10 or X11)""" + s = '#define ' + if h[:len(s)] == s: + return 'xbm' + +tests.append(test_xbm) + +def test_bmp(h, f): + if h[:2] == 'BM': + return 'bmp' + +tests.append(test_bmp) + +#--------------------# +# Small test program # +#--------------------# + +def test(): + import sys + recursive = 0 + if sys.argv[1:] and sys.argv[1] == '-r': + del sys.argv[1:2] + recursive = 1 + try: + if sys.argv[1:]: + testall(sys.argv[1:], recursive, 1) + else: + testall(['.'], recursive, 1) + except KeyboardInterrupt: + sys.stderr.write('\n[Interrupted]\n') + sys.exit(1) + +def testall(list, recursive, toplevel): + import sys + import os + for filename in list: + if os.path.isdir(filename): + print filename + '/:', + if recursive or toplevel: + print 'recursing down:' + import glob + names = glob.glob(os.path.join(filename, '*')) + testall(names, recursive, 0) + else: + print '*** directory (use -r) ***' + else: + print filename + ':', + sys.stdout.flush() + try: + print what(filename) + except IOError: + print '*** not found ***' diff --git a/src/main/resources/PythonLibs/importlib/__init__.py b/src/main/resources/PythonLibs/importlib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ad31a1ac4776f5b830eb3d5e02dbcd7470e5ece9 --- /dev/null +++ b/src/main/resources/PythonLibs/importlib/__init__.py @@ -0,0 +1,38 @@ +"""Backport of importlib.import_module from 3.x.""" +# While not critical (and in no way guaranteed!), it would be nice to keep this +# code compatible with Python 2.3. +import sys + +def _resolve_name(name, package, level): + """Return the absolute name of the module to be imported.""" + if not hasattr(package, 'rindex'): + raise ValueError("'package' not set to a string") + dot = len(package) + for x in xrange(level, 1, -1): + try: + dot = package.rindex('.', 0, dot) + except ValueError: + raise ValueError("attempted relative import beyond top-level " + "package") + return "%s.%s" % (package[:dot], name) + + +def import_module(name, package=None): + """Import a module. + + The 'package' argument is required when performing a relative import. It + specifies the package to use as the anchor point from which to resolve the + relative import to an absolute import. + + """ + if name.startswith('.'): + if not package: + raise TypeError("relative imports require the 'package' argument") + level = 0 + for character in name: + if character != '.': + break + level += 1 + name = _resolve_name(name[level:], package, level) + __import__(name) + return sys.modules[name] diff --git a/src/main/resources/PythonLibs/inspect.py b/src/main/resources/PythonLibs/inspect.py new file mode 100644 index 0000000000000000000000000000000000000000..b737a34929b356f28fdbd2a6beb28b6c489a4406 --- /dev/null +++ b/src/main/resources/PythonLibs/inspect.py @@ -0,0 +1,967 @@ +# -*- coding: iso-8859-1 -*- +"""Get useful information from live Python objects. + +This module encapsulates the interface provided by the internal special +attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion. +It also provides some help for examining source code and class layout. + +Here are some of the useful functions provided by this module: + + ismodule(), isclass(), ismethod(), isfunction(), isgeneratorfunction(), + isgenerator(), istraceback(), isframe(), iscode(), isbuiltin(), + isroutine() - check object types + getmembers() - get members of an object that satisfy a given condition + + getfile(), getsourcefile(), getsource() - find an object's source code + getdoc(), getcomments() - get documentation on an object + getmodule() - determine the module that an object came from + getclasstree() - arrange classes so as to represent their hierarchy + + getargspec(), getargvalues() - get info about function arguments + formatargspec(), formatargvalues() - format an argument spec + getouterframes(), getinnerframes() - get info about frames + currentframe() - get the current stack frame + stack(), trace() - get info about frames on the stack or in a traceback +""" + +# This module is in the public domain. No warranties. + +__author__ = 'Ka-Ping Yee <ping@lfw.org>' +__date__ = '1 Jan 2001' + +import sys +import os +import types +import string +import re +import dis +import imp +import tokenize +import linecache +from operator import attrgetter +from collections import namedtuple +_jython = sys.platform.startswith('java') +if _jython: + _ReflectedFunctionType = type(os.listdir) + +# These constants are from Include/code.h. +CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 0x1, 0x2, 0x4, 0x8 +CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40 +# See Include/object.h +TPFLAGS_IS_ABSTRACT = 1 << 20 + +# ----------------------------------------------------------- type-checking +def ismodule(object): + """Return true if the object is a module. + + Module objects provide these attributes: + __doc__ documentation string + __file__ filename (missing for built-in modules)""" + return isinstance(object, types.ModuleType) + +def isclass(object): + """Return true if the object is a class. + + Class objects provide these attributes: + __doc__ documentation string + __module__ name of module in which this class was defined""" + return isinstance(object, types.ClassType) or hasattr(object, '__bases__') + +def ismethod(object): + """Return true if the object is an instance method. + + Instance method objects provide these attributes: + __doc__ documentation string + __name__ name with which this method was defined + im_class class object in which this method belongs + im_func function object containing implementation of method + im_self instance to which this method is bound, or None""" + return isinstance(object, types.MethodType) + +def ismethoddescriptor(object): + """Return true if the object is a method descriptor. + + But not if ismethod() or isclass() or isfunction() are true. + + This is new in Python 2.2, and, for example, is true of int.__add__. + An object passing this test has a __get__ attribute but not a __set__ + attribute, but beyond that the set of attributes varies. __name__ is + usually sensible, and __doc__ often is. + + Methods implemented via descriptors that also pass one of the other + tests return false from the ismethoddescriptor() test, simply because + the other tests promise more -- you can, e.g., count on having the + im_func attribute (etc) when an object passes ismethod().""" + return (hasattr(object, "__get__") + and not hasattr(object, "__set__") # else it's a data descriptor + and not ismethod(object) # mutual exclusion + and not isfunction(object) + and not isclass(object)) + +def isdatadescriptor(object): + """Return true if the object is a data descriptor. + + Data descriptors have both a __get__ and a __set__ attribute. Examples are + properties (defined in Python) and getsets and members (defined in C). + Typically, data descriptors will also have __name__ and __doc__ attributes + (properties, getsets, and members have both of these attributes), but this + is not guaranteed.""" + return (hasattr(object, "__set__") and hasattr(object, "__get__")) + +if hasattr(types, 'MemberDescriptorType'): + # CPython and equivalent + def ismemberdescriptor(object): + """Return true if the object is a member descriptor. + + Member descriptors are specialized descriptors defined in extension + modules.""" + return isinstance(object, types.MemberDescriptorType) +else: + # Other implementations + def ismemberdescriptor(object): + """Return true if the object is a member descriptor. + + Member descriptors are specialized descriptors defined in extension + modules.""" + return False + +if hasattr(types, 'GetSetDescriptorType'): + # CPython and equivalent + def isgetsetdescriptor(object): + """Return true if the object is a getset descriptor. + + getset descriptors are specialized descriptors defined in extension + modules.""" + return isinstance(object, types.GetSetDescriptorType) +else: + # Other implementations + def isgetsetdescriptor(object): + """Return true if the object is a getset descriptor. + + getset descriptors are specialized descriptors defined in extension + modules.""" + return False + +def isfunction(object): + """Return true if the object is a user-defined function. + + Function objects provide these attributes: + __doc__ documentation string + __name__ name with which this function was defined + func_code code object containing compiled function bytecode + func_defaults tuple of any default values for arguments + func_doc (same as __doc__) + func_globals global namespace in which this function was defined + func_name (same as __name__)""" + return isinstance(object, types.FunctionType) + +def isgeneratorfunction(object): + """Return true if the object is a user-defined generator function. + + Generator function objects provides same attributes as functions. + + See isfunction.__doc__ for attributes listing.""" + return bool((isfunction(object) or ismethod(object)) and + object.func_code.co_flags & CO_GENERATOR) + +def isgenerator(object): + """Return true if the object is a generator. + + Generator objects provide these attributes: + __iter__ defined to support interation over container + close raises a new GeneratorExit exception inside the + generator to terminate the iteration + gi_code code object + gi_frame frame object or possibly None once the generator has + been exhausted + gi_running set to 1 when generator is executing, 0 otherwise + next return the next item from the container + send resumes the generator and "sends" a value that becomes + the result of the current yield-expression + throw used to raise an exception inside the generator""" + return isinstance(object, types.GeneratorType) + +def istraceback(object): + """Return true if the object is a traceback. + + Traceback objects provide these attributes: + tb_frame frame object at this level + tb_lasti index of last attempted instruction in bytecode + tb_lineno current line number in Python source code + tb_next next inner traceback object (called by this level)""" + return isinstance(object, types.TracebackType) + +def isframe(object): + """Return true if the object is a frame object. + + Frame objects provide these attributes: + f_back next outer frame object (this frame's caller) + f_builtins built-in namespace seen by this frame + f_code code object being executed in this frame + f_exc_traceback traceback if raised in this frame, or None + f_exc_type exception type if raised in this frame, or None + f_exc_value exception value if raised in this frame, or None + f_globals global namespace seen by this frame + f_lasti index of last attempted instruction in bytecode + f_lineno current line number in Python source code + f_locals local namespace seen by this frame + f_restricted 0 or 1 if frame is in restricted execution mode + f_trace tracing function for this frame, or None""" + return isinstance(object, types.FrameType) + +def iscode(object): + """Return true if the object is a code object. + + Code objects provide these attributes: + co_argcount number of arguments (not including * or ** args) + co_code string of raw compiled bytecode + co_consts tuple of constants used in the bytecode + co_filename name of file in which this code object was created + co_firstlineno number of first line in Python source code + co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg + co_lnotab encoded mapping of line numbers to bytecode indices + co_name name with which this code object was defined + co_names tuple of names of local variables + co_nlocals number of local variables + co_stacksize virtual machine stack space required + co_varnames tuple of names of arguments and local variables""" + return isinstance(object, types.CodeType) + +def isbuiltin(object): + """Return true if the object is a built-in function or method. + + Built-in functions and methods provide these attributes: + __doc__ documentation string + __name__ original name of this function or method + __self__ instance to which a method is bound, or None""" + return isinstance(object, types.BuiltinFunctionType) + +def isroutine(object): + """Return true if the object is any kind of function or method.""" + return (isbuiltin(object) + or isfunction(object) + or ismethod(object) + or ismethoddescriptor(object) + or (_jython and isinstance(object, _ReflectedFunctionType))) + +def isabstract(object): + """Return true if the object is an abstract base class (ABC).""" + return isinstance(object, type) and object.__flags__ & TPFLAGS_IS_ABSTRACT + +def getmembers(object, predicate=None): + """Return all members of an object as (name, value) pairs sorted by name. + Optionally, only return members that satisfy a given predicate.""" + results = [] + for key in dir(object): + value = getattr(object, key) + if not predicate or predicate(value): + results.append((key, value)) + results.sort() + return results + +Attribute = namedtuple('Attribute', 'name kind defining_class object') + +def classify_class_attrs(cls): + """Return list of attribute-descriptor tuples. + + For each name in dir(cls), the return list contains a 4-tuple + with these elements: + + 0. The name (a string). + + 1. The kind of attribute this is, one of these strings: + 'class method' created via classmethod() + 'static method' created via staticmethod() + 'property' created via property() + 'method' any other flavor of method + 'data' not a method + + 2. The class which defined this attribute (a class). + + 3. The object as obtained directly from the defining class's + __dict__, not via getattr. This is especially important for + data attributes: C.data is just a data object, but + C.__dict__['data'] may be a data descriptor with additional + info, like a __doc__ string. + """ + + mro = getmro(cls) + names = dir(cls) + result = [] + for name in names: + # Get the object associated with the name. + # Getting an obj from the __dict__ sometimes reveals more than + # using getattr. Static and class methods are dramatic examples. + if name in cls.__dict__: + obj = cls.__dict__[name] + else: + obj = getattr(cls, name) + + # Figure out where it was defined. + homecls = getattr(obj, "__objclass__", None) + if homecls is None: + # search the dicts. + for base in mro: + if name in base.__dict__: + homecls = base + break + + # Get the object again, in order to get it from the defining + # __dict__ instead of via getattr (if possible). + if homecls is not None and name in homecls.__dict__: + obj = homecls.__dict__[name] + + # Also get the object via getattr. + obj_via_getattr = getattr(cls, name) + + # Classify the object. + if isinstance(obj, staticmethod): + kind = "static method" + elif isinstance(obj, classmethod): + kind = "class method" + elif isinstance(obj, property): + kind = "property" + elif (ismethod(obj_via_getattr) or + ismethoddescriptor(obj_via_getattr)): + kind = "method" + else: + kind = "data" + + result.append(Attribute(name, kind, homecls, obj)) + + return result + +# ----------------------------------------------------------- class helpers +def _searchbases(cls, accum): + # Simulate the "classic class" search order. + if cls in accum: + return + accum.append(cls) + for base in cls.__bases__: + _searchbases(base, accum) + +def getmro(cls): + "Return tuple of base classes (including cls) in method resolution order." + if hasattr(cls, "__mro__"): + return cls.__mro__ + else: + result = [] + _searchbases(cls, result) + return tuple(result) + +# -------------------------------------------------- source code extraction +def indentsize(line): + """Return the indent size, in spaces, at the start of a line of text.""" + expline = string.expandtabs(line) + return len(expline) - len(string.lstrip(expline)) + +def getdoc(object): + """Get the documentation string for an object. + + All tabs are expanded to spaces. To clean up docstrings that are + indented to line up with blocks of code, any whitespace than can be + uniformly removed from the second line onwards is removed.""" + try: + doc = object.__doc__ + except AttributeError: + return None + if not isinstance(doc, types.StringTypes): + return None + return cleandoc(doc) + +def cleandoc(doc): + """Clean up indentation from docstrings. + + Any whitespace that can be uniformly removed from the second line + onwards is removed.""" + try: + lines = string.split(string.expandtabs(doc), '\n') + except UnicodeError: + return None + else: + # Find minimum indentation of any non-blank lines after first line. + margin = sys.maxint + for line in lines[1:]: + content = len(string.lstrip(line)) + if content: + indent = len(line) - content + margin = min(margin, indent) + # Remove indentation. + if lines: + lines[0] = lines[0].lstrip() + if margin < sys.maxint: + for i in range(1, len(lines)): lines[i] = lines[i][margin:] + # Remove any trailing or leading blank lines. + while lines and not lines[-1]: + lines.pop() + while lines and not lines[0]: + lines.pop(0) + return string.join(lines, '\n') + +def getfile(object): + """Work out which source or compiled file an object was defined in.""" + if ismodule(object): + if hasattr(object, '__file__'): + return object.__file__ + raise TypeError('arg is a built-in module') + if isclass(object): + object = sys.modules.get(object.__module__) + if hasattr(object, '__file__'): + return object.__file__ + raise TypeError('arg is a built-in class') + if ismethod(object): + object = object.im_func + if isfunction(object): + object = object.func_code + if istraceback(object): + object = object.tb_frame + if isframe(object): + object = object.f_code + if iscode(object): + return object.co_filename + raise TypeError('arg is not a module, class, method, ' + 'function, traceback, frame, or code object') + +ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') + +def getmoduleinfo(path): + """Get the module name, suffix, mode, and module type for a given file.""" + filename = os.path.basename(path) + suffixes = map(lambda info: + (-len(info[0]), info[0], info[1], info[2]), + imp.get_suffixes()) + suffixes.sort() # try longest suffixes first, in case they overlap + for neglen, suffix, mode, mtype in suffixes: + if filename[neglen:] == suffix: + return ModuleInfo(filename[:neglen], suffix, mode, mtype) + +def getmodulename(path): + """Return the module name for a given file, or None.""" + info = getmoduleinfo(path) + if info: return info[0] + +def getsourcefile(object): + """Return the Python source file an object was defined in, if it exists.""" + filename = getfile(object) + if string.lower(filename[-4:]) in ('.pyc', '.pyo'): + filename = filename[:-4] + '.py' + elif filename.endswith('$py.class'): + filename = filename[:-9] + '.py' + for suffix, mode, kind in imp.get_suffixes(): + if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix: + # Looks like a binary file. We want to only return a text file. + return None + if os.path.exists(filename): + return filename + # only return a non-existent filename if the module has a PEP 302 loader + if hasattr(getmodule(object, filename), '__loader__'): + return filename + +def getabsfile(object, _filename=None): + """Return an absolute path to the source or compiled file for an object. + + The idea is for each object to have a unique origin, so this routine + normalizes the result as much as possible.""" + if _filename is None: + _filename = getsourcefile(object) or getfile(object) + return os.path.normcase(os.path.abspath(_filename)) + +modulesbyfile = {} +_filesbymodname = {} + +def getmodule(object, _filename=None): + """Return the module an object was defined in, or None if not found.""" + if ismodule(object): + return object + if hasattr(object, '__module__'): + return sys.modules.get(object.__module__) + # Try the filename to modulename cache + if _filename is not None and _filename in modulesbyfile: + return sys.modules.get(modulesbyfile[_filename]) + # Try the cache again with the absolute file name + try: + file = getabsfile(object, _filename) + except TypeError: + return None + if file in modulesbyfile: + return sys.modules.get(modulesbyfile[file]) + # Update the filename to module name cache and check yet again + # Copy sys.modules in order to cope with changes while iterating + for modname, module in sys.modules.items(): + if ismodule(module) and hasattr(module, '__file__'): + f = module.__file__ + if f == _filesbymodname.get(modname, None): + # Have already mapped this module, so skip it + continue + _filesbymodname[modname] = f + f = getabsfile(module) + # Always map to the name the module knows itself by + modulesbyfile[f] = modulesbyfile[ + os.path.realpath(f)] = module.__name__ + if file in modulesbyfile: + return sys.modules.get(modulesbyfile[file]) + # Check the main module + main = sys.modules['__main__'] + if not hasattr(object, '__name__'): + return None + if hasattr(main, object.__name__): + mainobject = getattr(main, object.__name__) + if mainobject is object: + return main + # Check builtins + builtin = sys.modules['__builtin__'] + if hasattr(builtin, object.__name__): + builtinobject = getattr(builtin, object.__name__) + if builtinobject is object: + return builtin + +def findsource(object): + """Return the entire source file and starting line number for an object. + + The argument may be a module, class, method, function, traceback, frame, + or code object. The source code is returned as a list of all the lines + in the file and the line number indexes a line in that list. An IOError + is raised if the source code cannot be retrieved.""" + file = getsourcefile(object) or getfile(object) + module = getmodule(object, file) + if module: + lines = linecache.getlines(file, module.__dict__) + else: + lines = linecache.getlines(file) + if not lines: + raise IOError('could not get source code') + + if ismodule(object): + return lines, 0 + + if isclass(object): + name = object.__name__ + pat = re.compile(r'^(\s*)class\s*' + name + r'\b') + # make some effort to find the best matching class definition: + # use the one with the least indentation, which is the one + # that's most probably not inside a function definition. + candidates = [] + for i in range(len(lines)): + match = pat.match(lines[i]) + if match: + # if it's at toplevel, it's already the best one + if lines[i][0] == 'c': + return lines, i + # else add whitespace to candidate list + candidates.append((match.group(1), i)) + if candidates: + # this will sort by whitespace, and by line number, + # less whitespace first + candidates.sort() + return lines, candidates[0][1] + else: + raise IOError('could not find class definition') + + if ismethod(object): + object = object.im_func + if isfunction(object): + object = object.func_code + if istraceback(object): + object = object.tb_frame + if isframe(object): + object = object.f_code + if iscode(object): + if not hasattr(object, 'co_firstlineno'): + raise IOError('could not find function definition') + lnum = object.co_firstlineno - 1 + pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)') + while lnum > 0: + if pat.match(lines[lnum]): break + lnum = lnum - 1 + return lines, lnum + raise IOError('could not find code object') + +def getcomments(object): + """Get lines of comments immediately preceding an object's source code. + + Returns None when source can't be found. + """ + try: + lines, lnum = findsource(object) + except (IOError, TypeError): + return None + + if ismodule(object): + # Look for a comment block at the top of the file. + start = 0 + if lines and lines[0][:2] == '#!': start = 1 + while start < len(lines) and string.strip(lines[start]) in ('', '#'): + start = start + 1 + if start < len(lines) and lines[start][:1] == '#': + comments = [] + end = start + while end < len(lines) and lines[end][:1] == '#': + comments.append(string.expandtabs(lines[end])) + end = end + 1 + return string.join(comments, '') + + # Look for a preceding block of comments at the same indentation. + elif lnum > 0: + indent = indentsize(lines[lnum]) + end = lnum - 1 + if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \ + indentsize(lines[end]) == indent: + comments = [string.lstrip(string.expandtabs(lines[end]))] + if end > 0: + end = end - 1 + comment = string.lstrip(string.expandtabs(lines[end])) + while comment[:1] == '#' and indentsize(lines[end]) == indent: + comments[:0] = [comment] + end = end - 1 + if end < 0: break + comment = string.lstrip(string.expandtabs(lines[end])) + while comments and string.strip(comments[0]) == '#': + comments[:1] = [] + while comments and string.strip(comments[-1]) == '#': + comments[-1:] = [] + return string.join(comments, '') + +class EndOfBlock(Exception): pass + +class BlockFinder: + """Provide a tokeneater() method to detect the end of a code block.""" + def __init__(self): + self.indent = 0 + self.islambda = False + self.started = False + self.passline = False + self.last = 1 + + def tokeneater(self, type, token, srow_scol, erow_ecol, line): + srow, scol = srow_scol + erow, ecol = erow_ecol + if not self.started: + # look for the first "def", "class" or "lambda" + if token in ("def", "class", "lambda"): + if token == "lambda": + self.islambda = True + self.started = True + self.passline = True # skip to the end of the line + elif type == tokenize.NEWLINE: + self.passline = False # stop skipping when a NEWLINE is seen + self.last = srow + if self.islambda: # lambdas always end at the first NEWLINE + raise EndOfBlock + elif self.passline: + pass + elif type == tokenize.INDENT: + self.indent = self.indent + 1 + self.passline = True + elif type == tokenize.DEDENT: + self.indent = self.indent - 1 + # the end of matching indent/dedent pairs end a block + # (note that this only works for "def"/"class" blocks, + # not e.g. for "if: else:" or "try: finally:" blocks) + if self.indent <= 0: + raise EndOfBlock + elif self.indent == 0 and type not in (tokenize.COMMENT, tokenize.NL): + # any other token on the same indentation level end the previous + # block as well, except the pseudo-tokens COMMENT and NL. + raise EndOfBlock + +def getblock(lines): + """Extract the block of code at the top of the given list of lines.""" + blockfinder = BlockFinder() + try: + tokenize.tokenize(iter(lines).next, blockfinder.tokeneater) + except (EndOfBlock, IndentationError): + pass + return lines[:blockfinder.last] + +def getsourcelines(object): + """Return a list of source lines and starting line number for an object. + + The argument may be a module, class, method, function, traceback, frame, + or code object. The source code is returned as a list of the lines + corresponding to the object and the line number indicates where in the + original source file the first line of code was found. An IOError is + raised if the source code cannot be retrieved.""" + lines, lnum = findsource(object) + + if ismodule(object): return lines, 0 + else: return getblock(lines[lnum:]), lnum + 1 + +def getsource(object): + """Return the text of the source code for an object. + + The argument may be a module, class, method, function, traceback, frame, + or code object. The source code is returned as a single string. An + IOError is raised if the source code cannot be retrieved.""" + lines, lnum = getsourcelines(object) + return string.join(lines, '') + +# --------------------------------------------------- class tree extraction +def walktree(classes, children, parent): + """Recursive helper function for getclasstree().""" + results = [] + classes.sort(key=attrgetter('__module__', '__name__')) + for c in classes: + results.append((c, c.__bases__)) + if c in children: + results.append(walktree(children[c], children, c)) + return results + +def getclasstree(classes, unique=0): + """Arrange the given list of classes into a hierarchy of nested lists. + + Where a nested list appears, it contains classes derived from the class + whose entry immediately precedes the list. Each entry is a 2-tuple + containing a class and a tuple of its base classes. If the 'unique' + argument is true, exactly one entry appears in the returned structure + for each class in the given list. Otherwise, classes using multiple + inheritance and their descendants will appear multiple times.""" + children = {} + roots = [] + for c in classes: + if c.__bases__: + for parent in c.__bases__: + if not parent in children: + children[parent] = [] + children[parent].append(c) + if unique and parent in classes: break + elif c not in roots: + roots.append(c) + for parent in children: + if parent not in classes: + roots.append(parent) + return walktree(roots, children, None) + +# ------------------------------------------------ argument list extraction +Arguments = namedtuple('Arguments', 'args varargs keywords') + +def getargs(co): + """Get information about the arguments accepted by a code object. + + Three things are returned: (args, varargs, varkw), where 'args' is + a list of argument names (possibly containing nested lists), and + 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" + + if not iscode(co): + raise TypeError('arg is not a code object') + + if not _jython: + # Jython doesn't have co_code + code = co.co_code + + nargs = co.co_argcount + names = co.co_varnames + args = list(names[:nargs]) + step = 0 + + # The following acrobatics are for anonymous (tuple) arguments. + for i in range(nargs): + if args[i][:1] in ('', '.'): + stack, remain, count = [], [], [] + while step < len(code): + op = ord(code[step]) + step = step + 1 + if op >= dis.HAVE_ARGUMENT: + opname = dis.opname[op] + value = ord(code[step]) + ord(code[step+1])*256 + step = step + 2 + if opname in ('UNPACK_TUPLE', 'UNPACK_SEQUENCE'): + remain.append(value) + count.append(value) + elif opname == 'STORE_FAST': + stack.append(names[value]) + + # Special case for sublists of length 1: def foo((bar)) + # doesn't generate the UNPACK_TUPLE bytecode, so if + # `remain` is empty here, we have such a sublist. + if not remain: + stack[0] = [stack[0]] + break + else: + remain[-1] = remain[-1] - 1 + while remain[-1] == 0: + remain.pop() + size = count.pop() + stack[-size:] = [stack[-size:]] + if not remain: break + remain[-1] = remain[-1] - 1 + if not remain: break + args[i] = stack[0] + + varargs = None + if co.co_flags & CO_VARARGS: + varargs = co.co_varnames[nargs] + nargs = nargs + 1 + varkw = None + if co.co_flags & CO_VARKEYWORDS: + varkw = co.co_varnames[nargs] + return Arguments(args, varargs, varkw) + +ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') + +def getargspec(func): + """Get the names and default values of a function's arguments. + + A tuple of four things is returned: (args, varargs, varkw, defaults). + 'args' is a list of the argument names (it may contain nested lists). + 'varargs' and 'varkw' are the names of the * and ** arguments or None. + 'defaults' is an n-tuple of the default values of the last n arguments. + """ + + if ismethod(func): + func = func.im_func + if not isfunction(func): + raise TypeError('arg is not a Python function') + args, varargs, varkw = getargs(func.func_code) + return ArgSpec(args, varargs, varkw, func.func_defaults) + +ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') + +def getargvalues(frame): + """Get information about arguments passed into a particular frame. + + A tuple of four things is returned: (args, varargs, varkw, locals). + 'args' is a list of the argument names (it may contain nested lists). + 'varargs' and 'varkw' are the names of the * and ** arguments or None. + 'locals' is the locals dictionary of the given frame.""" + args, varargs, varkw = getargs(frame.f_code) + return ArgInfo(args, varargs, varkw, frame.f_locals) + +def joinseq(seq): + if len(seq) == 1: + return '(' + seq[0] + ',)' + else: + return '(' + string.join(seq, ', ') + ')' + +def strseq(object, convert, join=joinseq): + """Recursively walk a sequence, stringifying each element.""" + if type(object) in (list, tuple): + return join(map(lambda o, c=convert, j=join: strseq(o, c, j), object)) + else: + return convert(object) + +def formatargspec(args, varargs=None, varkw=None, defaults=None, + formatarg=str, + formatvarargs=lambda name: '*' + name, + formatvarkw=lambda name: '**' + name, + formatvalue=lambda value: '=' + repr(value), + join=joinseq): + """Format an argument spec from the 4 values returned by getargspec. + + The first four arguments are (args, varargs, varkw, defaults). The + other four arguments are the corresponding optional formatting functions + that are called to turn names and values into strings. The ninth + argument is an optional function to format the sequence of arguments.""" + specs = [] + if defaults: + firstdefault = len(args) - len(defaults) + for i in range(len(args)): + spec = strseq(args[i], formatarg, join) + if defaults and i >= firstdefault: + spec = spec + formatvalue(defaults[i - firstdefault]) + specs.append(spec) + if varargs is not None: + specs.append(formatvarargs(varargs)) + if varkw is not None: + specs.append(formatvarkw(varkw)) + return '(' + string.join(specs, ', ') + ')' + +def formatargvalues(args, varargs, varkw, locals, + formatarg=str, + formatvarargs=lambda name: '*' + name, + formatvarkw=lambda name: '**' + name, + formatvalue=lambda value: '=' + repr(value), + join=joinseq): + """Format an argument spec from the 4 values returned by getargvalues. + + The first four arguments are (args, varargs, varkw, locals). The + next four arguments are the corresponding optional formatting functions + that are called to turn names and values into strings. The ninth + argument is an optional function to format the sequence of arguments.""" + def convert(name, locals=locals, + formatarg=formatarg, formatvalue=formatvalue): + return formatarg(name) + formatvalue(locals[name]) + specs = [] + for i in range(len(args)): + specs.append(strseq(args[i], convert, join)) + if varargs: + specs.append(formatvarargs(varargs) + formatvalue(locals[varargs])) + if varkw: + specs.append(formatvarkw(varkw) + formatvalue(locals[varkw])) + return '(' + string.join(specs, ', ') + ')' + +# -------------------------------------------------- stack frame extraction + +Traceback = namedtuple('Traceback', 'filename lineno function code_context index') + +def getframeinfo(frame, context=1): + """Get information about a frame or traceback object. + + A tuple of five things is returned: the filename, the line number of + the current line, the function name, a list of lines of context from + the source code, and the index of the current line within that list. + The optional second argument specifies the number of lines of context + to return, which are centered around the current line.""" + if istraceback(frame): + lineno = frame.tb_lineno + frame = frame.tb_frame + else: + lineno = frame.f_lineno + if not isframe(frame): + raise TypeError('arg is not a frame or traceback object') + + filename = getsourcefile(frame) or getfile(frame) + if context > 0: + start = lineno - 1 - context//2 + try: + lines, lnum = findsource(frame) + except IOError: + lines = index = None + else: + start = max(start, 1) + start = max(0, min(start, len(lines) - context)) + lines = lines[start:start+context] + index = lineno - 1 - start + else: + lines = index = None + + return Traceback(filename, lineno, frame.f_code.co_name, lines, index) + +def getlineno(frame): + """Get the line number from a frame object, allowing for optimization.""" + # FrameType.f_lineno is now a descriptor that grovels co_lnotab + return frame.f_lineno + +def getouterframes(frame, context=1): + """Get a list of records for a frame and all higher (calling) frames. + + Each record contains a frame object, filename, line number, function + name, a list of lines of context, and index within the context.""" + framelist = [] + while frame: + framelist.append((frame,) + getframeinfo(frame, context)) + frame = frame.f_back + return framelist + +def getinnerframes(tb, context=1): + """Get a list of records for a traceback's frame and all lower frames. + + Each record contains a frame object, filename, line number, function + name, a list of lines of context, and index within the context.""" + framelist = [] + while tb: + framelist.append((tb.tb_frame,) + getframeinfo(tb, context)) + tb = tb.tb_next + return framelist + +if hasattr(sys, '_getframe'): + currentframe = sys._getframe +else: + currentframe = lambda _=None: None + +def stack(context=1): + """Return a list of records for the stack above the caller's frame.""" + return getouterframes(sys._getframe(1), context) + +def trace(context=1): + """Return a list of records for the stack below the current exception.""" + return getinnerframes(sys.exc_info()[2], context) diff --git a/src/main/resources/PythonLibs/io.py b/src/main/resources/PythonLibs/io.py new file mode 100644 index 0000000000000000000000000000000000000000..4102ad62d568900ff6360f5f3de3c75e8dbec9e9 --- /dev/null +++ b/src/main/resources/PythonLibs/io.py @@ -0,0 +1,107 @@ +# XXX Temporary addition to Jython while we use _jyio.py in place of _io. +# This module will stand in place of the lib-python io.py. The idea is +# gradually to switch, in _jyio, between Python implementation there and +# Java implementations imported from _io as classes in Java. In the end, +# we delete this and _jyio.py, and go back to using lib-python's io.py + +"""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 throw an IOError 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 a 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. + +# XXX edge cases when switching between reading/writing +# XXX need to support 1 meaning line-buffered +# XXX whenever an argument is None, use the default value +# XXX read/write ops should check readable/writable +# XXX buffered readinto should work with arbitrary buffer objects +# XXX use incremental encoder for text output, at least for UTF-16 and UTF-8-SIG +# XXX check writable, readable and seekable in appropriate places + + +__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"] + + +import abc + +# For the time being, import everything via _jyio instead of from _io directly +import _jyio +from _jyio import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, + open, + FileIO, + BytesIO, StringIO, BufferedReader, + BufferedWriter, BufferedRWPair, BufferedRandom, + IncrementalNewlineDecoder, TextIOWrapper) + +OpenWrapper = _jyio.open # for compatibility with _pyio + +# 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(_jyio._IOBase): + __metaclass__ = abc.ABCMeta + +class RawIOBase(_jyio._RawIOBase, IOBase): + pass + +class BufferedIOBase(_jyio._BufferedIOBase, IOBase): + pass + +class TextIOBase(_jyio._TextIOBase, IOBase): + pass + +RawIOBase.register(FileIO) + +for klass in (BytesIO, BufferedReader, BufferedWriter, BufferedRandom, + BufferedRWPair): + BufferedIOBase.register(klass) + +for klass in (StringIO, TextIOWrapper): + TextIOBase.register(klass) +del klass diff --git a/src/main/resources/PythonLibs/isql.py b/src/main/resources/PythonLibs/isql.py new file mode 100644 index 0000000000000000000000000000000000000000..b6cd8de8ee48906f566f48849bb3eb746889b166 --- /dev/null +++ b/src/main/resources/PythonLibs/isql.py @@ -0,0 +1,235 @@ +import dbexts, cmd, sys, os + +if sys.platform.startswith("java"): + import java.lang.String + +""" +Isql works in conjunction with dbexts to provide an interactive environment +for database work. +""" + +class IsqlExit(Exception): pass + +class Prompt: + """ + This class fixes a problem with the cmd.Cmd class since it uses an ivar 'prompt' + as opposed to a method 'prompt()'. To get around this, this class is plugged in + as a 'prompt' attribute and when invoked the '__str__' method is called which + figures out the appropriate prompt to display. I still think, even though this + is clever, the attribute version of 'prompt' is poor design. + """ + def __init__(self, isql): + self.isql = isql + def __str__(self): + prompt = "%s> " % (self.isql.db.dbname) + if len(self.isql.sqlbuffer) > 0: + prompt = "... " + return prompt + if sys.platform.startswith("java"): + def __tojava__(self, cls): + if cls == java.lang.String: + return self.__str__() + return False + +class IsqlCmd(cmd.Cmd): + + def __init__(self, db=None, delimiter=";", comment=('#', '--')): + cmd.Cmd.__init__(self, completekey=None) + if db is None or type(db) == type(""): + self.db = dbexts.dbexts(db) + else: + self.db = db + self.kw = {} + self.sqlbuffer = [] + self.comment = comment + self.delimiter = delimiter + self.prompt = Prompt(self) + + def parseline(self, line): + command, arg, line = cmd.Cmd.parseline(self, line) + if command and command <> "EOF": + command = command.lower() + return command, arg, line + + def do_which(self, arg): + """\nPrints the current db connection parameters.\n""" + print self.db + return False + + def do_EOF(self, arg): + return False + + def do_p(self, arg): + """\nExecute a python expression.\n""" + try: + exec arg.strip() in globals() + except: + print sys.exc_info()[1] + return False + + def do_column(self, arg): + """\nInstructions for column display.\n""" + return False + + def do_use(self, arg): + """\nUse a new database connection.\n""" + # this allows custom dbexts + self.db = self.db.__class__(arg.strip()) + return False + + def do_table(self, arg): + """\nPrints table meta-data. If no table name, prints all tables.\n""" + if len(arg.strip()): + self.db.table(arg, **self.kw) + else: + self.db.table(None, **self.kw) + return False + + def do_proc(self, arg): + """\nPrints store procedure meta-data.\n""" + if len(arg.strip()): + self.db.proc(arg, **self.kw) + else: + self.db.proc(None, **self.kw) + return False + + def do_schema(self, arg): + """\nPrints schema information.\n""" + print + self.db.schema(arg) + print + return False + + def do_delimiter(self, arg): + """\nChange the delimiter.\n""" + delimiter = arg.strip() + if len(delimiter) > 0: + self.delimiter = delimiter + + def do_o(self, arg): + """\nSet the output.\n""" + if not arg: + fp = self.db.out + try: + if fp: + fp.close() + finally: + self.db.out = None + else: + fp = open(arg, "w") + self.db.out = fp + + def do_q(self, arg): + """\nQuit.\n""" + try: + if self.db.out: + self.db.out.close() + finally: + return True + + def do_set(self, arg): + """\nSet a parameter. Some examples:\n set owner = 'informix'\n set types = ['VIEW', 'TABLE']\nThe right hand side is evaluated using `eval()`\n""" + if len(arg.strip()) == 0: + items = self.kw.items() + if len(items): + print + # format the results but don't include how many rows affected + for a in dbexts.console(items, ("key", "value"))[:-1]: + print a + print + return False + d = filter(lambda x: len(x) > 0, map(lambda x: x.strip(), arg.split("="))) + if len(d) == 1: + if self.kw.has_key(d[0]): + del self.kw[d[0]] + else: + self.kw[d[0]] = eval(d[1]) + + def do_i(self, arg): + fp = open(arg) + try: + print + for line in fp.readlines(): + line = self.precmd(line) + stop = self.onecmd(line) + stop = self.postcmd(stop, line) + finally: + fp.close() + return False + + def default(self, arg): + try: + token = arg.strip() + if not token: + return False + comment = [token.startswith(x) for x in self.comment] + if reduce(lambda x,y: x or y, comment): + return False + if token[0] == '\\': + token = token[1:] + # is it possible the line contains the delimiter + if len(token) >= len(self.delimiter): + # does the line end with the delimiter + if token[-1 * len(self.delimiter):] == self.delimiter: + # now add all up to the delimiter + self.sqlbuffer.append(token[:-1 * len(self.delimiter)]) + if self.sqlbuffer: + q = " ".join(self.sqlbuffer) + print q + self.db.isql(q, **self.kw) + self.sqlbuffer = [] + if self.db.updatecount: + print + if self.db.updatecount == 1: + print "1 row affected" + else: + print "%d rows affected" % (self.db.updatecount) + print + return False + if token: + self.sqlbuffer.append(token) + except: + self.sqlbuffer = [] + print + print sys.exc_info()[1] + print + return False + + def emptyline(self): + return False + + def postloop(self): + raise IsqlExit() + + def cmdloop(self, intro=None): + while 1: + try: + cmd.Cmd.cmdloop(self, intro) + except IsqlExit, e: + break + except Exception, e: + print + print e + print + intro = None + +if __name__ == '__main__': + import getopt + + try: + opts, args = getopt.getopt(sys.argv[1:], "b:", []) + except getopt.error, msg: + print + print msg + print "Try `%s --help` for more information." % (sys.argv[0]) + sys.exit(0) + + dbname = None + for opt, arg in opts: + if opt == '-b': + dbname = arg + + intro = "\nisql - interactive sql (%s)\n" % (__version__) + + isql = IsqlCmd(dbname) + isql.cmdloop() diff --git a/src/main/resources/PythonLibs/javapath.py b/src/main/resources/PythonLibs/javapath.py new file mode 100644 index 0000000000000000000000000000000000000000..e11bfbb2b4e049d786b25841521f3452d4b708df --- /dev/null +++ b/src/main/resources/PythonLibs/javapath.py @@ -0,0 +1,363 @@ +"""Common pathname manipulations, JDK version. + +Instead of importing this module directly, import os and refer to this +module as os.path. + +""" + +# Incompletely implemented: +# ismount -- How? +# normcase -- How? + +# Missing: +# sameopenfile -- Java doesn't have fstat nor file descriptors? +# samestat -- How? + +import stat +import sys +from java.io import File +import java.io.IOException +from java.lang import System +import os + +from org.python.core.Py import newString as asPyString +import warnings +warnings.warn('The javapath module is deprecated. Use the os.path module.', + DeprecationWarning, 2) + + +def _tostr(s, method): + if isinstance(s, basestring): + return s + raise TypeError, "%s() argument must be a str or unicode object, not %s" % ( + method, _type_name(s)) + +def _type_name(obj): + TPFLAGS_HEAPTYPE = 1 << 9 + type_name = '' + obj_type = type(obj) + is_heap = obj_type.__flags__ & TPFLAGS_HEAPTYPE == TPFLAGS_HEAPTYPE + if not is_heap and obj_type.__module__ != '__builtin__': + type_name = '%s.' % obj_type.__module__ + type_name += obj_type.__name__ + return type_name + +def dirname(path): + """Return the directory component of a pathname""" + path = _tostr(path, "dirname") + result = asPyString(File(path).getParent()) + if not result: + if isabs(path): + result = path # Must be root + else: + result = "" + return result + +def basename(path): + """Return the final component of a pathname""" + path = _tostr(path, "basename") + return asPyString(File(path).getName()) + +def split(path): + """Split a pathname. + + Return tuple "(head, tail)" where "tail" is everything after the + final slash. Either part may be empty. + + """ + path = _tostr(path, "split") + return (dirname(path), basename(path)) + +def splitext(path): + """Split the extension from a pathname. + + Extension is everything from the last dot to the end. Return + "(root, ext)", either part may be empty. + + """ + i = 0 + n = -1 + for c in path: + if c == '.': n = i + i = i+1 + if n < 0: + return (path, "") + else: + return (path[:n], path[n:]) + +def splitdrive(path): + """Split a pathname into drive and path specifiers. + + Returns a 2-tuple "(drive,path)"; either part may be empty. + """ + # Algorithm based on CPython's ntpath.splitdrive and ntpath.isabs. + if path[1:2] == ':' and path[0].lower() in 'abcdefghijklmnopqrstuvwxyz' \ + and (path[2:] == '' or path[2] in '/\\'): + return path[:2], path[2:] + return '', path + +def exists(path): + """Test whether a path exists. + + Returns false for broken symbolic links. + + """ + path = _tostr(path, "exists") + return File(sys.getPath(path)).exists() + +def isabs(path): + """Test whether a path is absolute""" + path = _tostr(path, "isabs") + return File(path).isAbsolute() + +def isfile(path): + """Test whether a path is a regular file""" + path = _tostr(path, "isfile") + return File(sys.getPath(path)).isFile() + +def isdir(path): + """Test whether a path is a directory""" + path = _tostr(path, "isdir") + return File(sys.getPath(path)).isDirectory() + +def join(path, *args): + """Join two or more pathname components, inserting os.sep as needed""" + path = _tostr(path, "join") + f = File(path) + for a in args: + a = _tostr(a, "join") + g = File(a) + if g.isAbsolute() or len(f.getPath()) == 0: + f = g + else: + if a == "": + a = os.sep + f = File(f, a) + return asPyString(f.getPath()) + +def normcase(path): + """Normalize case of pathname. + + XXX Not done right under JDK. + + """ + path = _tostr(path, "normcase") + return asPyString(File(path).getPath()) + +def commonprefix(m): + "Given a list of pathnames, return the longest common leading component" + if not m: return '' + prefix = m[0] + for item in m: + for i in range(len(prefix)): + if prefix[:i+1] <> item[:i+1]: + prefix = prefix[:i] + if i == 0: return '' + break + return prefix + +def islink(path): + """Test whether a path is a symbolic link""" + try: + st = os.lstat(path) + except (os.error, AttributeError): + return False + return stat.S_ISLNK(st.st_mode) + +def samefile(path, path2): + """Test whether two pathnames reference the same actual file""" + path = _tostr(path, "samefile") + path2 = _tostr(path2, "samefile") + return _realpath(path) == _realpath(path2) + +def ismount(path): + """Test whether a path is a mount point. + + XXX This incorrectly always returns false under JDK. + + """ + return 0 + +def walk(top, func, arg): + """Walk a directory tree. + + walk(top,func,args) calls func(arg, d, files) for each directory + "d" in the tree rooted at "top" (including "top" itself). "files" + is a list of all the files and subdirs in directory "d". + + """ + try: + names = os.listdir(top) + except os.error: + return + func(arg, top, names) + for name in names: + name = join(top, name) + if isdir(name) and not islink(name): + walk(name, func, arg) + +def expanduser(path): + if path[:1] == "~": + c = path[1:2] + if not c: + return gethome() + if c == os.sep: + return asPyString(File(gethome(), path[2:]).getPath()) + return path + +def getuser(): + return System.getProperty("user.name") + +def gethome(): + return System.getProperty("user.home") + + +# normpath() from Python 1.5.2, with Java appropriate generalizations + +# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. +# It should be understood that this may change the meaning of the path +# if it contains symbolic links! +def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + sep = os.sep + if sep == '\\': + path = path.replace("/", sep) + curdir = os.curdir + pardir = os.pardir + import string + # Treat initial slashes specially + slashes = '' + while path[:1] == sep: + slashes = slashes + sep + path = path[1:] + comps = string.splitfields(path, sep) + i = 0 + while i < len(comps): + if comps[i] == curdir: + del comps[i] + while i < len(comps) and comps[i] == '': + del comps[i] + elif comps[i] == pardir and i > 0 and comps[i-1] not in ('', pardir): + del comps[i-1:i+1] + i = i-1 + elif comps[i] == '' and i > 0 and comps[i-1] <> '': + del comps[i] + else: + i = i+1 + # If the path is now empty, substitute '.' + if not comps and not slashes: + comps.append(curdir) + return slashes + string.joinfields(comps, sep) + +def abspath(path): + """Return an absolute path normalized but symbolic links not eliminated""" + path = _tostr(path, "abspath") + return _abspath(path) + +def _abspath(path): + # Must use normpath separately because getAbsolutePath doesn't normalize + # and getCanonicalPath would eliminate symlinks. + return normpath(asPyString(File(sys.getPath(path)).getAbsolutePath())) + +def realpath(path): + """Return an absolute path normalized and symbolic links eliminated""" + path = _tostr(path, "realpath") + return _realpath(path) + +def _realpath(path): + try: + return asPyString(File(sys.getPath(path)).getCanonicalPath()) + except java.io.IOException: + return _abspath(path) + +def getsize(path): + path = _tostr(path, "getsize") + f = File(sys.getPath(path)) + size = f.length() + # Sadly, if the returned length is zero, we don't really know if the file + # is zero sized or does not exist. + if size == 0 and not f.exists(): + raise OSError(0, 'No such file or directory', path) + return size + +def getmtime(path): + path = _tostr(path, "getmtime") + f = File(sys.getPath(path)) + if not f.exists(): + raise OSError(0, 'No such file or directory', path) + return f.lastModified() / 1000.0 + +def getatime(path): + # We can't detect access time so we return modification time. This + # matches the behaviour in os.stat(). + path = _tostr(path, "getatime") + f = File(sys.getPath(path)) + if not f.exists(): + raise OSError(0, 'No such file or directory', path) + return f.lastModified() / 1000.0 + + +# expandvars is stolen from CPython-2.1.1's Lib/ntpath.py: + +# Expand paths containing shell variable substitutions. +# The following rules apply: +# - no expansion within single quotes +# - no escape character, except for '$$' which is translated into '$' +# - ${varname} is accepted. +# - varnames can be made out of letters, digits and the character '_' +# XXX With COMMAND.COM you can use any characters in a variable name, +# XXX except '^|<>='. + +def expandvars(path): + """Expand shell variables of form $var and ${var}. + + Unknown variables are left unchanged.""" + if '$' not in path: + return path + import string + varchars = string.letters + string.digits + '_-' + 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 + path + index = pathlen - 1 + 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] + if os.environ.has_key(var): + res = res + os.environ[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] + if os.environ.has_key(var): + res = res + os.environ[var] + if c != '': + res = res + c + else: + res = res + c + index = index + 1 + return res diff --git a/src/main/resources/PythonLibs/javashell.py b/src/main/resources/PythonLibs/javashell.py new file mode 100644 index 0000000000000000000000000000000000000000..261e433fa13be44d2e1083e5559e7730854b4a73 --- /dev/null +++ b/src/main/resources/PythonLibs/javashell.py @@ -0,0 +1,93 @@ +""" +Implement subshell functionality for Jython. + +This is mostly to provide the environ object for the os module, +and subshell execution functionality for os.system and popen* functions. + +javashell attempts to determine a suitable command shell for the host +operating system, and uses that shell to determine environment variables +and to provide subshell execution functionality. +""" +from java.lang import System, Runtime +from java.io import File +from java.io import IOException +from java.io import InputStreamReader +from java.io import BufferedReader +from UserDict import UserDict +import jarray +import os +import string +import subprocess +import sys +import types +import warnings +warnings.warn('The javashell module is deprecated. Use the subprocess module.', + DeprecationWarning, 2) + +__all__ = ["shellexecute"] + +def __warn( *args ): + print " ".join( [str( arg ) for arg in args ]) + +class _ShellEnv: + """Provide environment derived by spawning a subshell and parsing its + environment. Also supports subshell execution functions and provides + empty environment support for platforms with unknown shell functionality. + """ + def __init__( self, cmd=None, getEnv=None, keyTransform=None ): + """Construct _ShellEnv instance. + cmd: list of exec() arguments required to run a command in + subshell, or None + getEnv: shell command to list environment variables, or None. + deprecated + keyTransform: normalization function for environment keys, + such as 'string.upper', or None. deprecated. + """ + self.cmd = cmd + self.environment = os.environ + + def execute( self, cmd ): + """Execute cmd in a shell, and return the java.lang.Process instance. + Accepts either a string command to be executed in a shell, + or a sequence of [executable, args...]. + """ + shellCmd = self._formatCmd( cmd ) + + env = self._formatEnvironment( self.environment ) + try: + p = Runtime.getRuntime().exec( shellCmd, env, File(os.getcwd()) ) + return p + except IOException, ex: + raise OSError( + 0, + "Failed to execute command (%s): %s" % ( shellCmd, ex ) + ) + + ########## utility methods + def _formatCmd( self, cmd ): + """Format a command for execution in a shell.""" + if self.cmd is None: + msgFmt = "Unable to execute commands in subshell because shell" \ + " functionality not implemented for OS %s" \ + " Failed command=%s" + raise OSError( 0, msgFmt % ( os._name, cmd )) + + if isinstance(cmd, basestring): + shellCmd = self.cmd + [cmd] + else: + shellCmd = cmd + + return shellCmd + + def _formatEnvironment( self, env ): + """Format enviroment in lines suitable for Runtime.exec""" + lines = [] + for keyValue in env.items(): + lines.append( "%s=%s" % keyValue ) + return lines + +def _getOsType(): + return os._name + +_shellEnv = _ShellEnv(subprocess._shell_command) +shellexecute = _shellEnv.execute diff --git a/src/main/resources/PythonLibs/json/__init__.py b/src/main/resources/PythonLibs/json/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0be85da022b2e88ddc21eb7cec57b69775300a4c --- /dev/null +++ b/src/main/resources/PythonLibs/json/__init__.py @@ -0,0 +1,351 @@ +r"""JSON (JavaScript Object Notation) <http://json.org> is a subset of +JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data +interchange format. + +:mod:`json` exposes an API familiar to users of the standard library +:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained +version of the :mod:`json` library contained in Python 2.6, but maintains +compatibility with Python 2.4 and Python 2.5 and (currently) has +significant performance advantages, even without using the optional C +extension for speedups. + +Encoding basic Python object hierarchies:: + + >>> import json + >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) + '["foo", {"bar": ["baz", null, 1.0, 2]}]' + >>> print json.dumps("\"foo\bar") + "\"foo\bar" + >>> print json.dumps(u'\u1234') + "\u1234" + >>> print json.dumps('\\') + "\\" + >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True) + {"a": 0, "b": 0, "c": 0} + >>> from StringIO import StringIO + >>> io = StringIO() + >>> json.dump(['streaming API'], io) + >>> io.getvalue() + '["streaming API"]' + +Compact encoding:: + + >>> import json + >>> json.dumps([1,2,3,{'4': 5, '6': 7}], sort_keys=True, separators=(',',':')) + '[1,2,3,{"4":5,"6":7}]' + +Pretty printing:: + + >>> import json + >>> print json.dumps({'4': 5, '6': 7}, sort_keys=True, + ... indent=4, separators=(',', ': ')) + { + "4": 5, + "6": 7 + } + +Decoding JSON:: + + >>> import json + >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}] + >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj + True + >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar' + True + >>> from StringIO import StringIO + >>> io = StringIO('["streaming API"]') + >>> json.load(io)[0] == 'streaming API' + True + +Specializing JSON object decoding:: + + >>> import json + >>> def as_complex(dct): + ... if '__complex__' in dct: + ... return complex(dct['real'], dct['imag']) + ... return dct + ... + >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', + ... object_hook=as_complex) + (1+2j) + >>> from decimal import Decimal + >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1') + True + +Specializing JSON object encoding:: + + >>> import json + >>> def encode_complex(obj): + ... if isinstance(obj, complex): + ... return [obj.real, obj.imag] + ... raise TypeError(repr(o) + " is not JSON serializable") + ... + >>> json.dumps(2 + 1j, default=encode_complex) + '[2.0, 1.0]' + >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) + '[2.0, 1.0]' + >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) + '[2.0, 1.0]' + + +Using json.tool from the shell to validate and pretty-print:: + + $ echo '{"json":"obj"}' | python -m json.tool + { + "json": "obj" + } + $ echo '{ 1.2:3.4}' | python -m json.tool + Expecting property name enclosed in double quotes: line 1 column 3 (char 2) +""" +__version__ = '2.0.9' +__all__ = [ + 'dump', 'dumps', 'load', 'loads', + 'JSONDecoder', 'JSONEncoder', +] + +__author__ = 'Bob Ippolito <bob@redivi.com>' + +from .decoder import JSONDecoder +from .encoder import JSONEncoder + +_default_encoder = JSONEncoder( + skipkeys=False, + ensure_ascii=True, + check_circular=True, + allow_nan=True, + indent=None, + separators=None, + encoding='utf-8', + default=None, +) + +def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, + allow_nan=True, cls=None, indent=None, separators=None, + encoding='utf-8', default=None, sort_keys=False, **kw): + """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a + ``.write()``-supporting file-like object). + + If ``skipkeys`` is true then ``dict`` keys that are not basic types + (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) + will be skipped instead of raising a ``TypeError``. + + If ``ensure_ascii`` is true (the default), all non-ASCII characters in the + output are escaped with ``\uXXXX`` sequences, and the result is a ``str`` + instance consisting of ASCII characters only. If ``ensure_ascii`` is + ``False``, some chunks written to ``fp`` may be ``unicode`` instances. + This usually happens because the input contains unicode strings or the + ``encoding`` parameter is used. Unless ``fp.write()`` explicitly + understands ``unicode`` (as in ``codecs.getwriter``) this is likely to + cause an error. + + If ``check_circular`` is false, then the circular reference check + for container types will be skipped and a circular reference will + result in an ``OverflowError`` (or worse). + + If ``allow_nan`` is false, then it will be a ``ValueError`` to + serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) + in strict compliance of the JSON specification, instead of using the + JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). + + If ``indent`` is a non-negative integer, then JSON array elements and + object members will be pretty-printed with that indent level. An indent + level of 0 will only insert newlines. ``None`` is the most compact + representation. Since the default item separator is ``', '``, the + output might include trailing whitespace when ``indent`` is specified. + You can use ``separators=(',', ': ')`` to avoid this. + + If ``separators`` is an ``(item_separator, dict_separator)`` tuple + then it will be used instead of the default ``(', ', ': ')`` separators. + ``(',', ':')`` is the most compact JSON representation. + + ``encoding`` is the character encoding for str instances, default is UTF-8. + + ``default(obj)`` is a function that should return a serializable version + of obj or raise TypeError. The default simply raises TypeError. + + If *sort_keys* is ``True`` (default: ``False``), then the output of + dictionaries will be sorted by key. + + To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the + ``.default()`` method to serialize additional types), specify it with + the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. + + """ + # cached encoder + if (not skipkeys and ensure_ascii and + check_circular and allow_nan and + cls is None and indent is None and separators is None and + encoding == 'utf-8' and default is None and not sort_keys and not kw): + iterable = _default_encoder.iterencode(obj) + else: + if cls is None: + cls = JSONEncoder + iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, + check_circular=check_circular, allow_nan=allow_nan, indent=indent, + separators=separators, encoding=encoding, + default=default, sort_keys=sort_keys, **kw).iterencode(obj) + # could accelerate with writelines in some versions of Python, at + # a debuggability cost + for chunk in iterable: + fp.write(chunk) + + +def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, + allow_nan=True, cls=None, indent=None, separators=None, + encoding='utf-8', default=None, sort_keys=False, **kw): + """Serialize ``obj`` to a JSON formatted ``str``. + + If ``skipkeys`` is false then ``dict`` keys that are not basic types + (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) + will be skipped instead of raising a ``TypeError``. + + If ``ensure_ascii`` is false, all non-ASCII characters are not escaped, and + the return value may be a ``unicode`` instance. See ``dump`` for details. + + If ``check_circular`` is false, then the circular reference check + for container types will be skipped and a circular reference will + result in an ``OverflowError`` (or worse). + + If ``allow_nan`` is false, then it will be a ``ValueError`` to + serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in + strict compliance of the JSON specification, instead of using the + JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). + + If ``indent`` is a non-negative integer, then JSON array elements and + object members will be pretty-printed with that indent level. An indent + level of 0 will only insert newlines. ``None`` is the most compact + representation. Since the default item separator is ``', '``, the + output might include trailing whitespace when ``indent`` is specified. + You can use ``separators=(',', ': ')`` to avoid this. + + If ``separators`` is an ``(item_separator, dict_separator)`` tuple + then it will be used instead of the default ``(', ', ': ')`` separators. + ``(',', ':')`` is the most compact JSON representation. + + ``encoding`` is the character encoding for str instances, default is UTF-8. + + ``default(obj)`` is a function that should return a serializable version + of obj or raise TypeError. The default simply raises TypeError. + + If *sort_keys* is ``True`` (default: ``False``), then the output of + dictionaries will be sorted by key. + + To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the + ``.default()`` method to serialize additional types), specify it with + the ``cls`` kwarg; otherwise ``JSONEncoder`` is used. + + """ + # cached encoder + if (not skipkeys and ensure_ascii and + check_circular and allow_nan and + cls is None and indent is None and separators is None and + encoding == 'utf-8' and default is None and not sort_keys and not kw): + return _default_encoder.encode(obj) + if cls is None: + cls = JSONEncoder + return cls( + skipkeys=skipkeys, ensure_ascii=ensure_ascii, + check_circular=check_circular, allow_nan=allow_nan, indent=indent, + separators=separators, encoding=encoding, default=default, + sort_keys=sort_keys, **kw).encode(obj) + + +_default_decoder = JSONDecoder(encoding=None, object_hook=None, + object_pairs_hook=None) + + +def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, + parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): + """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing + a JSON document) to a Python object. + + If the contents of ``fp`` is encoded with an ASCII based encoding other + than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must + be specified. Encodings that are not ASCII based (such as UCS-2) are + not allowed, and should be wrapped with + ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode`` + object and passed to ``loads()`` + + ``object_hook`` is an optional function that will be called with the + result of any object literal decode (a ``dict``). The return value of + ``object_hook`` will be used instead of the ``dict``. This feature + can be used to implement custom decoders (e.g. JSON-RPC class hinting). + + ``object_pairs_hook`` is an optional function that will be called with the + result of any object literal decoded with an ordered list of pairs. The + return value of ``object_pairs_hook`` will be used instead of the ``dict``. + This feature can be used to implement custom decoders that rely on the + order that the key and value pairs are decoded (for example, + collections.OrderedDict will remember the order of insertion). If + ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. + + To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` + kwarg; otherwise ``JSONDecoder`` is used. + + """ + return loads(fp.read(), + encoding=encoding, cls=cls, object_hook=object_hook, + parse_float=parse_float, parse_int=parse_int, + parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, + **kw) + + +def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, + parse_int=None, parse_constant=None, object_pairs_hook=None, **kw): + """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON + document) to a Python object. + + If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding + other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name + must be specified. Encodings that are not ASCII based (such as UCS-2) + are not allowed and should be decoded to ``unicode`` first. + + ``object_hook`` is an optional function that will be called with the + result of any object literal decode (a ``dict``). The return value of + ``object_hook`` will be used instead of the ``dict``. This feature + can be used to implement custom decoders (e.g. JSON-RPC class hinting). + + ``object_pairs_hook`` is an optional function that will be called with the + result of any object literal decoded with an ordered list of pairs. The + return value of ``object_pairs_hook`` will be used instead of the ``dict``. + This feature can be used to implement custom decoders that rely on the + order that the key and value pairs are decoded (for example, + collections.OrderedDict will remember the order of insertion). If + ``object_hook`` is also defined, the ``object_pairs_hook`` takes priority. + + ``parse_float``, if specified, will be called with the string + of every JSON float to be decoded. By default this is equivalent to + float(num_str). This can be used to use another datatype or parser + for JSON floats (e.g. decimal.Decimal). + + ``parse_int``, if specified, will be called with the string + of every JSON int to be decoded. By default this is equivalent to + int(num_str). This can be used to use another datatype or parser + for JSON integers (e.g. float). + + ``parse_constant``, if specified, will be called with one of the + following strings: -Infinity, Infinity, NaN, null, true, false. + This can be used to raise an exception if invalid JSON numbers + are encountered. + + To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` + kwarg; otherwise ``JSONDecoder`` is used. + + """ + if (cls is None and encoding is None and object_hook is None and + parse_int is None and parse_float is None and + parse_constant is None and object_pairs_hook is None and not kw): + return _default_decoder.decode(s) + if cls is None: + cls = JSONDecoder + if object_hook is not None: + kw['object_hook'] = object_hook + if object_pairs_hook is not None: + kw['object_pairs_hook'] = object_pairs_hook + if parse_float is not None: + kw['parse_float'] = parse_float + if parse_int is not None: + kw['parse_int'] = parse_int + if parse_constant is not None: + kw['parse_constant'] = parse_constant + return cls(encoding=encoding, **kw).decode(s) diff --git a/src/main/resources/PythonLibs/json/decoder.py b/src/main/resources/PythonLibs/json/decoder.py new file mode 100644 index 0000000000000000000000000000000000000000..dc8916c9264f8189167d0a8c9923f0c51ea50c43 --- /dev/null +++ b/src/main/resources/PythonLibs/json/decoder.py @@ -0,0 +1,384 @@ +"""Implementation of JSONDecoder +""" +import re +import sys +import struct + +from json import scanner +try: + from _json import scanstring as c_scanstring +except ImportError: + c_scanstring = None + +__all__ = ['JSONDecoder'] + +FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL + +def _floatconstants(): + _BYTES = '7FF80000000000007FF0000000000000'.decode('hex') + if sys.byteorder != 'big': + _BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1] + nan, inf = struct.unpack('dd', _BYTES) + return nan, inf, -inf + +NaN, PosInf, NegInf = _floatconstants() + + +def linecol(doc, pos): + lineno = doc.count('\n', 0, pos) + 1 + if lineno == 1: + colno = pos + 1 + else: + colno = pos - doc.rindex('\n', 0, pos) + return lineno, colno + + +def errmsg(msg, doc, pos, end=None): + # Note that this function is called from _json + lineno, colno = linecol(doc, pos) + if end is None: + fmt = '{0}: line {1} column {2} (char {3})' + return fmt.format(msg, lineno, colno, pos) + #fmt = '%s: line %d column %d (char %d)' + #return fmt % (msg, lineno, colno, pos) + endlineno, endcolno = linecol(doc, end) + fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})' + return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end) + #fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' + #return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) + + +_CONSTANTS = { + '-Infinity': NegInf, + 'Infinity': PosInf, + 'NaN': NaN, +} + +STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS) +BACKSLASH = { + '"': u'"', '\\': u'\\', '/': u'/', + 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t', +} + +DEFAULT_ENCODING = "utf-8" + +def py_scanstring(s, end, encoding=None, strict=True, + _b=BACKSLASH, _m=STRINGCHUNK.match): + """Scan the string s for a JSON string. End is the index of the + character in s after the quote that started the JSON string. + Unescapes all valid JSON string escape sequences and raises ValueError + on attempt to decode an invalid string. If strict is False then literal + control characters are allowed in the string. + + Returns a tuple of the decoded string and the index of the character in s + after the end quote.""" + if encoding is None: + encoding = DEFAULT_ENCODING + chunks = [] + _append = chunks.append + begin = end - 1 + while 1: + chunk = _m(s, end) + if chunk is None: + raise ValueError( + errmsg("Unterminated string starting at", s, begin)) + end = chunk.end() + content, terminator = chunk.groups() + # Content is contains zero or more unescaped string characters + if content: + if not isinstance(content, unicode): + content = unicode(content, encoding) + _append(content) + # Terminator is the end of string, a literal control character, + # or a backslash denoting that an escape sequence follows + if terminator == '"': + break + elif terminator != '\\': + if strict: + #msg = "Invalid control character %r at" % (terminator,) + msg = "Invalid control character {0!r} at".format(terminator) + raise ValueError(errmsg(msg, s, end)) + else: + _append(terminator) + continue + try: + esc = s[end] + except IndexError: + raise ValueError( + errmsg("Unterminated string starting at", s, begin)) + # If not a unicode escape sequence, must be in the lookup table + if esc != 'u': + try: + char = _b[esc] + except KeyError: + msg = "Invalid \\escape: " + repr(esc) + raise ValueError(errmsg(msg, s, end)) + end += 1 + else: + # Unicode escape sequence + esc = s[end + 1:end + 5] + next_end = end + 5 + if len(esc) != 4: + msg = "Invalid \\uXXXX escape" + raise ValueError(errmsg(msg, s, end)) + uni = int(esc, 16) + # Check for surrogate pair on UCS-4 systems + if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535: + msg = "Invalid \\uXXXX\\uXXXX surrogate pair" + if not s[end + 5:end + 7] == '\\u': + raise ValueError(errmsg(msg, s, end)) + esc2 = s[end + 7:end + 11] + if len(esc2) != 4: + raise ValueError(errmsg(msg, s, end)) + uni2 = int(esc2, 16) + uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) + next_end += 6 + char = unichr(uni) + end = next_end + # Append the unescaped character + _append(char) + return u''.join(chunks), end + + +# Use speedup if available +scanstring = c_scanstring or py_scanstring + +WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS) +WHITESPACE_STR = ' \t\n\r' + +def JSONObject(s_and_end, encoding, strict, scan_once, object_hook, + object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + s, end = s_and_end + pairs = [] + pairs_append = pairs.append + # Use a slice to prevent IndexError from being raised, the following + # check will raise a more specific ValueError if the string is empty + nextchar = s[end:end + 1] + # Normally we expect nextchar == '"' + if nextchar != '"': + if nextchar in _ws: + end = _w(s, end).end() + nextchar = s[end:end + 1] + # Trivial empty object + if nextchar == '}': + if object_pairs_hook is not None: + result = object_pairs_hook(pairs) + return result, end + pairs = {} + if object_hook is not None: + pairs = object_hook(pairs) + return pairs, end + 1 + elif nextchar != '"': + raise ValueError(errmsg( + "Expecting property name enclosed in double quotes", s, end)) + end += 1 + while True: + key, end = scanstring(s, end, encoding, strict) + + # To skip some function call overhead we optimize the fast paths where + # the JSON key separator is ": " or just ":". + if s[end:end + 1] != ':': + end = _w(s, end).end() + if s[end:end + 1] != ':': + raise ValueError(errmsg("Expecting ':' delimiter", s, end)) + end += 1 + + try: + if s[end] in _ws: + end += 1 + if s[end] in _ws: + end = _w(s, end + 1).end() + except IndexError: + pass + + try: + value, end = scan_once(s, end) + except StopIteration: + raise ValueError(errmsg("Expecting object", s, end)) + pairs_append((key, value)) + + try: + nextchar = s[end] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end] + except IndexError: + nextchar = '' + end += 1 + + if nextchar == '}': + break + elif nextchar != ',': + raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1)) + + try: + nextchar = s[end] + if nextchar in _ws: + end += 1 + nextchar = s[end] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end] + except IndexError: + nextchar = '' + + end += 1 + if nextchar != '"': + raise ValueError(errmsg( + "Expecting property name enclosed in double quotes", s, end - 1)) + if object_pairs_hook is not None: + result = object_pairs_hook(pairs) + return result, end + pairs = dict(pairs) + if object_hook is not None: + pairs = object_hook(pairs) + return pairs, end + +def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + s, end = s_and_end + values = [] + nextchar = s[end:end + 1] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end:end + 1] + # Look-ahead for trivial empty array + if nextchar == ']': + return values, end + 1 + _append = values.append + while True: + try: + value, end = scan_once(s, end) + except StopIteration: + raise ValueError(errmsg("Expecting object", s, end)) + _append(value) + nextchar = s[end:end + 1] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end:end + 1] + end += 1 + if nextchar == ']': + break + elif nextchar != ',': + raise ValueError(errmsg("Expecting ',' delimiter", s, end)) + try: + if s[end] in _ws: + end += 1 + if s[end] in _ws: + end = _w(s, end + 1).end() + except IndexError: + pass + + return values, end + +class JSONDecoder(object): + """Simple JSON <http://json.org> decoder + + Performs the following translations in decoding by default: + + +---------------+-------------------+ + | JSON | Python | + +===============+===================+ + | object | dict | + +---------------+-------------------+ + | array | list | + +---------------+-------------------+ + | string | unicode | + +---------------+-------------------+ + | number (int) | int, long | + +---------------+-------------------+ + | number (real) | float | + +---------------+-------------------+ + | true | True | + +---------------+-------------------+ + | false | False | + +---------------+-------------------+ + | null | None | + +---------------+-------------------+ + + It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as + their corresponding ``float`` values, which is outside the JSON spec. + + """ + + def __init__(self, encoding=None, object_hook=None, parse_float=None, + parse_int=None, parse_constant=None, strict=True, + object_pairs_hook=None): + """``encoding`` determines the encoding used to interpret any ``str`` + objects decoded by this instance (utf-8 by default). It has no + effect when decoding ``unicode`` objects. + + Note that currently only encodings that are a superset of ASCII work, + strings of other encodings should be passed in as ``unicode``. + + ``object_hook``, if specified, will be called with the result + of every JSON object decoded and its return value will be used in + place of the given ``dict``. This can be used to provide custom + deserializations (e.g. to support JSON-RPC class hinting). + + ``object_pairs_hook``, if specified will be called with the result of + every JSON object decoded with an ordered list of pairs. The return + value of ``object_pairs_hook`` will be used instead of the ``dict``. + This feature can be used to implement custom decoders that rely on the + order that the key and value pairs are decoded (for example, + collections.OrderedDict will remember the order of insertion). If + ``object_hook`` is also defined, the ``object_pairs_hook`` takes + priority. + + ``parse_float``, if specified, will be called with the string + of every JSON float to be decoded. By default this is equivalent to + float(num_str). This can be used to use another datatype or parser + for JSON floats (e.g. decimal.Decimal). + + ``parse_int``, if specified, will be called with the string + of every JSON int to be decoded. By default this is equivalent to + int(num_str). This can be used to use another datatype or parser + for JSON integers (e.g. float). + + ``parse_constant``, if specified, will be called with one of the + following strings: -Infinity, Infinity, NaN. + This can be used to raise an exception if invalid JSON numbers + are encountered. + + If ``strict`` is false (true is the default), then control + characters will be allowed inside strings. Control characters in + this context are those with character codes in the 0-31 range, + including ``'\\t'`` (tab), ``'\\n'``, ``'\\r'`` and ``'\\0'``. + + """ + self.encoding = encoding + self.object_hook = object_hook + self.object_pairs_hook = object_pairs_hook + self.parse_float = parse_float or float + self.parse_int = parse_int or int + self.parse_constant = parse_constant or _CONSTANTS.__getitem__ + self.strict = strict + self.parse_object = JSONObject + self.parse_array = JSONArray + self.parse_string = scanstring + self.scan_once = scanner.make_scanner(self) + + def decode(self, s, _w=WHITESPACE.match): + """Return the Python representation of ``s`` (a ``str`` or ``unicode`` + instance containing a JSON document) + + """ + obj, end = self.raw_decode(s, idx=_w(s, 0).end()) + end = _w(s, end).end() + if end != len(s): + raise ValueError(errmsg("Extra data", s, end, len(s))) + return obj + + def raw_decode(self, s, idx=0): + """Decode a JSON document from ``s`` (a ``str`` or ``unicode`` + beginning with a JSON document) and return a 2-tuple of the Python + representation and the index in ``s`` where the document ended. + + This can be used to decode a JSON document from a string that may + have extraneous data at the end. + + """ + try: + obj, end = self.scan_once(s, idx) + except StopIteration: + raise ValueError("No JSON object could be decoded") + return obj, end diff --git a/src/main/resources/PythonLibs/json/encoder.py b/src/main/resources/PythonLibs/json/encoder.py new file mode 100644 index 0000000000000000000000000000000000000000..4d1aaa8eedfd6173beea57ac09a0fa9dcda34593 --- /dev/null +++ b/src/main/resources/PythonLibs/json/encoder.py @@ -0,0 +1,447 @@ +"""Implementation of JSONEncoder +""" +import re + +try: + from _json import encode_basestring_ascii as c_encode_basestring_ascii +except ImportError: + c_encode_basestring_ascii = None +try: + from _json import make_encoder as c_make_encoder +except ImportError: + c_make_encoder = None + +ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') +ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') +HAS_UTF8 = re.compile(r'[\x80-\xff]') +ESCAPE_DCT = { + '\\': '\\\\', + '"': '\\"', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', +} +for i in range(0x20): + ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i)) + #ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) + +INFINITY = float('inf') +FLOAT_REPR = repr + +def encode_basestring(s): + """Return a JSON representation of a Python string + + """ + def replace(match): + return ESCAPE_DCT[match.group(0)] + return '"' + ESCAPE.sub(replace, s) + '"' + + +def py_encode_basestring_ascii(s): + """Return an ASCII-only JSON representation of a Python string + + """ + if isinstance(s, str) and HAS_UTF8.search(s) is not None: + s = s.decode('utf-8') + def replace(match): + s = match.group(0) + try: + return ESCAPE_DCT[s] + except KeyError: + n = ord(s) + if n < 0x10000: + return '\\u{0:04x}'.format(n) + #return '\\u%04x' % (n,) + else: + # surrogate pair + n -= 0x10000 + s1 = 0xd800 | ((n >> 10) & 0x3ff) + s2 = 0xdc00 | (n & 0x3ff) + return '\\u{0:04x}\\u{1:04x}'.format(s1, s2) + #return '\\u%04x\\u%04x' % (s1, s2) + return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' + + +encode_basestring_ascii = ( + c_encode_basestring_ascii or py_encode_basestring_ascii) + +class JSONEncoder(object): + """Extensible JSON <http://json.org> encoder for Python data structures. + + Supports the following objects and types by default: + + +-------------------+---------------+ + | Python | JSON | + +===================+===============+ + | dict | object | + +-------------------+---------------+ + | list, tuple | array | + +-------------------+---------------+ + | str, unicode | string | + +-------------------+---------------+ + | int, long, float | number | + +-------------------+---------------+ + | True | true | + +-------------------+---------------+ + | False | false | + +-------------------+---------------+ + | None | null | + +-------------------+---------------+ + + To extend this to recognize other objects, subclass and implement a + ``.default()`` method with another method that returns a serializable + object for ``o`` if possible, otherwise it should call the superclass + implementation (to raise ``TypeError``). + + """ + item_separator = ', ' + key_separator = ': ' + def __init__(self, skipkeys=False, ensure_ascii=True, + check_circular=True, allow_nan=True, sort_keys=False, + indent=None, separators=None, encoding='utf-8', default=None): + """Constructor for JSONEncoder, with sensible defaults. + + If skipkeys is false, then it is a TypeError to attempt + encoding of keys that are not str, int, long, float or None. If + skipkeys is True, such items are simply skipped. + + If *ensure_ascii* is true (the default), all non-ASCII + characters in the output are escaped with \uXXXX sequences, + and the results are str instances consisting of ASCII + characters only. If ensure_ascii is False, a result may be a + unicode instance. This usually happens if the input contains + unicode strings or the *encoding* parameter is used. + + If check_circular is true, then lists, dicts, and custom encoded + objects will be checked for circular references during encoding to + prevent an infinite recursion (which would cause an OverflowError). + Otherwise, no such check takes place. + + If allow_nan is true, then NaN, Infinity, and -Infinity will be + encoded as such. This behavior is not JSON specification compliant, + but is consistent with most JavaScript based encoders and decoders. + Otherwise, it will be a ValueError to encode such floats. + + If sort_keys is true, then the output of dictionaries will be + sorted by key; this is useful for regression tests to ensure + that JSON serializations can be compared on a day-to-day basis. + + If indent is a non-negative integer, then JSON array + elements and object members will be pretty-printed with that + indent level. An indent level of 0 will only insert newlines. + None is the most compact representation. Since the default + item separator is ', ', the output might include trailing + whitespace when indent is specified. You can use + separators=(',', ': ') to avoid this. + + If specified, separators should be a (item_separator, key_separator) + tuple. The default is (', ', ': '). To get the most compact JSON + representation you should specify (',', ':') to eliminate whitespace. + + If specified, default is a function that gets called for objects + that can't otherwise be serialized. It should return a JSON encodable + version of the object or raise a ``TypeError``. + + If encoding is not None, then all input strings will be + transformed into unicode using that encoding prior to JSON-encoding. + The default is UTF-8. + + """ + + self.skipkeys = skipkeys + self.ensure_ascii = ensure_ascii + self.check_circular = check_circular + self.allow_nan = allow_nan + self.sort_keys = sort_keys + self.indent = indent + if separators is not None: + self.item_separator, self.key_separator = separators + if default is not None: + self.default = default + self.encoding = encoding + + def default(self, o): + """Implement this method in a subclass such that it returns + a serializable object for ``o``, or calls the base implementation + (to raise a ``TypeError``). + + For example, to support arbitrary iterators, you could + implement default like this:: + + def default(self, o): + try: + iterable = iter(o) + except TypeError: + pass + else: + return list(iterable) + return JSONEncoder.default(self, o) + + """ + raise TypeError(repr(o) + " is not JSON serializable") + + def encode(self, o): + """Return a JSON string representation of a Python data structure. + + >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) + '{"foo": ["bar", "baz"]}' + + """ + # This is for extremely simple cases and benchmarks. + if isinstance(o, basestring): + if isinstance(o, str): + _encoding = self.encoding + if (_encoding is not None + and not (_encoding == 'utf-8')): + o = o.decode(_encoding) + if self.ensure_ascii: + return encode_basestring_ascii(o) + else: + return encode_basestring(o) + # This doesn't pass the iterator directly to ''.join() because the + # exceptions aren't as detailed. The list call should be roughly + # equivalent to the PySequence_Fast that ''.join() would do. + chunks = self.iterencode(o, _one_shot=True) + if not isinstance(chunks, (list, tuple)): + chunks = list(chunks) + return ''.join(chunks) + + def iterencode(self, o, _one_shot=False): + """Encode the given object and yield each string + representation as available. + + For example:: + + for chunk in JSONEncoder().iterencode(bigobject): + mysocket.write(chunk) + + """ + if self.check_circular: + markers = {} + else: + markers = None + if self.ensure_ascii: + _encoder = encode_basestring_ascii + else: + _encoder = encode_basestring + if self.encoding != 'utf-8': + def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding): + if isinstance(o, str): + o = o.decode(_encoding) + return _orig_encoder(o) + + def floatstr(o, allow_nan=self.allow_nan, + _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY): + # Check for specials. Note that this type of test is processor + # and/or platform-specific, so do tests which don't depend on the + # internals. + + if o != o: + text = 'NaN' + elif o == _inf: + text = 'Infinity' + elif o == _neginf: + text = '-Infinity' + else: + return _repr(o) + + if not allow_nan: + raise ValueError( + "Out of range float values are not JSON compliant: " + + repr(o)) + + return text + + + if (_one_shot and c_make_encoder is not None + and self.indent is None and not self.sort_keys): + _iterencode = c_make_encoder( + markers, self.default, _encoder, self.indent, + self.key_separator, self.item_separator, self.sort_keys, + self.skipkeys, self.allow_nan) + else: + _iterencode = _make_iterencode( + markers, self.default, _encoder, self.indent, floatstr, + self.key_separator, self.item_separator, self.sort_keys, + self.skipkeys, _one_shot) + return _iterencode(o, 0) + +def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, + _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot, + ## HACK: hand-optimized bytecode; turn globals into locals + ValueError=ValueError, + basestring=basestring, + dict=dict, + float=float, + id=id, + int=int, + isinstance=isinstance, + list=list, + long=long, + str=str, + tuple=tuple, + ): + + def _iterencode_list(lst, _current_indent_level): + if not lst: + yield '[]' + return + if markers is not None: + markerid = id(lst) + if markerid in markers: + raise ValueError("Circular reference detected") + markers[markerid] = lst + buf = '[' + if _indent is not None: + _current_indent_level += 1 + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + separator = _item_separator + newline_indent + buf += newline_indent + else: + newline_indent = None + separator = _item_separator + first = True + for value in lst: + if first: + first = False + else: + buf = separator + if isinstance(value, basestring): + yield buf + _encoder(value) + elif value is None: + yield buf + 'null' + elif value is True: + yield buf + 'true' + elif value is False: + yield buf + 'false' + elif isinstance(value, (int, long)): + yield buf + str(value) + elif isinstance(value, float): + yield buf + _floatstr(value) + else: + yield buf + if isinstance(value, (list, tuple)): + chunks = _iterencode_list(value, _current_indent_level) + elif isinstance(value, dict): + chunks = _iterencode_dict(value, _current_indent_level) + else: + chunks = _iterencode(value, _current_indent_level) + for chunk in chunks: + yield chunk + if newline_indent is not None: + _current_indent_level -= 1 + yield '\n' + (' ' * (_indent * _current_indent_level)) + yield ']' + if markers is not None: + del markers[markerid] + + def _iterencode_dict(dct, _current_indent_level): + if not dct: + yield '{}' + return + if markers is not None: + markerid = id(dct) + if markerid in markers: + raise ValueError("Circular reference detected") + markers[markerid] = dct + yield '{' + if _indent is not None: + _current_indent_level += 1 + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + item_separator = _item_separator + newline_indent + yield newline_indent + else: + newline_indent = None + item_separator = _item_separator + first = True + if _sort_keys: + items = sorted(dct.items(), key=lambda kv: kv[0]) + else: + items = dct.iteritems() + for key, value in items: + if isinstance(key, basestring): + pass + # JavaScript is weakly typed for these, so it makes sense to + # also allow them. Many encoders seem to do something like this. + elif isinstance(key, float): + key = _floatstr(key) + elif key is True: + key = 'true' + elif key is False: + key = 'false' + elif key is None: + key = 'null' + elif isinstance(key, (int, long)): + key = str(key) + elif _skipkeys: + continue + else: + raise TypeError("key " + repr(key) + " is not a string") + if first: + first = False + else: + yield item_separator + yield _encoder(key) + yield _key_separator + if isinstance(value, basestring): + yield _encoder(value) + elif value is None: + yield 'null' + elif value is True: + yield 'true' + elif value is False: + yield 'false' + elif isinstance(value, (int, long)): + yield str(value) + elif isinstance(value, float): + yield _floatstr(value) + else: + if isinstance(value, (list, tuple)): + chunks = _iterencode_list(value, _current_indent_level) + elif isinstance(value, dict): + chunks = _iterencode_dict(value, _current_indent_level) + else: + chunks = _iterencode(value, _current_indent_level) + for chunk in chunks: + yield chunk + if newline_indent is not None: + _current_indent_level -= 1 + yield '\n' + (' ' * (_indent * _current_indent_level)) + yield '}' + if markers is not None: + del markers[markerid] + + def _iterencode(o, _current_indent_level): + if isinstance(o, basestring): + yield _encoder(o) + elif o is None: + yield 'null' + elif o is True: + yield 'true' + elif o is False: + yield 'false' + elif isinstance(o, (int, long)): + yield str(o) + elif isinstance(o, float): + yield _floatstr(o) + elif isinstance(o, (list, tuple)): + for chunk in _iterencode_list(o, _current_indent_level): + yield chunk + elif isinstance(o, dict): + for chunk in _iterencode_dict(o, _current_indent_level): + yield chunk + else: + if markers is not None: + markerid = id(o) + if markerid in markers: + raise ValueError("Circular reference detected") + markers[markerid] = o + o = _default(o) + for chunk in _iterencode(o, _current_indent_level): + yield chunk + if markers is not None: + del markers[markerid] + + return _iterencode diff --git a/src/main/resources/PythonLibs/json/scanner.py b/src/main/resources/PythonLibs/json/scanner.py new file mode 100644 index 0000000000000000000000000000000000000000..74e6805155d85399fd5a6a67d5b35765270f63db --- /dev/null +++ b/src/main/resources/PythonLibs/json/scanner.py @@ -0,0 +1,67 @@ +"""JSON token scanner +""" +import re +try: + from _json import make_scanner as c_make_scanner +except ImportError: + c_make_scanner = None + +__all__ = ['make_scanner'] + +NUMBER_RE = re.compile( + r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', + (re.VERBOSE | re.MULTILINE | re.DOTALL)) + +def py_make_scanner(context): + parse_object = context.parse_object + parse_array = context.parse_array + parse_string = context.parse_string + match_number = NUMBER_RE.match + encoding = context.encoding + strict = context.strict + parse_float = context.parse_float + parse_int = context.parse_int + parse_constant = context.parse_constant + object_hook = context.object_hook + object_pairs_hook = context.object_pairs_hook + + def _scan_once(string, idx): + try: + nextchar = string[idx] + except IndexError: + raise StopIteration + + if nextchar == '"': + return parse_string(string, idx + 1, encoding, strict) + elif nextchar == '{': + return parse_object((string, idx + 1), encoding, strict, + _scan_once, object_hook, object_pairs_hook) + elif nextchar == '[': + return parse_array((string, idx + 1), _scan_once) + elif nextchar == 'n' and string[idx:idx + 4] == 'null': + return None, idx + 4 + elif nextchar == 't' and string[idx:idx + 4] == 'true': + return True, idx + 4 + elif nextchar == 'f' and string[idx:idx + 5] == 'false': + return False, idx + 5 + + m = match_number(string, idx) + if m is not None: + integer, frac, exp = m.groups() + if frac or exp: + res = parse_float(integer + (frac or '') + (exp or '')) + else: + res = parse_int(integer) + return res, m.end() + elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': + return parse_constant('NaN'), idx + 3 + elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': + return parse_constant('Infinity'), idx + 8 + elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': + return parse_constant('-Infinity'), idx + 9 + else: + raise StopIteration + + return _scan_once + +make_scanner = c_make_scanner or py_make_scanner diff --git a/src/main/resources/PythonLibs/json/tool.py b/src/main/resources/PythonLibs/json/tool.py new file mode 100644 index 0000000000000000000000000000000000000000..fc5d74923df2abef7a6c94e2d34eba7c13fecded --- /dev/null +++ b/src/main/resources/PythonLibs/json/tool.py @@ -0,0 +1,40 @@ +r"""Command-line tool to validate and pretty-print JSON + +Usage:: + + $ echo '{"json":"obj"}' | python -m json.tool + { + "json": "obj" + } + $ echo '{ 1.2:3.4}' | python -m json.tool + Expecting property name enclosed in double quotes: line 1 column 3 (char 2) + +""" +import sys +import json + +def main(): + if len(sys.argv) == 1: + infile = sys.stdin + outfile = sys.stdout + elif len(sys.argv) == 2: + infile = open(sys.argv[1], 'rb') + outfile = sys.stdout + elif len(sys.argv) == 3: + infile = open(sys.argv[1], 'rb') + outfile = open(sys.argv[2], 'wb') + else: + raise SystemExit(sys.argv[0] + " [infile [outfile]]") + with infile: + try: + obj = json.load(infile) + except ValueError, e: + raise SystemExit(e) + with outfile: + json.dump(obj, outfile, sort_keys=True, + indent=4, separators=(',', ': ')) + outfile.write('\n') + + +if __name__ == '__main__': + main() diff --git a/src/main/resources/PythonLibs/keyword.py b/src/main/resources/PythonLibs/keyword.py new file mode 100644 index 0000000000000000000000000000000000000000..69794bda8c879a098a2adaef5e4bcee32f8683c8 --- /dev/null +++ b/src/main/resources/PythonLibs/keyword.py @@ -0,0 +1,93 @@ +#! /usr/bin/env python + +"""Keywords (from "graminit.c") + +This file is automatically generated; please don't muck it up! + +To update the symbols in this file, 'cd' to the top directory of +the python source tree after building the interpreter and run: + + ./python Lib/keyword.py +""" + +__all__ = ["iskeyword", "kwlist"] + +kwlist = [ +#--start keywords-- + 'and', + 'as', + 'assert', + 'break', + 'class', + 'continue', + 'def', + 'del', + 'elif', + 'else', + 'except', + 'exec', + 'finally', + 'for', + 'from', + 'global', + 'if', + 'import', + 'in', + 'is', + 'lambda', + 'not', + 'or', + 'pass', + 'print', + 'raise', + 'return', + 'try', + 'while', + 'with', + 'yield', +#--end keywords-- + ] + +iskeyword = frozenset(kwlist).__contains__ + +def main(): + import sys, re + + args = sys.argv[1:] + iptfile = args and args[0] or "Python/graminit.c" + if len(args) > 1: optfile = args[1] + else: optfile = "Lib/keyword.py" + + # scan the source file for keywords + fp = open(iptfile) + strprog = re.compile('"([^"]+)"') + lines = [] + for line in fp: + if '{1, "' in line: + match = strprog.search(line) + if match: + lines.append(" '" + match.group(1) + "',\n") + fp.close() + lines.sort() + + # load the output skeleton from the target + fp = open(optfile) + format = fp.readlines() + fp.close() + + # insert the lines of keywords + try: + start = format.index("#--start keywords--\n") + 1 + end = format.index("#--end keywords--\n") + format[start:end] = lines + except ValueError: + sys.stderr.write("target does not contain format markers\n") + sys.exit(1) + + # write the output file + fp = open(optfile, 'w') + fp.write(''.join(format)) + fp.close() + +if __name__ == "__main__": + main() diff --git a/src/main/resources/PythonLibs/linecache.py b/src/main/resources/PythonLibs/linecache.py new file mode 100644 index 0000000000000000000000000000000000000000..811f27fe3657c776fc5795d469f24cb21615492f --- /dev/null +++ b/src/main/resources/PythonLibs/linecache.py @@ -0,0 +1,135 @@ +"""Cache lines from files. + +This is intended to read lines from modules imported -- hence if a filename +is not found, it will look down the module search path for a file by +that name. +""" + +import sys +import os + +__all__ = ["getline", "clearcache", "checkcache"] + +def getline(filename, lineno, module_globals=None): + lines = getlines(filename, module_globals) + if 1 <= lineno <= len(lines): + return lines[lineno-1] + else: + return '' + + +# The cache + +cache = {} # The cache + + +def clearcache(): + """Clear the cache entirely.""" + + global cache + cache = {} + + +def getlines(filename, module_globals=None): + """Get the lines for a file from the cache. + Update the cache if it doesn't contain an entry for this file already.""" + + if filename in cache: + return cache[filename][2] + else: + return updatecache(filename, module_globals) + + +def checkcache(filename=None): + """Discard cache entries that are out of date. + (This is not checked upon each call!)""" + + if filename is None: + filenames = cache.keys() + else: + if filename in cache: + filenames = [filename] + else: + return + + for filename in filenames: + size, mtime, lines, fullname = cache[filename] + if mtime is None: + continue # no-op for files loaded via a __loader__ + try: + stat = os.stat(fullname) + except os.error: + del cache[filename] + continue + if size != stat.st_size or mtime != stat.st_mtime: + del cache[filename] + + +def updatecache(filename, module_globals=None): + """Update a cache entry and return its list of lines. + If something's wrong, print a message, discard the cache entry, + and return an empty list.""" + + if filename in cache: + del cache[filename] + if not filename or (filename.startswith('<') and filename.endswith('>')): + return [] + + fullname = filename + try: + stat = os.stat(fullname) + except OSError: + basename = filename + + # Try for a __loader__, if available + if module_globals and '__loader__' in module_globals: + name = module_globals.get('__name__') + loader = module_globals['__loader__'] + get_source = getattr(loader, 'get_source', None) + + if name and get_source: + try: + data = get_source(name) + except (ImportError, IOError): + pass + else: + if data is None: + # No luck, the PEP302 loader cannot find the source + # for this module. + return [] + cache[filename] = ( + len(data), None, + [line+'\n' for line in data.splitlines()], fullname + ) + return cache[filename][2] + + # Try looking through the module search path, which is only useful + # when handling a relative filename. + if os.path.isabs(filename): + return [] + + for dirname in sys.path: + # When using imputil, sys.path may contain things other than + # strings; ignore them when it happens. + try: + fullname = os.path.join(dirname, basename) + except (TypeError, AttributeError): + # Not sufficiently string-like to do anything useful with. + continue + try: + stat = os.stat(fullname) + break + except os.error: + pass + else: + return [] + try: + with open(fullname, 'rU') as fp: + lines = fp.readlines() + except IOError: + return [] + if lines and not lines[-1].endswith('\n'): + lines[-1] += '\n' + size, mtime = stat.st_size, stat.st_mtime + cache[filename] = size, mtime, lines, fullname + return lines diff --git a/src/main/resources/PythonLibs/locale.py b/src/main/resources/PythonLibs/locale.py new file mode 100644 index 0000000000000000000000000000000000000000..7ddfdb782c0d0945413ddbfebe2fd34975a896ec --- /dev/null +++ b/src/main/resources/PythonLibs/locale.py @@ -0,0 +1,1882 @@ +""" Locale support. + + The module provides low-level access to the C lib's locale APIs + and adds high level number formatting APIs as well as a locale + aliasing engine to complement these. + + The aliasing engine includes support for many commonly used locale + names and maps them to values suitable for passing to the C lib's + setlocale() function. It also includes default encodings for all + supported locale names. + +""" + +import sys +import encodings +import encodings.aliases +import re +import operator +import functools + +try: + _unicode = unicode +except NameError: + # If Python is built without Unicode support, the unicode type + # will not exist. Fake one. + class _unicode(object): + pass + +# Try importing the _locale module. +# +# If this fails, fall back on a basic 'C' locale emulation. + +# Yuck: LC_MESSAGES is non-standard: can't tell whether it exists before +# trying the import. So __all__ is also fiddled at the end of the file. +__all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error", + "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm", + "str", "atof", "atoi", "format", "format_string", "currency", + "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY", + "LC_NUMERIC", "LC_ALL", "CHAR_MAX"] + +try: + + from _locale import * + +except ImportError: + + # Locale emulation + + CHAR_MAX = 127 + LC_ALL = 6 + LC_COLLATE = 3 + LC_CTYPE = 0 + LC_MESSAGES = 5 + LC_MONETARY = 4 + LC_NUMERIC = 1 + LC_TIME = 2 + Error = ValueError + + def localeconv(): + """ localeconv() -> dict. + Returns numeric and monetary locale-specific parameters. + """ + # 'C' locale default values + return {'grouping': [127], + 'currency_symbol': '', + 'n_sign_posn': 127, + 'p_cs_precedes': 127, + 'n_cs_precedes': 127, + 'mon_grouping': [], + 'n_sep_by_space': 127, + 'decimal_point': '.', + 'negative_sign': '', + 'positive_sign': '', + 'p_sep_by_space': 127, + 'int_curr_symbol': '', + 'p_sign_posn': 127, + 'thousands_sep': '', + 'mon_thousands_sep': '', + 'frac_digits': 127, + 'mon_decimal_point': '', + 'int_frac_digits': 127} + + def setlocale(category, value=None): + """ setlocale(integer,string=None) -> string. + Activates/queries locale processing. + """ + if value not in (None, '', 'C'): + raise Error, '_locale emulation only supports "C" locale' + return 'C' + + def strcoll(a,b): + """ strcoll(string,string) -> int. + Compares two strings according to the locale. + """ + return cmp(a,b) + + def strxfrm(s): + """ strxfrm(string) -> string. + Returns a string that behaves for cmp locale-aware. + """ + return s + + +_localeconv = localeconv + +# With this dict, you can override some items of localeconv's return value. +# This is useful for testing purposes. +_override_localeconv = {} + +@functools.wraps(_localeconv) +def localeconv(): + d = _localeconv() + if _override_localeconv: + d.update(_override_localeconv) + return d + + +### Number formatting APIs + +# Author: Martin von Loewis +# improved by Georg Brandl + +# Iterate over grouping intervals +def _grouping_intervals(grouping): + last_interval = None + for interval in grouping: + # if grouping is -1, we are done + if interval == CHAR_MAX: + return + # 0: re-use last group ad infinitum + if interval == 0: + if last_interval is None: + raise ValueError("invalid grouping") + while True: + yield last_interval + yield interval + last_interval = interval + +#perform the grouping from right to left +def _group(s, monetary=False): + conv = localeconv() + thousands_sep = conv[monetary and 'mon_thousands_sep' or 'thousands_sep'] + grouping = conv[monetary and 'mon_grouping' or 'grouping'] + if not grouping: + return (s, 0) + if s[-1] == ' ': + stripped = s.rstrip() + right_spaces = s[len(stripped):] + s = stripped + else: + right_spaces = '' + left_spaces = '' + groups = [] + for interval in _grouping_intervals(grouping): + if not s or s[-1] not in "0123456789": + # only non-digit characters remain (sign, spaces) + left_spaces = s + s = '' + break + groups.append(s[-interval:]) + s = s[:-interval] + if s: + groups.append(s) + groups.reverse() + return ( + left_spaces + thousands_sep.join(groups) + right_spaces, + len(thousands_sep) * (len(groups) - 1) + ) + +# Strip a given amount of excess padding from the given string +def _strip_padding(s, amount): + lpos = 0 + while amount and s[lpos] == ' ': + lpos += 1 + amount -= 1 + rpos = len(s) - 1 + while amount and s[rpos] == ' ': + rpos -= 1 + amount -= 1 + return s[lpos:rpos+1] + +_percent_re = re.compile(r'%(?:\((?P<key>.*?)\))?' + r'(?P<modifiers>[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') + +def format(percent, value, grouping=False, monetary=False, *additional): + """Returns the locale-aware substitution of a %? specifier + (percent). + + additional is for format strings which contain one or more + '*' modifiers.""" + # this is only for one-percent-specifier strings and this should be checked + match = _percent_re.match(percent) + if not match or len(match.group())!= len(percent): + raise ValueError(("format() must be given exactly one %%char " + "format specifier, %s not valid") % repr(percent)) + return _format(percent, value, grouping, monetary, *additional) + +def _format(percent, value, grouping=False, monetary=False, *additional): + if additional: + formatted = percent % ((value,) + additional) + else: + formatted = percent % value + # floats and decimal ints need special action! + if percent[-1] in 'eEfFgG': + seps = 0 + parts = formatted.split('.') + if grouping: + parts[0], seps = _group(parts[0], monetary=monetary) + decimal_point = localeconv()[monetary and 'mon_decimal_point' + or 'decimal_point'] + formatted = decimal_point.join(parts) + if seps: + formatted = _strip_padding(formatted, seps) + elif percent[-1] in 'diu': + seps = 0 + if grouping: + formatted, seps = _group(formatted, monetary=monetary) + if seps: + formatted = _strip_padding(formatted, seps) + return formatted + +def format_string(f, val, grouping=False): + """Formats a string in the same way that the % formatting would use, + but takes the current locale into account. + Grouping is applied if the third parameter is true.""" + percents = list(_percent_re.finditer(f)) + new_f = _percent_re.sub('%s', f) + + if operator.isMappingType(val): + new_val = [] + for perc in percents: + if perc.group()[-1]=='%': + new_val.append('%') + else: + new_val.append(format(perc.group(), val, grouping)) + else: + if not isinstance(val, tuple): + val = (val,) + new_val = [] + i = 0 + for perc in percents: + if perc.group()[-1]=='%': + new_val.append('%') + else: + starcount = perc.group('modifiers').count('*') + new_val.append(_format(perc.group(), + val[i], + grouping, + False, + *val[i+1:i+1+starcount])) + i += (1 + starcount) + val = tuple(new_val) + + return new_f % val + +def currency(val, symbol=True, grouping=False, international=False): + """Formats val according to the currency settings + in the current locale.""" + conv = localeconv() + + # check for illegal values + digits = conv[international and 'int_frac_digits' or 'frac_digits'] + if digits == 127: + raise ValueError("Currency formatting is not possible using " + "the 'C' locale.") + + s = format('%%.%if' % digits, abs(val), grouping, monetary=True) + # '<' and '>' are markers if the sign must be inserted between symbol and value + s = '<' + s + '>' + + if symbol: + smb = conv[international and 'int_curr_symbol' or 'currency_symbol'] + precedes = conv[val<0 and 'n_cs_precedes' or 'p_cs_precedes'] + separated = conv[val<0 and 'n_sep_by_space' or 'p_sep_by_space'] + + if precedes: + s = smb + (separated and ' ' or '') + s + else: + s = s + (separated and ' ' or '') + smb + + sign_pos = conv[val<0 and 'n_sign_posn' or 'p_sign_posn'] + sign = conv[val<0 and 'negative_sign' or 'positive_sign'] + + if sign_pos == 0: + s = '(' + s + ')' + elif sign_pos == 1: + s = sign + s + elif sign_pos == 2: + s = s + sign + elif sign_pos == 3: + s = s.replace('<', sign) + elif sign_pos == 4: + s = s.replace('>', sign) + else: + # the default if nothing specified; + # this should be the most fitting sign position + s = sign + s + + return s.replace('<', '').replace('>', '') + +def str(val): + """Convert float to integer, taking the locale into account.""" + return format("%.12g", val) + +def atof(string, func=float): + "Parses a string as a float according to the locale settings." + #First, get rid of the grouping + ts = localeconv()['thousands_sep'] + if ts: + string = string.replace(ts, '') + #next, replace the decimal point with a dot + dd = localeconv()['decimal_point'] + if dd: + string = string.replace(dd, '.') + #finally, parse the string + return func(string) + +def atoi(str): + "Converts a string to an integer according to the locale settings." + return atof(str, int) + +def _test(): + setlocale(LC_ALL, "") + #do grouping + s1 = format("%d", 123456789,1) + print s1, "is", atoi(s1) + #standard formatting + s1 = str(3.14) + print s1, "is", atof(s1) + +### Locale name aliasing engine + +# Author: Marc-Andre Lemburg, mal@lemburg.com +# Various tweaks by Fredrik Lundh <fredrik@pythonware.com> + +# store away the low-level version of setlocale (it's +# overridden below) +_setlocale = setlocale + +# Avoid relying on the locale-dependent .lower() method +# (see issue #1813). +_ascii_lower_map = ''.join( + chr(x + 32 if x >= ord('A') and x <= ord('Z') else x) + for x in range(256) +) + +def normalize(localename): + + """ Returns a normalized locale code for the given locale + name. + + The returned locale code is formatted for use with + setlocale(). + + If normalization fails, the original name is returned + unchanged. + + If the given encoding is not known, the function defaults to + the default encoding for the locale code just like setlocale() + does. + + """ + # Normalize the locale name and extract the encoding + if isinstance(localename, _unicode): + localename = localename.encode('ascii') + fullname = localename.translate(_ascii_lower_map) + if ':' in fullname: + # ':' is sometimes used as encoding delimiter. + fullname = fullname.replace(':', '.') + if '.' in fullname: + langname, encoding = fullname.split('.')[:2] + fullname = langname + '.' + encoding + else: + langname = fullname + encoding = '' + + # First lookup: fullname (possibly with encoding) + norm_encoding = encoding.replace('-', '') + norm_encoding = norm_encoding.replace('_', '') + lookup_name = langname + '.' + encoding + code = locale_alias.get(lookup_name, None) + if code is not None: + return code + #print 'first lookup failed' + + # Second try: langname (without encoding) + code = locale_alias.get(langname, None) + if code is not None: + #print 'langname lookup succeeded' + if '.' in code: + langname, defenc = code.split('.') + else: + langname = code + defenc = '' + if encoding: + # Convert the encoding to a C lib compatible encoding string + norm_encoding = encodings.normalize_encoding(encoding) + #print 'norm encoding: %r' % norm_encoding + norm_encoding = encodings.aliases.aliases.get(norm_encoding, + norm_encoding) + #print 'aliased encoding: %r' % norm_encoding + encoding = locale_encoding_alias.get(norm_encoding, + norm_encoding) + else: + encoding = defenc + #print 'found encoding %r' % encoding + if encoding: + return langname + '.' + encoding + else: + return langname + + else: + return localename + +def _parse_localename(localename): + + """ Parses the locale code for localename and returns the + result as tuple (language code, encoding). + + The localename is normalized and passed through the locale + alias engine. A ValueError is raised in case the locale name + cannot be parsed. + + The language code corresponds to RFC 1766. code and encoding + can be None in case the values cannot be determined or are + unknown to this implementation. + + """ + code = normalize(localename) + if '@' in code: + # Deal with locale modifiers + code, modifier = code.split('@') + if modifier == 'euro' and '.' not in code: + # Assume Latin-9 for @euro locales. This is bogus, + # since some systems may use other encodings for these + # locales. Also, we ignore other modifiers. + return code, 'iso-8859-15' + + if '.' in code: + return tuple(code.split('.')[:2]) + elif code == 'C': + return None, None + raise ValueError, 'unknown locale: %s' % localename + +def _build_localename(localetuple): + + """ Builds a locale code from the given tuple (language code, + encoding). + + No aliasing or normalizing takes place. + + """ + language, encoding = localetuple + if language is None: + language = 'C' + if encoding is None: + return language + else: + return language + '.' + encoding + +def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): + + """ Tries to determine the default locale settings and returns + them as tuple (language code, encoding). + + According to POSIX, a program which has not called + setlocale(LC_ALL, "") runs using the portable 'C' locale. + Calling setlocale(LC_ALL, "") lets it use the default locale as + defined by the LANG variable. Since we don't want to interfere + with the current locale setting we thus emulate the behavior + in the way described above. + + To maintain compatibility with other platforms, not only the + LANG variable is tested, but a list of variables given as + envvars parameter. The first found to be defined will be + used. envvars defaults to the search path used in GNU gettext; + it must always contain the variable name 'LANG'. + + Except for the code 'C', the language code corresponds to RFC + 1766. code and encoding can be None in case the values cannot + be determined. + + """ + + try: + # check if it's supported by the _locale module + import _locale + code, encoding = _locale._getdefaultlocale() + except (ImportError, AttributeError): + pass + else: + # make sure the code/encoding values are valid + if sys.platform == "win32" and code and code[:2] == "0x": + # map windows language identifier to language name + code = windows_locale.get(int(code, 0)) + # ...add other platform-specific processing here, if + # necessary... + return code, encoding + + # fall back on POSIX behaviour + import os + lookup = os.environ.get + for variable in envvars: + localename = lookup(variable,None) + if localename: + if variable == 'LANGUAGE': + localename = localename.split(':')[0] + break + else: + localename = 'C' + return _parse_localename(localename) + + +def getlocale(category=LC_CTYPE): + + """ Returns the current setting for the given locale category as + tuple (language code, encoding). + + category may be one of the LC_* value except LC_ALL. It + defaults to LC_CTYPE. + + Except for the code 'C', the language code corresponds to RFC + 1766. code and encoding can be None in case the values cannot + be determined. + + """ + localename = _setlocale(category) + if category == LC_ALL and ';' in localename: + raise TypeError, 'category LC_ALL is not supported' + return _parse_localename(localename) + +def setlocale(category, locale=None): + + """ Set the locale for the given category. The locale can be + a string, an iterable of two strings (language code and encoding), + or None. + + Iterables are converted to strings using the locale aliasing + engine. Locale strings are passed directly to the C lib. + + category may be given as one of the LC_* values. + + """ + if locale and type(locale) is not type(""): + # convert to string + locale = normalize(_build_localename(locale)) + return _setlocale(category, locale) + +def resetlocale(category=LC_ALL): + + """ Sets the locale for category to the default setting. + + The default setting is determined by calling + getdefaultlocale(). category defaults to LC_ALL. + + """ + _setlocale(category, _build_localename(getdefaultlocale())) + +if sys.platform.startswith("win"): + # On Win32, this will return the ANSI code page + def getpreferredencoding(do_setlocale = True): + """Return the charset that the user is likely using.""" + import _locale + return _locale._getdefaultlocale()[1] +else: + # On Unix, if CODESET is available, use that. + try: + CODESET + except NameError: + # Fall back to parsing environment variables :-( + def getpreferredencoding(do_setlocale = True): + """Return the charset that the user is likely using, + by looking at environment variables.""" + return getdefaultlocale()[1] + else: + def getpreferredencoding(do_setlocale = True): + """Return the charset that the user is likely using, + according to the system configuration.""" + if do_setlocale: + oldloc = setlocale(LC_CTYPE) + try: + setlocale(LC_CTYPE, "") + except Error: + pass + result = nl_langinfo(CODESET) + setlocale(LC_CTYPE, oldloc) + return result + else: + return nl_langinfo(CODESET) + + +### Database +# +# The following data was extracted from the locale.alias file which +# comes with X11 and then hand edited removing the explicit encoding +# definitions and adding some more aliases. The file is usually +# available as /usr/lib/X11/locale/locale.alias. +# + +# +# The local_encoding_alias table maps lowercase encoding alias names +# to C locale encoding names (case-sensitive). Note that normalize() +# first looks up the encoding in the encodings.aliases dictionary and +# then applies this mapping to find the correct C lib name for the +# encoding. +# +locale_encoding_alias = { + + # Mappings for non-standard encoding names used in locale names + '437': 'C', + 'c': 'C', + 'en': 'ISO8859-1', + 'jis': 'JIS7', + 'jis7': 'JIS7', + 'ajec': 'eucJP', + + # Mappings from Python codec names to C lib encoding names + 'ascii': 'ISO8859-1', + 'latin_1': 'ISO8859-1', + 'iso8859_1': 'ISO8859-1', + 'iso8859_10': 'ISO8859-10', + 'iso8859_11': 'ISO8859-11', + 'iso8859_13': 'ISO8859-13', + 'iso8859_14': 'ISO8859-14', + 'iso8859_15': 'ISO8859-15', + 'iso8859_16': 'ISO8859-16', + 'iso8859_2': 'ISO8859-2', + 'iso8859_3': 'ISO8859-3', + 'iso8859_4': 'ISO8859-4', + 'iso8859_5': 'ISO8859-5', + 'iso8859_6': 'ISO8859-6', + 'iso8859_7': 'ISO8859-7', + 'iso8859_8': 'ISO8859-8', + 'iso8859_9': 'ISO8859-9', + 'iso2022_jp': 'JIS7', + 'shift_jis': 'SJIS', + 'tactis': 'TACTIS', + 'euc_jp': 'eucJP', + 'euc_kr': 'eucKR', + 'utf_8': 'UTF-8', + 'koi8_r': 'KOI8-R', + 'koi8_u': 'KOI8-U', + # XXX This list is still incomplete. If you know more + # mappings, please file a bug report. Thanks. +} + +# +# The locale_alias table maps lowercase alias names to C locale names +# (case-sensitive). Encodings are always separated from the locale +# name using a dot ('.'); they should only be given in case the +# language name is needed to interpret the given encoding alias +# correctly (CJK codes often have this need). +# +# Note that the normalize() function which uses this tables +# removes '_' and '-' characters from the encoding part of the +# locale name before doing the lookup. This saves a lot of +# space in the table. +# +# MAL 2004-12-10: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.4 +# and older): +# +# updated 'bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'bg_bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'bulgarian' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'cz_cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'czech' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'dutch' -> 'nl_BE.ISO8859-1' to 'nl_NL.ISO8859-1' +# updated 'et' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' +# updated 'et_ee' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' +# updated 'fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' +# updated 'fi_fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' +# updated 'iw' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'iw_il' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'japanese' -> 'ja_JP.SJIS' to 'ja_JP.eucJP' +# updated 'lt' -> 'lt_LT.ISO8859-4' to 'lt_LT.ISO8859-13' +# updated 'lv' -> 'lv_LV.ISO8859-4' to 'lv_LV.ISO8859-13' +# updated 'sl' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' +# updated 'slovene' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' +# updated 'th_th' -> 'th_TH.TACTIS' to 'th_TH.ISO8859-11' +# updated 'zh_cn' -> 'zh_CN.eucCN' to 'zh_CN.gb2312' +# updated 'zh_cn.big5' -> 'zh_TW.eucTW' to 'zh_TW.big5' +# updated 'zh_tw' -> 'zh_TW.eucTW' to 'zh_TW.big5' +# +# MAL 2008-05-30: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.5 +# and older): +# +# updated 'cs_cs.iso88592' -> 'cs_CZ.ISO8859-2' to 'cs_CS.ISO8859-2' +# updated 'serbocroatian' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh_hr.iso88592' -> 'sh_HR.ISO8859-2' to 'hr_HR.ISO8859-2' +# updated 'sh_sp' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh_yu' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sp' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sp_yu' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_sp' -> 'sr_SP.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sr_yu' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.cp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' +# updated 'sr_yu.iso88592' -> 'sr_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sr_yu.iso88595' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.iso88595@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.microsoftcp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' +# updated 'sr_yu.utf8@cyrillic' -> 'sr_YU.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_yu@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# +# AP 2010-04-12: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.6.5 +# and older): +# +# updated 'ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' +# updated 'ru_ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' +# updated 'serbocroatian' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sh' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sh_yu' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# updated 'sr@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# updated 'sr@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr_cs.utf8@latn' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr_yu' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8@latin' +# updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8' +# updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# + +locale_alias = { + 'a3': 'a3_AZ.KOI8-C', + 'a3_az': 'a3_AZ.KOI8-C', + 'a3_az.koi8c': 'a3_AZ.KOI8-C', + 'af': 'af_ZA.ISO8859-1', + 'af_za': 'af_ZA.ISO8859-1', + 'af_za.iso88591': 'af_ZA.ISO8859-1', + 'am': 'am_ET.UTF-8', + 'am_et': 'am_ET.UTF-8', + 'american': 'en_US.ISO8859-1', + 'american.iso88591': 'en_US.ISO8859-1', + 'ar': 'ar_AA.ISO8859-6', + 'ar_aa': 'ar_AA.ISO8859-6', + 'ar_aa.iso88596': 'ar_AA.ISO8859-6', + 'ar_ae': 'ar_AE.ISO8859-6', + 'ar_ae.iso88596': 'ar_AE.ISO8859-6', + 'ar_bh': 'ar_BH.ISO8859-6', + 'ar_bh.iso88596': 'ar_BH.ISO8859-6', + 'ar_dz': 'ar_DZ.ISO8859-6', + 'ar_dz.iso88596': 'ar_DZ.ISO8859-6', + 'ar_eg': 'ar_EG.ISO8859-6', + 'ar_eg.iso88596': 'ar_EG.ISO8859-6', + 'ar_iq': 'ar_IQ.ISO8859-6', + 'ar_iq.iso88596': 'ar_IQ.ISO8859-6', + 'ar_jo': 'ar_JO.ISO8859-6', + 'ar_jo.iso88596': 'ar_JO.ISO8859-6', + 'ar_kw': 'ar_KW.ISO8859-6', + 'ar_kw.iso88596': 'ar_KW.ISO8859-6', + 'ar_lb': 'ar_LB.ISO8859-6', + 'ar_lb.iso88596': 'ar_LB.ISO8859-6', + 'ar_ly': 'ar_LY.ISO8859-6', + 'ar_ly.iso88596': 'ar_LY.ISO8859-6', + 'ar_ma': 'ar_MA.ISO8859-6', + 'ar_ma.iso88596': 'ar_MA.ISO8859-6', + 'ar_om': 'ar_OM.ISO8859-6', + 'ar_om.iso88596': 'ar_OM.ISO8859-6', + 'ar_qa': 'ar_QA.ISO8859-6', + 'ar_qa.iso88596': 'ar_QA.ISO8859-6', + 'ar_sa': 'ar_SA.ISO8859-6', + 'ar_sa.iso88596': 'ar_SA.ISO8859-6', + 'ar_sd': 'ar_SD.ISO8859-6', + 'ar_sd.iso88596': 'ar_SD.ISO8859-6', + 'ar_sy': 'ar_SY.ISO8859-6', + 'ar_sy.iso88596': 'ar_SY.ISO8859-6', + 'ar_tn': 'ar_TN.ISO8859-6', + 'ar_tn.iso88596': 'ar_TN.ISO8859-6', + 'ar_ye': 'ar_YE.ISO8859-6', + 'ar_ye.iso88596': 'ar_YE.ISO8859-6', + 'arabic': 'ar_AA.ISO8859-6', + 'arabic.iso88596': 'ar_AA.ISO8859-6', + 'as': 'as_IN.UTF-8', + 'az': 'az_AZ.ISO8859-9E', + 'az_az': 'az_AZ.ISO8859-9E', + 'az_az.iso88599e': 'az_AZ.ISO8859-9E', + 'be': 'be_BY.CP1251', + 'be@latin': 'be_BY.UTF-8@latin', + 'be_by': 'be_BY.CP1251', + 'be_by.cp1251': 'be_BY.CP1251', + 'be_by.microsoftcp1251': 'be_BY.CP1251', + 'be_by.utf8@latin': 'be_BY.UTF-8@latin', + 'be_by@latin': 'be_BY.UTF-8@latin', + 'bg': 'bg_BG.CP1251', + 'bg_bg': 'bg_BG.CP1251', + 'bg_bg.cp1251': 'bg_BG.CP1251', + 'bg_bg.iso88595': 'bg_BG.ISO8859-5', + 'bg_bg.koi8r': 'bg_BG.KOI8-R', + 'bg_bg.microsoftcp1251': 'bg_BG.CP1251', + 'bn_in': 'bn_IN.UTF-8', + 'bokmal': 'nb_NO.ISO8859-1', + 'bokm\xe5l': 'nb_NO.ISO8859-1', + 'br': 'br_FR.ISO8859-1', + 'br_fr': 'br_FR.ISO8859-1', + 'br_fr.iso88591': 'br_FR.ISO8859-1', + 'br_fr.iso885914': 'br_FR.ISO8859-14', + 'br_fr.iso885915': 'br_FR.ISO8859-15', + 'br_fr.iso885915@euro': 'br_FR.ISO8859-15', + 'br_fr.utf8@euro': 'br_FR.UTF-8', + 'br_fr@euro': 'br_FR.ISO8859-15', + 'bs': 'bs_BA.ISO8859-2', + 'bs_ba': 'bs_BA.ISO8859-2', + 'bs_ba.iso88592': 'bs_BA.ISO8859-2', + 'bulgarian': 'bg_BG.CP1251', + 'c': 'C', + 'c-french': 'fr_CA.ISO8859-1', + 'c-french.iso88591': 'fr_CA.ISO8859-1', + 'c.en': 'C', + 'c.iso88591': 'en_US.ISO8859-1', + 'c_c': 'C', + 'c_c.c': 'C', + 'ca': 'ca_ES.ISO8859-1', + 'ca_ad': 'ca_AD.ISO8859-1', + 'ca_ad.iso88591': 'ca_AD.ISO8859-1', + 'ca_ad.iso885915': 'ca_AD.ISO8859-15', + 'ca_ad.iso885915@euro': 'ca_AD.ISO8859-15', + 'ca_ad.utf8@euro': 'ca_AD.UTF-8', + 'ca_ad@euro': 'ca_AD.ISO8859-15', + 'ca_es': 'ca_ES.ISO8859-1', + 'ca_es.iso88591': 'ca_ES.ISO8859-1', + 'ca_es.iso885915': 'ca_ES.ISO8859-15', + 'ca_es.iso885915@euro': 'ca_ES.ISO8859-15', + 'ca_es.utf8@euro': 'ca_ES.UTF-8', + 'ca_es@euro': 'ca_ES.ISO8859-15', + 'ca_fr': 'ca_FR.ISO8859-1', + 'ca_fr.iso88591': 'ca_FR.ISO8859-1', + 'ca_fr.iso885915': 'ca_FR.ISO8859-15', + 'ca_fr.iso885915@euro': 'ca_FR.ISO8859-15', + 'ca_fr.utf8@euro': 'ca_FR.UTF-8', + 'ca_fr@euro': 'ca_FR.ISO8859-15', + 'ca_it': 'ca_IT.ISO8859-1', + 'ca_it.iso88591': 'ca_IT.ISO8859-1', + 'ca_it.iso885915': 'ca_IT.ISO8859-15', + 'ca_it.iso885915@euro': 'ca_IT.ISO8859-15', + 'ca_it.utf8@euro': 'ca_IT.UTF-8', + 'ca_it@euro': 'ca_IT.ISO8859-15', + 'catalan': 'ca_ES.ISO8859-1', + 'cextend': 'en_US.ISO8859-1', + 'cextend.en': 'en_US.ISO8859-1', + 'chinese-s': 'zh_CN.eucCN', + 'chinese-t': 'zh_TW.eucTW', + 'croatian': 'hr_HR.ISO8859-2', + 'cs': 'cs_CZ.ISO8859-2', + 'cs_cs': 'cs_CZ.ISO8859-2', + 'cs_cs.iso88592': 'cs_CS.ISO8859-2', + 'cs_cz': 'cs_CZ.ISO8859-2', + 'cs_cz.iso88592': 'cs_CZ.ISO8859-2', + 'cy': 'cy_GB.ISO8859-1', + 'cy_gb': 'cy_GB.ISO8859-1', + 'cy_gb.iso88591': 'cy_GB.ISO8859-1', + 'cy_gb.iso885914': 'cy_GB.ISO8859-14', + 'cy_gb.iso885915': 'cy_GB.ISO8859-15', + 'cy_gb@euro': 'cy_GB.ISO8859-15', + 'cz': 'cs_CZ.ISO8859-2', + 'cz_cz': 'cs_CZ.ISO8859-2', + 'czech': 'cs_CZ.ISO8859-2', + 'da': 'da_DK.ISO8859-1', + 'da.iso885915': 'da_DK.ISO8859-15', + 'da_dk': 'da_DK.ISO8859-1', + 'da_dk.88591': 'da_DK.ISO8859-1', + 'da_dk.885915': 'da_DK.ISO8859-15', + 'da_dk.iso88591': 'da_DK.ISO8859-1', + 'da_dk.iso885915': 'da_DK.ISO8859-15', + 'da_dk@euro': 'da_DK.ISO8859-15', + 'danish': 'da_DK.ISO8859-1', + 'danish.iso88591': 'da_DK.ISO8859-1', + 'dansk': 'da_DK.ISO8859-1', + 'de': 'de_DE.ISO8859-1', + 'de.iso885915': 'de_DE.ISO8859-15', + 'de_at': 'de_AT.ISO8859-1', + 'de_at.iso88591': 'de_AT.ISO8859-1', + 'de_at.iso885915': 'de_AT.ISO8859-15', + 'de_at.iso885915@euro': 'de_AT.ISO8859-15', + 'de_at.utf8@euro': 'de_AT.UTF-8', + 'de_at@euro': 'de_AT.ISO8859-15', + 'de_be': 'de_BE.ISO8859-1', + 'de_be.iso88591': 'de_BE.ISO8859-1', + 'de_be.iso885915': 'de_BE.ISO8859-15', + 'de_be.iso885915@euro': 'de_BE.ISO8859-15', + 'de_be.utf8@euro': 'de_BE.UTF-8', + 'de_be@euro': 'de_BE.ISO8859-15', + 'de_ch': 'de_CH.ISO8859-1', + 'de_ch.iso88591': 'de_CH.ISO8859-1', + 'de_ch.iso885915': 'de_CH.ISO8859-15', + 'de_ch@euro': 'de_CH.ISO8859-15', + 'de_de': 'de_DE.ISO8859-1', + 'de_de.88591': 'de_DE.ISO8859-1', + 'de_de.885915': 'de_DE.ISO8859-15', + 'de_de.885915@euro': 'de_DE.ISO8859-15', + 'de_de.iso88591': 'de_DE.ISO8859-1', + 'de_de.iso885915': 'de_DE.ISO8859-15', + 'de_de.iso885915@euro': 'de_DE.ISO8859-15', + 'de_de.utf8@euro': 'de_DE.UTF-8', + 'de_de@euro': 'de_DE.ISO8859-15', + 'de_lu': 'de_LU.ISO8859-1', + 'de_lu.iso88591': 'de_LU.ISO8859-1', + 'de_lu.iso885915': 'de_LU.ISO8859-15', + 'de_lu.iso885915@euro': 'de_LU.ISO8859-15', + 'de_lu.utf8@euro': 'de_LU.UTF-8', + 'de_lu@euro': 'de_LU.ISO8859-15', + 'deutsch': 'de_DE.ISO8859-1', + 'dutch': 'nl_NL.ISO8859-1', + 'dutch.iso88591': 'nl_BE.ISO8859-1', + 'ee': 'ee_EE.ISO8859-4', + 'ee_ee': 'ee_EE.ISO8859-4', + 'ee_ee.iso88594': 'ee_EE.ISO8859-4', + 'eesti': 'et_EE.ISO8859-1', + 'el': 'el_GR.ISO8859-7', + 'el_gr': 'el_GR.ISO8859-7', + 'el_gr.iso88597': 'el_GR.ISO8859-7', + 'el_gr@euro': 'el_GR.ISO8859-15', + 'en': 'en_US.ISO8859-1', + 'en.iso88591': 'en_US.ISO8859-1', + 'en_au': 'en_AU.ISO8859-1', + 'en_au.iso88591': 'en_AU.ISO8859-1', + 'en_be': 'en_BE.ISO8859-1', + 'en_be@euro': 'en_BE.ISO8859-15', + 'en_bw': 'en_BW.ISO8859-1', + 'en_bw.iso88591': 'en_BW.ISO8859-1', + 'en_ca': 'en_CA.ISO8859-1', + 'en_ca.iso88591': 'en_CA.ISO8859-1', + 'en_gb': 'en_GB.ISO8859-1', + 'en_gb.88591': 'en_GB.ISO8859-1', + 'en_gb.iso88591': 'en_GB.ISO8859-1', + 'en_gb.iso885915': 'en_GB.ISO8859-15', + 'en_gb@euro': 'en_GB.ISO8859-15', + 'en_hk': 'en_HK.ISO8859-1', + 'en_hk.iso88591': 'en_HK.ISO8859-1', + 'en_ie': 'en_IE.ISO8859-1', + 'en_ie.iso88591': 'en_IE.ISO8859-1', + 'en_ie.iso885915': 'en_IE.ISO8859-15', + 'en_ie.iso885915@euro': 'en_IE.ISO8859-15', + 'en_ie.utf8@euro': 'en_IE.UTF-8', + 'en_ie@euro': 'en_IE.ISO8859-15', + 'en_in': 'en_IN.ISO8859-1', + 'en_nz': 'en_NZ.ISO8859-1', + 'en_nz.iso88591': 'en_NZ.ISO8859-1', + 'en_ph': 'en_PH.ISO8859-1', + 'en_ph.iso88591': 'en_PH.ISO8859-1', + 'en_sg': 'en_SG.ISO8859-1', + 'en_sg.iso88591': 'en_SG.ISO8859-1', + 'en_uk': 'en_GB.ISO8859-1', + 'en_us': 'en_US.ISO8859-1', + 'en_us.88591': 'en_US.ISO8859-1', + 'en_us.885915': 'en_US.ISO8859-15', + 'en_us.iso88591': 'en_US.ISO8859-1', + 'en_us.iso885915': 'en_US.ISO8859-15', + 'en_us.iso885915@euro': 'en_US.ISO8859-15', + 'en_us@euro': 'en_US.ISO8859-15', + 'en_us@euro@euro': 'en_US.ISO8859-15', + 'en_za': 'en_ZA.ISO8859-1', + 'en_za.88591': 'en_ZA.ISO8859-1', + 'en_za.iso88591': 'en_ZA.ISO8859-1', + 'en_za.iso885915': 'en_ZA.ISO8859-15', + 'en_za@euro': 'en_ZA.ISO8859-15', + 'en_zw': 'en_ZW.ISO8859-1', + 'en_zw.iso88591': 'en_ZW.ISO8859-1', + 'eng_gb': 'en_GB.ISO8859-1', + 'eng_gb.8859': 'en_GB.ISO8859-1', + 'english': 'en_EN.ISO8859-1', + 'english.iso88591': 'en_EN.ISO8859-1', + 'english_uk': 'en_GB.ISO8859-1', + 'english_uk.8859': 'en_GB.ISO8859-1', + 'english_united-states': 'en_US.ISO8859-1', + 'english_united-states.437': 'C', + 'english_us': 'en_US.ISO8859-1', + 'english_us.8859': 'en_US.ISO8859-1', + 'english_us.ascii': 'en_US.ISO8859-1', + 'eo': 'eo_XX.ISO8859-3', + 'eo_eo': 'eo_EO.ISO8859-3', + 'eo_eo.iso88593': 'eo_EO.ISO8859-3', + 'eo_xx': 'eo_XX.ISO8859-3', + 'eo_xx.iso88593': 'eo_XX.ISO8859-3', + 'es': 'es_ES.ISO8859-1', + 'es_ar': 'es_AR.ISO8859-1', + 'es_ar.iso88591': 'es_AR.ISO8859-1', + 'es_bo': 'es_BO.ISO8859-1', + 'es_bo.iso88591': 'es_BO.ISO8859-1', + 'es_cl': 'es_CL.ISO8859-1', + 'es_cl.iso88591': 'es_CL.ISO8859-1', + 'es_co': 'es_CO.ISO8859-1', + 'es_co.iso88591': 'es_CO.ISO8859-1', + 'es_cr': 'es_CR.ISO8859-1', + 'es_cr.iso88591': 'es_CR.ISO8859-1', + 'es_do': 'es_DO.ISO8859-1', + 'es_do.iso88591': 'es_DO.ISO8859-1', + 'es_ec': 'es_EC.ISO8859-1', + 'es_ec.iso88591': 'es_EC.ISO8859-1', + 'es_es': 'es_ES.ISO8859-1', + 'es_es.88591': 'es_ES.ISO8859-1', + 'es_es.iso88591': 'es_ES.ISO8859-1', + 'es_es.iso885915': 'es_ES.ISO8859-15', + 'es_es.iso885915@euro': 'es_ES.ISO8859-15', + 'es_es.utf8@euro': 'es_ES.UTF-8', + 'es_es@euro': 'es_ES.ISO8859-15', + 'es_gt': 'es_GT.ISO8859-1', + 'es_gt.iso88591': 'es_GT.ISO8859-1', + 'es_hn': 'es_HN.ISO8859-1', + 'es_hn.iso88591': 'es_HN.ISO8859-1', + 'es_mx': 'es_MX.ISO8859-1', + 'es_mx.iso88591': 'es_MX.ISO8859-1', + 'es_ni': 'es_NI.ISO8859-1', + 'es_ni.iso88591': 'es_NI.ISO8859-1', + 'es_pa': 'es_PA.ISO8859-1', + 'es_pa.iso88591': 'es_PA.ISO8859-1', + 'es_pa.iso885915': 'es_PA.ISO8859-15', + 'es_pa@euro': 'es_PA.ISO8859-15', + 'es_pe': 'es_PE.ISO8859-1', + 'es_pe.iso88591': 'es_PE.ISO8859-1', + 'es_pe.iso885915': 'es_PE.ISO8859-15', + 'es_pe@euro': 'es_PE.ISO8859-15', + 'es_pr': 'es_PR.ISO8859-1', + 'es_pr.iso88591': 'es_PR.ISO8859-1', + 'es_py': 'es_PY.ISO8859-1', + 'es_py.iso88591': 'es_PY.ISO8859-1', + 'es_py.iso885915': 'es_PY.ISO8859-15', + 'es_py@euro': 'es_PY.ISO8859-15', + 'es_sv': 'es_SV.ISO8859-1', + 'es_sv.iso88591': 'es_SV.ISO8859-1', + 'es_sv.iso885915': 'es_SV.ISO8859-15', + 'es_sv@euro': 'es_SV.ISO8859-15', + 'es_us': 'es_US.ISO8859-1', + 'es_us.iso88591': 'es_US.ISO8859-1', + 'es_uy': 'es_UY.ISO8859-1', + 'es_uy.iso88591': 'es_UY.ISO8859-1', + 'es_uy.iso885915': 'es_UY.ISO8859-15', + 'es_uy@euro': 'es_UY.ISO8859-15', + 'es_ve': 'es_VE.ISO8859-1', + 'es_ve.iso88591': 'es_VE.ISO8859-1', + 'es_ve.iso885915': 'es_VE.ISO8859-15', + 'es_ve@euro': 'es_VE.ISO8859-15', + 'estonian': 'et_EE.ISO8859-1', + 'et': 'et_EE.ISO8859-15', + 'et_ee': 'et_EE.ISO8859-15', + 'et_ee.iso88591': 'et_EE.ISO8859-1', + 'et_ee.iso885913': 'et_EE.ISO8859-13', + 'et_ee.iso885915': 'et_EE.ISO8859-15', + 'et_ee.iso88594': 'et_EE.ISO8859-4', + 'et_ee@euro': 'et_EE.ISO8859-15', + 'eu': 'eu_ES.ISO8859-1', + 'eu_es': 'eu_ES.ISO8859-1', + 'eu_es.iso88591': 'eu_ES.ISO8859-1', + 'eu_es.iso885915': 'eu_ES.ISO8859-15', + 'eu_es.iso885915@euro': 'eu_ES.ISO8859-15', + 'eu_es.utf8@euro': 'eu_ES.UTF-8', + 'eu_es@euro': 'eu_ES.ISO8859-15', + 'fa': 'fa_IR.UTF-8', + 'fa_ir': 'fa_IR.UTF-8', + 'fa_ir.isiri3342': 'fa_IR.ISIRI-3342', + 'fi': 'fi_FI.ISO8859-15', + 'fi.iso885915': 'fi_FI.ISO8859-15', + 'fi_fi': 'fi_FI.ISO8859-15', + 'fi_fi.88591': 'fi_FI.ISO8859-1', + 'fi_fi.iso88591': 'fi_FI.ISO8859-1', + 'fi_fi.iso885915': 'fi_FI.ISO8859-15', + 'fi_fi.iso885915@euro': 'fi_FI.ISO8859-15', + 'fi_fi.utf8@euro': 'fi_FI.UTF-8', + 'fi_fi@euro': 'fi_FI.ISO8859-15', + 'finnish': 'fi_FI.ISO8859-1', + 'finnish.iso88591': 'fi_FI.ISO8859-1', + 'fo': 'fo_FO.ISO8859-1', + 'fo_fo': 'fo_FO.ISO8859-1', + 'fo_fo.iso88591': 'fo_FO.ISO8859-1', + 'fo_fo.iso885915': 'fo_FO.ISO8859-15', + 'fo_fo@euro': 'fo_FO.ISO8859-15', + 'fr': 'fr_FR.ISO8859-1', + 'fr.iso885915': 'fr_FR.ISO8859-15', + 'fr_be': 'fr_BE.ISO8859-1', + 'fr_be.88591': 'fr_BE.ISO8859-1', + 'fr_be.iso88591': 'fr_BE.ISO8859-1', + 'fr_be.iso885915': 'fr_BE.ISO8859-15', + 'fr_be.iso885915@euro': 'fr_BE.ISO8859-15', + 'fr_be.utf8@euro': 'fr_BE.UTF-8', + 'fr_be@euro': 'fr_BE.ISO8859-15', + 'fr_ca': 'fr_CA.ISO8859-1', + 'fr_ca.88591': 'fr_CA.ISO8859-1', + 'fr_ca.iso88591': 'fr_CA.ISO8859-1', + 'fr_ca.iso885915': 'fr_CA.ISO8859-15', + 'fr_ca@euro': 'fr_CA.ISO8859-15', + 'fr_ch': 'fr_CH.ISO8859-1', + 'fr_ch.88591': 'fr_CH.ISO8859-1', + 'fr_ch.iso88591': 'fr_CH.ISO8859-1', + 'fr_ch.iso885915': 'fr_CH.ISO8859-15', + 'fr_ch@euro': 'fr_CH.ISO8859-15', + 'fr_fr': 'fr_FR.ISO8859-1', + 'fr_fr.88591': 'fr_FR.ISO8859-1', + 'fr_fr.iso88591': 'fr_FR.ISO8859-1', + 'fr_fr.iso885915': 'fr_FR.ISO8859-15', + 'fr_fr.iso885915@euro': 'fr_FR.ISO8859-15', + 'fr_fr.utf8@euro': 'fr_FR.UTF-8', + 'fr_fr@euro': 'fr_FR.ISO8859-15', + 'fr_lu': 'fr_LU.ISO8859-1', + 'fr_lu.88591': 'fr_LU.ISO8859-1', + 'fr_lu.iso88591': 'fr_LU.ISO8859-1', + 'fr_lu.iso885915': 'fr_LU.ISO8859-15', + 'fr_lu.iso885915@euro': 'fr_LU.ISO8859-15', + 'fr_lu.utf8@euro': 'fr_LU.UTF-8', + 'fr_lu@euro': 'fr_LU.ISO8859-15', + 'fran\xe7ais': 'fr_FR.ISO8859-1', + 'fre_fr': 'fr_FR.ISO8859-1', + 'fre_fr.8859': 'fr_FR.ISO8859-1', + 'french': 'fr_FR.ISO8859-1', + 'french.iso88591': 'fr_CH.ISO8859-1', + 'french_france': 'fr_FR.ISO8859-1', + 'french_france.8859': 'fr_FR.ISO8859-1', + 'ga': 'ga_IE.ISO8859-1', + 'ga_ie': 'ga_IE.ISO8859-1', + 'ga_ie.iso88591': 'ga_IE.ISO8859-1', + 'ga_ie.iso885914': 'ga_IE.ISO8859-14', + 'ga_ie.iso885915': 'ga_IE.ISO8859-15', + 'ga_ie.iso885915@euro': 'ga_IE.ISO8859-15', + 'ga_ie.utf8@euro': 'ga_IE.UTF-8', + 'ga_ie@euro': 'ga_IE.ISO8859-15', + 'galego': 'gl_ES.ISO8859-1', + 'galician': 'gl_ES.ISO8859-1', + 'gd': 'gd_GB.ISO8859-1', + 'gd_gb': 'gd_GB.ISO8859-1', + 'gd_gb.iso88591': 'gd_GB.ISO8859-1', + 'gd_gb.iso885914': 'gd_GB.ISO8859-14', + 'gd_gb.iso885915': 'gd_GB.ISO8859-15', + 'gd_gb@euro': 'gd_GB.ISO8859-15', + 'ger_de': 'de_DE.ISO8859-1', + 'ger_de.8859': 'de_DE.ISO8859-1', + 'german': 'de_DE.ISO8859-1', + 'german.iso88591': 'de_CH.ISO8859-1', + 'german_germany': 'de_DE.ISO8859-1', + 'german_germany.8859': 'de_DE.ISO8859-1', + 'gl': 'gl_ES.ISO8859-1', + 'gl_es': 'gl_ES.ISO8859-1', + 'gl_es.iso88591': 'gl_ES.ISO8859-1', + 'gl_es.iso885915': 'gl_ES.ISO8859-15', + 'gl_es.iso885915@euro': 'gl_ES.ISO8859-15', + 'gl_es.utf8@euro': 'gl_ES.UTF-8', + 'gl_es@euro': 'gl_ES.ISO8859-15', + 'greek': 'el_GR.ISO8859-7', + 'greek.iso88597': 'el_GR.ISO8859-7', + 'gu_in': 'gu_IN.UTF-8', + 'gv': 'gv_GB.ISO8859-1', + 'gv_gb': 'gv_GB.ISO8859-1', + 'gv_gb.iso88591': 'gv_GB.ISO8859-1', + 'gv_gb.iso885914': 'gv_GB.ISO8859-14', + 'gv_gb.iso885915': 'gv_GB.ISO8859-15', + 'gv_gb@euro': 'gv_GB.ISO8859-15', + 'he': 'he_IL.ISO8859-8', + 'he_il': 'he_IL.ISO8859-8', + 'he_il.cp1255': 'he_IL.CP1255', + 'he_il.iso88598': 'he_IL.ISO8859-8', + 'he_il.microsoftcp1255': 'he_IL.CP1255', + 'hebrew': 'iw_IL.ISO8859-8', + 'hebrew.iso88598': 'iw_IL.ISO8859-8', + 'hi': 'hi_IN.ISCII-DEV', + 'hi_in': 'hi_IN.ISCII-DEV', + 'hi_in.isciidev': 'hi_IN.ISCII-DEV', + 'hne': 'hne_IN.UTF-8', + 'hr': 'hr_HR.ISO8859-2', + 'hr_hr': 'hr_HR.ISO8859-2', + 'hr_hr.iso88592': 'hr_HR.ISO8859-2', + 'hrvatski': 'hr_HR.ISO8859-2', + 'hu': 'hu_HU.ISO8859-2', + 'hu_hu': 'hu_HU.ISO8859-2', + 'hu_hu.iso88592': 'hu_HU.ISO8859-2', + 'hungarian': 'hu_HU.ISO8859-2', + 'icelandic': 'is_IS.ISO8859-1', + 'icelandic.iso88591': 'is_IS.ISO8859-1', + 'id': 'id_ID.ISO8859-1', + 'id_id': 'id_ID.ISO8859-1', + 'in': 'id_ID.ISO8859-1', + 'in_id': 'id_ID.ISO8859-1', + 'is': 'is_IS.ISO8859-1', + 'is_is': 'is_IS.ISO8859-1', + 'is_is.iso88591': 'is_IS.ISO8859-1', + 'is_is.iso885915': 'is_IS.ISO8859-15', + 'is_is@euro': 'is_IS.ISO8859-15', + 'iso-8859-1': 'en_US.ISO8859-1', + 'iso-8859-15': 'en_US.ISO8859-15', + 'iso8859-1': 'en_US.ISO8859-1', + 'iso8859-15': 'en_US.ISO8859-15', + 'iso_8859_1': 'en_US.ISO8859-1', + 'iso_8859_15': 'en_US.ISO8859-15', + 'it': 'it_IT.ISO8859-1', + 'it.iso885915': 'it_IT.ISO8859-15', + 'it_ch': 'it_CH.ISO8859-1', + 'it_ch.iso88591': 'it_CH.ISO8859-1', + 'it_ch.iso885915': 'it_CH.ISO8859-15', + 'it_ch@euro': 'it_CH.ISO8859-15', + 'it_it': 'it_IT.ISO8859-1', + 'it_it.88591': 'it_IT.ISO8859-1', + 'it_it.iso88591': 'it_IT.ISO8859-1', + 'it_it.iso885915': 'it_IT.ISO8859-15', + 'it_it.iso885915@euro': 'it_IT.ISO8859-15', + 'it_it.utf8@euro': 'it_IT.UTF-8', + 'it_it@euro': 'it_IT.ISO8859-15', + 'italian': 'it_IT.ISO8859-1', + 'italian.iso88591': 'it_IT.ISO8859-1', + 'iu': 'iu_CA.NUNACOM-8', + 'iu_ca': 'iu_CA.NUNACOM-8', + 'iu_ca.nunacom8': 'iu_CA.NUNACOM-8', + 'iw': 'he_IL.ISO8859-8', + 'iw_il': 'he_IL.ISO8859-8', + 'iw_il.iso88598': 'he_IL.ISO8859-8', + 'ja': 'ja_JP.eucJP', + 'ja.jis': 'ja_JP.JIS7', + 'ja.sjis': 'ja_JP.SJIS', + 'ja_jp': 'ja_JP.eucJP', + 'ja_jp.ajec': 'ja_JP.eucJP', + 'ja_jp.euc': 'ja_JP.eucJP', + 'ja_jp.eucjp': 'ja_JP.eucJP', + 'ja_jp.iso-2022-jp': 'ja_JP.JIS7', + 'ja_jp.iso2022jp': 'ja_JP.JIS7', + 'ja_jp.jis': 'ja_JP.JIS7', + 'ja_jp.jis7': 'ja_JP.JIS7', + 'ja_jp.mscode': 'ja_JP.SJIS', + 'ja_jp.pck': 'ja_JP.SJIS', + 'ja_jp.sjis': 'ja_JP.SJIS', + 'ja_jp.ujis': 'ja_JP.eucJP', + 'japan': 'ja_JP.eucJP', + 'japanese': 'ja_JP.eucJP', + 'japanese-euc': 'ja_JP.eucJP', + 'japanese.euc': 'ja_JP.eucJP', + 'japanese.sjis': 'ja_JP.SJIS', + 'jp_jp': 'ja_JP.eucJP', + 'ka': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', + 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', + 'kl': 'kl_GL.ISO8859-1', + 'kl_gl': 'kl_GL.ISO8859-1', + 'kl_gl.iso88591': 'kl_GL.ISO8859-1', + 'kl_gl.iso885915': 'kl_GL.ISO8859-15', + 'kl_gl@euro': 'kl_GL.ISO8859-15', + 'km_kh': 'km_KH.UTF-8', + 'kn': 'kn_IN.UTF-8', + 'kn_in': 'kn_IN.UTF-8', + 'ko': 'ko_KR.eucKR', + 'ko_kr': 'ko_KR.eucKR', + 'ko_kr.euc': 'ko_KR.eucKR', + 'ko_kr.euckr': 'ko_KR.eucKR', + 'korean': 'ko_KR.eucKR', + 'korean.euc': 'ko_KR.eucKR', + 'ks': 'ks_IN.UTF-8', + 'ks_in@devanagari': 'ks_IN@devanagari.UTF-8', + 'kw': 'kw_GB.ISO8859-1', + 'kw_gb': 'kw_GB.ISO8859-1', + 'kw_gb.iso88591': 'kw_GB.ISO8859-1', + 'kw_gb.iso885914': 'kw_GB.ISO8859-14', + 'kw_gb.iso885915': 'kw_GB.ISO8859-15', + 'kw_gb@euro': 'kw_GB.ISO8859-15', + 'ky': 'ky_KG.UTF-8', + 'ky_kg': 'ky_KG.UTF-8', + 'lithuanian': 'lt_LT.ISO8859-13', + 'lo': 'lo_LA.MULELAO-1', + 'lo_la': 'lo_LA.MULELAO-1', + 'lo_la.cp1133': 'lo_LA.IBM-CP1133', + 'lo_la.ibmcp1133': 'lo_LA.IBM-CP1133', + 'lo_la.mulelao1': 'lo_LA.MULELAO-1', + 'lt': 'lt_LT.ISO8859-13', + 'lt_lt': 'lt_LT.ISO8859-13', + 'lt_lt.iso885913': 'lt_LT.ISO8859-13', + 'lt_lt.iso88594': 'lt_LT.ISO8859-4', + 'lv': 'lv_LV.ISO8859-13', + 'lv_lv': 'lv_LV.ISO8859-13', + 'lv_lv.iso885913': 'lv_LV.ISO8859-13', + 'lv_lv.iso88594': 'lv_LV.ISO8859-4', + 'mai': 'mai_IN.UTF-8', + 'mi': 'mi_NZ.ISO8859-1', + 'mi_nz': 'mi_NZ.ISO8859-1', + 'mi_nz.iso88591': 'mi_NZ.ISO8859-1', + 'mk': 'mk_MK.ISO8859-5', + 'mk_mk': 'mk_MK.ISO8859-5', + 'mk_mk.cp1251': 'mk_MK.CP1251', + 'mk_mk.iso88595': 'mk_MK.ISO8859-5', + 'mk_mk.microsoftcp1251': 'mk_MK.CP1251', + 'ml': 'ml_IN.UTF-8', + 'mr': 'mr_IN.UTF-8', + 'mr_in': 'mr_IN.UTF-8', + 'ms': 'ms_MY.ISO8859-1', + 'ms_my': 'ms_MY.ISO8859-1', + 'ms_my.iso88591': 'ms_MY.ISO8859-1', + 'mt': 'mt_MT.ISO8859-3', + 'mt_mt': 'mt_MT.ISO8859-3', + 'mt_mt.iso88593': 'mt_MT.ISO8859-3', + 'nb': 'nb_NO.ISO8859-1', + 'nb_no': 'nb_NO.ISO8859-1', + 'nb_no.88591': 'nb_NO.ISO8859-1', + 'nb_no.iso88591': 'nb_NO.ISO8859-1', + 'nb_no.iso885915': 'nb_NO.ISO8859-15', + 'nb_no@euro': 'nb_NO.ISO8859-15', + 'nl': 'nl_NL.ISO8859-1', + 'nl.iso885915': 'nl_NL.ISO8859-15', + 'nl_be': 'nl_BE.ISO8859-1', + 'nl_be.88591': 'nl_BE.ISO8859-1', + 'nl_be.iso88591': 'nl_BE.ISO8859-1', + 'nl_be.iso885915': 'nl_BE.ISO8859-15', + 'nl_be.iso885915@euro': 'nl_BE.ISO8859-15', + 'nl_be.utf8@euro': 'nl_BE.UTF-8', + 'nl_be@euro': 'nl_BE.ISO8859-15', + 'nl_nl': 'nl_NL.ISO8859-1', + 'nl_nl.88591': 'nl_NL.ISO8859-1', + 'nl_nl.iso88591': 'nl_NL.ISO8859-1', + 'nl_nl.iso885915': 'nl_NL.ISO8859-15', + 'nl_nl.iso885915@euro': 'nl_NL.ISO8859-15', + 'nl_nl.utf8@euro': 'nl_NL.UTF-8', + 'nl_nl@euro': 'nl_NL.ISO8859-15', + 'nn': 'nn_NO.ISO8859-1', + 'nn_no': 'nn_NO.ISO8859-1', + 'nn_no.88591': 'nn_NO.ISO8859-1', + 'nn_no.iso88591': 'nn_NO.ISO8859-1', + 'nn_no.iso885915': 'nn_NO.ISO8859-15', + 'nn_no@euro': 'nn_NO.ISO8859-15', + 'no': 'no_NO.ISO8859-1', + 'no@nynorsk': 'ny_NO.ISO8859-1', + 'no_no': 'no_NO.ISO8859-1', + 'no_no.88591': 'no_NO.ISO8859-1', + 'no_no.iso88591': 'no_NO.ISO8859-1', + 'no_no.iso885915': 'no_NO.ISO8859-15', + 'no_no.iso88591@bokmal': 'no_NO.ISO8859-1', + 'no_no.iso88591@nynorsk': 'no_NO.ISO8859-1', + 'no_no@euro': 'no_NO.ISO8859-15', + 'norwegian': 'no_NO.ISO8859-1', + 'norwegian.iso88591': 'no_NO.ISO8859-1', + 'nr': 'nr_ZA.ISO8859-1', + 'nr_za': 'nr_ZA.ISO8859-1', + 'nr_za.iso88591': 'nr_ZA.ISO8859-1', + 'nso': 'nso_ZA.ISO8859-15', + 'nso_za': 'nso_ZA.ISO8859-15', + 'nso_za.iso885915': 'nso_ZA.ISO8859-15', + 'ny': 'ny_NO.ISO8859-1', + 'ny_no': 'ny_NO.ISO8859-1', + 'ny_no.88591': 'ny_NO.ISO8859-1', + 'ny_no.iso88591': 'ny_NO.ISO8859-1', + 'ny_no.iso885915': 'ny_NO.ISO8859-15', + 'ny_no@euro': 'ny_NO.ISO8859-15', + 'nynorsk': 'nn_NO.ISO8859-1', + 'oc': 'oc_FR.ISO8859-1', + 'oc_fr': 'oc_FR.ISO8859-1', + 'oc_fr.iso88591': 'oc_FR.ISO8859-1', + 'oc_fr.iso885915': 'oc_FR.ISO8859-15', + 'oc_fr@euro': 'oc_FR.ISO8859-15', + 'or': 'or_IN.UTF-8', + 'pa': 'pa_IN.UTF-8', + 'pa_in': 'pa_IN.UTF-8', + 'pd': 'pd_US.ISO8859-1', + 'pd_de': 'pd_DE.ISO8859-1', + 'pd_de.iso88591': 'pd_DE.ISO8859-1', + 'pd_de.iso885915': 'pd_DE.ISO8859-15', + 'pd_de@euro': 'pd_DE.ISO8859-15', + 'pd_us': 'pd_US.ISO8859-1', + 'pd_us.iso88591': 'pd_US.ISO8859-1', + 'pd_us.iso885915': 'pd_US.ISO8859-15', + 'pd_us@euro': 'pd_US.ISO8859-15', + 'ph': 'ph_PH.ISO8859-1', + 'ph_ph': 'ph_PH.ISO8859-1', + 'ph_ph.iso88591': 'ph_PH.ISO8859-1', + 'pl': 'pl_PL.ISO8859-2', + 'pl_pl': 'pl_PL.ISO8859-2', + 'pl_pl.iso88592': 'pl_PL.ISO8859-2', + 'polish': 'pl_PL.ISO8859-2', + 'portuguese': 'pt_PT.ISO8859-1', + 'portuguese.iso88591': 'pt_PT.ISO8859-1', + 'portuguese_brazil': 'pt_BR.ISO8859-1', + 'portuguese_brazil.8859': 'pt_BR.ISO8859-1', + 'posix': 'C', + 'posix-utf2': 'C', + 'pp': 'pp_AN.ISO8859-1', + 'pp_an': 'pp_AN.ISO8859-1', + 'pp_an.iso88591': 'pp_AN.ISO8859-1', + 'pt': 'pt_PT.ISO8859-1', + 'pt.iso885915': 'pt_PT.ISO8859-15', + 'pt_br': 'pt_BR.ISO8859-1', + 'pt_br.88591': 'pt_BR.ISO8859-1', + 'pt_br.iso88591': 'pt_BR.ISO8859-1', + 'pt_br.iso885915': 'pt_BR.ISO8859-15', + 'pt_br@euro': 'pt_BR.ISO8859-15', + 'pt_pt': 'pt_PT.ISO8859-1', + 'pt_pt.88591': 'pt_PT.ISO8859-1', + 'pt_pt.iso88591': 'pt_PT.ISO8859-1', + 'pt_pt.iso885915': 'pt_PT.ISO8859-15', + 'pt_pt.iso885915@euro': 'pt_PT.ISO8859-15', + 'pt_pt.utf8@euro': 'pt_PT.UTF-8', + 'pt_pt@euro': 'pt_PT.ISO8859-15', + 'ro': 'ro_RO.ISO8859-2', + 'ro_ro': 'ro_RO.ISO8859-2', + 'ro_ro.iso88592': 'ro_RO.ISO8859-2', + 'romanian': 'ro_RO.ISO8859-2', + 'ru': 'ru_RU.UTF-8', + 'ru.koi8r': 'ru_RU.KOI8-R', + 'ru_ru': 'ru_RU.UTF-8', + 'ru_ru.cp1251': 'ru_RU.CP1251', + 'ru_ru.iso88595': 'ru_RU.ISO8859-5', + 'ru_ru.koi8r': 'ru_RU.KOI8-R', + 'ru_ru.microsoftcp1251': 'ru_RU.CP1251', + 'ru_ua': 'ru_UA.KOI8-U', + 'ru_ua.cp1251': 'ru_UA.CP1251', + 'ru_ua.koi8u': 'ru_UA.KOI8-U', + 'ru_ua.microsoftcp1251': 'ru_UA.CP1251', + 'rumanian': 'ro_RO.ISO8859-2', + 'russian': 'ru_RU.ISO8859-5', + 'rw': 'rw_RW.ISO8859-1', + 'rw_rw': 'rw_RW.ISO8859-1', + 'rw_rw.iso88591': 'rw_RW.ISO8859-1', + 'sd': 'sd_IN@devanagari.UTF-8', + 'se_no': 'se_NO.UTF-8', + 'serbocroatian': 'sr_RS.UTF-8@latin', + 'sh': 'sr_RS.UTF-8@latin', + 'sh_ba.iso88592@bosnia': 'sr_CS.ISO8859-2', + 'sh_hr': 'sh_HR.ISO8859-2', + 'sh_hr.iso88592': 'hr_HR.ISO8859-2', + 'sh_sp': 'sr_CS.ISO8859-2', + 'sh_yu': 'sr_RS.UTF-8@latin', + 'si': 'si_LK.UTF-8', + 'si_lk': 'si_LK.UTF-8', + 'sinhala': 'si_LK.UTF-8', + 'sk': 'sk_SK.ISO8859-2', + 'sk_sk': 'sk_SK.ISO8859-2', + 'sk_sk.iso88592': 'sk_SK.ISO8859-2', + 'sl': 'sl_SI.ISO8859-2', + 'sl_cs': 'sl_CS.ISO8859-2', + 'sl_si': 'sl_SI.ISO8859-2', + 'sl_si.iso88592': 'sl_SI.ISO8859-2', + 'slovak': 'sk_SK.ISO8859-2', + 'slovene': 'sl_SI.ISO8859-2', + 'slovenian': 'sl_SI.ISO8859-2', + 'sp': 'sr_CS.ISO8859-5', + 'sp_yu': 'sr_CS.ISO8859-5', + 'spanish': 'es_ES.ISO8859-1', + 'spanish.iso88591': 'es_ES.ISO8859-1', + 'spanish_spain': 'es_ES.ISO8859-1', + 'spanish_spain.8859': 'es_ES.ISO8859-1', + 'sq': 'sq_AL.ISO8859-2', + 'sq_al': 'sq_AL.ISO8859-2', + 'sq_al.iso88592': 'sq_AL.ISO8859-2', + 'sr': 'sr_RS.UTF-8', + 'sr@cyrillic': 'sr_RS.UTF-8', + 'sr@latin': 'sr_RS.UTF-8@latin', + 'sr@latn': 'sr_RS.UTF-8@latin', + 'sr_cs': 'sr_RS.UTF-8', + 'sr_cs.iso88592': 'sr_CS.ISO8859-2', + 'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2', + 'sr_cs.iso88595': 'sr_CS.ISO8859-5', + 'sr_cs.utf8@latn': 'sr_RS.UTF-8@latin', + 'sr_cs@latn': 'sr_RS.UTF-8@latin', + 'sr_me': 'sr_ME.UTF-8', + 'sr_rs': 'sr_RS.UTF-8', + 'sr_rs.utf8@latn': 'sr_RS.UTF-8@latin', + 'sr_rs@latin': 'sr_RS.UTF-8@latin', + 'sr_rs@latn': 'sr_RS.UTF-8@latin', + 'sr_sp': 'sr_CS.ISO8859-2', + 'sr_yu': 'sr_RS.UTF-8@latin', + 'sr_yu.cp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.iso88592': 'sr_CS.ISO8859-2', + 'sr_yu.iso88595': 'sr_CS.ISO8859-5', + 'sr_yu.iso88595@cyrillic': 'sr_CS.ISO8859-5', + 'sr_yu.microsoftcp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.utf8@cyrillic': 'sr_RS.UTF-8', + 'sr_yu@cyrillic': 'sr_RS.UTF-8', + 'ss': 'ss_ZA.ISO8859-1', + 'ss_za': 'ss_ZA.ISO8859-1', + 'ss_za.iso88591': 'ss_ZA.ISO8859-1', + 'st': 'st_ZA.ISO8859-1', + 'st_za': 'st_ZA.ISO8859-1', + 'st_za.iso88591': 'st_ZA.ISO8859-1', + 'sv': 'sv_SE.ISO8859-1', + 'sv.iso885915': 'sv_SE.ISO8859-15', + 'sv_fi': 'sv_FI.ISO8859-1', + 'sv_fi.iso88591': 'sv_FI.ISO8859-1', + 'sv_fi.iso885915': 'sv_FI.ISO8859-15', + 'sv_fi.iso885915@euro': 'sv_FI.ISO8859-15', + 'sv_fi.utf8@euro': 'sv_FI.UTF-8', + 'sv_fi@euro': 'sv_FI.ISO8859-15', + 'sv_se': 'sv_SE.ISO8859-1', + 'sv_se.88591': 'sv_SE.ISO8859-1', + 'sv_se.iso88591': 'sv_SE.ISO8859-1', + 'sv_se.iso885915': 'sv_SE.ISO8859-15', + 'sv_se@euro': 'sv_SE.ISO8859-15', + 'swedish': 'sv_SE.ISO8859-1', + 'swedish.iso88591': 'sv_SE.ISO8859-1', + 'ta': 'ta_IN.TSCII-0', + 'ta_in': 'ta_IN.TSCII-0', + 'ta_in.tscii': 'ta_IN.TSCII-0', + 'ta_in.tscii0': 'ta_IN.TSCII-0', + 'te': 'te_IN.UTF-8', + 'tg': 'tg_TJ.KOI8-C', + 'tg_tj': 'tg_TJ.KOI8-C', + 'tg_tj.koi8c': 'tg_TJ.KOI8-C', + 'th': 'th_TH.ISO8859-11', + 'th_th': 'th_TH.ISO8859-11', + 'th_th.iso885911': 'th_TH.ISO8859-11', + 'th_th.tactis': 'th_TH.TIS620', + 'th_th.tis620': 'th_TH.TIS620', + 'thai': 'th_TH.ISO8859-11', + 'tl': 'tl_PH.ISO8859-1', + 'tl_ph': 'tl_PH.ISO8859-1', + 'tl_ph.iso88591': 'tl_PH.ISO8859-1', + 'tn': 'tn_ZA.ISO8859-15', + 'tn_za': 'tn_ZA.ISO8859-15', + 'tn_za.iso885915': 'tn_ZA.ISO8859-15', + 'tr': 'tr_TR.ISO8859-9', + 'tr_tr': 'tr_TR.ISO8859-9', + 'tr_tr.iso88599': 'tr_TR.ISO8859-9', + 'ts': 'ts_ZA.ISO8859-1', + 'ts_za': 'ts_ZA.ISO8859-1', + 'ts_za.iso88591': 'ts_ZA.ISO8859-1', + 'tt': 'tt_RU.TATAR-CYR', + 'tt_ru': 'tt_RU.TATAR-CYR', + 'tt_ru.koi8c': 'tt_RU.KOI8-C', + 'tt_ru.tatarcyr': 'tt_RU.TATAR-CYR', + 'turkish': 'tr_TR.ISO8859-9', + 'turkish.iso88599': 'tr_TR.ISO8859-9', + 'uk': 'uk_UA.KOI8-U', + 'uk_ua': 'uk_UA.KOI8-U', + 'uk_ua.cp1251': 'uk_UA.CP1251', + 'uk_ua.iso88595': 'uk_UA.ISO8859-5', + 'uk_ua.koi8u': 'uk_UA.KOI8-U', + 'uk_ua.microsoftcp1251': 'uk_UA.CP1251', + 'univ': 'en_US.utf', + 'universal': 'en_US.utf', + 'universal.utf8@ucs4': 'en_US.UTF-8', + 'ur': 'ur_PK.CP1256', + 'ur_pk': 'ur_PK.CP1256', + 'ur_pk.cp1256': 'ur_PK.CP1256', + 'ur_pk.microsoftcp1256': 'ur_PK.CP1256', + 'uz': 'uz_UZ.UTF-8', + 'uz_uz': 'uz_UZ.UTF-8', + 'uz_uz.iso88591': 'uz_UZ.ISO8859-1', + 'uz_uz.utf8@cyrillic': 'uz_UZ.UTF-8', + 'uz_uz@cyrillic': 'uz_UZ.UTF-8', + 've': 've_ZA.UTF-8', + 've_za': 've_ZA.UTF-8', + 'vi': 'vi_VN.TCVN', + 'vi_vn': 'vi_VN.TCVN', + 'vi_vn.tcvn': 'vi_VN.TCVN', + 'vi_vn.tcvn5712': 'vi_VN.TCVN', + 'vi_vn.viscii': 'vi_VN.VISCII', + 'vi_vn.viscii111': 'vi_VN.VISCII', + 'wa': 'wa_BE.ISO8859-1', + 'wa_be': 'wa_BE.ISO8859-1', + 'wa_be.iso88591': 'wa_BE.ISO8859-1', + 'wa_be.iso885915': 'wa_BE.ISO8859-15', + 'wa_be.iso885915@euro': 'wa_BE.ISO8859-15', + 'wa_be@euro': 'wa_BE.ISO8859-15', + 'xh': 'xh_ZA.ISO8859-1', + 'xh_za': 'xh_ZA.ISO8859-1', + 'xh_za.iso88591': 'xh_ZA.ISO8859-1', + 'yi': 'yi_US.CP1255', + 'yi_us': 'yi_US.CP1255', + 'yi_us.cp1255': 'yi_US.CP1255', + 'yi_us.microsoftcp1255': 'yi_US.CP1255', + 'zh': 'zh_CN.eucCN', + 'zh_cn': 'zh_CN.gb2312', + 'zh_cn.big5': 'zh_TW.big5', + 'zh_cn.euc': 'zh_CN.eucCN', + 'zh_cn.gb18030': 'zh_CN.gb18030', + 'zh_cn.gb2312': 'zh_CN.gb2312', + 'zh_cn.gbk': 'zh_CN.gbk', + 'zh_hk': 'zh_HK.big5hkscs', + 'zh_hk.big5': 'zh_HK.big5', + 'zh_hk.big5hk': 'zh_HK.big5hkscs', + 'zh_hk.big5hkscs': 'zh_HK.big5hkscs', + 'zh_tw': 'zh_TW.big5', + 'zh_tw.big5': 'zh_TW.big5', + 'zh_tw.euc': 'zh_TW.eucTW', + 'zh_tw.euctw': 'zh_TW.eucTW', + 'zu': 'zu_ZA.ISO8859-1', + 'zu_za': 'zu_ZA.ISO8859-1', + 'zu_za.iso88591': 'zu_ZA.ISO8859-1', +} + +# +# This maps Windows language identifiers to locale strings. +# +# This list has been updated from +# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_238z.asp +# to include every locale up to Windows Vista. +# +# NOTE: this mapping is incomplete. If your language is missing, please +# submit a bug report to the Python bug tracker at http://bugs.python.org/ +# Make sure you include the missing language identifier and the suggested +# locale code. +# + +windows_locale = { + 0x0436: "af_ZA", # Afrikaans + 0x041c: "sq_AL", # Albanian + 0x0484: "gsw_FR",# Alsatian - France + 0x045e: "am_ET", # Amharic - Ethiopia + 0x0401: "ar_SA", # Arabic - Saudi Arabia + 0x0801: "ar_IQ", # Arabic - Iraq + 0x0c01: "ar_EG", # Arabic - Egypt + 0x1001: "ar_LY", # Arabic - Libya + 0x1401: "ar_DZ", # Arabic - Algeria + 0x1801: "ar_MA", # Arabic - Morocco + 0x1c01: "ar_TN", # Arabic - Tunisia + 0x2001: "ar_OM", # Arabic - Oman + 0x2401: "ar_YE", # Arabic - Yemen + 0x2801: "ar_SY", # Arabic - Syria + 0x2c01: "ar_JO", # Arabic - Jordan + 0x3001: "ar_LB", # Arabic - Lebanon + 0x3401: "ar_KW", # Arabic - Kuwait + 0x3801: "ar_AE", # Arabic - United Arab Emirates + 0x3c01: "ar_BH", # Arabic - Bahrain + 0x4001: "ar_QA", # Arabic - Qatar + 0x042b: "hy_AM", # Armenian + 0x044d: "as_IN", # Assamese - India + 0x042c: "az_AZ", # Azeri - Latin + 0x082c: "az_AZ", # Azeri - Cyrillic + 0x046d: "ba_RU", # Bashkir + 0x042d: "eu_ES", # Basque - Russia + 0x0423: "be_BY", # Belarusian + 0x0445: "bn_IN", # Begali + 0x201a: "bs_BA", # Bosnian - Cyrillic + 0x141a: "bs_BA", # Bosnian - Latin + 0x047e: "br_FR", # Breton - France + 0x0402: "bg_BG", # Bulgarian +# 0x0455: "my_MM", # Burmese - Not supported + 0x0403: "ca_ES", # Catalan + 0x0004: "zh_CHS",# Chinese - Simplified + 0x0404: "zh_TW", # Chinese - Taiwan + 0x0804: "zh_CN", # Chinese - PRC + 0x0c04: "zh_HK", # Chinese - Hong Kong S.A.R. + 0x1004: "zh_SG", # Chinese - Singapore + 0x1404: "zh_MO", # Chinese - Macao S.A.R. + 0x7c04: "zh_CHT",# Chinese - Traditional + 0x0483: "co_FR", # Corsican - France + 0x041a: "hr_HR", # Croatian + 0x101a: "hr_BA", # Croatian - Bosnia + 0x0405: "cs_CZ", # Czech + 0x0406: "da_DK", # Danish + 0x048c: "gbz_AF",# Dari - Afghanistan + 0x0465: "div_MV",# Divehi - Maldives + 0x0413: "nl_NL", # Dutch - The Netherlands + 0x0813: "nl_BE", # Dutch - Belgium + 0x0409: "en_US", # English - United States + 0x0809: "en_GB", # English - United Kingdom + 0x0c09: "en_AU", # English - Australia + 0x1009: "en_CA", # English - Canada + 0x1409: "en_NZ", # English - New Zealand + 0x1809: "en_IE", # English - Ireland + 0x1c09: "en_ZA", # English - South Africa + 0x2009: "en_JA", # English - Jamaica + 0x2409: "en_CB", # English - Carribbean + 0x2809: "en_BZ", # English - Belize + 0x2c09: "en_TT", # English - Trinidad + 0x3009: "en_ZW", # English - Zimbabwe + 0x3409: "en_PH", # English - Philippines + 0x4009: "en_IN", # English - India + 0x4409: "en_MY", # English - Malaysia + 0x4809: "en_IN", # English - Singapore + 0x0425: "et_EE", # Estonian + 0x0438: "fo_FO", # Faroese + 0x0464: "fil_PH",# Filipino + 0x040b: "fi_FI", # Finnish + 0x040c: "fr_FR", # French - France + 0x080c: "fr_BE", # French - Belgium + 0x0c0c: "fr_CA", # French - Canada + 0x100c: "fr_CH", # French - Switzerland + 0x140c: "fr_LU", # French - Luxembourg + 0x180c: "fr_MC", # French - Monaco + 0x0462: "fy_NL", # Frisian - Netherlands + 0x0456: "gl_ES", # Galician + 0x0437: "ka_GE", # Georgian + 0x0407: "de_DE", # German - Germany + 0x0807: "de_CH", # German - Switzerland + 0x0c07: "de_AT", # German - Austria + 0x1007: "de_LU", # German - Luxembourg + 0x1407: "de_LI", # German - Liechtenstein + 0x0408: "el_GR", # Greek + 0x046f: "kl_GL", # Greenlandic - Greenland + 0x0447: "gu_IN", # Gujarati + 0x0468: "ha_NG", # Hausa - Latin + 0x040d: "he_IL", # Hebrew + 0x0439: "hi_IN", # Hindi + 0x040e: "hu_HU", # Hungarian + 0x040f: "is_IS", # Icelandic + 0x0421: "id_ID", # Indonesian + 0x045d: "iu_CA", # Inuktitut - Syllabics + 0x085d: "iu_CA", # Inuktitut - Latin + 0x083c: "ga_IE", # Irish - Ireland + 0x0410: "it_IT", # Italian - Italy + 0x0810: "it_CH", # Italian - Switzerland + 0x0411: "ja_JP", # Japanese + 0x044b: "kn_IN", # Kannada - India + 0x043f: "kk_KZ", # Kazakh + 0x0453: "kh_KH", # Khmer - Cambodia + 0x0486: "qut_GT",# K'iche - Guatemala + 0x0487: "rw_RW", # Kinyarwanda - Rwanda + 0x0457: "kok_IN",# Konkani + 0x0412: "ko_KR", # Korean + 0x0440: "ky_KG", # Kyrgyz + 0x0454: "lo_LA", # Lao - Lao PDR + 0x0426: "lv_LV", # Latvian + 0x0427: "lt_LT", # Lithuanian + 0x082e: "dsb_DE",# Lower Sorbian - Germany + 0x046e: "lb_LU", # Luxembourgish + 0x042f: "mk_MK", # FYROM Macedonian + 0x043e: "ms_MY", # Malay - Malaysia + 0x083e: "ms_BN", # Malay - Brunei Darussalam + 0x044c: "ml_IN", # Malayalam - India + 0x043a: "mt_MT", # Maltese + 0x0481: "mi_NZ", # Maori + 0x047a: "arn_CL",# Mapudungun + 0x044e: "mr_IN", # Marathi + 0x047c: "moh_CA",# Mohawk - Canada + 0x0450: "mn_MN", # Mongolian - Cyrillic + 0x0850: "mn_CN", # Mongolian - PRC + 0x0461: "ne_NP", # Nepali + 0x0414: "nb_NO", # Norwegian - Bokmal + 0x0814: "nn_NO", # Norwegian - Nynorsk + 0x0482: "oc_FR", # Occitan - France + 0x0448: "or_IN", # Oriya - India + 0x0463: "ps_AF", # Pashto - Afghanistan + 0x0429: "fa_IR", # Persian + 0x0415: "pl_PL", # Polish + 0x0416: "pt_BR", # Portuguese - Brazil + 0x0816: "pt_PT", # Portuguese - Portugal + 0x0446: "pa_IN", # Punjabi + 0x046b: "quz_BO",# Quechua (Bolivia) + 0x086b: "quz_EC",# Quechua (Ecuador) + 0x0c6b: "quz_PE",# Quechua (Peru) + 0x0418: "ro_RO", # Romanian - Romania + 0x0417: "rm_CH", # Romansh + 0x0419: "ru_RU", # Russian + 0x243b: "smn_FI",# Sami Finland + 0x103b: "smj_NO",# Sami Norway + 0x143b: "smj_SE",# Sami Sweden + 0x043b: "se_NO", # Sami Northern Norway + 0x083b: "se_SE", # Sami Northern Sweden + 0x0c3b: "se_FI", # Sami Northern Finland + 0x203b: "sms_FI",# Sami Skolt + 0x183b: "sma_NO",# Sami Southern Norway + 0x1c3b: "sma_SE",# Sami Southern Sweden + 0x044f: "sa_IN", # Sanskrit + 0x0c1a: "sr_SP", # Serbian - Cyrillic + 0x1c1a: "sr_BA", # Serbian - Bosnia Cyrillic + 0x081a: "sr_SP", # Serbian - Latin + 0x181a: "sr_BA", # Serbian - Bosnia Latin + 0x045b: "si_LK", # Sinhala - Sri Lanka + 0x046c: "ns_ZA", # Northern Sotho + 0x0432: "tn_ZA", # Setswana - Southern Africa + 0x041b: "sk_SK", # Slovak + 0x0424: "sl_SI", # Slovenian + 0x040a: "es_ES", # Spanish - Spain + 0x080a: "es_MX", # Spanish - Mexico + 0x0c0a: "es_ES", # Spanish - Spain (Modern) + 0x100a: "es_GT", # Spanish - Guatemala + 0x140a: "es_CR", # Spanish - Costa Rica + 0x180a: "es_PA", # Spanish - Panama + 0x1c0a: "es_DO", # Spanish - Dominican Republic + 0x200a: "es_VE", # Spanish - Venezuela + 0x240a: "es_CO", # Spanish - Colombia + 0x280a: "es_PE", # Spanish - Peru + 0x2c0a: "es_AR", # Spanish - Argentina + 0x300a: "es_EC", # Spanish - Ecuador + 0x340a: "es_CL", # Spanish - Chile + 0x380a: "es_UR", # Spanish - Uruguay + 0x3c0a: "es_PY", # Spanish - Paraguay + 0x400a: "es_BO", # Spanish - Bolivia + 0x440a: "es_SV", # Spanish - El Salvador + 0x480a: "es_HN", # Spanish - Honduras + 0x4c0a: "es_NI", # Spanish - Nicaragua + 0x500a: "es_PR", # Spanish - Puerto Rico + 0x540a: "es_US", # Spanish - United States +# 0x0430: "", # Sutu - Not supported + 0x0441: "sw_KE", # Swahili + 0x041d: "sv_SE", # Swedish - Sweden + 0x081d: "sv_FI", # Swedish - Finland + 0x045a: "syr_SY",# Syriac + 0x0428: "tg_TJ", # Tajik - Cyrillic + 0x085f: "tmz_DZ",# Tamazight - Latin + 0x0449: "ta_IN", # Tamil + 0x0444: "tt_RU", # Tatar + 0x044a: "te_IN", # Telugu + 0x041e: "th_TH", # Thai + 0x0851: "bo_BT", # Tibetan - Bhutan + 0x0451: "bo_CN", # Tibetan - PRC + 0x041f: "tr_TR", # Turkish + 0x0442: "tk_TM", # Turkmen - Cyrillic + 0x0480: "ug_CN", # Uighur - Arabic + 0x0422: "uk_UA", # Ukrainian + 0x042e: "wen_DE",# Upper Sorbian - Germany + 0x0420: "ur_PK", # Urdu + 0x0820: "ur_IN", # Urdu - India + 0x0443: "uz_UZ", # Uzbek - Latin + 0x0843: "uz_UZ", # Uzbek - Cyrillic + 0x042a: "vi_VN", # Vietnamese + 0x0452: "cy_GB", # Welsh + 0x0488: "wo_SN", # Wolof - Senegal + 0x0434: "xh_ZA", # Xhosa - South Africa + 0x0485: "sah_RU",# Yakut - Cyrillic + 0x0478: "ii_CN", # Yi - PRC + 0x046a: "yo_NG", # Yoruba - Nigeria + 0x0435: "zu_ZA", # Zulu +} + +def _print_locale(): + + """ Test function. + """ + categories = {} + def _init_categories(categories=categories): + for k,v in globals().items(): + if k[:3] == 'LC_': + categories[k] = v + _init_categories() + del categories['LC_ALL'] + + print 'Locale defaults as determined by getdefaultlocale():' + print '-'*72 + lang, enc = getdefaultlocale() + print 'Language: ', lang or '(undefined)' + print 'Encoding: ', enc or '(undefined)' + print + + print 'Locale settings on startup:' + print '-'*72 + for name,category in categories.items(): + print name, '...' + lang, enc = getlocale(category) + print ' Language: ', lang or '(undefined)' + print ' Encoding: ', enc or '(undefined)' + print + + print + print 'Locale settings after calling resetlocale():' + print '-'*72 + resetlocale() + for name,category in categories.items(): + print name, '...' + lang, enc = getlocale(category) + print ' Language: ', lang or '(undefined)' + print ' Encoding: ', enc or '(undefined)' + print + + try: + setlocale(LC_ALL, "") + except: + print 'NOTE:' + print 'setlocale(LC_ALL, "") does not support the default locale' + print 'given in the OS environment variables.' + else: + print + print 'Locale settings after calling setlocale(LC_ALL, ""):' + print '-'*72 + for name,category in categories.items(): + print name, '...' + lang, enc = getlocale(category) + print ' Language: ', lang or '(undefined)' + print ' Encoding: ', enc or '(undefined)' + print + +### + +try: + LC_MESSAGES +except NameError: + pass +else: + __all__.append("LC_MESSAGES") + +if __name__=='__main__': + print 'Locale aliasing:' + print + _print_locale() + print + print 'Number formatting:' + print + _test() diff --git a/src/main/resources/PythonLibs/logging/__init__.py b/src/main/resources/PythonLibs/logging/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1a622a3d074778eba4a8e105f165161975834e3c --- /dev/null +++ b/src/main/resources/PythonLibs/logging/__init__.py @@ -0,0 +1,1726 @@ +# Copyright 2001-2012 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-2012 Vinay Sajip. All Rights Reserved. + +To use, simply 'import logging' and log away! +""" + +import sys, os, time, cStringIO, traceback, warnings, weakref + +__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', 'warn', 'warning'] + +try: + import codecs +except ImportError: + codecs = None + +try: + import thread + import threading +except ImportError: + thread = None + +__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>" +__status__ = "production" +__version__ = "0.5.1.2" +__date__ = "07 February 2010" + +#--------------------------------------------------------------------------- +# Miscellaneous module data +#--------------------------------------------------------------------------- +try: + unicode + _unicode = True +except NameError: + _unicode = False + +# +# _srcfile is used when walking the stack to check when we've got the first +# caller stack frame. +# +if hasattr(sys, 'frozen'): #support for py2exe + _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:]) +elif __file__[-4:].lower() in ['.pyc', '.pyo']: + _srcfile = __file__[:-4] + '.py' +else: + _srcfile = __file__ +_srcfile = os.path.normcase(_srcfile) + +# next bit filched from 1.5.2's inspect.py +def currentframe(): + """Return the frame object for the caller's stack frame.""" + try: + raise Exception + except: + return sys.exc_info()[2].tb_frame.f_back + +if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3) +# done filching + +# _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. +#if not hasattr(sys, "_getframe"): +# _srcfile = None + +# +#_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 = 1 + +# +# If you don't want threading information in the log, set this to zero +# +logThreads = 1 + +# +# If you don't want multiprocessing information in the log, set this to zero +# +logMultiprocessing = 1 + +# +# If you don't want process information in the log, set this to zero +# +logProcesses = 1 + +#--------------------------------------------------------------------------- +# 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 + +_levelNames = { + CRITICAL : 'CRITICAL', + ERROR : 'ERROR', + WARNING : 'WARNING', + INFO : 'INFO', + DEBUG : 'DEBUG', + NOTSET : 'NOTSET', + 'CRITICAL' : CRITICAL, + '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. + """ + return _levelNames.get(level, ("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... + _levelNames[level] = levelName + _levelNames[levelName] = level + finally: + _releaseLock() + +def _checkLevel(level): + if isinstance(level, (int, long)): + rv = level + elif str(level) == level: + if level not in _levelNames: + raise ValueError("Unknown level: %r" % level) + rv = _levelNames[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 thread: + _lock = threading.RLock() +else: + _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): + """ + 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.warn('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. + if args and len(args) == 1 and isinstance(args[0], dict) 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.lineno = lineno + self.funcName = func + self.created = ct + self.msecs = (ct - long(ct)) * 1000 + self.relativeCreated = (self.created - _startTime) * 1000 + if logThreads and thread: + self.thread = thread.get_ident() + self.threadName = threading.current_thread().name + else: + self.thread = None + self.threadName = None + if not logMultiprocessing: + 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 StandardError: + 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) + + def getMessage(self): + """ + Return the message for this LogRecord. + + Return the message for this LogRecord after merging any user-supplied + arguments with the message. + """ + if not _unicode: #if no unicode support... + msg = str(self.msg) + else: + msg = self.msg + if not isinstance(msg, basestring): + try: + msg = str(self.msg) + except UnicodeError: + msg = self.msg #Defer encoding till later + if self.args: + msg = msg % self.args + return msg + +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 = LogRecord(None, None, "", 0, "", (), None, None) + rv.__dict__.update(dict) + return rv + +#--------------------------------------------------------------------------- +# Formatter classes and functions +#--------------------------------------------------------------------------- + +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 + default value of "%s(message)\\n" 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): + """ + 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 omitted, you get the ISO8601 format). + """ + if fmt: + self._fmt = fmt + else: + self._fmt = "%(message)s" + self.datefmt = datefmt + + 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, the ISO8601 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("%Y-%m-%d %H:%M:%S", ct) + s = "%s,%03d" % (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 = cStringIO.StringIO() + traceback.print_exception(ei[0], ei[1], ei[2], 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._fmt.find("%(asctime)") >= 0 + + 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._fmt % record.__dict__ + 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" + try: + s = s + record.exc_text + except UnicodeError: + # Sometimes filenames have non-ASCII chars, which can lead + # to errors when s is Unicode and record.exc_text is str + # See issue 8924. + # We also use replace for when there are multiple + # encodings, e.g. UTF-8 for the filesystem and latin-1 + # for a script. See issue 13232. + s = s + record.exc_text.decode(sys.getfilesystemencoding(), + 'replace') + 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 1 + elif self.name == record.name: + return 1 + elif record.name.find(self.name, 0, self.nlen) != 0: + return 0 + 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. + """ + rv = 1 + for f in self.filters: + if not f.filter(record): + rv = 0 + 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. If _acquireLock is None, assume this is the case and do + # nothing. + if (_acquireLock is not None and _handlerList is not None and + _releaseLock is not None): + _acquireLock() + try: + if wr in _handlerList: + _handlerList.remove(wr) + finally: + _releaseLock() + +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 thread: + self.lock = threading.RLock() + else: + 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. + """ + 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 + ei = sys.exc_info() + try: + traceback.print_exception(ei[0], ei[1], ei[2], + None, sys.stderr) + sys.stderr.write('Logged from file %s, line %s\n' % ( + record.filename, record.lineno)) + except IOError: + pass # see issue 5971 + finally: + del ei + +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. + """ + + 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 + fs = "%s\n" + if not _unicode: #if no unicode support... + stream.write(fs % msg) + else: + try: + if (isinstance(msg, unicode) and + getattr(stream, 'encoding', None)): + ufs = fs.decode(stream.encoding) + try: + stream.write(ufs % msg) + except UnicodeEncodeError: + #Printing to terminals sometimes fails. For example, + #with an encoding of 'cp1251', the above write will + #work if written to a stream opened or wrapped by + #the codecs module, but fail when writing to a + #terminal even when the codepage is set to cp1251. + #An extra encoding step seems to be needed. + stream.write((ufs % msg).encode(stream.encoding)) + else: + stream.write(fs % msg) + except UnicodeError: + stream.write(fs % msg.encode("UTF-8")) + self.flush() + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + +class FileHandler(StreamHandler): + """ + A handler class which writes formatted logging records to disk files. + """ + def __init__(self, filename, mode='a', encoding=None, delay=0): + """ + Open the specified file and use it as the stream for logging. + """ + #keep the absolute path, otherwise derived classes which use this + #may come a cropper when the current directory changes + if codecs is None: + encoding = None + self.baseFilename = os.path.abspath(filename) + self.mode = mode + self.encoding = encoding + 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: + if self.stream: + self.flush() + if hasattr(self.stream, "close"): + self.stream.close() + StreamHandler.close(self) + self.stream = None + finally: + self.release() + + def _open(self): + """ + Open the current base file with the (original) mode and encoding. + Return the resulting stream. + """ + if self.encoding is None: + stream = open(self.baseFilename, self.mode) + else: + stream = codecs.open(self.baseFilename, self.mode, self.encoding) + return stream + + 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) + +#--------------------------------------------------------------------------- +# 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.loggers = [alogger] + self.loggerMap = { alogger : None } + + def append(self, alogger): + """ + Add the specified logger as a child of this placeholder. + """ + #if alogger not in self.loggers: + if alogger not in self.loggerMap: + #self.loggers.append(alogger) + self.loggerMap[alogger] = None + +# +# Determine which class to use when instantiating loggers. +# +_loggerClass = None + +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 = 0 + self.loggerDict = {} + self.loggerClass = 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, basestring): + raise TypeError('A logger name must be string or Unicode') + if isinstance(name, unicode): + name = name.encode('utf-8') + _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 _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 = 1 + self.handlers = [] + self.disabled = 0 + + def setLevel(self, level): + """ + Set the logging level of this logger. + """ + 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) + + warn = warning + + 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, **kwargs): + """ + Convenience method for logging an ERROR with exception information. + """ + kwargs['exc_info'] = 1 + self.error(msg, *args, **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): + """ + 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)" + while hasattr(f, "f_code"): + co = f.f_code + filename = os.path.normcase(co.co_filename) + if filename == _srcfile: + f = f.f_back + continue + rv = (co.co_filename, f.f_lineno, co.co_name) + break + return rv + + def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None): + """ + A factory method which can be overridden in subclasses to create + specialized LogRecords. + """ + rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func) + 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): + """ + Low-level logging routine which creates a LogRecord and then calls + all the handlers of this logger to handle the record. + """ + 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 = self.findCaller() + except ValueError: + fn, lno, func = "(unknown file)", 0, "(unknown function)" + else: + fn, lno, func = "(unknown file)", 0, "(unknown function)" + if exc_info: + if not isinstance(exc_info, tuple): + exc_info = sys.exc_info() + record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra) + 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 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) and raiseExceptions and not self.manager.emittedNoHandlerWarning: + sys.stderr.write("No handlers could be found for logger" + " \"%s\"\n" % self.name) + self.manager.emittedNoHandlerWarning = 1 + + 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 0 + 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) + +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 + + def debug(self, msg, *args, **kwargs): + """ + Delegate a debug call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.debug(msg, *args, **kwargs) + + def info(self, msg, *args, **kwargs): + """ + Delegate an info call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.info(msg, *args, **kwargs) + + def warning(self, msg, *args, **kwargs): + """ + Delegate a warning call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.warning(msg, *args, **kwargs) + + def error(self, msg, *args, **kwargs): + """ + Delegate an error call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.error(msg, *args, **kwargs) + + def exception(self, msg, *args, **kwargs): + """ + Delegate an exception call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + kwargs["exc_info"] = 1 + self.logger.error(msg, *args, **kwargs) + + def critical(self, msg, *args, **kwargs): + """ + Delegate a critical call to the underlying logger, after adding + contextual information from this adapter instance. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.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. + """ + msg, kwargs = self.process(msg, kwargs) + self.logger.log(level, msg, *args, **kwargs) + + def isEnabledFor(self, level): + """ + See if the underlying logger is enabled for the specified level. + """ + return self.logger.isEnabledFor(level) + +root = RootLogger(WARNING) +Logger.root = root +Logger.manager = Manager(Logger.root) + +#--------------------------------------------------------------------------- +# Configuration classes and functions +#--------------------------------------------------------------------------- + +BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" + +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. + 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. + + 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. + """ + # Add thread safety in case someone mistakenly calls + # basicConfig() from multiple threads + _acquireLock() + try: + if len(root.handlers) == 0: + filename = kwargs.get("filename") + if filename: + mode = kwargs.get("filemode", 'a') + hdlr = FileHandler(filename, mode) + else: + stream = kwargs.get("stream") + hdlr = StreamHandler(stream) + fs = kwargs.get("format", BASIC_FORMAT) + dfs = kwargs.get("datefmt", None) + fmt = Formatter(fs, dfs) + hdlr.setFormatter(fmt) + root.addHandler(hdlr) + level = kwargs.get("level") + if level is not None: + root.setLevel(level) + 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 getRootLogger(): +# """ +# Return the root logger. +# +# Note that getLogger('') now does the same thing, so this function is +# deprecated and may disappear in the future. +# """ +# return root + +def critical(msg, *args, **kwargs): + """ + Log a message with severity 'CRITICAL' on the root logger. + """ + 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 len(root.handlers) == 0: + basicConfig() + root.error(msg, *args, **kwargs) + +def exception(msg, *args, **kwargs): + """ + Log a message with severity 'ERROR' on the root logger, + with exception information. + """ + kwargs['exc_info'] = 1 + error(msg, *args, **kwargs) + +def warning(msg, *args, **kwargs): + """ + Log a message with severity 'WARNING' on the root logger. + """ + if len(root.handlers) == 0: + basicConfig() + root.warning(msg, *args, **kwargs) + +warn = warning + +def info(msg, *args, **kwargs): + """ + Log a message with severity 'INFO' on the root logger. + """ + 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 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 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 (IOError, 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: + 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): + pass + + def emit(self, record): + pass + + 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/src/main/resources/PythonLibs/logging/config.py b/src/main/resources/PythonLibs/logging/config.py new file mode 100644 index 0000000000000000000000000000000000000000..6840590709f3dc536219a7e9b4e9a37a16ff63db --- /dev/null +++ b/src/main/resources/PythonLibs/logging/config.py @@ -0,0 +1,909 @@ +# Copyright 2001-2010 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. + +""" +Configuration functions for the logging package for Python. The core package +is based on PEP 282 and comments thereto in comp.lang.python, and influenced +by Apache's log4j system. + +Copyright (C) 2001-2010 Vinay Sajip. All Rights Reserved. + +To use, simply 'import logging' and log away! +""" + +import sys, logging, logging.handlers, socket, struct, os, traceback, re +import types, cStringIO + +try: + import thread + import threading +except ImportError: + thread = None + +from SocketServer import ThreadingTCPServer, StreamRequestHandler + + +DEFAULT_LOGGING_CONFIG_PORT = 9030 + +if sys.platform == "win32": + RESET_ERROR = 10054 #WSAECONNRESET +else: + RESET_ERROR = 104 #ECONNRESET + +# +# The following code implements a socket listener for on-the-fly +# reconfiguration of logging. +# +# _listener holds the server object doing the listening +_listener = None + +def fileConfig(fname, defaults=None, disable_existing_loggers=True): + """ + Read the logging configuration from a ConfigParser-format file. + + This can be called several times from an application, allowing an end user + the ability to select from various pre-canned configurations (if the + developer provides a mechanism to present the choices and load the chosen + configuration). + """ + import ConfigParser + + cp = ConfigParser.ConfigParser(defaults) + if hasattr(fname, 'readline'): + cp.readfp(fname) + else: + cp.read(fname) + + formatters = _create_formatters(cp) + + # critical section + logging._acquireLock() + try: + logging._handlers.clear() + del logging._handlerList[:] + # Handlers add themselves to logging._handlers + handlers = _install_handlers(cp, formatters) + _install_loggers(cp, handlers, disable_existing_loggers) + finally: + logging._releaseLock() + + +def _resolve(name): + """Resolve a dotted name to a global object.""" + name = name.split('.') + used = name.pop(0) + found = __import__(used) + for n in name: + used = used + '.' + n + try: + found = getattr(found, n) + except AttributeError: + __import__(used) + found = getattr(found, n) + return found + +def _strip_spaces(alist): + return map(lambda x: x.strip(), alist) + +def _encoded(s): + return s if isinstance(s, str) else s.encode('utf-8') + +def _create_formatters(cp): + """Create and return formatters""" + flist = cp.get("formatters", "keys") + if not len(flist): + return {} + flist = flist.split(",") + flist = _strip_spaces(flist) + formatters = {} + for form in flist: + sectname = "formatter_%s" % form + opts = cp.options(sectname) + if "format" in opts: + fs = cp.get(sectname, "format", 1) + else: + fs = None + if "datefmt" in opts: + dfs = cp.get(sectname, "datefmt", 1) + else: + dfs = None + c = logging.Formatter + if "class" in opts: + class_name = cp.get(sectname, "class") + if class_name: + c = _resolve(class_name) + f = c(fs, dfs) + formatters[form] = f + return formatters + + +def _install_handlers(cp, formatters): + """Install and return handlers""" + hlist = cp.get("handlers", "keys") + if not len(hlist): + return {} + hlist = hlist.split(",") + hlist = _strip_spaces(hlist) + handlers = {} + fixups = [] #for inter-handler references + for hand in hlist: + sectname = "handler_%s" % hand + klass = cp.get(sectname, "class") + opts = cp.options(sectname) + if "formatter" in opts: + fmt = cp.get(sectname, "formatter") + else: + fmt = "" + try: + klass = eval(klass, vars(logging)) + except (AttributeError, NameError): + klass = _resolve(klass) + args = cp.get(sectname, "args") + args = eval(args, vars(logging)) + h = klass(*args) + if "level" in opts: + level = cp.get(sectname, "level") + h.setLevel(logging._levelNames[level]) + if len(fmt): + h.setFormatter(formatters[fmt]) + if issubclass(klass, logging.handlers.MemoryHandler): + if "target" in opts: + target = cp.get(sectname,"target") + else: + target = "" + if len(target): #the target handler may not be loaded yet, so keep for later... + fixups.append((h, target)) + handlers[hand] = h + #now all handlers are loaded, fixup inter-handler references... + for h, t in fixups: + h.setTarget(handlers[t]) + return handlers + + +def _install_loggers(cp, handlers, disable_existing_loggers): + """Create and install loggers""" + + # configure the root first + llist = cp.get("loggers", "keys") + llist = llist.split(",") + llist = list(map(lambda x: x.strip(), llist)) + llist.remove("root") + sectname = "logger_root" + root = logging.root + log = root + opts = cp.options(sectname) + if "level" in opts: + level = cp.get(sectname, "level") + log.setLevel(logging._levelNames[level]) + for h in root.handlers[:]: + root.removeHandler(h) + hlist = cp.get(sectname, "handlers") + if len(hlist): + hlist = hlist.split(",") + hlist = _strip_spaces(hlist) + for hand in hlist: + log.addHandler(handlers[hand]) + + #and now the others... + #we don't want to lose the existing loggers, + #since other threads may have pointers to them. + #existing is set to contain all existing loggers, + #and as we go through the new configuration we + #remove any which are configured. At the end, + #what's left in existing is the set of loggers + #which were in the previous configuration but + #which are not in the new configuration. + existing = list(root.manager.loggerDict.keys()) + #The list needs to be sorted so that we can + #avoid disabling child loggers of explicitly + #named loggers. With a sorted list it is easier + #to find the child loggers. + existing.sort() + #We'll keep the list of existing loggers + #which are children of named loggers here... + child_loggers = [] + #now set up the new ones... + for log in llist: + sectname = "logger_%s" % log + qn = cp.get(sectname, "qualname") + opts = cp.options(sectname) + if "propagate" in opts: + propagate = cp.getint(sectname, "propagate") + else: + propagate = 1 + logger = logging.getLogger(qn) + if qn in existing: + i = existing.index(qn) + 1 # start with the entry after qn + prefixed = qn + "." + pflen = len(prefixed) + num_existing = len(existing) + while i < num_existing: + if existing[i][:pflen] == prefixed: + child_loggers.append(existing[i]) + i += 1 + existing.remove(qn) + if "level" in opts: + level = cp.get(sectname, "level") + logger.setLevel(logging._levelNames[level]) + for h in logger.handlers[:]: + logger.removeHandler(h) + logger.propagate = propagate + logger.disabled = 0 + hlist = cp.get(sectname, "handlers") + if len(hlist): + hlist = hlist.split(",") + hlist = _strip_spaces(hlist) + for hand in hlist: + logger.addHandler(handlers[hand]) + + #Disable any old loggers. There's no point deleting + #them as other threads may continue to hold references + #and by disabling them, you stop them doing any logging. + #However, don't disable children of named loggers, as that's + #probably not what was intended by the user. + for log in existing: + logger = root.manager.loggerDict[log] + if log in child_loggers: + logger.level = logging.NOTSET + logger.handlers = [] + logger.propagate = 1 + elif disable_existing_loggers: + logger.disabled = 1 + + + +IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) + + +def valid_ident(s): + m = IDENTIFIER.match(s) + if not m: + raise ValueError('Not a valid Python identifier: %r' % s) + return True + + +# The ConvertingXXX classes are wrappers around standard Python containers, +# and they serve to convert any suitable values in the container. The +# conversion converts base dicts, lists and tuples to their wrapped +# equivalents, whereas strings which match a conversion format are converted +# appropriately. +# +# Each wrapper should have a configurator attribute holding the actual +# configurator to use for conversion. + +class ConvertingDict(dict): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def get(self, key, default=None): + value = dict.get(self, key, default) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + +class ConvertingList(list): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, idx=-1): + value = list.pop(self, idx) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + +class ConvertingTuple(tuple): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + +class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$') + + WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') + DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') + INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + DIGIT_PATTERN = re.compile(r'^\d+$') + + value_converters = { + 'ext' : 'ext_convert', + 'cfg' : 'cfg_convert', + } + + # We might want to use a different one, e.g. importlib + importer = __import__ + + def __init__(self, config): + self.config = ConvertingDict(config) + self.config.configurator = self + + def resolve(self, s): + """ + Resolve strings to objects using standard import and attribute + syntax. + """ + name = s.split('.') + used = name.pop(0) + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v + + def ext_convert(self, value): + """Default converter for the ext:// protocol.""" + return self.resolve(value) + + def cfg_convert(self, value): + """Default converter for the cfg:// protocol.""" + rest = value + m = self.WORD_PATTERN.match(rest) + if m is None: + raise ValueError("Unable to convert %r" % value) + else: + rest = rest[m.end():] + d = self.config[m.groups()[0]] + #print d, rest + while rest: + m = self.DOT_PATTERN.match(rest) + if m: + d = d[m.groups()[0]] + else: + m = self.INDEX_PATTERN.match(rest) + if m: + idx = m.groups()[0] + if not self.DIGIT_PATTERN.match(idx): + d = d[idx] + else: + try: + n = int(idx) # try as number first (most likely) + d = d[n] + except TypeError: + d = d[idx] + if m: + rest = rest[m.end():] + else: + raise ValueError('Unable to convert ' + '%r at %r' % (value, rest)) + #rest should be empty + return d + + def convert(self, value): + """ + Convert values to an appropriate type. dicts, lists and tuples are + replaced by their converting alternatives. Strings are checked to + see if they have a conversion format and are converted if they do. + """ + if not isinstance(value, ConvertingDict) and isinstance(value, dict): + value = ConvertingDict(value) + value.configurator = self + elif not isinstance(value, ConvertingList) and isinstance(value, list): + value = ConvertingList(value) + value.configurator = self + elif not isinstance(value, ConvertingTuple) and\ + isinstance(value, tuple): + value = ConvertingTuple(value) + value.configurator = self + elif isinstance(value, basestring): # str for py3k + m = self.CONVERT_PATTERN.match(value) + if m: + d = m.groupdict() + prefix = d['prefix'] + converter = self.value_converters.get(prefix, None) + if converter: + suffix = d['suffix'] + converter = getattr(self, converter) + value = converter(suffix) + return value + + def configure_custom(self, config): + """Configure an object with a user-supplied factory.""" + c = config.pop('()') + if not hasattr(c, '__call__') and hasattr(types, 'ClassType') and type(c) != types.ClassType: + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + result = c(**kwargs) + if props: + for name, value in props.items(): + setattr(result, name, value) + return result + + def as_tuple(self, value): + """Utility function which converts lists to tuples.""" + if isinstance(value, list): + value = tuple(value) + return value + +class DictConfigurator(BaseConfigurator): + """ + Configure logging using a dictionary-like object to describe the + configuration. + """ + + def configure(self): + """Do the configuration.""" + + config = self.config + if 'version' not in config: + raise ValueError("dictionary doesn't specify a version") + if config['version'] != 1: + raise ValueError("Unsupported version: %s" % config['version']) + incremental = config.pop('incremental', False) + EMPTY_DICT = {} + logging._acquireLock() + try: + if incremental: + handlers = config.get('handlers', EMPTY_DICT) + for name in handlers: + if name not in logging._handlers: + raise ValueError('No handler found with ' + 'name %r' % name) + else: + try: + handler = logging._handlers[name] + handler_config = handlers[name] + level = handler_config.get('level', None) + if level: + handler.setLevel(logging._checkLevel(level)) + except StandardError, e: + raise ValueError('Unable to configure handler ' + '%r: %s' % (name, e)) + loggers = config.get('loggers', EMPTY_DICT) + for name in loggers: + try: + self.configure_logger(name, loggers[name], True) + except StandardError, e: + raise ValueError('Unable to configure logger ' + '%r: %s' % (name, e)) + root = config.get('root', None) + if root: + try: + self.configure_root(root, True) + except StandardError, e: + raise ValueError('Unable to configure root ' + 'logger: %s' % e) + else: + disable_existing = config.pop('disable_existing_loggers', True) + + logging._handlers.clear() + del logging._handlerList[:] + + # Do formatters first - they don't refer to anything else + formatters = config.get('formatters', EMPTY_DICT) + for name in formatters: + try: + formatters[name] = self.configure_formatter( + formatters[name]) + except StandardError, e: + raise ValueError('Unable to configure ' + 'formatter %r: %s' % (name, e)) + # Next, do filters - they don't refer to anything else, either + filters = config.get('filters', EMPTY_DICT) + for name in filters: + try: + filters[name] = self.configure_filter(filters[name]) + except StandardError, e: + raise ValueError('Unable to configure ' + 'filter %r: %s' % (name, e)) + + # Next, do handlers - they refer to formatters and filters + # As handlers can refer to other handlers, sort the keys + # to allow a deterministic order of configuration + handlers = config.get('handlers', EMPTY_DICT) + for name in sorted(handlers): + try: + handler = self.configure_handler(handlers[name]) + handler.name = name + handlers[name] = handler + except StandardError, e: + raise ValueError('Unable to configure handler ' + '%r: %s' % (name, e)) + # Next, do loggers - they refer to handlers and filters + + #we don't want to lose the existing loggers, + #since other threads may have pointers to them. + #existing is set to contain all existing loggers, + #and as we go through the new configuration we + #remove any which are configured. At the end, + #what's left in existing is the set of loggers + #which were in the previous configuration but + #which are not in the new configuration. + root = logging.root + existing = root.manager.loggerDict.keys() + #The list needs to be sorted so that we can + #avoid disabling child loggers of explicitly + #named loggers. With a sorted list it is easier + #to find the child loggers. + existing.sort() + #We'll keep the list of existing loggers + #which are children of named loggers here... + child_loggers = [] + #now set up the new ones... + loggers = config.get('loggers', EMPTY_DICT) + for name in loggers: + name = _encoded(name) + if name in existing: + i = existing.index(name) + prefixed = name + "." + pflen = len(prefixed) + num_existing = len(existing) + i = i + 1 # look at the entry after name + while (i < num_existing) and\ + (existing[i][:pflen] == prefixed): + child_loggers.append(existing[i]) + i = i + 1 + existing.remove(name) + try: + self.configure_logger(name, loggers[name]) + except StandardError, e: + raise ValueError('Unable to configure logger ' + '%r: %s' % (name, e)) + + #Disable any old loggers. There's no point deleting + #them as other threads may continue to hold references + #and by disabling them, you stop them doing any logging. + #However, don't disable children of named loggers, as that's + #probably not what was intended by the user. + for log in existing: + logger = root.manager.loggerDict[log] + if log in child_loggers: + logger.level = logging.NOTSET + logger.handlers = [] + logger.propagate = True + elif disable_existing: + logger.disabled = True + + # And finally, do the root logger + root = config.get('root', None) + if root: + try: + self.configure_root(root) + except StandardError, e: + raise ValueError('Unable to configure root ' + 'logger: %s' % e) + finally: + logging._releaseLock() + + def configure_formatter(self, config): + """Configure a formatter from a dictionary.""" + if '()' in config: + factory = config['()'] # for use in exception handler + try: + result = self.configure_custom(config) + except TypeError, te: + if "'format'" not in str(te): + raise + #Name of parameter changed from fmt to format. + #Retry with old name. + #This is so that code can be used with older Python versions + #(e.g. by Django) + config['fmt'] = config.pop('format') + config['()'] = factory + result = self.configure_custom(config) + else: + fmt = config.get('format', None) + dfmt = config.get('datefmt', None) + result = logging.Formatter(fmt, dfmt) + return result + + def configure_filter(self, config): + """Configure a filter from a dictionary.""" + if '()' in config: + result = self.configure_custom(config) + else: + name = config.get('name', '') + result = logging.Filter(name) + return result + + def add_filters(self, filterer, filters): + """Add filters to a filterer from a list of names.""" + for f in filters: + try: + filterer.addFilter(self.config['filters'][f]) + except StandardError, e: + raise ValueError('Unable to add filter %r: %s' % (f, e)) + + def configure_handler(self, config): + """Configure a handler from a dictionary.""" + formatter = config.pop('formatter', None) + if formatter: + try: + formatter = self.config['formatters'][formatter] + except StandardError, e: + raise ValueError('Unable to set formatter ' + '%r: %s' % (formatter, e)) + level = config.pop('level', None) + filters = config.pop('filters', None) + if '()' in config: + c = config.pop('()') + if not hasattr(c, '__call__') and hasattr(types, 'ClassType') and type(c) != types.ClassType: + c = self.resolve(c) + factory = c + else: + klass = self.resolve(config.pop('class')) + #Special case for handler which refers to another handler + if issubclass(klass, logging.handlers.MemoryHandler) and\ + 'target' in config: + try: + config['target'] = self.config['handlers'][config['target']] + except StandardError, e: + raise ValueError('Unable to set target handler ' + '%r: %s' % (config['target'], e)) + elif issubclass(klass, logging.handlers.SMTPHandler) and\ + 'mailhost' in config: + config['mailhost'] = self.as_tuple(config['mailhost']) + elif issubclass(klass, logging.handlers.SysLogHandler) and\ + 'address' in config: + config['address'] = self.as_tuple(config['address']) + factory = klass + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + try: + result = factory(**kwargs) + except TypeError, te: + if "'stream'" not in str(te): + raise + #The argument name changed from strm to stream + #Retry with old name. + #This is so that code can be used with older Python versions + #(e.g. by Django) + kwargs['strm'] = kwargs.pop('stream') + result = factory(**kwargs) + if formatter: + result.setFormatter(formatter) + if level is not None: + result.setLevel(logging._checkLevel(level)) + if filters: + self.add_filters(result, filters) + return result + + def add_handlers(self, logger, handlers): + """Add handlers to a logger from a list of names.""" + for h in handlers: + try: + logger.addHandler(self.config['handlers'][h]) + except StandardError, e: + raise ValueError('Unable to add handler %r: %s' % (h, e)) + + def common_logger_config(self, logger, config, incremental=False): + """ + Perform configuration which is common to root and non-root loggers. + """ + level = config.get('level', None) + if level is not None: + logger.setLevel(logging._checkLevel(level)) + if not incremental: + #Remove any existing handlers + for h in logger.handlers[:]: + logger.removeHandler(h) + handlers = config.get('handlers', None) + if handlers: + self.add_handlers(logger, handlers) + filters = config.get('filters', None) + if filters: + self.add_filters(logger, filters) + + def configure_logger(self, name, config, incremental=False): + """Configure a non-root logger from a dictionary.""" + logger = logging.getLogger(name) + self.common_logger_config(logger, config, incremental) + propagate = config.get('propagate', None) + if propagate is not None: + logger.propagate = propagate + + def configure_root(self, config, incremental=False): + """Configure a root logger from a dictionary.""" + root = logging.getLogger() + self.common_logger_config(root, config, incremental) + +dictConfigClass = DictConfigurator + +def dictConfig(config): + """Configure logging using a dictionary.""" + dictConfigClass(config).configure() + + +def listen(port=DEFAULT_LOGGING_CONFIG_PORT): + """ + Start up a socket server on the specified port, and listen for new + configurations. + + These will be sent as a file suitable for processing by fileConfig(). + Returns a Thread object on which you can call start() to start the server, + and which you can join() when appropriate. To stop the server, call + stopListening(). + """ + if not thread: + raise NotImplementedError("listen() needs threading to work") + + class ConfigStreamHandler(StreamRequestHandler): + """ + Handler for a logging configuration request. + + It expects a completely new logging configuration and uses fileConfig + to install it. + """ + def handle(self): + """ + Handle a request. + + Each request is expected to be a 4-byte length, packed using + struct.pack(">L", n), followed by the config file. + Uses fileConfig() to do the grunt work. + """ + import tempfile + try: + conn = self.connection + chunk = conn.recv(4) + if len(chunk) == 4: + slen = struct.unpack(">L", chunk)[0] + chunk = self.connection.recv(slen) + while len(chunk) < slen: + chunk = chunk + conn.recv(slen - len(chunk)) + try: + import json + d =json.loads(chunk) + assert isinstance(d, dict) + dictConfig(d) + except: + #Apply new configuration. + + file = cStringIO.StringIO(chunk) + try: + fileConfig(file) + except (KeyboardInterrupt, SystemExit): + raise + except: + traceback.print_exc() + if self.server.ready: + self.server.ready.set() + except socket.error, e: + if not isinstance(e.args, tuple): + raise + else: + errcode = e.args[0] + if errcode != RESET_ERROR: + raise + + class ConfigSocketReceiver(ThreadingTCPServer): + """ + A simple TCP socket-based logging config receiver. + """ + + allow_reuse_address = 1 + + def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT, + handler=None, ready=None): + ThreadingTCPServer.__init__(self, (host, port), handler) + logging._acquireLock() + self.abort = 0 + logging._releaseLock() + self.timeout = 1 + self.ready = ready + + def serve_until_stopped(self): + if sys.platform.startswith('java'): + from select import cpython_compatible_select as select + else: + from select import select + abort = 0 + while not abort: + rd, wr, ex = select([self.socket.fileno()], + [], [], + self.timeout) + if rd: + self.handle_request() + logging._acquireLock() + abort = self.abort + logging._releaseLock() + self.socket.close() + + class Server(threading.Thread): + + def __init__(self, rcvr, hdlr, port): + super(Server, self).__init__() + self.rcvr = rcvr + self.hdlr = hdlr + self.port = port + self.ready = threading.Event() + + def run(self): + server = self.rcvr(port=self.port, handler=self.hdlr, + ready=self.ready) + if self.port == 0: + self.port = server.server_address[1] + self.ready.set() + global _listener + logging._acquireLock() + _listener = server + logging._releaseLock() + server.serve_until_stopped() + + return Server(ConfigSocketReceiver, ConfigStreamHandler, port) + +def stopListening(): + """ + Stop the listening server which was created with a call to listen(). + """ + global _listener + logging._acquireLock() + try: + if _listener: + _listener.abort = 1 + _listener = None + finally: + logging._releaseLock() diff --git a/src/main/resources/PythonLibs/logging/handlers.py b/src/main/resources/PythonLibs/logging/handlers.py new file mode 100644 index 0000000000000000000000000000000000000000..26dfe4a1d18520c46d86e4d54c84d07e4ba6b83f --- /dev/null +++ b/src/main/resources/PythonLibs/logging/handlers.py @@ -0,0 +1,1198 @@ +# Copyright 2001-2012 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. + +""" +Additional handlers for the logging package for Python. The core package is +based on PEP 282 and comments thereto in comp.lang.python. + +Copyright (C) 2001-2012 Vinay Sajip. All Rights Reserved. + +To use, simply 'import logging.handlers' and log away! +""" + +import errno, logging, socket, os, cPickle, struct, time, re +from stat import ST_DEV, ST_INO, ST_MTIME + +try: + import codecs +except ImportError: + codecs = None +try: + unicode + _unicode = True +except NameError: + _unicode = False + +# +# Some constants... +# + +DEFAULT_TCP_LOGGING_PORT = 9020 +DEFAULT_UDP_LOGGING_PORT = 9021 +DEFAULT_HTTP_LOGGING_PORT = 9022 +DEFAULT_SOAP_LOGGING_PORT = 9023 +SYSLOG_UDP_PORT = 514 +SYSLOG_TCP_PORT = 514 + +_MIDNIGHT = 24 * 60 * 60 # number of seconds in a day + +class BaseRotatingHandler(logging.FileHandler): + """ + Base class for handlers that rotate log files at a certain point. + Not meant to be instantiated directly. Instead, use RotatingFileHandler + or TimedRotatingFileHandler. + """ + def __init__(self, filename, mode, encoding=None, delay=0): + """ + Use the specified filename for streamed logging + """ + if codecs is None: + encoding = None + logging.FileHandler.__init__(self, filename, mode, encoding, delay) + self.mode = mode + self.encoding = encoding + + def emit(self, record): + """ + Emit a record. + + Output the record to the file, catering for rollover as described + in doRollover(). + """ + try: + if self.shouldRollover(record): + self.doRollover() + logging.FileHandler.emit(self, record) + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + +class RotatingFileHandler(BaseRotatingHandler): + """ + Handler for logging to a set of files, which switches from one file + to the next when the current file reaches a certain size. + """ + def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0): + """ + Open the specified file and use it as the stream for logging. + + By default, the file grows indefinitely. You can specify particular + values of maxBytes and backupCount to allow the file to rollover at + a predetermined size. + + Rollover occurs whenever the current log file is nearly maxBytes in + length. If backupCount is >= 1, the system will successively create + new files with the same pathname as the base file, but with extensions + ".1", ".2" etc. appended to it. For example, with a backupCount of 5 + and a base file name of "app.log", you would get "app.log", + "app.log.1", "app.log.2", ... through to "app.log.5". The file being + written to is always "app.log" - when it gets filled up, it is closed + and renamed to "app.log.1", and if files "app.log.1", "app.log.2" etc. + exist, then they are renamed to "app.log.2", "app.log.3" etc. + respectively. + + If maxBytes is zero, rollover never occurs. + """ + # If rotation/rollover is wanted, it doesn't make sense to use another + # mode. If for example 'w' were specified, then if there were multiple + # runs of the calling application, the logs from previous runs would be + # lost if the 'w' is respected, because the log file would be truncated + # on each run. + if maxBytes > 0: + mode = 'a' + BaseRotatingHandler.__init__(self, filename, mode, encoding, delay) + self.maxBytes = maxBytes + self.backupCount = backupCount + + def doRollover(self): + """ + Do a rollover, as described in __init__(). + """ + if self.stream: + self.stream.close() + self.stream = None + if self.backupCount > 0: + for i in range(self.backupCount - 1, 0, -1): + sfn = "%s.%d" % (self.baseFilename, i) + dfn = "%s.%d" % (self.baseFilename, i + 1) + if os.path.exists(sfn): + #print "%s -> %s" % (sfn, dfn) + if os.path.exists(dfn): + os.remove(dfn) + os.rename(sfn, dfn) + dfn = self.baseFilename + ".1" + if os.path.exists(dfn): + os.remove(dfn) + os.rename(self.baseFilename, dfn) + #print "%s -> %s" % (self.baseFilename, dfn) + self.stream = self._open() + + def shouldRollover(self, record): + """ + Determine if rollover should occur. + + Basically, see if the supplied record would cause the file to exceed + the size limit we have. + """ + if self.stream is None: # delay was set... + self.stream = self._open() + if self.maxBytes > 0: # are we rolling over? + msg = "%s\n" % self.format(record) + self.stream.seek(0, 2) #due to non-posix-compliant Windows feature + if self.stream.tell() + len(msg) >= self.maxBytes: + return 1 + return 0 + +class TimedRotatingFileHandler(BaseRotatingHandler): + """ + Handler for logging to a file, rotating the log file at certain timed + intervals. + + If backupCount is > 0, when rollover is done, no more than backupCount + files are kept - the oldest ones are deleted. + """ + def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False): + BaseRotatingHandler.__init__(self, filename, 'a', encoding, delay) + self.when = when.upper() + self.backupCount = backupCount + self.utc = utc + # Calculate the real rollover interval, which is just the number of + # seconds between rollovers. Also set the filename suffix used when + # a rollover occurs. Current 'when' events supported: + # S - Seconds + # M - Minutes + # H - Hours + # D - Days + # midnight - roll over at midnight + # W{0-6} - roll over on a certain day; 0 - Monday + # + # Case of the 'when' specifier is not important; lower or upper case + # will work. + if self.when == 'S': + self.interval = 1 # one second + self.suffix = "%Y-%m-%d_%H-%M-%S" + self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}$" + elif self.when == 'M': + self.interval = 60 # one minute + self.suffix = "%Y-%m-%d_%H-%M" + self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}$" + elif self.when == 'H': + self.interval = 60 * 60 # one hour + self.suffix = "%Y-%m-%d_%H" + self.extMatch = r"^\d{4}-\d{2}-\d{2}_\d{2}$" + elif self.when == 'D' or self.when == 'MIDNIGHT': + self.interval = 60 * 60 * 24 # one day + self.suffix = "%Y-%m-%d" + self.extMatch = r"^\d{4}-\d{2}-\d{2}$" + elif self.when.startswith('W'): + self.interval = 60 * 60 * 24 * 7 # one week + if len(self.when) != 2: + raise ValueError("You must specify a day for weekly rollover from 0 to 6 (0 is Monday): %s" % self.when) + if self.when[1] < '0' or self.when[1] > '6': + raise ValueError("Invalid day specified for weekly rollover: %s" % self.when) + self.dayOfWeek = int(self.when[1]) + self.suffix = "%Y-%m-%d" + self.extMatch = r"^\d{4}-\d{2}-\d{2}$" + else: + raise ValueError("Invalid rollover interval specified: %s" % self.when) + + self.extMatch = re.compile(self.extMatch) + self.interval = self.interval * interval # multiply by units requested + if os.path.exists(filename): + t = os.stat(filename)[ST_MTIME] + else: + t = int(time.time()) + self.rolloverAt = self.computeRollover(t) + + def computeRollover(self, currentTime): + """ + Work out the rollover time based on the specified time. + """ + result = currentTime + self.interval + # If we are rolling over at midnight or weekly, then the interval is already known. + # What we need to figure out is WHEN the next interval is. In other words, + # if you are rolling over at midnight, then your base interval is 1 day, + # but you want to start that one day clock at midnight, not now. So, we + # have to fudge the rolloverAt value in order to trigger the first rollover + # at the right time. After that, the regular interval will take care of + # the rest. Note that this code doesn't care about leap seconds. :) + if self.when == 'MIDNIGHT' or self.when.startswith('W'): + # This could be done with less code, but I wanted it to be clear + if self.utc: + t = time.gmtime(currentTime) + else: + t = time.localtime(currentTime) + currentHour = t[3] + currentMinute = t[4] + currentSecond = t[5] + # r is the number of seconds left between now and midnight + r = _MIDNIGHT - ((currentHour * 60 + currentMinute) * 60 + + currentSecond) + result = currentTime + r + # If we are rolling over on a certain day, add in the number of days until + # the next rollover, but offset by 1 since we just calculated the time + # until the next day starts. There are three cases: + # Case 1) The day to rollover is today; in this case, do nothing + # Case 2) The day to rollover is further in the interval (i.e., today is + # day 2 (Wednesday) and rollover is on day 6 (Sunday). Days to + # next rollover is simply 6 - 2 - 1, or 3. + # Case 3) The day to rollover is behind us in the interval (i.e., today + # is day 5 (Saturday) and rollover is on day 3 (Thursday). + # Days to rollover is 6 - 5 + 3, or 4. In this case, it's the + # number of days left in the current week (1) plus the number + # of days in the next week until the rollover day (3). + # The calculations described in 2) and 3) above need to have a day added. + # This is because the above time calculation takes us to midnight on this + # day, i.e. the start of the next day. + if self.when.startswith('W'): + day = t[6] # 0 is Monday + if day != self.dayOfWeek: + if day < self.dayOfWeek: + daysToWait = self.dayOfWeek - day + else: + daysToWait = 6 - day + self.dayOfWeek + 1 + newRolloverAt = result + (daysToWait * (60 * 60 * 24)) + if not self.utc: + dstNow = t[-1] + dstAtRollover = time.localtime(newRolloverAt)[-1] + if dstNow != dstAtRollover: + if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour + addend = -3600 + else: # DST bows out before next rollover, so we need to add an hour + addend = 3600 + newRolloverAt += addend + result = newRolloverAt + return result + + def shouldRollover(self, record): + """ + Determine if rollover should occur. + + record is not used, as we are just comparing times, but it is needed so + the method signatures are the same + """ + t = int(time.time()) + if t >= self.rolloverAt: + return 1 + #print "No need to rollover: %d, %d" % (t, self.rolloverAt) + return 0 + + def getFilesToDelete(self): + """ + Determine the files to delete when rolling over. + + More specific than the earlier method, which just used glob.glob(). + """ + dirName, baseName = os.path.split(self.baseFilename) + fileNames = os.listdir(dirName) + result = [] + prefix = baseName + "." + plen = len(prefix) + for fileName in fileNames: + if fileName[:plen] == prefix: + suffix = fileName[plen:] + if self.extMatch.match(suffix): + result.append(os.path.join(dirName, fileName)) + result.sort() + if len(result) < self.backupCount: + result = [] + else: + result = result[:len(result) - self.backupCount] + return result + + def doRollover(self): + """ + do a rollover; in this case, a date/time stamp is appended to the filename + when the rollover happens. However, you want the file to be named for the + start of the interval, not the current time. If there is a backup count, + then we have to get a list of matching filenames, sort them and remove + the one with the oldest suffix. + """ + if self.stream: + self.stream.close() + self.stream = None + # get the time that this sequence started at and make it a TimeTuple + currentTime = int(time.time()) + dstNow = time.localtime(currentTime)[-1] + t = self.rolloverAt - self.interval + if self.utc: + timeTuple = time.gmtime(t) + else: + timeTuple = time.localtime(t) + dstThen = timeTuple[-1] + if dstNow != dstThen: + if dstNow: + addend = 3600 + else: + addend = -3600 + timeTuple = time.localtime(t + addend) + dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple) + if os.path.exists(dfn): + os.remove(dfn) + os.rename(self.baseFilename, dfn) + if self.backupCount > 0: + # find the oldest log file and delete it + #s = glob.glob(self.baseFilename + ".20*") + #if len(s) > self.backupCount: + # s.sort() + # os.remove(s[0]) + for s in self.getFilesToDelete(): + os.remove(s) + #print "%s -> %s" % (self.baseFilename, dfn) + self.stream = self._open() + newRolloverAt = self.computeRollover(currentTime) + while newRolloverAt <= currentTime: + newRolloverAt = newRolloverAt + self.interval + #If DST changes and midnight or weekly rollover, adjust for this. + if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc: + dstAtRollover = time.localtime(newRolloverAt)[-1] + if dstNow != dstAtRollover: + if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour + addend = -3600 + else: # DST bows out before next rollover, so we need to add an hour + addend = 3600 + newRolloverAt += addend + self.rolloverAt = newRolloverAt + +class WatchedFileHandler(logging.FileHandler): + """ + A handler for logging to a file, which watches the file + to see if it has changed while in use. This can happen because of + usage of programs such as newsyslog and logrotate which perform + log file rotation. This handler, intended for use under Unix, + watches the file to see if it has changed since the last emit. + (A file has changed if its device or inode have changed.) + If it has changed, the old file stream is closed, and the file + opened to get a new stream. + + This handler is not appropriate for use under Windows, because + under Windows open files cannot be moved or renamed - logging + opens the files with exclusive locks - and so there is no need + for such a handler. Furthermore, ST_INO is not supported under + Windows; stat always returns zero for this value. + + This handler is based on a suggestion and patch by Chad J. + Schroeder. + """ + def __init__(self, filename, mode='a', encoding=None, delay=0): + logging.FileHandler.__init__(self, filename, mode, encoding, delay) + self.dev, self.ino = -1, -1 + self._statstream() + + def _statstream(self): + if self.stream: + sres = os.fstat(self.stream.fileno()) + self.dev, self.ino = sres[ST_DEV], sres[ST_INO] + + def emit(self, record): + """ + Emit a record. + + First check if the underlying file has changed, and if it + has, close the old stream and reopen the file to get the + current stream. + """ + # Reduce the chance of race conditions by stat'ing by path only + # once and then fstat'ing our new fd if we opened a new log stream. + # See issue #14632: Thanks to John Mulligan for the problem report + # and patch. + try: + # stat the file by path, checking for existence + sres = os.stat(self.baseFilename) + except OSError as err: + if err.errno == errno.ENOENT: + sres = None + else: + raise + # compare file system stat with that of our stream file handle + if not sres or sres[ST_DEV] != self.dev or sres[ST_INO] != self.ino: + if self.stream is not None: + # we have an open file handle, clean it up + self.stream.flush() + self.stream.close() + # open a new file handle and get new stat info from that fd + self.stream = self._open() + self._statstream() + logging.FileHandler.emit(self, record) + +class SocketHandler(logging.Handler): + """ + A handler class which writes logging records, in pickle format, to + a streaming socket. The socket is kept open across logging calls. + If the peer resets it, an attempt is made to reconnect on the next call. + The pickle which is sent is that of the LogRecord's attribute dictionary + (__dict__), so that the receiver does not need to have the logging module + installed in order to process the logging event. + + To unpickle the record at the receiving end into a LogRecord, use the + makeLogRecord function. + """ + + def __init__(self, host, port): + """ + Initializes the handler with a specific host address and port. + + The attribute 'closeOnError' is set to 1 - which means that if + a socket error occurs, the socket is silently closed and then + reopened on the next logging call. + """ + logging.Handler.__init__(self) + self.host = host + self.port = port + self.sock = None + self.closeOnError = 0 + self.retryTime = None + # + # Exponential backoff parameters. + # + self.retryStart = 1.0 + self.retryMax = 30.0 + self.retryFactor = 2.0 + + def makeSocket(self, timeout=1): + """ + A factory method which allows subclasses to define the precise + type of socket they want. + """ + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if hasattr(s, 'settimeout'): + s.settimeout(timeout) + s.connect((self.host, self.port)) + return s + + def createSocket(self): + """ + Try to create a socket, using an exponential backoff with + a max retry time. Thanks to Robert Olson for the original patch + (SF #815911) which has been slightly refactored. + """ + now = time.time() + # Either retryTime is None, in which case this + # is the first time back after a disconnect, or + # we've waited long enough. + if self.retryTime is None: + attempt = 1 + else: + attempt = (now >= self.retryTime) + if attempt: + try: + self.sock = self.makeSocket() + self.retryTime = None # next time, no delay before trying + except socket.error: + #Creation failed, so set the retry time and return. + if self.retryTime is None: + self.retryPeriod = self.retryStart + else: + self.retryPeriod = self.retryPeriod * self.retryFactor + if self.retryPeriod > self.retryMax: + self.retryPeriod = self.retryMax + self.retryTime = now + self.retryPeriod + + def send(self, s): + """ + Send a pickled string to the socket. + + This function allows for partial sends which can happen when the + network is busy. + """ + if self.sock is None: + self.createSocket() + #self.sock can be None either because we haven't reached the retry + #time yet, or because we have reached the retry time and retried, + #but are still unable to connect. + if self.sock: + try: + if hasattr(self.sock, "sendall"): + self.sock.sendall(s) + else: + sentsofar = 0 + left = len(s) + while left > 0: + sent = self.sock.send(s[sentsofar:]) + sentsofar = sentsofar + sent + left = left - sent + except socket.error: + self.sock.close() + self.sock = None # so we can call createSocket next time + + def makePickle(self, record): + """ + Pickles the record in binary format with a length prefix, and + returns it ready for transmission across the socket. + """ + ei = record.exc_info + if ei: + # just to get traceback text into record.exc_text ... + dummy = self.format(record) + record.exc_info = None # to avoid Unpickleable error + # See issue #14436: If msg or args are objects, they may not be + # available on the receiving end. So we convert the msg % args + # to a string, save it as msg and zap the args. + d = dict(record.__dict__) + d['msg'] = record.getMessage() + d['args'] = None + s = cPickle.dumps(d, 1) + if ei: + record.exc_info = ei # for next handler + slen = struct.pack(">L", len(s)) + return slen + s + + def handleError(self, record): + """ + Handle an error during logging. + + An error has occurred during logging. Most likely cause - + connection lost. Close the socket so that we can retry on the + next event. + """ + if self.closeOnError and self.sock: + self.sock.close() + self.sock = None #try to reconnect next time + else: + logging.Handler.handleError(self, record) + + def emit(self, record): + """ + Emit a record. + + Pickles the record and writes it to the socket in binary format. + If there is an error with the socket, silently drop the packet. + If there was a problem with the socket, re-establishes the + socket. + """ + try: + s = self.makePickle(record) + self.send(s) + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + + def close(self): + """ + Closes the socket. + """ + self.acquire() + try: + if self.sock: + self.sock.close() + self.sock = None + finally: + self.release() + logging.Handler.close(self) + +class DatagramHandler(SocketHandler): + """ + A handler class which writes logging records, in pickle format, to + a datagram socket. The pickle which is sent is that of the LogRecord's + attribute dictionary (__dict__), so that the receiver does not need to + have the logging module installed in order to process the logging event. + + To unpickle the record at the receiving end into a LogRecord, use the + makeLogRecord function. + + """ + def __init__(self, host, port): + """ + Initializes the handler with a specific host address and port. + """ + SocketHandler.__init__(self, host, port) + self.closeOnError = 0 + + def makeSocket(self): + """ + The factory method of SocketHandler is here overridden to create + a UDP socket (SOCK_DGRAM). + """ + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + return s + + def send(self, s): + """ + Send a pickled string to a socket. + + This function no longer allows for partial sends which can happen + when the network is busy - UDP does not guarantee delivery and + can deliver packets out of sequence. + """ + if self.sock is None: + self.createSocket() + self.sock.sendto(s, (self.host, self.port)) + +class SysLogHandler(logging.Handler): + """ + A handler class which sends formatted logging records to a syslog + server. Based on Sam Rushing's syslog module: + http://www.nightmare.com/squirl/python-ext/misc/syslog.py + Contributed by Nicolas Untz (after which minor refactoring changes + have been made). + """ + + # from <linux/sys/syslog.h>: + # ====================================================================== + # priorities/facilities are encoded into a single 32-bit quantity, where + # the bottom 3 bits are the priority (0-7) and the top 28 bits are the + # facility (0-big number). Both the priorities and the facilities map + # roughly one-to-one to strings in the syslogd(8) source code. This + # mapping is included in this file. + # + # priorities (these are ordered) + + LOG_EMERG = 0 # system is unusable + LOG_ALERT = 1 # action must be taken immediately + LOG_CRIT = 2 # critical conditions + LOG_ERR = 3 # error conditions + LOG_WARNING = 4 # warning conditions + LOG_NOTICE = 5 # normal but significant condition + LOG_INFO = 6 # informational + LOG_DEBUG = 7 # debug-level messages + + # facility codes + LOG_KERN = 0 # kernel messages + LOG_USER = 1 # random user-level messages + LOG_MAIL = 2 # mail system + LOG_DAEMON = 3 # system daemons + LOG_AUTH = 4 # security/authorization messages + LOG_SYSLOG = 5 # messages generated internally by syslogd + LOG_LPR = 6 # line printer subsystem + LOG_NEWS = 7 # network news subsystem + LOG_UUCP = 8 # UUCP subsystem + LOG_CRON = 9 # clock daemon + LOG_AUTHPRIV = 10 # security/authorization messages (private) + LOG_FTP = 11 # FTP daemon + + # other codes through 15 reserved for system use + LOG_LOCAL0 = 16 # reserved for local use + LOG_LOCAL1 = 17 # reserved for local use + LOG_LOCAL2 = 18 # reserved for local use + LOG_LOCAL3 = 19 # reserved for local use + LOG_LOCAL4 = 20 # reserved for local use + LOG_LOCAL5 = 21 # reserved for local use + LOG_LOCAL6 = 22 # reserved for local use + LOG_LOCAL7 = 23 # reserved for local use + + priority_names = { + "alert": LOG_ALERT, + "crit": LOG_CRIT, + "critical": LOG_CRIT, + "debug": LOG_DEBUG, + "emerg": LOG_EMERG, + "err": LOG_ERR, + "error": LOG_ERR, # DEPRECATED + "info": LOG_INFO, + "notice": LOG_NOTICE, + "panic": LOG_EMERG, # DEPRECATED + "warn": LOG_WARNING, # DEPRECATED + "warning": LOG_WARNING, + } + + facility_names = { + "auth": LOG_AUTH, + "authpriv": LOG_AUTHPRIV, + "cron": LOG_CRON, + "daemon": LOG_DAEMON, + "ftp": LOG_FTP, + "kern": LOG_KERN, + "lpr": LOG_LPR, + "mail": LOG_MAIL, + "news": LOG_NEWS, + "security": LOG_AUTH, # DEPRECATED + "syslog": LOG_SYSLOG, + "user": LOG_USER, + "uucp": LOG_UUCP, + "local0": LOG_LOCAL0, + "local1": LOG_LOCAL1, + "local2": LOG_LOCAL2, + "local3": LOG_LOCAL3, + "local4": LOG_LOCAL4, + "local5": LOG_LOCAL5, + "local6": LOG_LOCAL6, + "local7": LOG_LOCAL7, + } + + #The map below appears to be trivially lowercasing the key. However, + #there's more to it than meets the eye - in some locales, lowercasing + #gives unexpected results. See SF #1524081: in the Turkish locale, + #"INFO".lower() != "info" + priority_map = { + "DEBUG" : "debug", + "INFO" : "info", + "WARNING" : "warning", + "ERROR" : "error", + "CRITICAL" : "critical" + } + + def __init__(self, address=('localhost', SYSLOG_UDP_PORT), + facility=LOG_USER, socktype=socket.SOCK_DGRAM): + """ + Initialize a handler. + + If address is specified as a string, a UNIX socket is used. To log to a + local syslogd, "SysLogHandler(address="/dev/log")" can be used. + If facility is not specified, LOG_USER is used. + """ + logging.Handler.__init__(self) + + self.address = address + self.facility = facility + self.socktype = socktype + + if isinstance(address, basestring): + self.unixsocket = 1 + self._connect_unixsocket(address) + else: + self.unixsocket = 0 + self.socket = socket.socket(socket.AF_INET, socktype) + if socktype == socket.SOCK_STREAM: + self.socket.connect(address) + self.formatter = None + + def _connect_unixsocket(self, address): + self.socket = socket.socket(socket.AF_UNIX, self.socktype) + try: + self.socket.connect(address) + except socket.error: + self.socket.close() + raise + + # curious: when talking to the unix-domain '/dev/log' socket, a + # zero-terminator seems to be required. this string is placed + # into a class variable so that it can be overridden if + # necessary. + log_format_string = '<%d>%s\000' + + def encodePriority(self, facility, priority): + """ + Encode the facility and priority. You can pass in strings or + integers - if strings are passed, the facility_names and + priority_names mapping dictionaries are used to convert them to + integers. + """ + if isinstance(facility, basestring): + facility = self.facility_names[facility] + if isinstance(priority, basestring): + priority = self.priority_names[priority] + return (facility << 3) | priority + + def close (self): + """ + Closes the socket. + """ + self.acquire() + try: + if self.unixsocket: + self.socket.close() + finally: + self.release() + logging.Handler.close(self) + + def mapPriority(self, levelName): + """ + Map a logging level name to a key in the priority_names map. + This is useful in two scenarios: when custom levels are being + used, and in the case where you can't do a straightforward + mapping by lowercasing the logging level name because of locale- + specific issues (see SF #1524081). + """ + return self.priority_map.get(levelName, "warning") + + def emit(self, record): + """ + Emit a record. + + The record is formatted, and then sent to the syslog server. If + exception information is present, it is NOT sent to the server. + """ + msg = self.format(record) + '\000' + """ + We need to convert record level to lowercase, maybe this will + change in the future. + """ + prio = '<%d>' % self.encodePriority(self.facility, + self.mapPriority(record.levelname)) + # Message is a string. Convert to bytes as required by RFC 5424 + if type(msg) is unicode: + msg = msg.encode('utf-8') + msg = prio + msg + try: + if self.unixsocket: + try: + self.socket.send(msg) + except socket.error: + self._connect_unixsocket(self.address) + self.socket.send(msg) + elif self.socktype == socket.SOCK_DGRAM: + self.socket.sendto(msg, self.address) + else: + self.socket.sendall(msg) + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + +class SMTPHandler(logging.Handler): + """ + A handler class which sends an SMTP email for each logging event. + """ + def __init__(self, mailhost, fromaddr, toaddrs, subject, + credentials=None, secure=None): + """ + Initialize the handler. + + Initialize the instance with the from and to addresses and subject + line of the email. To specify a non-standard SMTP port, use the + (host, port) tuple format for the mailhost argument. To specify + authentication credentials, supply a (username, password) tuple + for the credentials argument. To specify the use of a secure + protocol (TLS), pass in a tuple for the secure argument. This will + only be used when authentication credentials are supplied. The tuple + will be either an empty tuple, or a single-value tuple with the name + of a keyfile, or a 2-value tuple with the names of the keyfile and + certificate file. (This tuple is passed to the `starttls` method). + """ + logging.Handler.__init__(self) + if isinstance(mailhost, tuple): + self.mailhost, self.mailport = mailhost + else: + self.mailhost, self.mailport = mailhost, None + if isinstance(credentials, tuple): + self.username, self.password = credentials + else: + self.username = None + self.fromaddr = fromaddr + if isinstance(toaddrs, basestring): + toaddrs = [toaddrs] + self.toaddrs = toaddrs + self.subject = subject + self.secure = secure + self._timeout = 5.0 + + def getSubject(self, record): + """ + Determine the subject for the email. + + If you want to specify a subject line which is record-dependent, + override this method. + """ + return self.subject + + def emit(self, record): + """ + Emit a record. + + Format the record and send it to the specified addressees. + """ + try: + import smtplib + from email.utils import formatdate + port = self.mailport + if not port: + port = smtplib.SMTP_PORT + smtp = smtplib.SMTP(self.mailhost, port, timeout=self._timeout) + msg = self.format(record) + msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % ( + self.fromaddr, + ",".join(self.toaddrs), + self.getSubject(record), + formatdate(), msg) + if self.username: + if self.secure is not None: + smtp.ehlo() + smtp.starttls(*self.secure) + smtp.ehlo() + smtp.login(self.username, self.password) + smtp.sendmail(self.fromaddr, self.toaddrs, msg) + smtp.quit() + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + +class NTEventLogHandler(logging.Handler): + """ + A handler class which sends events to the NT Event Log. Adds a + registry entry for the specified application name. If no dllname is + provided, win32service.pyd (which contains some basic message + placeholders) is used. Note that use of these placeholders will make + your event logs big, as the entire message source is held in the log. + If you want slimmer logs, you have to pass in the name of your own DLL + which contains the message definitions you want to use in the event log. + """ + def __init__(self, appname, dllname=None, logtype="Application"): + logging.Handler.__init__(self) + try: + import win32evtlogutil, win32evtlog + self.appname = appname + self._welu = win32evtlogutil + if not dllname: + dllname = os.path.split(self._welu.__file__) + dllname = os.path.split(dllname[0]) + dllname = os.path.join(dllname[0], r'win32service.pyd') + self.dllname = dllname + self.logtype = logtype + self._welu.AddSourceToRegistry(appname, dllname, logtype) + self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE + self.typemap = { + logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE, + logging.INFO : win32evtlog.EVENTLOG_INFORMATION_TYPE, + logging.WARNING : win32evtlog.EVENTLOG_WARNING_TYPE, + logging.ERROR : win32evtlog.EVENTLOG_ERROR_TYPE, + logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE, + } + except ImportError: + print("The Python Win32 extensions for NT (service, event "\ + "logging) appear not to be available.") + self._welu = None + + def getMessageID(self, record): + """ + Return the message ID for the event record. If you are using your + own messages, you could do this by having the msg passed to the + logger being an ID rather than a formatting string. Then, in here, + you could use a dictionary lookup to get the message ID. This + version returns 1, which is the base message ID in win32service.pyd. + """ + return 1 + + def getEventCategory(self, record): + """ + Return the event category for the record. + + Override this if you want to specify your own categories. This version + returns 0. + """ + return 0 + + def getEventType(self, record): + """ + Return the event type for the record. + + Override this if you want to specify your own types. This version does + a mapping using the handler's typemap attribute, which is set up in + __init__() to a dictionary which contains mappings for DEBUG, INFO, + WARNING, ERROR and CRITICAL. If you are using your own levels you will + either need to override this method or place a suitable dictionary in + the handler's typemap attribute. + """ + return self.typemap.get(record.levelno, self.deftype) + + def emit(self, record): + """ + Emit a record. + + Determine the message ID, event category and event type. Then + log the message in the NT event log. + """ + if self._welu: + try: + id = self.getMessageID(record) + cat = self.getEventCategory(record) + type = self.getEventType(record) + msg = self.format(record) + self._welu.ReportEvent(self.appname, id, cat, type, [msg]) + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + + def close(self): + """ + Clean up this handler. + + You can remove the application name from the registry as a + source of event log entries. However, if you do this, you will + not be able to see the events as you intended in the Event Log + Viewer - it needs to be able to access the registry to get the + DLL name. + """ + #self._welu.RemoveSourceFromRegistry(self.appname, self.logtype) + logging.Handler.close(self) + +class HTTPHandler(logging.Handler): + """ + A class which sends records to a Web server, using either GET or + POST semantics. + """ + def __init__(self, host, url, method="GET"): + """ + Initialize the instance with the host, the request URL, and the method + ("GET" or "POST") + """ + logging.Handler.__init__(self) + method = method.upper() + if method not in ["GET", "POST"]: + raise ValueError("method must be GET or POST") + self.host = host + self.url = url + self.method = method + + def mapLogRecord(self, record): + """ + Default implementation of mapping the log record into a dict + that is sent as the CGI data. Overwrite in your class. + Contributed by Franz Glasner. + """ + return record.__dict__ + + def emit(self, record): + """ + Emit a record. + + Send the record to the Web server as a percent-encoded dictionary + """ + try: + import httplib, urllib + host = self.host + h = httplib.HTTP(host) + url = self.url + data = urllib.urlencode(self.mapLogRecord(record)) + if self.method == "GET": + if (url.find('?') >= 0): + sep = '&' + else: + sep = '?' + url = url + "%c%s" % (sep, data) + h.putrequest(self.method, url) + # support multiple hosts on one IP address... + # need to strip optional :port from host, if present + i = host.find(":") + if i >= 0: + host = host[:i] + h.putheader("Host", host) + if self.method == "POST": + h.putheader("Content-type", + "application/x-www-form-urlencoded") + h.putheader("Content-length", str(len(data))) + h.endheaders(data if self.method == "POST" else None) + h.getreply() #can't do anything with the result + except (KeyboardInterrupt, SystemExit): + raise + except: + self.handleError(record) + +class BufferingHandler(logging.Handler): + """ + A handler class which buffers logging records in memory. Whenever each + record is added to the buffer, a check is made to see if the buffer should + be flushed. If it should, then flush() is expected to do what's needed. + """ + def __init__(self, capacity): + """ + Initialize the handler with the buffer size. + """ + logging.Handler.__init__(self) + self.capacity = capacity + self.buffer = [] + + def shouldFlush(self, record): + """ + Should the handler flush its buffer? + + Returns true if the buffer is up to capacity. This method can be + overridden to implement custom flushing strategies. + """ + return (len(self.buffer) >= self.capacity) + + def emit(self, record): + """ + Emit a record. + + Append the record. If shouldFlush() tells us to, call flush() to process + the buffer. + """ + self.buffer.append(record) + if self.shouldFlush(record): + self.flush() + + def flush(self): + """ + Override to implement custom flushing behaviour. + + This version just zaps the buffer to empty. + """ + self.acquire() + try: + self.buffer = [] + finally: + self.release() + + def close(self): + """ + Close the handler. + + This version just flushes and chains to the parent class' close(). + """ + self.flush() + logging.Handler.close(self) + +class MemoryHandler(BufferingHandler): + """ + A handler class which buffers logging records in memory, periodically + flushing them to a target handler. Flushing occurs whenever the buffer + is full, or when an event of a certain severity or greater is seen. + """ + def __init__(self, capacity, flushLevel=logging.ERROR, target=None): + """ + Initialize the handler with the buffer size, the level at which + flushing should occur and an optional target. + + Note that without a target being set either here or via setTarget(), + a MemoryHandler is no use to anyone! + """ + BufferingHandler.__init__(self, capacity) + self.flushLevel = flushLevel + self.target = target + + def shouldFlush(self, record): + """ + Check for buffer full or a record at the flushLevel or higher. + """ + return (len(self.buffer) >= self.capacity) or \ + (record.levelno >= self.flushLevel) + + def setTarget(self, target): + """ + Set the target handler for this handler. + """ + self.target = target + + def flush(self): + """ + For a MemoryHandler, flushing means just sending the buffered + records to the target, if there is one. Override if you want + different behaviour. + """ + self.acquire() + try: + if self.target: + for record in self.buffer: + self.target.handle(record) + self.buffer = [] + finally: + self.release() + + def close(self): + """ + Flush, set the target to None and lose the buffer. + """ + self.flush() + self.acquire() + try: + self.target = None + BufferingHandler.close(self) + finally: + self.release() diff --git a/src/main/resources/PythonLibs/macpath.py b/src/main/resources/PythonLibs/macpath.py new file mode 100644 index 0000000000000000000000000000000000000000..cd4cb8581af67e6e7d1bef020f71fb9bc750b470 --- /dev/null +++ b/src/main/resources/PythonLibs/macpath.py @@ -0,0 +1,215 @@ +"""Pathname and path-related operations for the Macintosh.""" + +import os +import warnings +from stat import * +import genericpath +from genericpath import * + +__all__ = ["normcase","isabs","join","splitdrive","split","splitext", + "basename","dirname","commonprefix","getsize","getmtime", + "getatime","getctime", "islink","exists","lexists","isdir","isfile", + "walk","expanduser","expandvars","normpath","abspath", + "curdir","pardir","sep","pathsep","defpath","altsep","extsep", + "devnull","realpath","supports_unicode_filenames"] + +# strings representing various path-related bits and pieces +curdir = ':' +pardir = '::' +extsep = '.' +sep = ':' +pathsep = '\n' +defpath = ':' +altsep = None +devnull = 'Dev:Null' + +# Normalize the case of a pathname. Dummy in Posix, but <s>.lower() here. + +def normcase(path): + return path.lower() + + +def isabs(s): + """Return true if a path is absolute. + On the Mac, relative paths begin with a colon, + but as a special case, paths with no colons at all are also relative. + Anything else is absolute (the string up to the first colon is the + volume name).""" + + return ':' in s and s[0] != ':' + + +def join(s, *p): + path = s + for t in p: + if (not s) or isabs(t): + path = t + continue + if t[:1] == ':': + t = t[1:] + if ':' not in path: + path = ':' + path + if path[-1:] != ':': + path = path + ':' + path = path + t + return path + + +def split(s): + """Split a pathname into two parts: the directory leading up to the final + bit, and the basename (the filename, without colons, in that directory). + The result (s, t) is such that join(s, t) yields the original argument.""" + + if ':' not in s: return '', s + colon = 0 + for i in range(len(s)): + if s[i] == ':': colon = i + 1 + path, file = s[:colon-1], s[colon:] + if path and not ':' in path: + path = path + ':' + return path, file + + +def splitext(p): + return genericpath._splitext(p, sep, altsep, extsep) +splitext.__doc__ = genericpath._splitext.__doc__ + +def splitdrive(p): + """Split a pathname into a drive specification and the rest of the + path. Useful on DOS/Windows/NT; on the Mac, the drive is always + empty (don't use the volume name -- it doesn't have the same + syntactic and semantic oddities as DOS drive letters, such as there + being a separate current directory per drive).""" + + return '', p + + +# Short interfaces to split() + +def dirname(s): return split(s)[0] +def basename(s): return split(s)[1] + +def ismount(s): + if not isabs(s): + return False + components = split(s) + return len(components) == 2 and components[1] == '' + +def islink(s): + """Return true if the pathname refers to a symbolic link.""" + + try: + import Carbon.File + return Carbon.File.ResolveAliasFile(s, 0)[2] + except: + return False + +# Is `stat`/`lstat` a meaningful difference on the Mac? This is safe in any +# case. + +def lexists(path): + """Test whether a path exists. Returns True for broken symbolic links""" + + try: + st = os.lstat(path) + except os.error: + return False + return True + +def expandvars(path): + """Dummy to retain interface-compatibility with other operating systems.""" + return path + + +def expanduser(path): + """Dummy to retain interface-compatibility with other operating systems.""" + return path + +class norm_error(Exception): + """Path cannot be normalized""" + +def normpath(s): + """Normalize a pathname. Will return the same result for + equivalent paths.""" + + if ":" not in s: + return ":"+s + + comps = s.split(":") + i = 1 + while i < len(comps)-1: + if comps[i] == "" and comps[i-1] != "": + if i > 1: + del comps[i-1:i+1] + i = i - 1 + else: + # best way to handle this is to raise an exception + raise norm_error, 'Cannot use :: immediately after volume name' + else: + i = i + 1 + + s = ":".join(comps) + + # remove trailing ":" except for ":" and "Volume:" + if s[-1] == ":" and len(comps) > 2 and s != ":"*len(s): + s = s[:-1] + return s + + +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) and not islink(name): + walk(name, func, arg) + + +def abspath(path): + """Return an absolute path.""" + if not isabs(path): + if isinstance(path, unicode): + cwd = os.getcwdu() + else: + cwd = os.getcwd() + path = join(cwd, path) + return normpath(path) + +# realpath is a no-op on systems without islink support +def realpath(path): + path = abspath(path) + try: + import Carbon.File + except ImportError: + return path + if not path: + return path + components = path.split(':') + path = components[0] + ':' + for c in components[1:]: + path = join(path, c) + try: + path = Carbon.File.FSResolveAliasFile(path, 1)[0].as_pathname() + except Carbon.File.Error: + pass + return path + +supports_unicode_filenames = True diff --git a/src/main/resources/PythonLibs/macurl2path.py b/src/main/resources/PythonLibs/macurl2path.py new file mode 100644 index 0000000000000000000000000000000000000000..4c5ae64572e26ab59f299ce83b16ca42827b44a2 --- /dev/null +++ b/src/main/resources/PythonLibs/macurl2path.py @@ -0,0 +1,97 @@ +"""Macintosh-specific module for conversion between pathnames and URLs. + +Do not import directly; use urllib instead.""" + +import urllib +import os + +__all__ = ["url2pathname","pathname2url"] + +def url2pathname(pathname): + """OS-specific conversion from a relative URL of the 'file' scheme + to a file system path; not recommended for general use.""" + # + # XXXX The .. handling should be fixed... + # + tp = urllib.splittype(pathname)[0] + if tp and tp != 'file': + raise RuntimeError, 'Cannot convert non-local URL to pathname' + # Turn starting /// into /, an empty hostname means current host + if pathname[:3] == '///': + pathname = pathname[2:] + elif pathname[:2] == '//': + raise RuntimeError, 'Cannot convert non-local URL to pathname' + components = pathname.split('/') + # Remove . and embedded .. + i = 0 + while i < len(components): + if components[i] == '.': + del components[i] + elif components[i] == '..' and i > 0 and \ + components[i-1] not in ('', '..'): + del components[i-1:i+1] + i = i-1 + elif components[i] == '' and i > 0 and components[i-1] != '': + del components[i] + else: + i = i+1 + if not components[0]: + # Absolute unix path, don't start with colon + rv = ':'.join(components[1:]) + else: + # relative unix path, start with colon. First replace + # leading .. by empty strings (giving ::file) + i = 0 + while i < len(components) and components[i] == '..': + components[i] = '' + i = i + 1 + rv = ':' + ':'.join(components) + # and finally unquote slashes and other funny characters + return urllib.unquote(rv) + +def pathname2url(pathname): + """OS-specific conversion from a file system path to a relative URL + of the 'file' scheme; not recommended for general use.""" + if '/' in pathname: + raise RuntimeError, "Cannot convert pathname containing slashes" + components = pathname.split(':') + # Remove empty first and/or last component + if components[0] == '': + del components[0] + if components[-1] == '': + del components[-1] + # Replace empty string ('::') by .. (will result in '/../' later) + for i in range(len(components)): + if components[i] == '': + components[i] = '..' + # Truncate names longer than 31 bytes + components = map(_pncomp2url, components) + + if os.path.isabs(pathname): + return '/' + '/'.join(components) + else: + return '/'.join(components) + +def _pncomp2url(component): + component = urllib.quote(component[:31], safe='') # We want to quote slashes + return component + +def test(): + for url in ["index.html", + "bar/index.html", + "/foo/bar/index.html", + "/foo/bar/", + "/"]: + print '%r -> %r' % (url, url2pathname(url)) + for path in ["drive:", + "drive:dir:", + "drive:dir:file", + "drive:file", + "file", + ":file", + ":dir:", + ":dir:file"]: + print '%r -> %r' % (path, pathname2url(path)) + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/mailbox.py b/src/main/resources/PythonLibs/mailbox.py new file mode 100644 index 0000000000000000000000000000000000000000..530d3c5a66ef729f430308bc025d6c7474bb7997 --- /dev/null +++ b/src/main/resources/PythonLibs/mailbox.py @@ -0,0 +1,2230 @@ +#! /usr/bin/env python + +"""Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.""" + +# Notes for authors of new mailbox subclasses: +# +# Remember to fsync() changes to disk before closing a modified file +# or returning from a flush() method. See functions _sync_flush() and +# _sync_close(). + +import sys +import os +import time +import calendar +import socket +import errno +import copy +import email +import email.message +import email.generator +import StringIO +try: + if sys.platform == 'os2emx': + # OS/2 EMX fcntl() not adequate + raise ImportError + import fcntl +except ImportError: + fcntl = None + +import warnings +with warnings.catch_warnings(): + if sys.py3kwarning: + warnings.filterwarnings("ignore", ".*rfc822 has been removed", + DeprecationWarning) + import rfc822 + +__all__ = [ 'Mailbox', 'Maildir', 'mbox', 'MH', 'Babyl', 'MMDF', + 'Message', 'MaildirMessage', 'mboxMessage', 'MHMessage', + 'BabylMessage', 'MMDFMessage', 'UnixMailbox', + 'PortableUnixMailbox', 'MmdfMailbox', 'MHMailbox', 'BabylMailbox' ] + +class Mailbox: + """A group of messages in a particular place.""" + + def __init__(self, path, factory=None, create=True): + """Initialize a Mailbox instance.""" + self._path = os.path.abspath(os.path.expanduser(path)) + self._factory = factory + + def add(self, message): + """Add message and return assigned key.""" + raise NotImplementedError('Method must be implemented by subclass') + + def remove(self, key): + """Remove the keyed message; raise KeyError if it doesn't exist.""" + raise NotImplementedError('Method must be implemented by subclass') + + def __delitem__(self, key): + self.remove(key) + + def discard(self, key): + """If the keyed message exists, remove it.""" + try: + self.remove(key) + except KeyError: + pass + + def __setitem__(self, key, message): + """Replace the keyed message; raise KeyError if it doesn't exist.""" + raise NotImplementedError('Method must be implemented by subclass') + + def get(self, key, default=None): + """Return the keyed message, or default if it doesn't exist.""" + try: + return self.__getitem__(key) + except KeyError: + return default + + def __getitem__(self, key): + """Return the keyed message; raise KeyError if it doesn't exist.""" + if not self._factory: + return self.get_message(key) + else: + return self._factory(self.get_file(key)) + + def get_message(self, key): + """Return a Message representation or raise a KeyError.""" + raise NotImplementedError('Method must be implemented by subclass') + + def get_string(self, key): + """Return a string representation or raise a KeyError.""" + raise NotImplementedError('Method must be implemented by subclass') + + def get_file(self, key): + """Return a file-like representation or raise a KeyError.""" + raise NotImplementedError('Method must be implemented by subclass') + + def iterkeys(self): + """Return an iterator over keys.""" + raise NotImplementedError('Method must be implemented by subclass') + + def keys(self): + """Return a list of keys.""" + return list(self.iterkeys()) + + def itervalues(self): + """Return an iterator over all messages.""" + for key in self.iterkeys(): + try: + value = self[key] + except KeyError: + continue + yield value + + def __iter__(self): + return self.itervalues() + + def values(self): + """Return a list of messages. Memory intensive.""" + return list(self.itervalues()) + + def iteritems(self): + """Return an iterator over (key, message) tuples.""" + for key in self.iterkeys(): + try: + value = self[key] + except KeyError: + continue + yield (key, value) + + def items(self): + """Return a list of (key, message) tuples. Memory intensive.""" + return list(self.iteritems()) + + def has_key(self, key): + """Return True if the keyed message exists, False otherwise.""" + raise NotImplementedError('Method must be implemented by subclass') + + def __contains__(self, key): + return self.has_key(key) + + def __len__(self): + """Return a count of messages in the mailbox.""" + raise NotImplementedError('Method must be implemented by subclass') + + def clear(self): + """Delete all messages.""" + for key in self.iterkeys(): + self.discard(key) + + def pop(self, key, default=None): + """Delete the keyed message and return it, or default.""" + try: + result = self[key] + except KeyError: + return default + self.discard(key) + return result + + def popitem(self): + """Delete an arbitrary (key, message) pair and return it.""" + for key in self.iterkeys(): + return (key, self.pop(key)) # This is only run once. + else: + raise KeyError('No messages in mailbox') + + def update(self, arg=None): + """Change the messages that correspond to certain keys.""" + if hasattr(arg, 'iteritems'): + source = arg.iteritems() + elif hasattr(arg, 'items'): + source = arg.items() + else: + source = arg + bad_key = False + for key, message in source: + try: + self[key] = message + except KeyError: + bad_key = True + if bad_key: + raise KeyError('No message with key(s)') + + def flush(self): + """Write any pending changes to the disk.""" + raise NotImplementedError('Method must be implemented by subclass') + + def lock(self): + """Lock the mailbox.""" + raise NotImplementedError('Method must be implemented by subclass') + + def unlock(self): + """Unlock the mailbox if it is locked.""" + raise NotImplementedError('Method must be implemented by subclass') + + def close(self): + """Flush and close the mailbox.""" + raise NotImplementedError('Method must be implemented by subclass') + + # Whether each message must end in a newline + _append_newline = False + + def _dump_message(self, message, target, mangle_from_=False): + # Most files are opened in binary mode to allow predictable seeking. + # To get native line endings on disk, the user-friendly \n line endings + # used in strings and by email.Message are translated here. + """Dump message contents to target file.""" + if isinstance(message, email.message.Message): + buffer = StringIO.StringIO() + gen = email.generator.Generator(buffer, mangle_from_, 0) + gen.flatten(message) + buffer.seek(0) + data = buffer.read().replace('\n', os.linesep) + target.write(data) + if self._append_newline and not data.endswith(os.linesep): + # Make sure the message ends with a newline + target.write(os.linesep) + elif isinstance(message, str): + if mangle_from_: + message = message.replace('\nFrom ', '\n>From ') + message = message.replace('\n', os.linesep) + target.write(message) + if self._append_newline and not message.endswith(os.linesep): + # Make sure the message ends with a newline + target.write(os.linesep) + elif hasattr(message, 'read'): + lastline = None + while True: + line = message.readline() + if line == '': + break + if mangle_from_ and line.startswith('From '): + line = '>From ' + line[5:] + line = line.replace('\n', os.linesep) + target.write(line) + lastline = line + if self._append_newline and lastline and not lastline.endswith(os.linesep): + # Make sure the message ends with a newline + target.write(os.linesep) + else: + raise TypeError('Invalid message type: %s' % type(message)) + + +class Maildir(Mailbox): + """A qmail-style Maildir mailbox.""" + + colon = ':' + + def __init__(self, dirname, factory=rfc822.Message, create=True): + """Initialize a Maildir instance.""" + Mailbox.__init__(self, dirname, factory, create) + self._paths = { + 'tmp': os.path.join(self._path, 'tmp'), + 'new': os.path.join(self._path, 'new'), + 'cur': os.path.join(self._path, 'cur'), + } + if not os.path.exists(self._path): + if create: + os.mkdir(self._path, 0700) + for path in self._paths.values(): + os.mkdir(path, 0o700) + else: + raise NoSuchMailboxError(self._path) + self._toc = {} + self._toc_mtimes = {'cur': 0, 'new': 0} + self._last_read = 0 # Records last time we read cur/new + self._skewfactor = 0.1 # Adjust if os/fs clocks are skewing + + def add(self, message): + """Add message and return assigned key.""" + tmp_file = self._create_tmp() + try: + self._dump_message(message, tmp_file) + except BaseException: + tmp_file.close() + os.remove(tmp_file.name) + raise + _sync_close(tmp_file) + if isinstance(message, MaildirMessage): + subdir = message.get_subdir() + suffix = self.colon + message.get_info() + if suffix == self.colon: + suffix = '' + else: + subdir = 'new' + suffix = '' + uniq = os.path.basename(tmp_file.name).split(self.colon)[0] + dest = os.path.join(self._path, subdir, uniq + suffix) + try: + if hasattr(os, 'link'): + os.link(tmp_file.name, dest) + os.remove(tmp_file.name) + else: + os.rename(tmp_file.name, dest) + except OSError, e: + os.remove(tmp_file.name) + if e.errno == errno.EEXIST: + raise ExternalClashError('Name clash with existing message: %s' + % dest) + else: + raise + if isinstance(message, MaildirMessage): + os.utime(dest, (os.path.getatime(dest), message.get_date())) + return uniq + + def remove(self, key): + """Remove the keyed message; raise KeyError if it doesn't exist.""" + os.remove(os.path.join(self._path, self._lookup(key))) + + def discard(self, key): + """If the keyed message exists, remove it.""" + # This overrides an inapplicable implementation in the superclass. + try: + self.remove(key) + except KeyError: + pass + except OSError, e: + if e.errno != errno.ENOENT: + raise + + def __setitem__(self, key, message): + """Replace the keyed message; raise KeyError if it doesn't exist.""" + old_subpath = self._lookup(key) + temp_key = self.add(message) + temp_subpath = self._lookup(temp_key) + if isinstance(message, MaildirMessage): + # temp's subdir and suffix were specified by message. + dominant_subpath = temp_subpath + else: + # temp's subdir and suffix were defaults from add(). + dominant_subpath = old_subpath + subdir = os.path.dirname(dominant_subpath) + if self.colon in dominant_subpath: + suffix = self.colon + dominant_subpath.split(self.colon)[-1] + else: + suffix = '' + self.discard(key) + new_path = os.path.join(self._path, subdir, key + suffix) + os.rename(os.path.join(self._path, temp_subpath), new_path) + if isinstance(message, MaildirMessage): + os.utime(new_path, (os.path.getatime(new_path), + message.get_date())) + + def get_message(self, key): + """Return a Message representation or raise a KeyError.""" + subpath = self._lookup(key) + f = open(os.path.join(self._path, subpath), 'r') + try: + if self._factory: + msg = self._factory(f) + else: + msg = MaildirMessage(f) + finally: + f.close() + subdir, name = os.path.split(subpath) + msg.set_subdir(subdir) + if self.colon in name: + msg.set_info(name.split(self.colon)[-1]) + msg.set_date(os.path.getmtime(os.path.join(self._path, subpath))) + return msg + + def get_string(self, key): + """Return a string representation or raise a KeyError.""" + f = open(os.path.join(self._path, self._lookup(key)), 'r') + try: + return f.read() + finally: + f.close() + + def get_file(self, key): + """Return a file-like representation or raise a KeyError.""" + f = open(os.path.join(self._path, self._lookup(key)), 'rb') + return _ProxyFile(f) + + def iterkeys(self): + """Return an iterator over keys.""" + self._refresh() + for key in self._toc: + try: + self._lookup(key) + except KeyError: + continue + yield key + + def has_key(self, key): + """Return True if the keyed message exists, False otherwise.""" + self._refresh() + return key in self._toc + + def __len__(self): + """Return a count of messages in the mailbox.""" + self._refresh() + return len(self._toc) + + def flush(self): + """Write any pending changes to disk.""" + # Maildir changes are always written immediately, so there's nothing + # to do. + pass + + def lock(self): + """Lock the mailbox.""" + return + + def unlock(self): + """Unlock the mailbox if it is locked.""" + return + + def close(self): + """Flush and close the mailbox.""" + return + + def list_folders(self): + """Return a list of folder names.""" + result = [] + for entry in os.listdir(self._path): + if len(entry) > 1 and entry[0] == '.' and \ + os.path.isdir(os.path.join(self._path, entry)): + result.append(entry[1:]) + return result + + def get_folder(self, folder): + """Return a Maildir instance for the named folder.""" + return Maildir(os.path.join(self._path, '.' + folder), + factory=self._factory, + create=False) + + def add_folder(self, folder): + """Create a folder and return a Maildir instance representing it.""" + path = os.path.join(self._path, '.' + folder) + result = Maildir(path, factory=self._factory) + maildirfolder_path = os.path.join(path, 'maildirfolder') + if not os.path.exists(maildirfolder_path): + os.close(os.open(maildirfolder_path, os.O_CREAT | os.O_WRONLY, + 0666)) + return result + + def remove_folder(self, folder): + """Delete the named folder, which must be empty.""" + path = os.path.join(self._path, '.' + folder) + for entry in os.listdir(os.path.join(path, 'new')) + \ + os.listdir(os.path.join(path, 'cur')): + if len(entry) < 1 or entry[0] != '.': + raise NotEmptyError('Folder contains message(s): %s' % folder) + for entry in os.listdir(path): + if entry != 'new' and entry != 'cur' and entry != 'tmp' and \ + os.path.isdir(os.path.join(path, entry)): + raise NotEmptyError("Folder contains subdirectory '%s': %s" % + (folder, entry)) + for root, dirs, files in os.walk(path, topdown=False): + for entry in files: + os.remove(os.path.join(root, entry)) + for entry in dirs: + os.rmdir(os.path.join(root, entry)) + os.rmdir(path) + + def clean(self): + """Delete old files in "tmp".""" + now = time.time() + for entry in os.listdir(os.path.join(self._path, 'tmp')): + path = os.path.join(self._path, 'tmp', entry) + if now - os.path.getatime(path) > 129600: # 60 * 60 * 36 + os.remove(path) + + _count = 1 # This is used to generate unique file names. + + def _create_tmp(self): + """Create a file in the tmp subdirectory and open and return it.""" + now = time.time() + hostname = socket.gethostname() + if '/' in hostname: + hostname = hostname.replace('/', r'\057') + if ':' in hostname: + hostname = hostname.replace(':', r'\072') + uniq = "%s.M%sP%sQ%s.%s" % (int(now), int(now % 1 * 1e6), os.getpid(), + Maildir._count, hostname) + path = os.path.join(self._path, 'tmp', uniq) + try: + os.stat(path) + except OSError, e: + if e.errno == errno.ENOENT: + Maildir._count += 1 + try: + return _create_carefully(path) + except OSError, e: + if e.errno != errno.EEXIST: + raise + else: + raise + + # Fall through to here if stat succeeded or open raised EEXIST. + raise ExternalClashError('Name clash prevented file creation: %s' % + path) + + def _refresh(self): + """Update table of contents mapping.""" + # If it has been less than two seconds since the last _refresh() call, + # we have to unconditionally re-read the mailbox just in case it has + # been modified, because os.path.mtime() has a 2 sec resolution in the + # most common worst case (FAT) and a 1 sec resolution typically. This + # results in a few unnecessary re-reads when _refresh() is called + # multiple times in that interval, but once the clock ticks over, we + # will only re-read as needed. Because the filesystem might be being + # served by an independent system with its own clock, we record and + # compare with the mtimes from the filesystem. Because the other + # system's clock might be skewing relative to our clock, we add an + # extra delta to our wait. The default is one tenth second, but is an + # instance variable and so can be adjusted if dealing with a + # particularly skewed or irregular system. + if time.time() - self._last_read > 2 + self._skewfactor: + refresh = False + for subdir in self._toc_mtimes: + mtime = os.path.getmtime(self._paths[subdir]) + if mtime > self._toc_mtimes[subdir]: + refresh = True + self._toc_mtimes[subdir] = mtime + if not refresh: + return + # Refresh toc + self._toc = {} + for subdir in self._toc_mtimes: + path = self._paths[subdir] + for entry in os.listdir(path): + p = os.path.join(path, entry) + if os.path.isdir(p): + continue + uniq = entry.split(self.colon)[0] + self._toc[uniq] = os.path.join(subdir, entry) + self._last_read = time.time() + + def _lookup(self, key): + """Use TOC to return subpath for given key, or raise a KeyError.""" + try: + if os.path.exists(os.path.join(self._path, self._toc[key])): + return self._toc[key] + except KeyError: + pass + self._refresh() + try: + return self._toc[key] + except KeyError: + raise KeyError('No message with key: %s' % key) + + # This method is for backward compatibility only. + def next(self): + """Return the next message in a one-time iteration.""" + if not hasattr(self, '_onetime_keys'): + self._onetime_keys = self.iterkeys() + while True: + try: + return self[self._onetime_keys.next()] + except StopIteration: + return None + except KeyError: + continue + + +class _singlefileMailbox(Mailbox): + """A single-file mailbox.""" + + def __init__(self, path, factory=None, create=True): + """Initialize a single-file mailbox.""" + Mailbox.__init__(self, path, factory, create) + try: + f = open(self._path, 'rb+') + except IOError, e: + if e.errno == errno.ENOENT: + if create: + f = open(self._path, 'wb+') + else: + raise NoSuchMailboxError(self._path) + elif e.errno in (errno.EACCES, errno.EROFS): + f = open(self._path, 'rb') + else: + raise + self._file = f + self._toc = None + self._next_key = 0 + self._pending = False # No changes require rewriting the file. + self._pending_sync = False # No need to sync the file + self._locked = False + self._file_length = None # Used to record mailbox size + + def add(self, message): + """Add message and return assigned key.""" + self._lookup() + self._toc[self._next_key] = self._append_message(message) + self._next_key += 1 + # _append_message appends the message to the mailbox file. We + # don't need a full rewrite + rename, sync is enough. + self._pending_sync = True + return self._next_key - 1 + + def remove(self, key): + """Remove the keyed message; raise KeyError if it doesn't exist.""" + self._lookup(key) + del self._toc[key] + self._pending = True + + def __setitem__(self, key, message): + """Replace the keyed message; raise KeyError if it doesn't exist.""" + self._lookup(key) + self._toc[key] = self._append_message(message) + self._pending = True + + def iterkeys(self): + """Return an iterator over keys.""" + self._lookup() + for key in self._toc.keys(): + yield key + + def has_key(self, key): + """Return True if the keyed message exists, False otherwise.""" + self._lookup() + return key in self._toc + + def __len__(self): + """Return a count of messages in the mailbox.""" + self._lookup() + return len(self._toc) + + def lock(self): + """Lock the mailbox.""" + if not self._locked: + _lock_file(self._file) + self._locked = True + + def unlock(self): + """Unlock the mailbox if it is locked.""" + if self._locked: + _unlock_file(self._file) + self._locked = False + + def flush(self): + """Write any pending changes to disk.""" + if not self._pending: + if self._pending_sync: + # Messages have only been added, so syncing the file + # is enough. + _sync_flush(self._file) + self._pending_sync = False + return + + # In order to be writing anything out at all, self._toc must + # already have been generated (and presumably has been modified + # by adding or deleting an item). + assert self._toc is not None + + # Check length of self._file; if it's changed, some other process + # has modified the mailbox since we scanned it. + self._file.seek(0, 2) + cur_len = self._file.tell() + if cur_len != self._file_length: + raise ExternalClashError('Size of mailbox file changed ' + '(expected %i, found %i)' % + (self._file_length, cur_len)) + + new_file = _create_temporary(self._path) + try: + new_toc = {} + self._pre_mailbox_hook(new_file) + for key in sorted(self._toc.keys()): + start, stop = self._toc[key] + self._file.seek(start) + self._pre_message_hook(new_file) + new_start = new_file.tell() + while True: + buffer = self._file.read(min(4096, + stop - self._file.tell())) + if buffer == '': + break + new_file.write(buffer) + new_toc[key] = (new_start, new_file.tell()) + self._post_message_hook(new_file) + self._file_length = new_file.tell() + except: + new_file.close() + os.remove(new_file.name) + raise + _sync_close(new_file) + # self._file is about to get replaced, so no need to sync. + self._file.close() + # Make sure the new file's mode is the same as the old file's + mode = os.stat(self._path).st_mode + os.chmod(new_file.name, mode) + try: + os.rename(new_file.name, self._path) + except OSError, e: + if e.errno == errno.EEXIST or \ + (os.name == 'os2' and e.errno == errno.EACCES): + os.remove(self._path) + os.rename(new_file.name, self._path) + else: + raise + self._file = open(self._path, 'rb+') + self._toc = new_toc + self._pending = False + self._pending_sync = False + if self._locked: + _lock_file(self._file, dotlock=False) + + def _pre_mailbox_hook(self, f): + """Called before writing the mailbox to file f.""" + return + + def _pre_message_hook(self, f): + """Called before writing each message to file f.""" + return + + def _post_message_hook(self, f): + """Called after writing each message to file f.""" + return + + def close(self): + """Flush and close the mailbox.""" + self.flush() + if self._locked: + self.unlock() + self._file.close() # Sync has been done by self.flush() above. + + def _lookup(self, key=None): + """Return (start, stop) or raise KeyError.""" + if self._toc is None: + self._generate_toc() + if key is not None: + try: + return self._toc[key] + except KeyError: + raise KeyError('No message with key: %s' % key) + + def _append_message(self, message): + """Append message to mailbox and return (start, stop) offsets.""" + self._file.seek(0, 2) + before = self._file.tell() + if len(self._toc) == 0 and not self._pending: + # This is the first message, and the _pre_mailbox_hook + # hasn't yet been called. If self._pending is True, + # messages have been removed, so _pre_mailbox_hook must + # have been called already. + self._pre_mailbox_hook(self._file) + try: + self._pre_message_hook(self._file) + offsets = self._install_message(message) + self._post_message_hook(self._file) + except BaseException: + self._file.truncate(before) + raise + self._file.flush() + self._file_length = self._file.tell() # Record current length of mailbox + return offsets + + + +class _mboxMMDF(_singlefileMailbox): + """An mbox or MMDF mailbox.""" + + _mangle_from_ = True + + def get_message(self, key): + """Return a Message representation or raise a KeyError.""" + start, stop = self._lookup(key) + self._file.seek(start) + from_line = self._file.readline().replace(os.linesep, '') + string = self._file.read(stop - self._file.tell()) + msg = self._message_factory(string.replace(os.linesep, '\n')) + msg.set_from(from_line[5:]) + return msg + + def get_string(self, key, from_=False): + """Return a string representation or raise a KeyError.""" + start, stop = self._lookup(key) + self._file.seek(start) + if not from_: + self._file.readline() + string = self._file.read(stop - self._file.tell()) + return string.replace(os.linesep, '\n') + + def get_file(self, key, from_=False): + """Return a file-like representation or raise a KeyError.""" + start, stop = self._lookup(key) + self._file.seek(start) + if not from_: + self._file.readline() + return _PartialFile(self._file, self._file.tell(), stop) + + def _install_message(self, message): + """Format a message and blindly write to self._file.""" + from_line = None + if isinstance(message, str) and message.startswith('From '): + newline = message.find('\n') + if newline != -1: + from_line = message[:newline] + message = message[newline + 1:] + else: + from_line = message + message = '' + elif isinstance(message, _mboxMMDFMessage): + from_line = 'From ' + message.get_from() + elif isinstance(message, email.message.Message): + from_line = message.get_unixfrom() # May be None. + if from_line is None: + from_line = 'From MAILER-DAEMON %s' % time.asctime(time.gmtime()) + start = self._file.tell() + self._file.write(from_line + os.linesep) + self._dump_message(message, self._file, self._mangle_from_) + stop = self._file.tell() + return (start, stop) + + +class mbox(_mboxMMDF): + """A classic mbox mailbox.""" + + _mangle_from_ = True + + # All messages must end in a newline character, and + # _post_message_hooks outputs an empty line between messages. + _append_newline = True + + def __init__(self, path, factory=None, create=True): + """Initialize an mbox mailbox.""" + self._message_factory = mboxMessage + _mboxMMDF.__init__(self, path, factory, create) + + def _post_message_hook(self, f): + """Called after writing each message to file f.""" + f.write(os.linesep) + + def _generate_toc(self): + """Generate key-to-(start, stop) table of contents.""" + starts, stops = [], [] + last_was_empty = False + self._file.seek(0) + while True: + line_pos = self._file.tell() + line = self._file.readline() + if line.startswith('From '): + if len(stops) < len(starts): + if last_was_empty: + stops.append(line_pos - len(os.linesep)) + else: + # The last line before the "From " line wasn't + # blank, but we consider it a start of a + # message anyway. + stops.append(line_pos) + starts.append(line_pos) + last_was_empty = False + elif not line: + if last_was_empty: + stops.append(line_pos - len(os.linesep)) + else: + stops.append(line_pos) + break + elif line == os.linesep: + last_was_empty = True + else: + last_was_empty = False + self._toc = dict(enumerate(zip(starts, stops))) + self._next_key = len(self._toc) + self._file_length = self._file.tell() + + +class MMDF(_mboxMMDF): + """An MMDF mailbox.""" + + def __init__(self, path, factory=None, create=True): + """Initialize an MMDF mailbox.""" + self._message_factory = MMDFMessage + _mboxMMDF.__init__(self, path, factory, create) + + def _pre_message_hook(self, f): + """Called before writing each message to file f.""" + f.write('\001\001\001\001' + os.linesep) + + def _post_message_hook(self, f): + """Called after writing each message to file f.""" + f.write(os.linesep + '\001\001\001\001' + os.linesep) + + def _generate_toc(self): + """Generate key-to-(start, stop) table of contents.""" + starts, stops = [], [] + self._file.seek(0) + next_pos = 0 + while True: + line_pos = next_pos + line = self._file.readline() + next_pos = self._file.tell() + if line.startswith('\001\001\001\001' + os.linesep): + starts.append(next_pos) + while True: + line_pos = next_pos + line = self._file.readline() + next_pos = self._file.tell() + if line == '\001\001\001\001' + os.linesep: + stops.append(line_pos - len(os.linesep)) + break + elif line == '': + stops.append(line_pos) + break + elif line == '': + break + self._toc = dict(enumerate(zip(starts, stops))) + self._next_key = len(self._toc) + self._file.seek(0, 2) + self._file_length = self._file.tell() + + +class MH(Mailbox): + """An MH mailbox.""" + + def __init__(self, path, factory=None, create=True): + """Initialize an MH instance.""" + Mailbox.__init__(self, path, factory, create) + if not os.path.exists(self._path): + if create: + os.mkdir(self._path, 0700) + os.close(os.open(os.path.join(self._path, '.mh_sequences'), + os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0600)) + else: + raise NoSuchMailboxError(self._path) + self._locked = False + + def add(self, message): + """Add message and return assigned key.""" + keys = self.keys() + if len(keys) == 0: + new_key = 1 + else: + new_key = max(keys) + 1 + new_path = os.path.join(self._path, str(new_key)) + f = _create_carefully(new_path) + closed = False + try: + if self._locked: + _lock_file(f) + try: + try: + self._dump_message(message, f) + except BaseException: + # Unlock and close so it can be deleted on Windows + if self._locked: + _unlock_file(f) + _sync_close(f) + closed = True + os.remove(new_path) + raise + if isinstance(message, MHMessage): + self._dump_sequences(message, new_key) + finally: + if self._locked: + _unlock_file(f) + finally: + if not closed: + _sync_close(f) + return new_key + + def remove(self, key): + """Remove the keyed message; raise KeyError if it doesn't exist.""" + path = os.path.join(self._path, str(key)) + try: + f = open(path, 'rb+') + except IOError, e: + if e.errno == errno.ENOENT: + raise KeyError('No message with key: %s' % key) + else: + raise + else: + f.close() + os.remove(path) + + def __setitem__(self, key, message): + """Replace the keyed message; raise KeyError if it doesn't exist.""" + path = os.path.join(self._path, str(key)) + try: + f = open(path, 'rb+') + except IOError, e: + if e.errno == errno.ENOENT: + raise KeyError('No message with key: %s' % key) + else: + raise + try: + if self._locked: + _lock_file(f) + try: + os.close(os.open(path, os.O_WRONLY | os.O_TRUNC)) + self._dump_message(message, f) + if isinstance(message, MHMessage): + self._dump_sequences(message, key) + finally: + if self._locked: + _unlock_file(f) + finally: + _sync_close(f) + + def get_message(self, key): + """Return a Message representation or raise a KeyError.""" + try: + if self._locked: + f = open(os.path.join(self._path, str(key)), 'r+') + else: + f = open(os.path.join(self._path, str(key)), 'r') + except IOError, e: + if e.errno == errno.ENOENT: + raise KeyError('No message with key: %s' % key) + else: + raise + try: + if self._locked: + _lock_file(f) + try: + msg = MHMessage(f) + finally: + if self._locked: + _unlock_file(f) + finally: + f.close() + for name, key_list in self.get_sequences().iteritems(): + if key in key_list: + msg.add_sequence(name) + return msg + + def get_string(self, key): + """Return a string representation or raise a KeyError.""" + try: + if self._locked: + f = open(os.path.join(self._path, str(key)), 'r+') + else: + f = open(os.path.join(self._path, str(key)), 'r') + except IOError, e: + if e.errno == errno.ENOENT: + raise KeyError('No message with key: %s' % key) + else: + raise + try: + if self._locked: + _lock_file(f) + try: + return f.read() + finally: + if self._locked: + _unlock_file(f) + finally: + f.close() + + def get_file(self, key): + """Return a file-like representation or raise a KeyError.""" + try: + f = open(os.path.join(self._path, str(key)), 'rb') + except IOError, e: + if e.errno == errno.ENOENT: + raise KeyError('No message with key: %s' % key) + else: + raise + return _ProxyFile(f) + + def iterkeys(self): + """Return an iterator over keys.""" + return iter(sorted(int(entry) for entry in os.listdir(self._path) + if entry.isdigit())) + + def has_key(self, key): + """Return True if the keyed message exists, False otherwise.""" + return os.path.exists(os.path.join(self._path, str(key))) + + def __len__(self): + """Return a count of messages in the mailbox.""" + return len(list(self.iterkeys())) + + def lock(self): + """Lock the mailbox.""" + if not self._locked: + self._file = open(os.path.join(self._path, '.mh_sequences'), 'rb+') + _lock_file(self._file) + self._locked = True + + def unlock(self): + """Unlock the mailbox if it is locked.""" + if self._locked: + _unlock_file(self._file) + _sync_close(self._file) + del self._file + self._locked = False + + def flush(self): + """Write any pending changes to the disk.""" + return + + def close(self): + """Flush and close the mailbox.""" + if self._locked: + self.unlock() + + def list_folders(self): + """Return a list of folder names.""" + result = [] + for entry in os.listdir(self._path): + if os.path.isdir(os.path.join(self._path, entry)): + result.append(entry) + return result + + def get_folder(self, folder): + """Return an MH instance for the named folder.""" + return MH(os.path.join(self._path, folder), + factory=self._factory, create=False) + + def add_folder(self, folder): + """Create a folder and return an MH instance representing it.""" + return MH(os.path.join(self._path, folder), + factory=self._factory) + + def remove_folder(self, folder): + """Delete the named folder, which must be empty.""" + path = os.path.join(self._path, folder) + entries = os.listdir(path) + if entries == ['.mh_sequences']: + os.remove(os.path.join(path, '.mh_sequences')) + elif entries == []: + pass + else: + raise NotEmptyError('Folder not empty: %s' % self._path) + os.rmdir(path) + + def get_sequences(self): + """Return a name-to-key-list dictionary to define each sequence.""" + results = {} + f = open(os.path.join(self._path, '.mh_sequences'), 'r') + try: + all_keys = set(self.keys()) + for line in f: + try: + name, contents = line.split(':') + keys = set() + for spec in contents.split(): + if spec.isdigit(): + keys.add(int(spec)) + else: + start, stop = (int(x) for x in spec.split('-')) + keys.update(range(start, stop + 1)) + results[name] = [key for key in sorted(keys) \ + if key in all_keys] + if len(results[name]) == 0: + del results[name] + except ValueError: + raise FormatError('Invalid sequence specification: %s' % + line.rstrip()) + finally: + f.close() + return results + + def set_sequences(self, sequences): + """Set sequences using the given name-to-key-list dictionary.""" + f = open(os.path.join(self._path, '.mh_sequences'), 'r+') + try: + os.close(os.open(f.name, os.O_WRONLY | os.O_TRUNC)) + for name, keys in sequences.iteritems(): + if len(keys) == 0: + continue + f.write('%s:' % name) + prev = None + completing = False + for key in sorted(set(keys)): + if key - 1 == prev: + if not completing: + completing = True + f.write('-') + elif completing: + completing = False + f.write('%s %s' % (prev, key)) + else: + f.write(' %s' % key) + prev = key + if completing: + f.write(str(prev) + '\n') + else: + f.write('\n') + finally: + _sync_close(f) + + def pack(self): + """Re-name messages to eliminate numbering gaps. Invalidates keys.""" + sequences = self.get_sequences() + prev = 0 + changes = [] + for key in self.iterkeys(): + if key - 1 != prev: + changes.append((key, prev + 1)) + if hasattr(os, 'link'): + os.link(os.path.join(self._path, str(key)), + os.path.join(self._path, str(prev + 1))) + os.unlink(os.path.join(self._path, str(key))) + else: + os.rename(os.path.join(self._path, str(key)), + os.path.join(self._path, str(prev + 1))) + prev += 1 + self._next_key = prev + 1 + if len(changes) == 0: + return + for name, key_list in sequences.items(): + for old, new in changes: + if old in key_list: + key_list[key_list.index(old)] = new + self.set_sequences(sequences) + + def _dump_sequences(self, message, key): + """Inspect a new MHMessage and update sequences appropriately.""" + pending_sequences = message.get_sequences() + all_sequences = self.get_sequences() + for name, key_list in all_sequences.iteritems(): + if name in pending_sequences: + key_list.append(key) + elif key in key_list: + del key_list[key_list.index(key)] + for sequence in pending_sequences: + if sequence not in all_sequences: + all_sequences[sequence] = [key] + self.set_sequences(all_sequences) + + +class Babyl(_singlefileMailbox): + """An Rmail-style Babyl mailbox.""" + + _special_labels = frozenset(('unseen', 'deleted', 'filed', 'answered', + 'forwarded', 'edited', 'resent')) + + def __init__(self, path, factory=None, create=True): + """Initialize a Babyl mailbox.""" + _singlefileMailbox.__init__(self, path, factory, create) + self._labels = {} + + def add(self, message): + """Add message and return assigned key.""" + key = _singlefileMailbox.add(self, message) + if isinstance(message, BabylMessage): + self._labels[key] = message.get_labels() + return key + + def remove(self, key): + """Remove the keyed message; raise KeyError if it doesn't exist.""" + _singlefileMailbox.remove(self, key) + if key in self._labels: + del self._labels[key] + + def __setitem__(self, key, message): + """Replace the keyed message; raise KeyError if it doesn't exist.""" + _singlefileMailbox.__setitem__(self, key, message) + if isinstance(message, BabylMessage): + self._labels[key] = message.get_labels() + + def get_message(self, key): + """Return a Message representation or raise a KeyError.""" + start, stop = self._lookup(key) + self._file.seek(start) + self._file.readline() # Skip '1,' line specifying labels. + original_headers = StringIO.StringIO() + while True: + line = self._file.readline() + if line == '*** EOOH ***' + os.linesep or line == '': + break + original_headers.write(line.replace(os.linesep, '\n')) + visible_headers = StringIO.StringIO() + while True: + line = self._file.readline() + if line == os.linesep or line == '': + break + visible_headers.write(line.replace(os.linesep, '\n')) + body = self._file.read(stop - self._file.tell()).replace(os.linesep, + '\n') + msg = BabylMessage(original_headers.getvalue() + body) + msg.set_visible(visible_headers.getvalue()) + if key in self._labels: + msg.set_labels(self._labels[key]) + return msg + + def get_string(self, key): + """Return a string representation or raise a KeyError.""" + start, stop = self._lookup(key) + self._file.seek(start) + self._file.readline() # Skip '1,' line specifying labels. + original_headers = StringIO.StringIO() + while True: + line = self._file.readline() + if line == '*** EOOH ***' + os.linesep or line == '': + break + original_headers.write(line.replace(os.linesep, '\n')) + while True: + line = self._file.readline() + if line == os.linesep or line == '': + break + return original_headers.getvalue() + \ + self._file.read(stop - self._file.tell()).replace(os.linesep, + '\n') + + def get_file(self, key): + """Return a file-like representation or raise a KeyError.""" + return StringIO.StringIO(self.get_string(key).replace('\n', + os.linesep)) + + def get_labels(self): + """Return a list of user-defined labels in the mailbox.""" + self._lookup() + labels = set() + for label_list in self._labels.values(): + labels.update(label_list) + labels.difference_update(self._special_labels) + return list(labels) + + def _generate_toc(self): + """Generate key-to-(start, stop) table of contents.""" + starts, stops = [], [] + self._file.seek(0) + next_pos = 0 + label_lists = [] + while True: + line_pos = next_pos + line = self._file.readline() + next_pos = self._file.tell() + if line == '\037\014' + os.linesep: + if len(stops) < len(starts): + stops.append(line_pos - len(os.linesep)) + starts.append(next_pos) + labels = [label.strip() for label + in self._file.readline()[1:].split(',') + if label.strip() != ''] + label_lists.append(labels) + elif line == '\037' or line == '\037' + os.linesep: + if len(stops) < len(starts): + stops.append(line_pos - len(os.linesep)) + elif line == '': + stops.append(line_pos - len(os.linesep)) + break + self._toc = dict(enumerate(zip(starts, stops))) + self._labels = dict(enumerate(label_lists)) + self._next_key = len(self._toc) + self._file.seek(0, 2) + self._file_length = self._file.tell() + + def _pre_mailbox_hook(self, f): + """Called before writing the mailbox to file f.""" + f.write('BABYL OPTIONS:%sVersion: 5%sLabels:%s%s\037' % + (os.linesep, os.linesep, ','.join(self.get_labels()), + os.linesep)) + + def _pre_message_hook(self, f): + """Called before writing each message to file f.""" + f.write('\014' + os.linesep) + + def _post_message_hook(self, f): + """Called after writing each message to file f.""" + f.write(os.linesep + '\037') + + def _install_message(self, message): + """Write message contents and return (start, stop).""" + start = self._file.tell() + if isinstance(message, BabylMessage): + special_labels = [] + labels = [] + for label in message.get_labels(): + if label in self._special_labels: + special_labels.append(label) + else: + labels.append(label) + self._file.write('1') + for label in special_labels: + self._file.write(', ' + label) + self._file.write(',,') + for label in labels: + self._file.write(' ' + label + ',') + self._file.write(os.linesep) + else: + self._file.write('1,,' + os.linesep) + if isinstance(message, email.message.Message): + orig_buffer = StringIO.StringIO() + orig_generator = email.generator.Generator(orig_buffer, False, 0) + orig_generator.flatten(message) + orig_buffer.seek(0) + while True: + line = orig_buffer.readline() + self._file.write(line.replace('\n', os.linesep)) + if line == '\n' or line == '': + break + self._file.write('*** EOOH ***' + os.linesep) + if isinstance(message, BabylMessage): + vis_buffer = StringIO.StringIO() + vis_generator = email.generator.Generator(vis_buffer, False, 0) + vis_generator.flatten(message.get_visible()) + while True: + line = vis_buffer.readline() + self._file.write(line.replace('\n', os.linesep)) + if line == '\n' or line == '': + break + else: + orig_buffer.seek(0) + while True: + line = orig_buffer.readline() + self._file.write(line.replace('\n', os.linesep)) + if line == '\n' or line == '': + break + while True: + buffer = orig_buffer.read(4096) # Buffer size is arbitrary. + if buffer == '': + break + self._file.write(buffer.replace('\n', os.linesep)) + elif isinstance(message, str): + body_start = message.find('\n\n') + 2 + if body_start - 2 != -1: + self._file.write(message[:body_start].replace('\n', + os.linesep)) + self._file.write('*** EOOH ***' + os.linesep) + self._file.write(message[:body_start].replace('\n', + os.linesep)) + self._file.write(message[body_start:].replace('\n', + os.linesep)) + else: + self._file.write('*** EOOH ***' + os.linesep + os.linesep) + self._file.write(message.replace('\n', os.linesep)) + elif hasattr(message, 'readline'): + original_pos = message.tell() + first_pass = True + while True: + line = message.readline() + self._file.write(line.replace('\n', os.linesep)) + if line == '\n' or line == '': + if first_pass: + first_pass = False + self._file.write('*** EOOH ***' + os.linesep) + message.seek(original_pos) + else: + break + while True: + buffer = message.read(4096) # Buffer size is arbitrary. + if buffer == '': + break + self._file.write(buffer.replace('\n', os.linesep)) + else: + raise TypeError('Invalid message type: %s' % type(message)) + stop = self._file.tell() + return (start, stop) + + +class Message(email.message.Message): + """Message with mailbox-format-specific properties.""" + + def __init__(self, message=None): + """Initialize a Message instance.""" + if isinstance(message, email.message.Message): + self._become_message(copy.deepcopy(message)) + if isinstance(message, Message): + message._explain_to(self) + elif isinstance(message, str): + self._become_message(email.message_from_string(message)) + elif hasattr(message, "read"): + self._become_message(email.message_from_file(message)) + elif message is None: + email.message.Message.__init__(self) + else: + raise TypeError('Invalid message type: %s' % type(message)) + + def _become_message(self, message): + """Assume the non-format-specific state of message.""" + for name in ('_headers', '_unixfrom', '_payload', '_charset', + 'preamble', 'epilogue', 'defects', '_default_type'): + self.__dict__[name] = message.__dict__[name] + + def _explain_to(self, message): + """Copy format-specific state to message insofar as possible.""" + if isinstance(message, Message): + return # There's nothing format-specific to explain. + else: + raise TypeError('Cannot convert to specified type') + + +class MaildirMessage(Message): + """Message with Maildir-specific properties.""" + + def __init__(self, message=None): + """Initialize a MaildirMessage instance.""" + self._subdir = 'new' + self._info = '' + self._date = time.time() + Message.__init__(self, message) + + def get_subdir(self): + """Return 'new' or 'cur'.""" + return self._subdir + + def set_subdir(self, subdir): + """Set subdir to 'new' or 'cur'.""" + if subdir == 'new' or subdir == 'cur': + self._subdir = subdir + else: + raise ValueError("subdir must be 'new' or 'cur': %s" % subdir) + + def get_flags(self): + """Return as a string the flags that are set.""" + if self._info.startswith('2,'): + return self._info[2:] + else: + return '' + + def set_flags(self, flags): + """Set the given flags and unset all others.""" + self._info = '2,' + ''.join(sorted(flags)) + + def add_flag(self, flag): + """Set the given flag(s) without changing others.""" + self.set_flags(''.join(set(self.get_flags()) | set(flag))) + + def remove_flag(self, flag): + """Unset the given string flag(s) without changing others.""" + if self.get_flags() != '': + self.set_flags(''.join(set(self.get_flags()) - set(flag))) + + def get_date(self): + """Return delivery date of message, in seconds since the epoch.""" + return self._date + + def set_date(self, date): + """Set delivery date of message, in seconds since the epoch.""" + try: + self._date = float(date) + except ValueError: + raise TypeError("can't convert to float: %s" % date) + + def get_info(self): + """Get the message's "info" as a string.""" + return self._info + + def set_info(self, info): + """Set the message's "info" string.""" + if isinstance(info, str): + self._info = info + else: + raise TypeError('info must be a string: %s' % type(info)) + + def _explain_to(self, message): + """Copy Maildir-specific state to message insofar as possible.""" + if isinstance(message, MaildirMessage): + message.set_flags(self.get_flags()) + message.set_subdir(self.get_subdir()) + message.set_date(self.get_date()) + elif isinstance(message, _mboxMMDFMessage): + flags = set(self.get_flags()) + if 'S' in flags: + message.add_flag('R') + if self.get_subdir() == 'cur': + message.add_flag('O') + if 'T' in flags: + message.add_flag('D') + if 'F' in flags: + message.add_flag('F') + if 'R' in flags: + message.add_flag('A') + message.set_from('MAILER-DAEMON', time.gmtime(self.get_date())) + elif isinstance(message, MHMessage): + flags = set(self.get_flags()) + if 'S' not in flags: + message.add_sequence('unseen') + if 'R' in flags: + message.add_sequence('replied') + if 'F' in flags: + message.add_sequence('flagged') + elif isinstance(message, BabylMessage): + flags = set(self.get_flags()) + if 'S' not in flags: + message.add_label('unseen') + if 'T' in flags: + message.add_label('deleted') + if 'R' in flags: + message.add_label('answered') + if 'P' in flags: + message.add_label('forwarded') + elif isinstance(message, Message): + pass + else: + raise TypeError('Cannot convert to specified type: %s' % + type(message)) + + +class _mboxMMDFMessage(Message): + """Message with mbox- or MMDF-specific properties.""" + + def __init__(self, message=None): + """Initialize an mboxMMDFMessage instance.""" + self.set_from('MAILER-DAEMON', True) + if isinstance(message, email.message.Message): + unixfrom = message.get_unixfrom() + if unixfrom is not None and unixfrom.startswith('From '): + self.set_from(unixfrom[5:]) + Message.__init__(self, message) + + def get_from(self): + """Return contents of "From " line.""" + return self._from + + def set_from(self, from_, time_=None): + """Set "From " line, formatting and appending time_ if specified.""" + if time_ is not None: + if time_ is True: + time_ = time.gmtime() + from_ += ' ' + time.asctime(time_) + self._from = from_ + + def get_flags(self): + """Return as a string the flags that are set.""" + return self.get('Status', '') + self.get('X-Status', '') + + def set_flags(self, flags): + """Set the given flags and unset all others.""" + flags = set(flags) + status_flags, xstatus_flags = '', '' + for flag in ('R', 'O'): + if flag in flags: + status_flags += flag + flags.remove(flag) + for flag in ('D', 'F', 'A'): + if flag in flags: + xstatus_flags += flag + flags.remove(flag) + xstatus_flags += ''.join(sorted(flags)) + try: + self.replace_header('Status', status_flags) + except KeyError: + self.add_header('Status', status_flags) + try: + self.replace_header('X-Status', xstatus_flags) + except KeyError: + self.add_header('X-Status', xstatus_flags) + + def add_flag(self, flag): + """Set the given flag(s) without changing others.""" + self.set_flags(''.join(set(self.get_flags()) | set(flag))) + + def remove_flag(self, flag): + """Unset the given string flag(s) without changing others.""" + if 'Status' in self or 'X-Status' in self: + self.set_flags(''.join(set(self.get_flags()) - set(flag))) + + def _explain_to(self, message): + """Copy mbox- or MMDF-specific state to message insofar as possible.""" + if isinstance(message, MaildirMessage): + flags = set(self.get_flags()) + if 'O' in flags: + message.set_subdir('cur') + if 'F' in flags: + message.add_flag('F') + if 'A' in flags: + message.add_flag('R') + if 'R' in flags: + message.add_flag('S') + if 'D' in flags: + message.add_flag('T') + del message['status'] + del message['x-status'] + maybe_date = ' '.join(self.get_from().split()[-5:]) + try: + message.set_date(calendar.timegm(time.strptime(maybe_date, + '%a %b %d %H:%M:%S %Y'))) + except (ValueError, OverflowError): + pass + elif isinstance(message, _mboxMMDFMessage): + message.set_flags(self.get_flags()) + message.set_from(self.get_from()) + elif isinstance(message, MHMessage): + flags = set(self.get_flags()) + if 'R' not in flags: + message.add_sequence('unseen') + if 'A' in flags: + message.add_sequence('replied') + if 'F' in flags: + message.add_sequence('flagged') + del message['status'] + del message['x-status'] + elif isinstance(message, BabylMessage): + flags = set(self.get_flags()) + if 'R' not in flags: + message.add_label('unseen') + if 'D' in flags: + message.add_label('deleted') + if 'A' in flags: + message.add_label('answered') + del message['status'] + del message['x-status'] + elif isinstance(message, Message): + pass + else: + raise TypeError('Cannot convert to specified type: %s' % + type(message)) + + +class mboxMessage(_mboxMMDFMessage): + """Message with mbox-specific properties.""" + + +class MHMessage(Message): + """Message with MH-specific properties.""" + + def __init__(self, message=None): + """Initialize an MHMessage instance.""" + self._sequences = [] + Message.__init__(self, message) + + def get_sequences(self): + """Return a list of sequences that include the message.""" + return self._sequences[:] + + def set_sequences(self, sequences): + """Set the list of sequences that include the message.""" + self._sequences = list(sequences) + + def add_sequence(self, sequence): + """Add sequence to list of sequences including the message.""" + if isinstance(sequence, str): + if not sequence in self._sequences: + self._sequences.append(sequence) + else: + raise TypeError('sequence must be a string: %s' % type(sequence)) + + def remove_sequence(self, sequence): + """Remove sequence from the list of sequences including the message.""" + try: + self._sequences.remove(sequence) + except ValueError: + pass + + def _explain_to(self, message): + """Copy MH-specific state to message insofar as possible.""" + if isinstance(message, MaildirMessage): + sequences = set(self.get_sequences()) + if 'unseen' in sequences: + message.set_subdir('cur') + else: + message.set_subdir('cur') + message.add_flag('S') + if 'flagged' in sequences: + message.add_flag('F') + if 'replied' in sequences: + message.add_flag('R') + elif isinstance(message, _mboxMMDFMessage): + sequences = set(self.get_sequences()) + if 'unseen' not in sequences: + message.add_flag('RO') + else: + message.add_flag('O') + if 'flagged' in sequences: + message.add_flag('F') + if 'replied' in sequences: + message.add_flag('A') + elif isinstance(message, MHMessage): + for sequence in self.get_sequences(): + message.add_sequence(sequence) + elif isinstance(message, BabylMessage): + sequences = set(self.get_sequences()) + if 'unseen' in sequences: + message.add_label('unseen') + if 'replied' in sequences: + message.add_label('answered') + elif isinstance(message, Message): + pass + else: + raise TypeError('Cannot convert to specified type: %s' % + type(message)) + + +class BabylMessage(Message): + """Message with Babyl-specific properties.""" + + def __init__(self, message=None): + """Initialize an BabylMessage instance.""" + self._labels = [] + self._visible = Message() + Message.__init__(self, message) + + def get_labels(self): + """Return a list of labels on the message.""" + return self._labels[:] + + def set_labels(self, labels): + """Set the list of labels on the message.""" + self._labels = list(labels) + + def add_label(self, label): + """Add label to list of labels on the message.""" + if isinstance(label, str): + if label not in self._labels: + self._labels.append(label) + else: + raise TypeError('label must be a string: %s' % type(label)) + + def remove_label(self, label): + """Remove label from the list of labels on the message.""" + try: + self._labels.remove(label) + except ValueError: + pass + + def get_visible(self): + """Return a Message representation of visible headers.""" + return Message(self._visible) + + def set_visible(self, visible): + """Set the Message representation of visible headers.""" + self._visible = Message(visible) + + def update_visible(self): + """Update and/or sensibly generate a set of visible headers.""" + for header in self._visible.keys(): + if header in self: + self._visible.replace_header(header, self[header]) + else: + del self._visible[header] + for header in ('Date', 'From', 'Reply-To', 'To', 'CC', 'Subject'): + if header in self and header not in self._visible: + self._visible[header] = self[header] + + def _explain_to(self, message): + """Copy Babyl-specific state to message insofar as possible.""" + if isinstance(message, MaildirMessage): + labels = set(self.get_labels()) + if 'unseen' in labels: + message.set_subdir('cur') + else: + message.set_subdir('cur') + message.add_flag('S') + if 'forwarded' in labels or 'resent' in labels: + message.add_flag('P') + if 'answered' in labels: + message.add_flag('R') + if 'deleted' in labels: + message.add_flag('T') + elif isinstance(message, _mboxMMDFMessage): + labels = set(self.get_labels()) + if 'unseen' not in labels: + message.add_flag('RO') + else: + message.add_flag('O') + if 'deleted' in labels: + message.add_flag('D') + if 'answered' in labels: + message.add_flag('A') + elif isinstance(message, MHMessage): + labels = set(self.get_labels()) + if 'unseen' in labels: + message.add_sequence('unseen') + if 'answered' in labels: + message.add_sequence('replied') + elif isinstance(message, BabylMessage): + message.set_visible(self.get_visible()) + for label in self.get_labels(): + message.add_label(label) + elif isinstance(message, Message): + pass + else: + raise TypeError('Cannot convert to specified type: %s' % + type(message)) + + +class MMDFMessage(_mboxMMDFMessage): + """Message with MMDF-specific properties.""" + + +class _ProxyFile: + """A read-only wrapper of a file.""" + + def __init__(self, f, pos=None): + """Initialize a _ProxyFile.""" + self._file = f + if pos is None: + self._pos = f.tell() + else: + self._pos = pos + + def read(self, size=None): + """Read bytes.""" + return self._read(size, self._file.read) + + def readline(self, size=None): + """Read a line.""" + return self._read(size, self._file.readline) + + def readlines(self, sizehint=None): + """Read multiple lines.""" + result = [] + for line in self: + result.append(line) + if sizehint is not None: + sizehint -= len(line) + if sizehint <= 0: + break + return result + + def __iter__(self): + """Iterate over lines.""" + return iter(self.readline, "") + + def tell(self): + """Return the position.""" + return self._pos + + def seek(self, offset, whence=0): + """Change position.""" + if whence == 1: + self._file.seek(self._pos) + self._file.seek(offset, whence) + self._pos = self._file.tell() + + def close(self): + """Close the file.""" + if hasattr(self, '_file'): + if hasattr(self._file, 'close'): + self._file.close() + del self._file + + def _read(self, size, read_method): + """Read size bytes using read_method.""" + if size is None: + size = -1 + self._file.seek(self._pos) + result = read_method(size) + self._pos = self._file.tell() + return result + + +class _PartialFile(_ProxyFile): + """A read-only wrapper of part of a file.""" + + def __init__(self, f, start=None, stop=None): + """Initialize a _PartialFile.""" + _ProxyFile.__init__(self, f, start) + self._start = start + self._stop = stop + + def tell(self): + """Return the position with respect to start.""" + return _ProxyFile.tell(self) - self._start + + def seek(self, offset, whence=0): + """Change position, possibly with respect to start or stop.""" + if whence == 0: + self._pos = self._start + whence = 1 + elif whence == 2: + self._pos = self._stop + whence = 1 + _ProxyFile.seek(self, offset, whence) + + def _read(self, size, read_method): + """Read size bytes using read_method, honoring start and stop.""" + remaining = self._stop - self._pos + if remaining <= 0: + return '' + if size is None or size < 0 or size > remaining: + size = remaining + return _ProxyFile._read(self, size, read_method) + + def close(self): + # do *not* close the underlying file object for partial files, + # since it's global to the mailbox object + if hasattr(self, '_file'): + del self._file + + +def _lock_file(f, dotlock=True): + """Lock file f using lockf and dot locking.""" + dotlock_done = False + try: + if fcntl: + try: + fcntl.lockf(f, fcntl.LOCK_EX | fcntl.LOCK_NB) + except IOError, e: + if e.errno in (errno.EAGAIN, errno.EACCES, errno.EROFS): + raise ExternalClashError('lockf: lock unavailable: %s' % + f.name) + else: + raise + if dotlock: + try: + pre_lock = _create_temporary(f.name + '.lock') + pre_lock.close() + except IOError, e: + if e.errno in (errno.EACCES, errno.EROFS): + return # Without write access, just skip dotlocking. + else: + raise + try: + if hasattr(os, 'link'): + os.link(pre_lock.name, f.name + '.lock') + dotlock_done = True + os.unlink(pre_lock.name) + else: + os.rename(pre_lock.name, f.name + '.lock') + dotlock_done = True + except OSError, e: + if e.errno == errno.EEXIST or \ + (os.name == 'os2' and e.errno == errno.EACCES): + os.remove(pre_lock.name) + raise ExternalClashError('dot lock unavailable: %s' % + f.name) + else: + raise + except: + if fcntl: + fcntl.lockf(f, fcntl.LOCK_UN) + if dotlock_done: + os.remove(f.name + '.lock') + raise + +def _unlock_file(f): + """Unlock file f using lockf and dot locking.""" + if fcntl: + fcntl.lockf(f, fcntl.LOCK_UN) + if os.path.exists(f.name + '.lock'): + os.remove(f.name + '.lock') + +def _create_carefully(path): + """Create a file if it doesn't exist and open for reading and writing.""" + fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0666) + try: + return open(path, 'rb+') + finally: + os.close(fd) + +def _create_temporary(path): + """Create a temp file based on path and open for reading and writing.""" + return _create_carefully('%s.%s.%s.%s' % (path, int(time.time()), + socket.gethostname(), + os.getpid())) + +def _sync_flush(f): + """Ensure changes to file f are physically on disk.""" + f.flush() + if hasattr(os, 'fsync'): + os.fsync(f.fileno()) + +def _sync_close(f): + """Close file f, ensuring all changes are physically on disk.""" + _sync_flush(f) + f.close() + +## Start: classes from the original module (for backward compatibility). + +# Note that the Maildir class, whose name is unchanged, itself offers a next() +# method for backward compatibility. + +class _Mailbox: + + def __init__(self, fp, factory=rfc822.Message): + self.fp = fp + self.seekp = 0 + self.factory = factory + + def __iter__(self): + return iter(self.next, None) + + def next(self): + while 1: + self.fp.seek(self.seekp) + try: + self._search_start() + except EOFError: + self.seekp = self.fp.tell() + return None + start = self.fp.tell() + self._search_end() + self.seekp = stop = self.fp.tell() + if start != stop: + break + return self.factory(_PartialFile(self.fp, start, stop)) + +# Recommended to use PortableUnixMailbox instead! +class UnixMailbox(_Mailbox): + + def _search_start(self): + while 1: + pos = self.fp.tell() + line = self.fp.readline() + if not line: + raise EOFError + if line[:5] == 'From ' and self._isrealfromline(line): + self.fp.seek(pos) + return + + def _search_end(self): + self.fp.readline() # Throw away header line + while 1: + pos = self.fp.tell() + line = self.fp.readline() + if not line: + return + if line[:5] == 'From ' and self._isrealfromline(line): + self.fp.seek(pos) + return + + # An overridable mechanism to test for From-line-ness. You can either + # specify a different regular expression or define a whole new + # _isrealfromline() method. Note that this only gets called for lines + # starting with the 5 characters "From ". + # + # BAW: According to + #http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html + # the only portable, reliable way to find message delimiters in a BSD (i.e + # Unix mailbox) style folder is to search for "\n\nFrom .*\n", or at the + # beginning of the file, "^From .*\n". While _fromlinepattern below seems + # like a good idea, in practice, there are too many variations for more + # strict parsing of the line to be completely accurate. + # + # _strict_isrealfromline() is the old version which tries to do stricter + # parsing of the From_ line. _portable_isrealfromline() simply returns + # true, since it's never called if the line doesn't already start with + # "From ". + # + # This algorithm, and the way it interacts with _search_start() and + # _search_end() may not be completely correct, because it doesn't check + # that the two characters preceding "From " are \n\n or the beginning of + # the file. Fixing this would require a more extensive rewrite than is + # necessary. For convenience, we've added a PortableUnixMailbox class + # which does no checking of the format of the 'From' line. + + _fromlinepattern = (r"From \s*[^\s]+\s+\w\w\w\s+\w\w\w\s+\d?\d\s+" + r"\d?\d:\d\d(:\d\d)?(\s+[^\s]+)?\s+\d\d\d\d\s*" + r"[^\s]*\s*" + "$") + _regexp = None + + def _strict_isrealfromline(self, line): + if not self._regexp: + import re + self._regexp = re.compile(self._fromlinepattern) + return self._regexp.match(line) + + def _portable_isrealfromline(self, line): + return True + + _isrealfromline = _strict_isrealfromline + + +class PortableUnixMailbox(UnixMailbox): + _isrealfromline = UnixMailbox._portable_isrealfromline + + +class MmdfMailbox(_Mailbox): + + def _search_start(self): + while 1: + line = self.fp.readline() + if not line: + raise EOFError + if line[:5] == '\001\001\001\001\n': + return + + def _search_end(self): + while 1: + pos = self.fp.tell() + line = self.fp.readline() + if not line: + return + if line == '\001\001\001\001\n': + self.fp.seek(pos) + return + + +class MHMailbox: + + def __init__(self, dirname, factory=rfc822.Message): + import re + pat = re.compile('^[1-9][0-9]*$') + self.dirname = dirname + # the three following lines could be combined into: + # list = map(long, filter(pat.match, os.listdir(self.dirname))) + list = os.listdir(self.dirname) + list = filter(pat.match, list) + list = map(long, list) + list.sort() + # This only works in Python 1.6 or later; + # before that str() added 'L': + self.boxes = map(str, list) + self.boxes.reverse() + self.factory = factory + + def __iter__(self): + return iter(self.next, None) + + def next(self): + if not self.boxes: + return None + fn = self.boxes.pop() + fp = open(os.path.join(self.dirname, fn)) + msg = self.factory(fp) + try: + msg._mh_msgno = fn + except (AttributeError, TypeError): + pass + return msg + + +class BabylMailbox(_Mailbox): + + def _search_start(self): + while 1: + line = self.fp.readline() + if not line: + raise EOFError + if line == '*** EOOH ***\n': + return + + def _search_end(self): + while 1: + pos = self.fp.tell() + line = self.fp.readline() + if not line: + return + if line == '\037\014\n' or line == '\037': + self.fp.seek(pos) + return + +## End: classes from the original module (for backward compatibility). + + +class Error(Exception): + """Raised for module-specific errors.""" + +class NoSuchMailboxError(Error): + """The specified mailbox does not exist and won't be created.""" + +class NotEmptyError(Error): + """The specified mailbox is not empty and deletion was requested.""" + +class ExternalClashError(Error): + """Another process caused an action to fail.""" + +class FormatError(Error): + """A file appears to have an invalid format.""" diff --git a/src/main/resources/PythonLibs/mailcap.py b/src/main/resources/PythonLibs/mailcap.py new file mode 100644 index 0000000000000000000000000000000000000000..b2ddacd046db4555b65ebd84455dc38a70e9b486 --- /dev/null +++ b/src/main/resources/PythonLibs/mailcap.py @@ -0,0 +1,255 @@ +"""Mailcap file handling. See RFC 1524.""" + +import os + +__all__ = ["getcaps","findmatch"] + +# Part 1: top-level interface. + +def getcaps(): + """Return a dictionary containing the mailcap database. + + The dictionary maps a MIME type (in all lowercase, e.g. 'text/plain') + to a list of dictionaries corresponding to mailcap entries. The list + collects all the entries for that MIME type from all available mailcap + files. Each dictionary contains key-value pairs for that MIME type, + where the viewing command is stored with the key "view". + + """ + caps = {} + for mailcap in listmailcapfiles(): + try: + fp = open(mailcap, 'r') + except IOError: + continue + morecaps = readmailcapfile(fp) + fp.close() + for key, value in morecaps.iteritems(): + if not key in caps: + caps[key] = value + else: + caps[key] = caps[key] + value + return caps + +def listmailcapfiles(): + """Return a list of all mailcap files found on the system.""" + # XXX Actually, this is Unix-specific + if 'MAILCAPS' in os.environ: + str = os.environ['MAILCAPS'] + mailcaps = str.split(':') + else: + if 'HOME' in os.environ: + home = os.environ['HOME'] + else: + # Don't bother with getpwuid() + home = '.' # Last resort + mailcaps = [home + '/.mailcap', '/etc/mailcap', + '/usr/etc/mailcap', '/usr/local/etc/mailcap'] + return mailcaps + + +# Part 2: the parser. + +def readmailcapfile(fp): + """Read a mailcap file and return a dictionary keyed by MIME type. + + Each MIME type is mapped to an entry consisting of a list of + dictionaries; the list will contain more than one such dictionary + if a given MIME type appears more than once in the mailcap file. + Each dictionary contains key-value pairs for that MIME type, where + the viewing command is stored with the key "view". + """ + caps = {} + while 1: + line = fp.readline() + if not line: break + # Ignore comments and blank lines + if line[0] == '#' or line.strip() == '': + continue + nextline = line + # Join continuation lines + while nextline[-2:] == '\\\n': + nextline = fp.readline() + if not nextline: nextline = '\n' + line = line[:-2] + nextline + # Parse the line + key, fields = parseline(line) + if not (key and fields): + continue + # Normalize the key + types = key.split('/') + for j in range(len(types)): + types[j] = types[j].strip() + key = '/'.join(types).lower() + # Update the database + if key in caps: + caps[key].append(fields) + else: + caps[key] = [fields] + return caps + +def parseline(line): + """Parse one entry in a mailcap file and return a dictionary. + + The viewing command is stored as the value with the key "view", + and the rest of the fields produce key-value pairs in the dict. + """ + fields = [] + i, n = 0, len(line) + while i < n: + field, i = parsefield(line, i, n) + fields.append(field) + i = i+1 # Skip semicolon + if len(fields) < 2: + return None, None + key, view, rest = fields[0], fields[1], fields[2:] + fields = {'view': view} + for field in rest: + i = field.find('=') + if i < 0: + fkey = field + fvalue = "" + else: + fkey = field[:i].strip() + fvalue = field[i+1:].strip() + if fkey in fields: + # Ignore it + pass + else: + fields[fkey] = fvalue + return key, fields + +def parsefield(line, i, n): + """Separate one key-value pair in a mailcap entry.""" + start = i + while i < n: + c = line[i] + if c == ';': + break + elif c == '\\': + i = i+2 + else: + i = i+1 + return line[start:i].strip(), i + + +# Part 3: using the database. + +def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]): + """Find a match for a mailcap entry. + + Return a tuple containing the command line, and the mailcap entry + used; (None, None) if no match is found. This may invoke the + 'test' command of several matching entries before deciding which + entry to use. + + """ + entries = lookup(caps, MIMEtype, key) + # XXX This code should somehow check for the needsterminal flag. + for e in entries: + if 'test' in e: + test = subst(e['test'], filename, plist) + if test and os.system(test) != 0: + continue + command = subst(e[key], MIMEtype, filename, plist) + return command, e + return None, None + +def lookup(caps, MIMEtype, key=None): + entries = [] + if MIMEtype in caps: + entries = entries + caps[MIMEtype] + MIMEtypes = MIMEtype.split('/') + MIMEtype = MIMEtypes[0] + '/*' + if MIMEtype in caps: + entries = entries + caps[MIMEtype] + if key is not None: + entries = filter(lambda e, key=key: key in e, entries) + return entries + +def subst(field, MIMEtype, filename, plist=[]): + # XXX Actually, this is Unix-specific + res = '' + i, n = 0, len(field) + while i < n: + c = field[i]; i = i+1 + if c != '%': + if c == '\\': + c = field[i:i+1]; i = i+1 + res = res + c + else: + c = field[i]; i = i+1 + if c == '%': + res = res + c + elif c == 's': + res = res + filename + elif c == 't': + res = res + MIMEtype + elif c == '{': + start = i + while i < n and field[i] != '}': + i = i+1 + name = field[start:i] + i = i+1 + res = res + findparam(name, plist) + # XXX To do: + # %n == number of parts if type is multipart/* + # %F == list of alternating type and filename for parts + else: + res = res + '%' + c + return res + +def findparam(name, plist): + name = name.lower() + '=' + n = len(name) + for p in plist: + if p[:n].lower() == name: + return p[n:] + return '' + + +# Part 4: test program. + +def test(): + import sys + caps = getcaps() + if not sys.argv[1:]: + show(caps) + return + for i in range(1, len(sys.argv), 2): + args = sys.argv[i:i+2] + if len(args) < 2: + print "usage: mailcap [MIMEtype file] ..." + return + MIMEtype = args[0] + file = args[1] + command, e = findmatch(caps, MIMEtype, 'view', file) + if not command: + print "No viewer found for", type + else: + print "Executing:", command + sts = os.system(command) + if sts: + print "Exit status:", sts + +def show(caps): + print "Mailcap files:" + for fn in listmailcapfiles(): print "\t" + fn + print + if not caps: caps = getcaps() + print "Mailcap entries:" + print + ckeys = caps.keys() + ckeys.sort() + for type in ckeys: + print type + entries = caps[type] + for e in entries: + keys = e.keys() + keys.sort() + for k in keys: + print " %-15s" % k, e[k] + print + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/markupbase.py b/src/main/resources/PythonLibs/markupbase.py new file mode 100644 index 0000000000000000000000000000000000000000..ddeb9835b80e5d76144c82a96cd394ccc9fe6fb8 --- /dev/null +++ b/src/main/resources/PythonLibs/markupbase.py @@ -0,0 +1,396 @@ +"""Shared support for scanning document type declarations in HTML and XHTML. + +This module is used as a foundation for the HTMLParser and sgmllib +modules (indirectly, for htmllib as well). It has no documented +public API and should not be used directly. + +""" + +import re + +_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*').match +_declstringlit_match = re.compile(r'(\'[^\']*\'|"[^"]*")\s*').match +_commentclose = re.compile(r'--\s*>') +_markedsectionclose = re.compile(r']\s*]\s*>') + +# An analysis of the MS-Word extensions is available at +# http://www.planetpublish.com/xmlarena/xap/Thursday/WordtoXML.pdf + +_msmarkedsectionclose = re.compile(r']\s*>') + +del re + + +class ParserBase: + """Parser base class which provides some common support methods used + by the SGML/HTML and XHTML parsers.""" + + def __init__(self): + if self.__class__ is ParserBase: + raise RuntimeError( + "markupbase.ParserBase must be subclassed") + + def error(self, message): + raise NotImplementedError( + "subclasses of ParserBase must override error()") + + def reset(self): + self.lineno = 1 + self.offset = 0 + + def getpos(self): + """Return current line number and offset.""" + return self.lineno, self.offset + + # Internal -- update line number and offset. This should be + # called for each piece of data exactly once, in order -- in other + # words the concatenation of all the input strings to this + # function should be exactly the entire input. + def updatepos(self, i, j): + if i >= j: + return j + rawdata = self.rawdata + nlines = rawdata.count("\n", i, j) + if nlines: + self.lineno = self.lineno + nlines + pos = rawdata.rindex("\n", i, j) # Should not fail + self.offset = j-(pos+1) + else: + self.offset = self.offset + j-i + return j + + _decl_otherchars = '' + + # Internal -- parse declaration (for use by subclasses). + def parse_declaration(self, i): + # This is some sort of declaration; in "HTML as + # deployed," this should only be the document type + # declaration ("<!DOCTYPE html...>"). + # ISO 8879:1986, however, has more complex + # declaration syntax for elements in <!...>, including: + # --comment-- + # [marked section] + # name in the following list: ENTITY, DOCTYPE, ELEMENT, + # ATTLIST, NOTATION, SHORTREF, USEMAP, + # LINKTYPE, LINK, IDLINK, USELINK, SYSTEM + rawdata = self.rawdata + j = i + 2 + assert rawdata[i:j] == "<!", "unexpected call to parse_declaration" + if rawdata[j:j+1] == ">": + # the empty comment <!> + return j + 1 + if rawdata[j:j+1] in ("-", ""): + # Start of comment followed by buffer boundary, + # or just a buffer boundary. + return -1 + # A simple, practical version could look like: ((name|stringlit) S*) + '>' + n = len(rawdata) + if rawdata[j:j+2] == '--': #comment + # Locate --.*-- as the body of the comment + return self.parse_comment(i) + elif rawdata[j] == '[': #marked section + # Locate [statusWord [...arbitrary SGML...]] as the body of the marked section + # Where statusWord is one of TEMP, CDATA, IGNORE, INCLUDE, RCDATA + # Note that this is extended by Microsoft Office "Save as Web" function + # to include [if...] and [endif]. + return self.parse_marked_section(i) + else: #all other declaration elements + decltype, j = self._scan_name(j, i) + if j < 0: + return j + if decltype == "doctype": + self._decl_otherchars = '' + while j < n: + c = rawdata[j] + if c == ">": + # end of declaration syntax + data = rawdata[i+2:j] + if decltype == "doctype": + self.handle_decl(data) + else: + # According to the HTML5 specs sections "8.2.4.44 Bogus + # comment state" and "8.2.4.45 Markup declaration open + # state", a comment token should be emitted. + # Calling unknown_decl provides more flexibility though. + self.unknown_decl(data) + return j + 1 + if c in "\"'": + m = _declstringlit_match(rawdata, j) + if not m: + return -1 # incomplete + j = m.end() + elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": + name, j = self._scan_name(j, i) + elif c in self._decl_otherchars: + j = j + 1 + elif c == "[": + # this could be handled in a separate doctype parser + if decltype == "doctype": + j = self._parse_doctype_subset(j + 1, i) + elif decltype in ("attlist", "linktype", "link", "element"): + # must tolerate []'d groups in a content model in an element declaration + # also in data attribute specifications of attlist declaration + # also link type declaration subsets in linktype declarations + # also link attribute specification lists in link declarations + self.error("unsupported '[' char in %s declaration" % decltype) + else: + self.error("unexpected '[' char in declaration") + else: + self.error( + "unexpected %r char in declaration" % rawdata[j]) + if j < 0: + return j + return -1 # incomplete + + # Internal -- parse a marked section + # Override this to handle MS-word extension syntax <![if word]>content<![endif]> + def parse_marked_section(self, i, report=1): + rawdata= self.rawdata + assert rawdata[i:i+3] == '<![', "unexpected call to parse_marked_section()" + sectName, j = self._scan_name( i+3, i ) + if j < 0: + return j + if sectName in ("temp", "cdata", "ignore", "include", "rcdata"): + # look for standard ]]> ending + match= _markedsectionclose.search(rawdata, i+3) + elif sectName in ("if", "else", "endif"): + # look for MS Office ]> ending + match= _msmarkedsectionclose.search(rawdata, i+3) + else: + self.error('unknown status keyword %r in marked section' % rawdata[i+3:j]) + if not match: + return -1 + if report: + j = match.start(0) + self.unknown_decl(rawdata[i+3: j]) + return match.end(0) + + # Internal -- parse comment, return length or -1 if not terminated + def parse_comment(self, i, report=1): + rawdata = self.rawdata + if rawdata[i:i+4] != '<!--': + self.error('unexpected call to parse_comment()') + match = _commentclose.search(rawdata, i+4) + if not match: + return -1 + if report: + j = match.start(0) + self.handle_comment(rawdata[i+4: j]) + return match.end(0) + + # Internal -- scan past the internal subset in a <!DOCTYPE declaration, + # returning the index just past any whitespace following the trailing ']'. + def _parse_doctype_subset(self, i, declstartpos): + rawdata = self.rawdata + n = len(rawdata) + j = i + while j < n: + c = rawdata[j] + if c == "<": + s = rawdata[j:j+2] + if s == "<": + # end of buffer; incomplete + return -1 + if s != "<!": + self.updatepos(declstartpos, j + 1) + self.error("unexpected char in internal subset (in %r)" % s) + if (j + 2) == n: + # end of buffer; incomplete + return -1 + if (j + 4) > n: + # end of buffer; incomplete + return -1 + if rawdata[j:j+4] == "<!--": + j = self.parse_comment(j, report=0) + if j < 0: + return j + continue + name, j = self._scan_name(j + 2, declstartpos) + if j == -1: + return -1 + if name not in ("attlist", "element", "entity", "notation"): + self.updatepos(declstartpos, j + 2) + self.error( + "unknown declaration %r in internal subset" % name) + # handle the individual names + meth = getattr(self, "_parse_doctype_" + name) + j = meth(j, declstartpos) + if j < 0: + return j + elif c == "%": + # parameter entity reference + if (j + 1) == n: + # end of buffer; incomplete + return -1 + s, j = self._scan_name(j + 1, declstartpos) + if j < 0: + return j + if rawdata[j] == ";": + j = j + 1 + elif c == "]": + j = j + 1 + while j < n and rawdata[j].isspace(): + j = j + 1 + if j < n: + if rawdata[j] == ">": + return j + self.updatepos(declstartpos, j) + self.error("unexpected char after internal subset") + else: + return -1 + elif c.isspace(): + j = j + 1 + else: + self.updatepos(declstartpos, j) + self.error("unexpected char %r in internal subset" % c) + # end of buffer reached + return -1 + + # Internal -- scan past <!ELEMENT declarations + def _parse_doctype_element(self, i, declstartpos): + name, j = self._scan_name(i, declstartpos) + if j == -1: + return -1 + # style content model; just skip until '>' + rawdata = self.rawdata + if '>' in rawdata[j:]: + return rawdata.find(">", j) + 1 + return -1 + + # Internal -- scan past <!ATTLIST declarations + def _parse_doctype_attlist(self, i, declstartpos): + rawdata = self.rawdata + name, j = self._scan_name(i, declstartpos) + c = rawdata[j:j+1] + if c == "": + return -1 + if c == ">": + return j + 1 + while 1: + # scan a series of attribute descriptions; simplified: + # name type [value] [#constraint] + name, j = self._scan_name(j, declstartpos) + if j < 0: + return j + c = rawdata[j:j+1] + if c == "": + return -1 + if c == "(": + # an enumerated type; look for ')' + if ")" in rawdata[j:]: + j = rawdata.find(")", j) + 1 + else: + return -1 + while rawdata[j:j+1].isspace(): + j = j + 1 + if not rawdata[j:]: + # end of buffer, incomplete + return -1 + else: + name, j = self._scan_name(j, declstartpos) + c = rawdata[j:j+1] + if not c: + return -1 + if c in "'\"": + m = _declstringlit_match(rawdata, j) + if m: + j = m.end() + else: + return -1 + c = rawdata[j:j+1] + if not c: + return -1 + if c == "#": + if rawdata[j:] == "#": + # end of buffer + return -1 + name, j = self._scan_name(j + 1, declstartpos) + if j < 0: + return j + c = rawdata[j:j+1] + if not c: + return -1 + if c == '>': + # all done + return j + 1 + + # Internal -- scan past <!NOTATION declarations + def _parse_doctype_notation(self, i, declstartpos): + name, j = self._scan_name(i, declstartpos) + if j < 0: + return j + rawdata = self.rawdata + while 1: + c = rawdata[j:j+1] + if not c: + # end of buffer; incomplete + return -1 + if c == '>': + return j + 1 + if c in "'\"": + m = _declstringlit_match(rawdata, j) + if not m: + return -1 + j = m.end() + else: + name, j = self._scan_name(j, declstartpos) + if j < 0: + return j + + # Internal -- scan past <!ENTITY declarations + def _parse_doctype_entity(self, i, declstartpos): + rawdata = self.rawdata + if rawdata[i:i+1] == "%": + j = i + 1 + while 1: + c = rawdata[j:j+1] + if not c: + return -1 + if c.isspace(): + j = j + 1 + else: + break + else: + j = i + name, j = self._scan_name(j, declstartpos) + if j < 0: + return j + while 1: + c = self.rawdata[j:j+1] + if not c: + return -1 + if c in "'\"": + m = _declstringlit_match(rawdata, j) + if m: + j = m.end() + else: + return -1 # incomplete + elif c == ">": + return j + 1 + else: + name, j = self._scan_name(j, declstartpos) + if j < 0: + return j + + # Internal -- scan a name token and the new position and the token, or + # return -1 if we've reached the end of the buffer. + def _scan_name(self, i, declstartpos): + rawdata = self.rawdata + n = len(rawdata) + if i == n: + return None, -1 + m = _declname_match(rawdata, i) + if m: + s = m.group() + name = s.strip() + if (i + len(s)) == n: + return None, -1 # end of buffer + return name.lower(), m.end() + else: + self.updatepos(declstartpos, i) + self.error("expected name token at %r" + % rawdata[declstartpos:declstartpos+20]) + + # To be overridden -- handlers for unknown objects + def unknown_decl(self, data): + pass diff --git a/src/main/resources/PythonLibs/marshal.py b/src/main/resources/PythonLibs/marshal.py new file mode 100644 index 0000000000000000000000000000000000000000..ea8b2913444e6c8cfeecbb04649fdb5ec7f507d1 --- /dev/null +++ b/src/main/resources/PythonLibs/marshal.py @@ -0,0 +1,28 @@ +"""Marshal module written in Python. + +This doesn't marshal code objects, but supports everything else. +Performance or careful error checking is not an issue. + +""" + +import cStringIO +from _marshal import Marshaller, Unmarshaller + +def dump(x, f, version=2): + Marshaller(f, version).dump(x) + +# XXX - added just for debugging. remove! +def load(f, debug=False): + u = Unmarshaller(f) + if debug: + u._debug() + return u.load() + +def dumps(x, version=2): + f = cStringIO.StringIO() + dump(x, f, version) + return f.getvalue() + +def loads(s): + f = cStringIO.StringIO(s) + return load(f) diff --git a/src/main/resources/PythonLibs/md5.py b/src/main/resources/PythonLibs/md5.py new file mode 100644 index 0000000000000000000000000000000000000000..a44ca3b49340283afa075b12b3abd7ed0bbf8815 --- /dev/null +++ b/src/main/resources/PythonLibs/md5.py @@ -0,0 +1,14 @@ +# $Id$ +# +# Copyright (C) 2005 Gregory P. Smith (greg@krypto.org) +# Licensed to PSF under a Contributor Agreement. + +import warnings +warnings.warn("the md5 module is deprecated; use hashlib instead", + DeprecationWarning, 2) + +from hashlib import md5 +new = md5 + +blocksize = 1 # legacy value (wrong in any useful sense) +digest_size = 16 diff --git a/src/main/resources/PythonLibs/mhlib.py b/src/main/resources/PythonLibs/mhlib.py new file mode 100644 index 0000000000000000000000000000000000000000..856e87804cd968ca90a21e27c5be22e30236c1ce --- /dev/null +++ b/src/main/resources/PythonLibs/mhlib.py @@ -0,0 +1,1005 @@ +"""MH interface -- purely object-oriented (well, almost) + +Executive summary: + +import mhlib + +mh = mhlib.MH() # use default mailbox directory and profile +mh = mhlib.MH(mailbox) # override mailbox location (default from profile) +mh = mhlib.MH(mailbox, profile) # override mailbox and profile + +mh.error(format, ...) # print error message -- can be overridden +s = mh.getprofile(key) # profile entry (None if not set) +path = mh.getpath() # mailbox pathname +name = mh.getcontext() # name of current folder +mh.setcontext(name) # set name of current folder + +list = mh.listfolders() # names of top-level folders +list = mh.listallfolders() # names of all folders, including subfolders +list = mh.listsubfolders(name) # direct subfolders of given folder +list = mh.listallsubfolders(name) # all subfolders of given folder + +mh.makefolder(name) # create new folder +mh.deletefolder(name) # delete folder -- must have no subfolders + +f = mh.openfolder(name) # new open folder object + +f.error(format, ...) # same as mh.error(format, ...) +path = f.getfullname() # folder's full pathname +path = f.getsequencesfilename() # full pathname of folder's sequences file +path = f.getmessagefilename(n) # full pathname of message n in folder + +list = f.listmessages() # list of messages in folder (as numbers) +n = f.getcurrent() # get current message +f.setcurrent(n) # set current message +list = f.parsesequence(seq) # parse msgs syntax into list of messages +n = f.getlast() # get last message (0 if no messagse) +f.setlast(n) # set last message (internal use only) + +dict = f.getsequences() # dictionary of sequences in folder {name: list} +f.putsequences(dict) # write sequences back to folder + +f.createmessage(n, fp) # add message from file f as number n +f.removemessages(list) # remove messages in list from folder +f.refilemessages(list, tofolder) # move messages in list to other folder +f.movemessage(n, tofolder, ton) # move one message to a given destination +f.copymessage(n, tofolder, ton) # copy one message to a given destination + +m = f.openmessage(n) # new open message object (costs a file descriptor) +m is a derived class of mimetools.Message(rfc822.Message), with: +s = m.getheadertext() # text of message's headers +s = m.getheadertext(pred) # text of message's headers, filtered by pred +s = m.getbodytext() # text of message's body, decoded +s = m.getbodytext(0) # text of message's body, not decoded +""" +from warnings import warnpy3k +warnpy3k("the mhlib module has been removed in Python 3.0; use the mailbox " + "module instead", stacklevel=2) +del warnpy3k + +# XXX To do, functionality: +# - annotate messages +# - send messages +# +# XXX To do, organization: +# - move IntSet to separate file +# - move most Message functionality to module mimetools + + +# Customizable defaults + +MH_PROFILE = '~/.mh_profile' +PATH = '~/Mail' +MH_SEQUENCES = '.mh_sequences' +FOLDER_PROTECT = 0700 + + +# Imported modules + +import os +import sys +import re +import mimetools +import multifile +import shutil +from bisect import bisect + +__all__ = ["MH","Error","Folder","Message"] + +# Exported constants + +class Error(Exception): + pass + + +class MH: + """Class representing a particular collection of folders. + Optional constructor arguments are the pathname for the directory + containing the collection, and the MH profile to use. + If either is omitted or empty a default is used; the default + directory is taken from the MH profile if it is specified there.""" + + def __init__(self, path = None, profile = None): + """Constructor.""" + if profile is None: profile = MH_PROFILE + self.profile = os.path.expanduser(profile) + if path is None: path = self.getprofile('Path') + if not path: path = PATH + if not os.path.isabs(path) and path[0] != '~': + path = os.path.join('~', path) + path = os.path.expanduser(path) + if not os.path.isdir(path): raise Error, 'MH() path not found' + self.path = path + + def __repr__(self): + """String representation.""" + return 'MH(%r, %r)' % (self.path, self.profile) + + def error(self, msg, *args): + """Routine to print an error. May be overridden by a derived class.""" + sys.stderr.write('MH error: %s\n' % (msg % args)) + + def getprofile(self, key): + """Return a profile entry, None if not found.""" + return pickline(self.profile, key) + + def getpath(self): + """Return the path (the name of the collection's directory).""" + return self.path + + def getcontext(self): + """Return the name of the current folder.""" + context = pickline(os.path.join(self.getpath(), 'context'), + 'Current-Folder') + if not context: context = 'inbox' + return context + + def setcontext(self, context): + """Set the name of the current folder.""" + fn = os.path.join(self.getpath(), 'context') + f = open(fn, "w") + f.write("Current-Folder: %s\n" % context) + f.close() + + def listfolders(self): + """Return the names of the top-level folders.""" + folders = [] + path = self.getpath() + for name in os.listdir(path): + fullname = os.path.join(path, name) + if os.path.isdir(fullname): + folders.append(name) + folders.sort() + return folders + + def listsubfolders(self, name): + """Return the names of the subfolders in a given folder + (prefixed with the given folder name).""" + fullname = os.path.join(self.path, name) + # Get the link count so we can avoid listing folders + # that have no subfolders. + nlinks = os.stat(fullname).st_nlink + if nlinks <= 2: + return [] + subfolders = [] + subnames = os.listdir(fullname) + for subname in subnames: + fullsubname = os.path.join(fullname, subname) + if os.path.isdir(fullsubname): + name_subname = os.path.join(name, subname) + subfolders.append(name_subname) + # Stop looking for subfolders when + # we've seen them all + nlinks = nlinks - 1 + if nlinks <= 2: + break + subfolders.sort() + return subfolders + + def listallfolders(self): + """Return the names of all folders and subfolders, recursively.""" + return self.listallsubfolders('') + + def listallsubfolders(self, name): + """Return the names of subfolders in a given folder, recursively.""" + fullname = os.path.join(self.path, name) + # Get the link count so we can avoid listing folders + # that have no subfolders. + nlinks = os.stat(fullname).st_nlink + if nlinks <= 2: + return [] + subfolders = [] + subnames = os.listdir(fullname) + for subname in subnames: + if subname[0] == ',' or isnumeric(subname): continue + fullsubname = os.path.join(fullname, subname) + if os.path.isdir(fullsubname): + name_subname = os.path.join(name, subname) + subfolders.append(name_subname) + if not os.path.islink(fullsubname): + subsubfolders = self.listallsubfolders( + name_subname) + subfolders = subfolders + subsubfolders + # Stop looking for subfolders when + # we've seen them all + nlinks = nlinks - 1 + if nlinks <= 2: + break + subfolders.sort() + return subfolders + + def openfolder(self, name): + """Return a new Folder object for the named folder.""" + return Folder(self, name) + + def makefolder(self, name): + """Create a new folder (or raise os.error if it cannot be created).""" + protect = pickline(self.profile, 'Folder-Protect') + if protect and isnumeric(protect): + mode = int(protect, 8) + else: + mode = FOLDER_PROTECT + os.mkdir(os.path.join(self.getpath(), name), mode) + + def deletefolder(self, name): + """Delete a folder. This removes files in the folder but not + subdirectories. Raise os.error if deleting the folder itself fails.""" + fullname = os.path.join(self.getpath(), name) + for subname in os.listdir(fullname): + fullsubname = os.path.join(fullname, subname) + try: + os.unlink(fullsubname) + except os.error: + self.error('%s not deleted, continuing...' % + fullsubname) + os.rmdir(fullname) + + +numericprog = re.compile('^[1-9][0-9]*$') +def isnumeric(str): + return numericprog.match(str) is not None + +class Folder: + """Class representing a particular folder.""" + + def __init__(self, mh, name): + """Constructor.""" + self.mh = mh + self.name = name + if not os.path.isdir(self.getfullname()): + raise Error, 'no folder %s' % name + + def __repr__(self): + """String representation.""" + return 'Folder(%r, %r)' % (self.mh, self.name) + + def error(self, *args): + """Error message handler.""" + self.mh.error(*args) + + def getfullname(self): + """Return the full pathname of the folder.""" + return os.path.join(self.mh.path, self.name) + + def getsequencesfilename(self): + """Return the full pathname of the folder's sequences file.""" + return os.path.join(self.getfullname(), MH_SEQUENCES) + + def getmessagefilename(self, n): + """Return the full pathname of a message in the folder.""" + return os.path.join(self.getfullname(), str(n)) + + def listsubfolders(self): + """Return list of direct subfolders.""" + return self.mh.listsubfolders(self.name) + + def listallsubfolders(self): + """Return list of all subfolders.""" + return self.mh.listallsubfolders(self.name) + + def listmessages(self): + """Return the list of messages currently present in the folder. + As a side effect, set self.last to the last message (or 0).""" + messages = [] + match = numericprog.match + append = messages.append + for name in os.listdir(self.getfullname()): + if match(name): + append(name) + messages = map(int, messages) + messages.sort() + if messages: + self.last = messages[-1] + else: + self.last = 0 + return messages + + def getsequences(self): + """Return the set of sequences for the folder.""" + sequences = {} + fullname = self.getsequencesfilename() + try: + f = open(fullname, 'r') + except IOError: + return sequences + while 1: + line = f.readline() + if not line: break + fields = line.split(':') + if len(fields) != 2: + self.error('bad sequence in %s: %s' % + (fullname, line.strip())) + key = fields[0].strip() + value = IntSet(fields[1].strip(), ' ').tolist() + sequences[key] = value + return sequences + + def putsequences(self, sequences): + """Write the set of sequences back to the folder.""" + fullname = self.getsequencesfilename() + f = None + for key, seq in sequences.iteritems(): + s = IntSet('', ' ') + s.fromlist(seq) + if not f: f = open(fullname, 'w') + f.write('%s: %s\n' % (key, s.tostring())) + if not f: + try: + os.unlink(fullname) + except os.error: + pass + else: + f.close() + + def getcurrent(self): + """Return the current message. Raise Error when there is none.""" + seqs = self.getsequences() + try: + return max(seqs['cur']) + except (ValueError, KeyError): + raise Error, "no cur message" + + def setcurrent(self, n): + """Set the current message.""" + updateline(self.getsequencesfilename(), 'cur', str(n), 0) + + def parsesequence(self, seq): + """Parse an MH sequence specification into a message list. + Attempt to mimic mh-sequence(5) as close as possible. + Also attempt to mimic observed behavior regarding which + conditions cause which error messages.""" + # XXX Still not complete (see mh-format(5)). + # Missing are: + # - 'prev', 'next' as count + # - Sequence-Negation option + all = self.listmessages() + # Observed behavior: test for empty folder is done first + if not all: + raise Error, "no messages in %s" % self.name + # Common case first: all is frequently the default + if seq == 'all': + return all + # Test for X:Y before X-Y because 'seq:-n' matches both + i = seq.find(':') + if i >= 0: + head, dir, tail = seq[:i], '', seq[i+1:] + if tail[:1] in '-+': + dir, tail = tail[:1], tail[1:] + if not isnumeric(tail): + raise Error, "bad message list %s" % seq + try: + count = int(tail) + except (ValueError, OverflowError): + # Can't use sys.maxint because of i+count below + count = len(all) + try: + anchor = self._parseindex(head, all) + except Error, msg: + seqs = self.getsequences() + if not head in seqs: + if not msg: + msg = "bad message list %s" % seq + raise Error, msg, sys.exc_info()[2] + msgs = seqs[head] + if not msgs: + raise Error, "sequence %s empty" % head + if dir == '-': + return msgs[-count:] + else: + return msgs[:count] + else: + if not dir: + if head in ('prev', 'last'): + dir = '-' + if dir == '-': + i = bisect(all, anchor) + return all[max(0, i-count):i] + else: + i = bisect(all, anchor-1) + return all[i:i+count] + # Test for X-Y next + i = seq.find('-') + if i >= 0: + begin = self._parseindex(seq[:i], all) + end = self._parseindex(seq[i+1:], all) + i = bisect(all, begin-1) + j = bisect(all, end) + r = all[i:j] + if not r: + raise Error, "bad message list %s" % seq + return r + # Neither X:Y nor X-Y; must be a number or a (pseudo-)sequence + try: + n = self._parseindex(seq, all) + except Error, msg: + seqs = self.getsequences() + if not seq in seqs: + if not msg: + msg = "bad message list %s" % seq + raise Error, msg + return seqs[seq] + else: + if n not in all: + if isnumeric(seq): + raise Error, "message %d doesn't exist" % n + else: + raise Error, "no %s message" % seq + else: + return [n] + + def _parseindex(self, seq, all): + """Internal: parse a message number (or cur, first, etc.).""" + if isnumeric(seq): + try: + return int(seq) + except (OverflowError, ValueError): + return sys.maxint + if seq in ('cur', '.'): + return self.getcurrent() + if seq == 'first': + return all[0] + if seq == 'last': + return all[-1] + if seq == 'next': + n = self.getcurrent() + i = bisect(all, n) + try: + return all[i] + except IndexError: + raise Error, "no next message" + if seq == 'prev': + n = self.getcurrent() + i = bisect(all, n-1) + if i == 0: + raise Error, "no prev message" + try: + return all[i-1] + except IndexError: + raise Error, "no prev message" + raise Error, None + + def openmessage(self, n): + """Open a message -- returns a Message object.""" + return Message(self, n) + + def removemessages(self, list): + """Remove one or more messages -- may raise os.error.""" + errors = [] + deleted = [] + for n in list: + path = self.getmessagefilename(n) + commapath = self.getmessagefilename(',' + str(n)) + try: + os.unlink(commapath) + except os.error: + pass + try: + os.rename(path, commapath) + except os.error, msg: + errors.append(msg) + else: + deleted.append(n) + if deleted: + self.removefromallsequences(deleted) + if errors: + if len(errors) == 1: + raise os.error, errors[0] + else: + raise os.error, ('multiple errors:', errors) + + def refilemessages(self, list, tofolder, keepsequences=0): + """Refile one or more messages -- may raise os.error. + 'tofolder' is an open folder object.""" + errors = [] + refiled = {} + for n in list: + ton = tofolder.getlast() + 1 + path = self.getmessagefilename(n) + topath = tofolder.getmessagefilename(ton) + try: + os.rename(path, topath) + except os.error: + # Try copying + try: + shutil.copy2(path, topath) + os.unlink(path) + except (IOError, os.error), msg: + errors.append(msg) + try: + os.unlink(topath) + except os.error: + pass + continue + tofolder.setlast(ton) + refiled[n] = ton + if refiled: + if keepsequences: + tofolder._copysequences(self, refiled.items()) + self.removefromallsequences(refiled.keys()) + if errors: + if len(errors) == 1: + raise os.error, errors[0] + else: + raise os.error, ('multiple errors:', errors) + + def _copysequences(self, fromfolder, refileditems): + """Helper for refilemessages() to copy sequences.""" + fromsequences = fromfolder.getsequences() + tosequences = self.getsequences() + changed = 0 + for name, seq in fromsequences.items(): + try: + toseq = tosequences[name] + new = 0 + except KeyError: + toseq = [] + new = 1 + for fromn, ton in refileditems: + if fromn in seq: + toseq.append(ton) + changed = 1 + if new and toseq: + tosequences[name] = toseq + if changed: + self.putsequences(tosequences) + + def movemessage(self, n, tofolder, ton): + """Move one message over a specific destination message, + which may or may not already exist.""" + path = self.getmessagefilename(n) + # Open it to check that it exists + f = open(path) + f.close() + del f + topath = tofolder.getmessagefilename(ton) + backuptopath = tofolder.getmessagefilename(',%d' % ton) + try: + os.rename(topath, backuptopath) + except os.error: + pass + try: + os.rename(path, topath) + except os.error: + # Try copying + ok = 0 + try: + tofolder.setlast(None) + shutil.copy2(path, topath) + ok = 1 + finally: + if not ok: + try: + os.unlink(topath) + except os.error: + pass + os.unlink(path) + self.removefromallsequences([n]) + + def copymessage(self, n, tofolder, ton): + """Copy one message over a specific destination message, + which may or may not already exist.""" + path = self.getmessagefilename(n) + # Open it to check that it exists + f = open(path) + f.close() + del f + topath = tofolder.getmessagefilename(ton) + backuptopath = tofolder.getmessagefilename(',%d' % ton) + try: + os.rename(topath, backuptopath) + except os.error: + pass + ok = 0 + try: + tofolder.setlast(None) + shutil.copy2(path, topath) + ok = 1 + finally: + if not ok: + try: + os.unlink(topath) + except os.error: + pass + + def createmessage(self, n, txt): + """Create a message, with text from the open file txt.""" + path = self.getmessagefilename(n) + backuppath = self.getmessagefilename(',%d' % n) + try: + os.rename(path, backuppath) + except os.error: + pass + ok = 0 + BUFSIZE = 16*1024 + try: + f = open(path, "w") + while 1: + buf = txt.read(BUFSIZE) + if not buf: + break + f.write(buf) + f.close() + ok = 1 + finally: + if not ok: + try: + os.unlink(path) + except os.error: + pass + + def removefromallsequences(self, list): + """Remove one or more messages from all sequences (including last) + -- but not from 'cur'!!!""" + if hasattr(self, 'last') and self.last in list: + del self.last + sequences = self.getsequences() + changed = 0 + for name, seq in sequences.items(): + if name == 'cur': + continue + for n in list: + if n in seq: + seq.remove(n) + changed = 1 + if not seq: + del sequences[name] + if changed: + self.putsequences(sequences) + + def getlast(self): + """Return the last message number.""" + if not hasattr(self, 'last'): + self.listmessages() # Set self.last + return self.last + + def setlast(self, last): + """Set the last message number.""" + if last is None: + if hasattr(self, 'last'): + del self.last + else: + self.last = last + +class Message(mimetools.Message): + + def __init__(self, f, n, fp = None): + """Constructor.""" + self.folder = f + self.number = n + if fp is None: + path = f.getmessagefilename(n) + fp = open(path, 'r') + mimetools.Message.__init__(self, fp) + + def __repr__(self): + """String representation.""" + return 'Message(%s, %s)' % (repr(self.folder), self.number) + + def getheadertext(self, pred = None): + """Return the message's header text as a string. If an + argument is specified, it is used as a filter predicate to + decide which headers to return (its argument is the header + name converted to lower case).""" + if pred is None: + return ''.join(self.headers) + headers = [] + hit = 0 + for line in self.headers: + if not line[0].isspace(): + i = line.find(':') + if i > 0: + hit = pred(line[:i].lower()) + if hit: headers.append(line) + return ''.join(headers) + + def getbodytext(self, decode = 1): + """Return the message's body text as string. This undoes a + Content-Transfer-Encoding, but does not interpret other MIME + features (e.g. multipart messages). To suppress decoding, + pass 0 as an argument.""" + self.fp.seek(self.startofbody) + encoding = self.getencoding() + if not decode or encoding in ('', '7bit', '8bit', 'binary'): + return self.fp.read() + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + output = StringIO() + mimetools.decode(self.fp, output, encoding) + return output.getvalue() + + def getbodyparts(self): + """Only for multipart messages: return the message's body as a + list of SubMessage objects. Each submessage object behaves + (almost) as a Message object.""" + if self.getmaintype() != 'multipart': + raise Error, 'Content-Type is not multipart/*' + bdry = self.getparam('boundary') + if not bdry: + raise Error, 'multipart/* without boundary param' + self.fp.seek(self.startofbody) + mf = multifile.MultiFile(self.fp) + mf.push(bdry) + parts = [] + while mf.next(): + n = "%s.%r" % (self.number, 1 + len(parts)) + part = SubMessage(self.folder, n, mf) + parts.append(part) + mf.pop() + return parts + + def getbody(self): + """Return body, either a string or a list of messages.""" + if self.getmaintype() == 'multipart': + return self.getbodyparts() + else: + return self.getbodytext() + + +class SubMessage(Message): + + def __init__(self, f, n, fp): + """Constructor.""" + Message.__init__(self, f, n, fp) + if self.getmaintype() == 'multipart': + self.body = Message.getbodyparts(self) + else: + self.body = Message.getbodytext(self) + self.bodyencoded = Message.getbodytext(self, decode=0) + # XXX If this is big, should remember file pointers + + def __repr__(self): + """String representation.""" + f, n, fp = self.folder, self.number, self.fp + return 'SubMessage(%s, %s, %s)' % (f, n, fp) + + def getbodytext(self, decode = 1): + if not decode: + return self.bodyencoded + if type(self.body) == type(''): + return self.body + + def getbodyparts(self): + if type(self.body) == type([]): + return self.body + + def getbody(self): + return self.body + + +class IntSet: + """Class implementing sets of integers. + + This is an efficient representation for sets consisting of several + continuous ranges, e.g. 1-100,200-400,402-1000 is represented + internally as a list of three pairs: [(1,100), (200,400), + (402,1000)]. The internal representation is always kept normalized. + + The constructor has up to three arguments: + - the string used to initialize the set (default ''), + - the separator between ranges (default ',') + - the separator between begin and end of a range (default '-') + The separators must be strings (not regexprs) and should be different. + + The tostring() function yields a string that can be passed to another + IntSet constructor; __repr__() is a valid IntSet constructor itself. + """ + + # XXX The default begin/end separator means that negative numbers are + # not supported very well. + # + # XXX There are currently no operations to remove set elements. + + def __init__(self, data = None, sep = ',', rng = '-'): + self.pairs = [] + self.sep = sep + self.rng = rng + if data: self.fromstring(data) + + def reset(self): + self.pairs = [] + + def __cmp__(self, other): + return cmp(self.pairs, other.pairs) + + def __hash__(self): + return hash(self.pairs) + + def __repr__(self): + return 'IntSet(%r, %r, %r)' % (self.tostring(), self.sep, self.rng) + + def normalize(self): + self.pairs.sort() + i = 1 + while i < len(self.pairs): + alo, ahi = self.pairs[i-1] + blo, bhi = self.pairs[i] + if ahi >= blo-1: + self.pairs[i-1:i+1] = [(alo, max(ahi, bhi))] + else: + i = i+1 + + def tostring(self): + s = '' + for lo, hi in self.pairs: + if lo == hi: t = repr(lo) + else: t = repr(lo) + self.rng + repr(hi) + if s: s = s + (self.sep + t) + else: s = t + return s + + def tolist(self): + l = [] + for lo, hi in self.pairs: + m = range(lo, hi+1) + l = l + m + return l + + def fromlist(self, list): + for i in list: + self.append(i) + + def clone(self): + new = IntSet() + new.pairs = self.pairs[:] + return new + + def min(self): + return self.pairs[0][0] + + def max(self): + return self.pairs[-1][-1] + + def contains(self, x): + for lo, hi in self.pairs: + if lo <= x <= hi: return True + return False + + def append(self, x): + for i in range(len(self.pairs)): + lo, hi = self.pairs[i] + if x < lo: # Need to insert before + if x+1 == lo: + self.pairs[i] = (x, hi) + else: + self.pairs.insert(i, (x, x)) + if i > 0 and x-1 == self.pairs[i-1][1]: + # Merge with previous + self.pairs[i-1:i+1] = [ + (self.pairs[i-1][0], + self.pairs[i][1]) + ] + return + if x <= hi: # Already in set + return + i = len(self.pairs) - 1 + if i >= 0: + lo, hi = self.pairs[i] + if x-1 == hi: + self.pairs[i] = lo, x + return + self.pairs.append((x, x)) + + def addpair(self, xlo, xhi): + if xlo > xhi: return + self.pairs.append((xlo, xhi)) + self.normalize() + + def fromstring(self, data): + new = [] + for part in data.split(self.sep): + list = [] + for subp in part.split(self.rng): + s = subp.strip() + list.append(int(s)) + if len(list) == 1: + new.append((list[0], list[0])) + elif len(list) == 2 and list[0] <= list[1]: + new.append((list[0], list[1])) + else: + raise ValueError, 'bad data passed to IntSet' + self.pairs = self.pairs + new + self.normalize() + + +# Subroutines to read/write entries in .mh_profile and .mh_sequences + +def pickline(file, key, casefold = 1): + try: + f = open(file, 'r') + except IOError: + return None + pat = re.escape(key) + ':' + prog = re.compile(pat, casefold and re.IGNORECASE) + while 1: + line = f.readline() + if not line: break + if prog.match(line): + text = line[len(key)+1:] + while 1: + line = f.readline() + if not line or not line[0].isspace(): + break + text = text + line + return text.strip() + return None + +def updateline(file, key, value, casefold = 1): + try: + f = open(file, 'r') + lines = f.readlines() + f.close() + except IOError: + lines = [] + pat = re.escape(key) + ':(.*)\n' + prog = re.compile(pat, casefold and re.IGNORECASE) + if value is None: + newline = None + else: + newline = '%s: %s\n' % (key, value) + for i in range(len(lines)): + line = lines[i] + if prog.match(line): + if newline is None: + del lines[i] + else: + lines[i] = newline + break + else: + if newline is not None: + lines.append(newline) + tempfile = file + "~" + f = open(tempfile, 'w') + for line in lines: + f.write(line) + f.close() + os.rename(tempfile, file) + + +# Test program + +def test(): + global mh, f + os.system('rm -rf $HOME/Mail/@test') + mh = MH() + def do(s): print s; print eval(s) + do('mh.listfolders()') + do('mh.listallfolders()') + testfolders = ['@test', '@test/test1', '@test/test2', + '@test/test1/test11', '@test/test1/test12', + '@test/test1/test11/test111'] + for t in testfolders: do('mh.makefolder(%r)' % (t,)) + do('mh.listsubfolders(\'@test\')') + do('mh.listallsubfolders(\'@test\')') + f = mh.openfolder('@test') + do('f.listsubfolders()') + do('f.listallsubfolders()') + do('f.getsequences()') + seqs = f.getsequences() + seqs['foo'] = IntSet('1-10 12-20', ' ').tolist() + print seqs + f.putsequences(seqs) + do('f.getsequences()') + for t in reversed(testfolders): do('mh.deletefolder(%r)' % (t,)) + do('mh.getcontext()') + context = mh.getcontext() + f = mh.openfolder(context) + do('f.getcurrent()') + for seq in ('first', 'last', 'cur', '.', 'prev', 'next', + 'first:3', 'last:3', 'cur:3', 'cur:-3', + 'prev:3', 'next:3', + '1:3', '1:-3', '100:3', '100:-3', '10000:3', '10000:-3', + 'all'): + try: + do('f.parsesequence(%r)' % (seq,)) + except Error, msg: + print "Error:", msg + stuff = os.popen("pick %r 2>/dev/null" % (seq,)).read() + list = map(int, stuff.split()) + print list, "<-- pick" + do('f.listmessages()') + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/mimetools.py b/src/main/resources/PythonLibs/mimetools.py new file mode 100644 index 0000000000000000000000000000000000000000..71ca8f8593f2b64d08ddeb02a38dee1fef827f1c --- /dev/null +++ b/src/main/resources/PythonLibs/mimetools.py @@ -0,0 +1,250 @@ +"""Various tools used by MIME-reading or MIME-writing programs.""" + + +import os +import sys +import tempfile +from warnings import filterwarnings, catch_warnings +with catch_warnings(): + if sys.py3kwarning: + filterwarnings("ignore", ".*rfc822 has been removed", DeprecationWarning) + import rfc822 + +from warnings import warnpy3k +warnpy3k("in 3.x, mimetools has been removed in favor of the email package", + stacklevel=2) + +__all__ = ["Message","choose_boundary","encode","decode","copyliteral", + "copybinary"] + +class Message(rfc822.Message): + """A derived class of rfc822.Message that knows about MIME headers and + contains some hooks for decoding encoded and multipart messages.""" + + def __init__(self, fp, seekable = 1): + rfc822.Message.__init__(self, fp, seekable) + self.encodingheader = \ + self.getheader('content-transfer-encoding') + self.typeheader = \ + self.getheader('content-type') + self.parsetype() + self.parseplist() + + def parsetype(self): + str = self.typeheader + if str is None: + str = 'text/plain' + if ';' in str: + i = str.index(';') + self.plisttext = str[i:] + str = str[:i] + else: + self.plisttext = '' + fields = str.split('/') + for i in range(len(fields)): + fields[i] = fields[i].strip().lower() + self.type = '/'.join(fields) + self.maintype = fields[0] + self.subtype = '/'.join(fields[1:]) + + def parseplist(self): + str = self.plisttext + self.plist = [] + while str[:1] == ';': + str = str[1:] + if ';' in str: + # XXX Should parse quotes! + end = str.index(';') + else: + end = len(str) + f = str[:end] + if '=' in f: + i = f.index('=') + f = f[:i].strip().lower() + \ + '=' + f[i+1:].strip() + self.plist.append(f.strip()) + str = str[end:] + + def getplist(self): + return self.plist + + def getparam(self, name): + name = name.lower() + '=' + n = len(name) + for p in self.plist: + if p[:n] == name: + return rfc822.unquote(p[n:]) + return None + + def getparamnames(self): + result = [] + for p in self.plist: + i = p.find('=') + if i >= 0: + result.append(p[:i].lower()) + return result + + def getencoding(self): + if self.encodingheader is None: + return '7bit' + return self.encodingheader.lower() + + def gettype(self): + return self.type + + def getmaintype(self): + return self.maintype + + def getsubtype(self): + return self.subtype + + + + +# Utility functions +# ----------------- + +try: + import thread +except ImportError: + import dummy_thread as thread +_counter_lock = thread.allocate_lock() +del thread + +_counter = 0 +def _get_next_counter(): + global _counter + _counter_lock.acquire() + _counter += 1 + result = _counter + _counter_lock.release() + return result + +_prefix = None + +def choose_boundary(): + """Return a string usable as a multipart boundary. + + The string chosen is unique within a single program run, and + incorporates the user id (if available), process id (if available), + and current time. So it's very unlikely the returned string appears + in message text, but there's no guarantee. + + The boundary contains dots so you have to quote it in the header.""" + + global _prefix + import time + if _prefix is None: + import socket + try: + hostid = socket.gethostbyname(socket.gethostname()) + except socket.gaierror: + hostid = '127.0.0.1' + try: + uid = repr(os.getuid()) + except AttributeError: + uid = '1' + try: + pid = repr(os.getpid()) + except AttributeError: + pid = '1' + _prefix = hostid + '.' + uid + '.' + pid + return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter()) + + +# Subroutines for decoding some common content-transfer-types + +def decode(input, output, encoding): + """Decode common content-transfer-encodings (base64, quopri, uuencode).""" + if encoding == 'base64': + import base64 + return base64.decode(input, output) + if encoding == 'quoted-printable': + import quopri + return quopri.decode(input, output) + if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): + import uu + return uu.decode(input, output) + if encoding in ('7bit', '8bit'): + return output.write(input.read()) + if encoding in decodetab: + pipethrough(input, decodetab[encoding], output) + else: + raise ValueError, \ + 'unknown Content-Transfer-Encoding: %s' % encoding + +def encode(input, output, encoding): + """Encode common content-transfer-encodings (base64, quopri, uuencode).""" + if encoding == 'base64': + import base64 + return base64.encode(input, output) + if encoding == 'quoted-printable': + import quopri + return quopri.encode(input, output, 0) + if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): + import uu + return uu.encode(input, output) + if encoding in ('7bit', '8bit'): + return output.write(input.read()) + if encoding in encodetab: + pipethrough(input, encodetab[encoding], output) + else: + raise ValueError, \ + 'unknown Content-Transfer-Encoding: %s' % encoding + +# The following is no longer used for standard encodings + +# XXX This requires that uudecode and mmencode are in $PATH + +uudecode_pipe = '''( +TEMP=/tmp/@uu.$$ +sed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode +cat $TEMP +rm $TEMP +)''' + +decodetab = { + 'uuencode': uudecode_pipe, + 'x-uuencode': uudecode_pipe, + 'uue': uudecode_pipe, + 'x-uue': uudecode_pipe, + 'quoted-printable': 'mmencode -u -q', + 'base64': 'mmencode -u -b', +} + +encodetab = { + 'x-uuencode': 'uuencode tempfile', + 'uuencode': 'uuencode tempfile', + 'x-uue': 'uuencode tempfile', + 'uue': 'uuencode tempfile', + 'quoted-printable': 'mmencode -q', + 'base64': 'mmencode -b', +} + +def pipeto(input, command): + pipe = os.popen(command, 'w') + copyliteral(input, pipe) + pipe.close() + +def pipethrough(input, command, output): + (fd, tempname) = tempfile.mkstemp() + temp = os.fdopen(fd, 'w') + copyliteral(input, temp) + temp.close() + pipe = os.popen(command + ' <' + tempname, 'r') + copybinary(pipe, output) + pipe.close() + os.unlink(tempname) + +def copyliteral(input, output): + while 1: + line = input.readline() + if not line: break + output.write(line) + +def copybinary(input, output): + BUFSIZE = 8192 + while 1: + line = input.read(BUFSIZE) + if not line: break + output.write(line) diff --git a/src/main/resources/PythonLibs/mimetypes.py b/src/main/resources/PythonLibs/mimetypes.py new file mode 100644 index 0000000000000000000000000000000000000000..ba4ea8257b660b0f8f1043aed2bc3a06bdfb40c5 --- /dev/null +++ b/src/main/resources/PythonLibs/mimetypes.py @@ -0,0 +1,592 @@ +"""Guess the MIME type of a file. + +This module defines two useful functions: + +guess_type(url, strict=1) -- guess the MIME type and encoding of a URL. + +guess_extension(type, strict=1) -- guess the extension for a given MIME type. + +It also contains the following, for tuning the behavior: + +Data: + +knownfiles -- list of files to parse +inited -- flag set when init() has been called +suffix_map -- dictionary mapping suffixes to suffixes +encodings_map -- dictionary mapping suffixes to encodings +types_map -- dictionary mapping suffixes to types + +Functions: + +init([files]) -- parse a list of files, default knownfiles (on Windows, the + default values are taken from the registry) +read_mime_types(file) -- parse one file, return a dictionary or None +""" + +import os +import sys +import posixpath +import urllib +try: + import _winreg +except ImportError: + _winreg = None + +__all__ = [ + "guess_type","guess_extension","guess_all_extensions", + "add_type","read_mime_types","init" +] + +knownfiles = [ + "/etc/mime.types", + "/etc/httpd/mime.types", # Mac OS X + "/etc/httpd/conf/mime.types", # Apache + "/etc/apache/mime.types", # Apache 1 + "/etc/apache2/mime.types", # Apache 2 + "/usr/local/etc/httpd/conf/mime.types", + "/usr/local/lib/netscape/mime.types", + "/usr/local/etc/httpd/conf/mime.types", # Apache 1.2 + "/usr/local/etc/mime.types", # Apache 1.3 + ] + +inited = False +_db = None + + +class MimeTypes: + """MIME-types datastore. + + This datastore can handle information from mime.types-style files + and supports basic determination of MIME type from a filename or + URL, and can guess a reasonable extension given a MIME type. + """ + + def __init__(self, filenames=(), strict=True): + if not inited: + init() + self.encodings_map = encodings_map.copy() + self.suffix_map = suffix_map.copy() + self.types_map = ({}, {}) # dict for (non-strict, strict) + self.types_map_inv = ({}, {}) + for (ext, type) in types_map.items(): + self.add_type(type, ext, True) + for (ext, type) in common_types.items(): + self.add_type(type, ext, False) + for name in filenames: + self.read(name, strict) + + def add_type(self, type, ext, strict=True): + """Add a mapping between a type and an extension. + + When the extension is already known, the new + type will replace the old one. When the type + is already known the extension will be added + to the list of known extensions. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + self.types_map[strict][ext] = type + exts = self.types_map_inv[strict].setdefault(type, []) + if ext not in exts: + exts.append(ext) + + def guess_type(self, url, strict=True): + """Guess the type of a file based on its URL. + + Return value is a tuple (type, encoding) where type is None if + the type can't be guessed (no or unknown suffix) or a string + of the form type/subtype, usable for a MIME Content-type + header; and encoding is None for no encoding or the name of + the program used to encode (e.g. compress or gzip). The + mappings are table driven. Encoding suffixes are case + sensitive; type suffixes are first tried case sensitive, then + case insensitive. + + The suffixes .tgz, .taz and .tz (case sensitive!) are all + mapped to '.tar.gz'. (This is table-driven too, using the + dictionary suffix_map.) + + Optional `strict' argument when False adds a bunch of commonly found, + but non-standard types. + """ + scheme, url = urllib.splittype(url) + if scheme == 'data': + # syntax of data URLs: + # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + # mediatype := [ type "/" subtype ] *( ";" parameter ) + # data := *urlchar + # parameter := attribute "=" value + # type/subtype defaults to "text/plain" + comma = url.find(',') + if comma < 0: + # bad data URL + return None, None + semi = url.find(';', 0, comma) + if semi >= 0: + type = url[:semi] + else: + type = url[:comma] + if '=' in type or '/' not in type: + type = 'text/plain' + return type, None # never compressed, so encoding is None + base, ext = posixpath.splitext(url) + while ext in self.suffix_map: + base, ext = posixpath.splitext(base + self.suffix_map[ext]) + if ext in self.encodings_map: + encoding = self.encodings_map[ext] + base, ext = posixpath.splitext(base) + else: + encoding = None + types_map = self.types_map[True] + if ext in types_map: + return types_map[ext], encoding + elif ext.lower() in types_map: + return types_map[ext.lower()], encoding + elif strict: + return None, encoding + types_map = self.types_map[False] + if ext in types_map: + return types_map[ext], encoding + elif ext.lower() in types_map: + return types_map[ext.lower()], encoding + else: + return None, encoding + + def guess_all_extensions(self, type, strict=True): + """Guess the extensions for a file based on its MIME type. + + Return value is a list of strings giving the possible filename + extensions, including the leading dot ('.'). The extension is not + guaranteed to have been associated with any particular data stream, + but would be mapped to the MIME type `type' by guess_type(). + + Optional `strict' argument when false adds a bunch of commonly found, + but non-standard types. + """ + type = type.lower() + extensions = self.types_map_inv[True].get(type, []) + if not strict: + for ext in self.types_map_inv[False].get(type, []): + if ext not in extensions: + extensions.append(ext) + return extensions + + def guess_extension(self, type, strict=True): + """Guess the extension for a file based on its MIME type. + + Return value is a string giving a filename extension, + including the leading dot ('.'). The extension is not + guaranteed to have been associated with any particular data + stream, but would be mapped to the MIME type `type' by + guess_type(). If no extension can be guessed for `type', None + is returned. + + Optional `strict' argument when false adds a bunch of commonly found, + but non-standard types. + """ + extensions = self.guess_all_extensions(type, strict) + if not extensions: + return None + return extensions[0] + + def read(self, filename, strict=True): + """ + Read a single mime.types-format file, specified by pathname. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + with open(filename) as fp: + self.readfp(fp, strict) + + def readfp(self, fp, strict=True): + """ + Read a single mime.types-format file. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + while 1: + line = fp.readline() + if not line: + break + words = line.split() + for i in range(len(words)): + if words[i][0] == '#': + del words[i:] + break + if not words: + continue + type, suffixes = words[0], words[1:] + for suff in suffixes: + self.add_type(type, '.' + suff, strict) + + def read_windows_registry(self, strict=True): + """ + Load the MIME types database from Windows registry. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + + # Windows only + if not _winreg: + return + + def enum_types(mimedb): + i = 0 + while True: + try: + ctype = _winreg.EnumKey(mimedb, i) + except EnvironmentError: + break + try: + ctype = ctype.encode(default_encoding) # omit in 3.x! + except UnicodeEncodeError: + pass + else: + yield ctype + i += 1 + + default_encoding = sys.getdefaultencoding() + with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, + r'MIME\Database\Content Type') as mimedb: + for ctype in enum_types(mimedb): + try: + with _winreg.OpenKey(mimedb, ctype) as key: + suffix, datatype = _winreg.QueryValueEx(key, + 'Extension') + except EnvironmentError: + continue + if datatype != _winreg.REG_SZ: + continue + try: + suffix = suffix.encode(default_encoding) # omit in 3.x! + except UnicodeEncodeError: + continue + self.add_type(ctype, suffix, strict) + + +def guess_type(url, strict=True): + """Guess the type of a file based on its URL. + + Return value is a tuple (type, encoding) where type is None if the + type can't be guessed (no or unknown suffix) or a string of the + form type/subtype, usable for a MIME Content-type header; and + encoding is None for no encoding or the name of the program used + to encode (e.g. compress or gzip). The mappings are table + driven. Encoding suffixes are case sensitive; type suffixes are + first tried case sensitive, then case insensitive. + + The suffixes .tgz, .taz and .tz (case sensitive!) are all mapped + to ".tar.gz". (This is table-driven too, using the dictionary + suffix_map). + + Optional `strict' argument when false adds a bunch of commonly found, but + non-standard types. + """ + if _db is None: + init() + return _db.guess_type(url, strict) + + +def guess_all_extensions(type, strict=True): + """Guess the extensions for a file based on its MIME type. + + Return value is a list of strings giving the possible filename + extensions, including the leading dot ('.'). The extension is not + guaranteed to have been associated with any particular data + stream, but would be mapped to the MIME type `type' by + guess_type(). If no extension can be guessed for `type', None + is returned. + + Optional `strict' argument when false adds a bunch of commonly found, + but non-standard types. + """ + if _db is None: + init() + return _db.guess_all_extensions(type, strict) + +def guess_extension(type, strict=True): + """Guess the extension for a file based on its MIME type. + + Return value is a string giving a filename extension, including the + leading dot ('.'). The extension is not guaranteed to have been + associated with any particular data stream, but would be mapped to the + MIME type `type' by guess_type(). If no extension can be guessed for + `type', None is returned. + + Optional `strict' argument when false adds a bunch of commonly found, + but non-standard types. + """ + if _db is None: + init() + return _db.guess_extension(type, strict) + +def add_type(type, ext, strict=True): + """Add a mapping between a type and an extension. + + When the extension is already known, the new + type will replace the old one. When the type + is already known the extension will be added + to the list of known extensions. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + if _db is None: + init() + return _db.add_type(type, ext, strict) + + +def init(files=None): + global suffix_map, types_map, encodings_map, common_types + global inited, _db + inited = True # so that MimeTypes.__init__() doesn't call us again + db = MimeTypes() + if files is None: + if _winreg: + db.read_windows_registry() + files = knownfiles + for file in files: + if os.path.isfile(file): + db.read(file) + encodings_map = db.encodings_map + suffix_map = db.suffix_map + types_map = db.types_map[True] + common_types = db.types_map[False] + # Make the DB a global variable now that it is fully initialized + _db = db + + +def read_mime_types(file): + try: + f = open(file) + except IOError: + return None + db = MimeTypes() + db.readfp(f, True) + return db.types_map[True] + + +def _default_mime_types(): + global suffix_map + global encodings_map + global types_map + global common_types + + suffix_map = { + '.tgz': '.tar.gz', + '.taz': '.tar.gz', + '.tz': '.tar.gz', + '.tbz2': '.tar.bz2', + } + + encodings_map = { + '.gz': 'gzip', + '.Z': 'compress', + '.bz2': 'bzip2', + } + + # Before adding new types, make sure they are either registered with IANA, + # at http://www.isi.edu/in-notes/iana/assignments/media-types + # or extensions, i.e. using the x- prefix + + # If you add to these, please keep them sorted! + types_map = { + '.a' : 'application/octet-stream', + '.ai' : 'application/postscript', + '.aif' : 'audio/x-aiff', + '.aifc' : 'audio/x-aiff', + '.aiff' : 'audio/x-aiff', + '.au' : 'audio/basic', + '.avi' : 'video/x-msvideo', + '.bat' : 'text/plain', + '.bcpio' : 'application/x-bcpio', + '.bin' : 'application/octet-stream', + '.bmp' : 'image/x-ms-bmp', + '.c' : 'text/plain', + # Duplicates :( + '.cdf' : 'application/x-cdf', + '.cdf' : 'application/x-netcdf', + '.cpio' : 'application/x-cpio', + '.csh' : 'application/x-csh', + '.css' : 'text/css', + '.dll' : 'application/octet-stream', + '.doc' : 'application/msword', + '.dot' : 'application/msword', + '.dvi' : 'application/x-dvi', + '.eml' : 'message/rfc822', + '.eps' : 'application/postscript', + '.etx' : 'text/x-setext', + '.exe' : 'application/octet-stream', + '.gif' : 'image/gif', + '.gtar' : 'application/x-gtar', + '.h' : 'text/plain', + '.hdf' : 'application/x-hdf', + '.htm' : 'text/html', + '.html' : 'text/html', + '.ico' : 'image/vnd.microsoft.icon', + '.ief' : 'image/ief', + '.jpe' : 'image/jpeg', + '.jpeg' : 'image/jpeg', + '.jpg' : 'image/jpeg', + '.js' : 'application/javascript', + '.ksh' : 'text/plain', + '.latex' : 'application/x-latex', + '.m1v' : 'video/mpeg', + '.man' : 'application/x-troff-man', + '.me' : 'application/x-troff-me', + '.mht' : 'message/rfc822', + '.mhtml' : 'message/rfc822', + '.mif' : 'application/x-mif', + '.mov' : 'video/quicktime', + '.movie' : 'video/x-sgi-movie', + '.mp2' : 'audio/mpeg', + '.mp3' : 'audio/mpeg', + '.mp4' : 'video/mp4', + '.mpa' : 'video/mpeg', + '.mpe' : 'video/mpeg', + '.mpeg' : 'video/mpeg', + '.mpg' : 'video/mpeg', + '.ms' : 'application/x-troff-ms', + '.nc' : 'application/x-netcdf', + '.nws' : 'message/rfc822', + '.o' : 'application/octet-stream', + '.obj' : 'application/octet-stream', + '.oda' : 'application/oda', + '.p12' : 'application/x-pkcs12', + '.p7c' : 'application/pkcs7-mime', + '.pbm' : 'image/x-portable-bitmap', + '.pdf' : 'application/pdf', + '.pfx' : 'application/x-pkcs12', + '.pgm' : 'image/x-portable-graymap', + '.pl' : 'text/plain', + '.png' : 'image/png', + '.pnm' : 'image/x-portable-anymap', + '.pot' : 'application/vnd.ms-powerpoint', + '.ppa' : 'application/vnd.ms-powerpoint', + '.ppm' : 'image/x-portable-pixmap', + '.pps' : 'application/vnd.ms-powerpoint', + '.ppt' : 'application/vnd.ms-powerpoint', + '.ps' : 'application/postscript', + '.pwz' : 'application/vnd.ms-powerpoint', + '.py' : 'text/x-python', + '.pyc' : 'application/x-python-code', + '.pyo' : 'application/x-python-code', + '.qt' : 'video/quicktime', + '.ra' : 'audio/x-pn-realaudio', + '.ram' : 'application/x-pn-realaudio', + '.ras' : 'image/x-cmu-raster', + '.rdf' : 'application/xml', + '.rgb' : 'image/x-rgb', + '.roff' : 'application/x-troff', + '.rtx' : 'text/richtext', + '.sgm' : 'text/x-sgml', + '.sgml' : 'text/x-sgml', + '.sh' : 'application/x-sh', + '.shar' : 'application/x-shar', + '.snd' : 'audio/basic', + '.so' : 'application/octet-stream', + '.src' : 'application/x-wais-source', + '.sv4cpio': 'application/x-sv4cpio', + '.sv4crc' : 'application/x-sv4crc', + '.swf' : 'application/x-shockwave-flash', + '.t' : 'application/x-troff', + '.tar' : 'application/x-tar', + '.tcl' : 'application/x-tcl', + '.tex' : 'application/x-tex', + '.texi' : 'application/x-texinfo', + '.texinfo': 'application/x-texinfo', + '.tif' : 'image/tiff', + '.tiff' : 'image/tiff', + '.tr' : 'application/x-troff', + '.tsv' : 'text/tab-separated-values', + '.txt' : 'text/plain', + '.ustar' : 'application/x-ustar', + '.vcf' : 'text/x-vcard', + '.wav' : 'audio/x-wav', + '.wiz' : 'application/msword', + '.wsdl' : 'application/xml', + '.xbm' : 'image/x-xbitmap', + '.xlb' : 'application/vnd.ms-excel', + # Duplicates :( + '.xls' : 'application/excel', + '.xls' : 'application/vnd.ms-excel', + '.xml' : 'text/xml', + '.xpdl' : 'application/xml', + '.xpm' : 'image/x-xpixmap', + '.xsl' : 'application/xml', + '.xwd' : 'image/x-xwindowdump', + '.zip' : 'application/zip', + } + + # These are non-standard types, commonly found in the wild. They will + # only match if strict=0 flag is given to the API methods. + + # Please sort these too + common_types = { + '.jpg' : 'image/jpg', + '.mid' : 'audio/midi', + '.midi': 'audio/midi', + '.pct' : 'image/pict', + '.pic' : 'image/pict', + '.pict': 'image/pict', + '.rtf' : 'application/rtf', + '.xul' : 'text/xul' + } + + +_default_mime_types() + + +if __name__ == '__main__': + import getopt + + USAGE = """\ +Usage: mimetypes.py [options] type + +Options: + --help / -h -- print this message and exit + --lenient / -l -- additionally search of some common, but non-standard + types. + --extension / -e -- guess extension instead of type + +More than one type argument may be given. +""" + + def usage(code, msg=''): + print USAGE + if msg: print msg + sys.exit(code) + + try: + opts, args = getopt.getopt(sys.argv[1:], 'hle', + ['help', 'lenient', 'extension']) + except getopt.error, msg: + usage(1, msg) + + strict = 1 + extension = 0 + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-l', '--lenient'): + strict = 0 + elif opt in ('-e', '--extension'): + extension = 1 + for gtype in args: + if extension: + guess = guess_extension(gtype, strict) + if not guess: print "I don't know anything about type", gtype + else: print guess + else: + guess, encoding = guess_type(gtype, strict) + if not guess: print "I don't know anything about type", gtype + else: print 'type:', guess, 'encoding:', encoding diff --git a/src/main/resources/PythonLibs/mimify.py b/src/main/resources/PythonLibs/mimify.py new file mode 100644 index 0000000000000000000000000000000000000000..1c15983d1e2647c13e04422e29f27bb42db1d647 --- /dev/null +++ b/src/main/resources/PythonLibs/mimify.py @@ -0,0 +1,468 @@ +#! /usr/bin/env python + +"""Mimification and unmimification of mail messages. + +Decode quoted-printable parts of a mail message or encode using +quoted-printable. + +Usage: + mimify(input, output) + unmimify(input, output, decode_base64 = 0) +to encode and decode respectively. Input and output may be the name +of a file or an open file object. Only a readline() method is used +on the input file, only a write() method is used on the output file. +When using file names, the input and output file names may be the +same. + +Interactive usage: + mimify.py -e [infile [outfile]] + mimify.py -d [infile [outfile]] +to encode and decode respectively. Infile defaults to standard +input and outfile to standard output. +""" + +# Configure +MAXLEN = 200 # if lines longer than this, encode as quoted-printable +CHARSET = 'ISO-8859-1' # default charset for non-US-ASCII mail +QUOTE = '> ' # string replies are quoted with +# End configure + +import re + +import warnings +warnings.warn("the mimify module is deprecated; use the email package instead", + DeprecationWarning, 2) + +__all__ = ["mimify","unmimify","mime_encode_header","mime_decode_header"] + +qp = re.compile('^content-transfer-encoding:\\s*quoted-printable', re.I) +base64_re = re.compile('^content-transfer-encoding:\\s*base64', re.I) +mp = re.compile('^content-type:.*multipart/.*boundary="?([^;"\n]*)', re.I|re.S) +chrset = re.compile('^(content-type:.*charset=")(us-ascii|iso-8859-[0-9]+)(".*)', re.I|re.S) +he = re.compile('^-*\n') +mime_code = re.compile('=([0-9a-f][0-9a-f])', re.I) +mime_head = re.compile('=\\?iso-8859-1\\?q\\?([^? \t\n]+)\\?=', re.I) +repl = re.compile('^subject:\\s+re: ', re.I) + +class File: + """A simple fake file object that knows about limited read-ahead and + boundaries. The only supported method is readline().""" + + def __init__(self, file, boundary): + self.file = file + self.boundary = boundary + self.peek = None + + def readline(self): + if self.peek is not None: + return '' + line = self.file.readline() + if not line: + return line + if self.boundary: + if line == self.boundary + '\n': + self.peek = line + return '' + if line == self.boundary + '--\n': + self.peek = line + return '' + return line + +class HeaderFile: + def __init__(self, file): + self.file = file + self.peek = None + + def readline(self): + if self.peek is not None: + line = self.peek + self.peek = None + else: + line = self.file.readline() + if not line: + return line + if he.match(line): + return line + while 1: + self.peek = self.file.readline() + if len(self.peek) == 0 or \ + (self.peek[0] != ' ' and self.peek[0] != '\t'): + return line + line = line + self.peek + self.peek = None + +def mime_decode(line): + """Decode a single line of quoted-printable text to 8bit.""" + newline = '' + pos = 0 + while 1: + res = mime_code.search(line, pos) + if res is None: + break + newline = newline + line[pos:res.start(0)] + \ + chr(int(res.group(1), 16)) + pos = res.end(0) + return newline + line[pos:] + +def mime_decode_header(line): + """Decode a header line to 8bit.""" + newline = '' + pos = 0 + while 1: + res = mime_head.search(line, pos) + if res is None: + break + match = res.group(1) + # convert underscores to spaces (before =XX conversion!) + match = ' '.join(match.split('_')) + newline = newline + line[pos:res.start(0)] + mime_decode(match) + pos = res.end(0) + return newline + line[pos:] + +def unmimify_part(ifile, ofile, decode_base64 = 0): + """Convert a quoted-printable part of a MIME mail message to 8bit.""" + multipart = None + quoted_printable = 0 + is_base64 = 0 + is_repl = 0 + if ifile.boundary and ifile.boundary[:2] == QUOTE: + prefix = QUOTE + else: + prefix = '' + + # read header + hfile = HeaderFile(ifile) + while 1: + line = hfile.readline() + if not line: + return + if prefix and line[:len(prefix)] == prefix: + line = line[len(prefix):] + pref = prefix + else: + pref = '' + line = mime_decode_header(line) + if qp.match(line): + quoted_printable = 1 + continue # skip this header + if decode_base64 and base64_re.match(line): + is_base64 = 1 + continue + ofile.write(pref + line) + if not prefix and repl.match(line): + # we're dealing with a reply message + is_repl = 1 + mp_res = mp.match(line) + if mp_res: + multipart = '--' + mp_res.group(1) + if he.match(line): + break + if is_repl and (quoted_printable or multipart): + is_repl = 0 + + # read body + while 1: + line = ifile.readline() + if not line: + return + line = re.sub(mime_head, '\\1', line) + if prefix and line[:len(prefix)] == prefix: + line = line[len(prefix):] + pref = prefix + else: + pref = '' +## if is_repl and len(line) >= 4 and line[:4] == QUOTE+'--' and line[-3:] != '--\n': +## multipart = line[:-1] + while multipart: + if line == multipart + '--\n': + ofile.write(pref + line) + multipart = None + line = None + break + if line == multipart + '\n': + ofile.write(pref + line) + nifile = File(ifile, multipart) + unmimify_part(nifile, ofile, decode_base64) + line = nifile.peek + if not line: + # premature end of file + break + continue + # not a boundary between parts + break + if line and quoted_printable: + while line[-2:] == '=\n': + line = line[:-2] + newline = ifile.readline() + if newline[:len(QUOTE)] == QUOTE: + newline = newline[len(QUOTE):] + line = line + newline + line = mime_decode(line) + if line and is_base64 and not pref: + import base64 + line = base64.decodestring(line) + if line: + ofile.write(pref + line) + +def unmimify(infile, outfile, decode_base64 = 0): + """Convert quoted-printable parts of a MIME mail message to 8bit.""" + if type(infile) == type(''): + ifile = open(infile) + if type(outfile) == type('') and infile == outfile: + import os + d, f = os.path.split(infile) + os.rename(infile, os.path.join(d, ',' + f)) + else: + ifile = infile + if type(outfile) == type(''): + ofile = open(outfile, 'w') + else: + ofile = outfile + nifile = File(ifile, None) + unmimify_part(nifile, ofile, decode_base64) + ofile.flush() + +mime_char = re.compile('[=\177-\377]') # quote these chars in body +mime_header_char = re.compile('[=?\177-\377]') # quote these in header + +def mime_encode(line, header): + """Code a single line as quoted-printable. + If header is set, quote some extra characters.""" + if header: + reg = mime_header_char + else: + reg = mime_char + newline = '' + pos = 0 + if len(line) >= 5 and line[:5] == 'From ': + # quote 'From ' at the start of a line for stupid mailers + newline = ('=%02x' % ord('F')).upper() + pos = 1 + while 1: + res = reg.search(line, pos) + if res is None: + break + newline = newline + line[pos:res.start(0)] + \ + ('=%02x' % ord(res.group(0))).upper() + pos = res.end(0) + line = newline + line[pos:] + + newline = '' + while len(line) >= 75: + i = 73 + while line[i] == '=' or line[i-1] == '=': + i = i - 1 + i = i + 1 + newline = newline + line[:i] + '=\n' + line = line[i:] + return newline + line + +mime_header = re.compile('([ \t(]|^)([-a-zA-Z0-9_+]*[\177-\377][-a-zA-Z0-9_+\177-\377]*)(?=[ \t)]|\n)') + +def mime_encode_header(line): + """Code a single header line as quoted-printable.""" + newline = '' + pos = 0 + while 1: + res = mime_header.search(line, pos) + if res is None: + break + newline = '%s%s%s=?%s?Q?%s?=' % \ + (newline, line[pos:res.start(0)], res.group(1), + CHARSET, mime_encode(res.group(2), 1)) + pos = res.end(0) + return newline + line[pos:] + +mv = re.compile('^mime-version:', re.I) +cte = re.compile('^content-transfer-encoding:', re.I) +iso_char = re.compile('[\177-\377]') + +def mimify_part(ifile, ofile, is_mime): + """Convert an 8bit part of a MIME mail message to quoted-printable.""" + has_cte = is_qp = is_base64 = 0 + multipart = None + must_quote_body = must_quote_header = has_iso_chars = 0 + + header = [] + header_end = '' + message = [] + message_end = '' + # read header + hfile = HeaderFile(ifile) + while 1: + line = hfile.readline() + if not line: + break + if not must_quote_header and iso_char.search(line): + must_quote_header = 1 + if mv.match(line): + is_mime = 1 + if cte.match(line): + has_cte = 1 + if qp.match(line): + is_qp = 1 + elif base64_re.match(line): + is_base64 = 1 + mp_res = mp.match(line) + if mp_res: + multipart = '--' + mp_res.group(1) + if he.match(line): + header_end = line + break + header.append(line) + + # read body + while 1: + line = ifile.readline() + if not line: + break + if multipart: + if line == multipart + '--\n': + message_end = line + break + if line == multipart + '\n': + message_end = line + break + if is_base64: + message.append(line) + continue + if is_qp: + while line[-2:] == '=\n': + line = line[:-2] + newline = ifile.readline() + if newline[:len(QUOTE)] == QUOTE: + newline = newline[len(QUOTE):] + line = line + newline + line = mime_decode(line) + message.append(line) + if not has_iso_chars: + if iso_char.search(line): + has_iso_chars = must_quote_body = 1 + if not must_quote_body: + if len(line) > MAXLEN: + must_quote_body = 1 + + # convert and output header and body + for line in header: + if must_quote_header: + line = mime_encode_header(line) + chrset_res = chrset.match(line) + if chrset_res: + if has_iso_chars: + # change us-ascii into iso-8859-1 + if chrset_res.group(2).lower() == 'us-ascii': + line = '%s%s%s' % (chrset_res.group(1), + CHARSET, + chrset_res.group(3)) + else: + # change iso-8859-* into us-ascii + line = '%sus-ascii%s' % chrset_res.group(1, 3) + if has_cte and cte.match(line): + line = 'Content-Transfer-Encoding: ' + if is_base64: + line = line + 'base64\n' + elif must_quote_body: + line = line + 'quoted-printable\n' + else: + line = line + '7bit\n' + ofile.write(line) + if (must_quote_header or must_quote_body) and not is_mime: + ofile.write('Mime-Version: 1.0\n') + ofile.write('Content-Type: text/plain; ') + if has_iso_chars: + ofile.write('charset="%s"\n' % CHARSET) + else: + ofile.write('charset="us-ascii"\n') + if must_quote_body and not has_cte: + ofile.write('Content-Transfer-Encoding: quoted-printable\n') + ofile.write(header_end) + + for line in message: + if must_quote_body: + line = mime_encode(line, 0) + ofile.write(line) + ofile.write(message_end) + + line = message_end + while multipart: + if line == multipart + '--\n': + # read bit after the end of the last part + while 1: + line = ifile.readline() + if not line: + return + if must_quote_body: + line = mime_encode(line, 0) + ofile.write(line) + if line == multipart + '\n': + nifile = File(ifile, multipart) + mimify_part(nifile, ofile, 1) + line = nifile.peek + if not line: + # premature end of file + break + ofile.write(line) + continue + # unexpectedly no multipart separator--copy rest of file + while 1: + line = ifile.readline() + if not line: + return + if must_quote_body: + line = mime_encode(line, 0) + ofile.write(line) + +def mimify(infile, outfile): + """Convert 8bit parts of a MIME mail message to quoted-printable.""" + if type(infile) == type(''): + ifile = open(infile) + if type(outfile) == type('') and infile == outfile: + import os + d, f = os.path.split(infile) + os.rename(infile, os.path.join(d, ',' + f)) + else: + ifile = infile + if type(outfile) == type(''): + ofile = open(outfile, 'w') + else: + ofile = outfile + nifile = File(ifile, None) + mimify_part(nifile, ofile, 0) + ofile.flush() + +import sys +if __name__ == '__main__' or (len(sys.argv) > 0 and sys.argv[0] == 'mimify'): + import getopt + usage = 'Usage: mimify [-l len] -[ed] [infile [outfile]]' + + decode_base64 = 0 + opts, args = getopt.getopt(sys.argv[1:], 'l:edb') + if len(args) not in (0, 1, 2): + print usage + sys.exit(1) + if (('-e', '') in opts) == (('-d', '') in opts) or \ + ((('-b', '') in opts) and (('-d', '') not in opts)): + print usage + sys.exit(1) + for o, a in opts: + if o == '-e': + encode = mimify + elif o == '-d': + encode = unmimify + elif o == '-l': + try: + MAXLEN = int(a) + except (ValueError, OverflowError): + print usage + sys.exit(1) + elif o == '-b': + decode_base64 = 1 + if len(args) == 0: + encode_args = (sys.stdin, sys.stdout) + elif len(args) == 1: + encode_args = (args[0], sys.stdout) + else: + encode_args = (args[0], args[1]) + if decode_base64: + encode_args = encode_args + (decode_base64,) + encode(*encode_args) diff --git a/src/main/resources/PythonLibs/modjy/__init__.py b/src/main/resources/PythonLibs/modjy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a172fcc2ee30f9473f75aaba569b19e32d752e0c --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/__init__.py @@ -0,0 +1,22 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +__all__ = ['modjy', 'modjy_exceptions', 'modjy_impl', 'modjy_log', 'modjy_params', 'modjy_publish', 'modjy_response', 'modjy_write', 'modjy_wsgi',] + diff --git a/src/main/resources/PythonLibs/modjy/modjy.py b/src/main/resources/PythonLibs/modjy/modjy.py new file mode 100644 index 0000000000000000000000000000000000000000..cd6c398a5261f201271a32a08336c779be9f71c7 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy.py @@ -0,0 +1,121 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +import jarray +import synchronize +import sys +import types + +sys.add_package("javax.servlet") +sys.add_package("javax.servlet.http") +sys.add_package("org.python.core") + +from modjy_exceptions import * +from modjy_log import * +from modjy_params import modjy_param_mgr, modjy_servlet_params +from modjy_wsgi import modjy_wsgi +from modjy_response import start_response_object +from modjy_impl import modjy_impl +from modjy_publish import modjy_publisher + +from javax.servlet.http import HttpServlet + +class modjy_servlet(HttpServlet, modjy_publisher, modjy_wsgi, modjy_impl): + + def __init__(self): + HttpServlet.__init__(self) + + def do_param(self, name, value): + if name[:3] == 'log': + getattr(self.log, "set_%s" % name)(value) + else: + self.params[name] = value + + def process_param_container(self, param_container): + param_enum = param_container.getInitParameterNames() + while param_enum.hasMoreElements(): + param_name = param_enum.nextElement() + self.do_param(param_name, param_container.getInitParameter(param_name)) + + def get_params(self): + self.process_param_container(self.servlet_context) + self.process_param_container(self.servlet) + + def init(self, delegator): + self.servlet = delegator + self.servlet_context = self.servlet.getServletContext() + self.servlet_config = self.servlet.getServletConfig() + self.log = modjy_logger(self.servlet_context) + self.params = modjy_param_mgr(modjy_servlet_params) + self.get_params() + self.init_impl() + self.init_publisher() + import modjy_exceptions + self.exc_handler = getattr(modjy_exceptions, '%s_handler' % self.params['exc_handler'])() + + def service (self, req, resp): + wsgi_environ = {} + try: + self.dispatch_to_application(req, resp, wsgi_environ) + except ModjyException, mx: + self.log.error("Exception servicing request: %s" % str(mx)) + typ, value, tb = sys.exc_info()[:] + self.exc_handler.handle(req, resp, wsgi_environ, mx, (typ, value, tb) ) + + def get_j2ee_ns(self, req, resp): + return { + 'servlet': self.servlet, + 'servlet_context': self.servlet_context, + 'servlet_config': self.servlet_config, + 'request': req, + 'response': resp, + } + + def dispatch_to_application(self, req, resp, environ): + app_callable = self.get_app_object(req, environ) + self.set_wsgi_environment(req, resp, environ, self.params, self.get_j2ee_ns(req, resp)) + response_callable = start_response_object(req, resp) + try: + app_return = self.call_application(app_callable, environ, response_callable) + if app_return is None: + raise ReturnNotIterable("Application returned None: must return an iterable") + self.deal_with_app_return(environ, response_callable, app_return) + except ModjyException, mx: + self.raise_exc(mx.__class__, str(mx)) + except Exception, x: + self.raise_exc(ApplicationException, str(x)) + + def call_application(self, app_callable, environ, response_callable): + if self.params['multithread']: + return app_callable.__call__(environ, response_callable) + else: + return synchronize.apply_synchronized( \ + app_callable, \ + app_callable, \ + (environ, response_callable)) + + def expand_relative_path(self, path): + if path.startswith("$"): + return self.servlet.getServletContext().getRealPath(path[1:]) + return path + + def raise_exc(self, exc_class, message): + self.log.error(message) + raise exc_class(message) diff --git a/src/main/resources/PythonLibs/modjy/modjy_exceptions.py b/src/main/resources/PythonLibs/modjy/modjy_exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..8ce6e35ac61c94eeb1250846151a1e7229a23cf4 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_exceptions.py @@ -0,0 +1,91 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +import sys +import StringIO +import traceback + +from java.lang import IllegalStateException +from java.io import IOException +from javax.servlet import ServletException + +class ModjyException(Exception): pass + +class ModjyIOException(ModjyException): pass + +class ConfigException(ModjyException): pass +class BadParameter(ConfigException): pass +class ApplicationNotFound(ConfigException): pass +class NoCallable(ConfigException): pass + +class RequestException(ModjyException): pass + +class ApplicationException(ModjyException): pass +class StartResponseNotCalled(ApplicationException): pass +class StartResponseCalledTwice(ApplicationException): pass +class ResponseCommitted(ApplicationException): pass +class HopByHopHeaderSet(ApplicationException): pass +class WrongLength(ApplicationException): pass +class BadArgument(ApplicationException): pass +class ReturnNotIterable(ApplicationException): pass +class NonStringOutput(ApplicationException): pass + +class exception_handler: + + def handle(self, req, resp, environ, exc, exc_info): + pass + + def get_status_and_message(self, req, resp, exc): + return resp.SC_INTERNAL_SERVER_ERROR, "Server configuration error" + +# +# Special exception handler for testing +# + +class testing_handler(exception_handler): + + def handle(self, req, resp, environ, exc, exc_info): + typ, value, tb = exc_info + err_msg = StringIO.StringIO() + err_msg.write("%s: %s\n" % (typ, value,) ) + err_msg.write(">Environment\n") + for k in environ.keys(): + err_msg.write("%s=%s\n" % (k, repr(environ[k])) ) + err_msg.write("<Environment\n") + err_msg.write(">TraceBack\n") + for line in traceback.format_exception(typ, value, tb): + err_msg.write(line) + err_msg.write("<TraceBack\n") + try: + status, message = self.get_status_and_message(req, resp, exc) + resp.setStatus(status) + resp.setContentLength(len(err_msg.getvalue())) + resp.getOutputStream().write(err_msg.getvalue()) + except IllegalStateException, ise: + raise exc # Let the container deal with it + +# +# Standard exception handler +# + +class standard_handler(exception_handler): + + def handle(self, req, resp, environ, exc, exc_info): + raise exc_info[0], exc_info[1], exc_info[2] diff --git a/src/main/resources/PythonLibs/modjy/modjy_impl.py b/src/main/resources/PythonLibs/modjy/modjy_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..82662937f489c8979dfdf689ed815ccaf8f3fc02 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_impl.py @@ -0,0 +1,101 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +import types +import sys + +from modjy_exceptions import * + +class modjy_impl: + + def deal_with_app_return(self, environ, start_response_callable, app_return): + self.log.debug("Processing app return type: %s" % str(type(app_return))) + if isinstance(app_return, types.StringTypes): + raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return))) + if type(app_return) is types.FileType: + pass # TBD: What to do here? can't call fileno() + if hasattr(app_return, '__len__') and callable(app_return.__len__): + expected_pieces = app_return.__len__() + else: + expected_pieces = -1 + try: + try: + ix = 0 + for next_piece in app_return: + if not isinstance(next_piece, types.StringTypes): + raise NonStringOutput("Application returned iterable containing non-strings: %s" % str(type(next_piece))) + if ix == 0: + # The application may have called start_response in the first iteration + if not start_response_callable.called: + raise StartResponseNotCalled("Start_response callable was never called.") + if not start_response_callable.content_length \ + and expected_pieces == 1 \ + and start_response_callable.write_callable.num_writes == 0: + # Take the length of the first piece + start_response_callable.set_content_length(len(next_piece)) + start_response_callable.write_callable(next_piece) + ix += 1 + if ix == expected_pieces: + break + if expected_pieces != -1 and ix != expected_pieces: + raise WrongLength("Iterator len() was wrong. Expected %d pieces: got %d" % (expected_pieces, ix) ) + except AttributeError, ax: + if str(ax) == "__getitem__": + raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return))) + else: + raise ax + except TypeError, tx: + raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return))) + except ModjyException, mx: + raise mx + except Exception, x: + raise ApplicationException(x) + finally: + if hasattr(app_return, 'close') and callable(app_return.close): + app_return.close() + + def init_impl(self): + self.do_j_env_params() + + def add_packages(self, package_list): + packages = [p.strip() for p in package_list.split(';')] + for p in packages: + self.log.info("Adding java package %s to jython" % p) + sys.add_package(p) + + def add_classdirs(self, classdir_list): + classdirs = [cd.strip() for cd in classdir_list.split(';')] + for cd in classdirs: + self.log.info("Adding directory %s to jython class file search path" % cd) + sys.add_classdir(cd) + + def add_extdirs(self, extdir_list): + extdirs = [ed.strip() for ed in extdir_list.split(';')] + for ed in extdirs: + self.log.info("Adding directory %s for .jars and .zips search path" % ed) + sys.add_extdir(self.expand_relative_path(ed)) + + def do_j_env_params(self): + if self.params['packages']: + self.add_packages(self.params['packages']) + if self.params['classdirs']: + self.add_classdirs(self.params['classdirs']) + if self.params['extdirs']: + self.add_extdirs(self.params['extdirs']) diff --git a/src/main/resources/PythonLibs/modjy/modjy_input.py b/src/main/resources/PythonLibs/modjy/modjy_input.py new file mode 100644 index 0000000000000000000000000000000000000000..ca6e72702a661cdc5ef244400c9981d38cade2f5 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_input.py @@ -0,0 +1,167 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +# +# This code adapted from the socket._fileobject class +# + +import jarray + +class modjy_input_object(object): + + def __init__(self, servlet_inputstream, bufsize=8192): + self.istream = servlet_inputstream + self.buffer_size = bufsize + self.buffer = "" + + def istream_read(self, n): + data = jarray.zeros(n, 'b') + m = self.istream.read(data) + if m == -1: # indicates EOF has been reached, so we just return the empty string + return "" + elif m <= 0: + return "" + if m < n: + data = data[:m] + return data.tostring() + + def read(self, size=-1): + data = self.buffer + if size < 0: + # Read until EOF + buffers = [] + if data: + buffers.append(data) + self.buffer = "" + recv_size = self.buffer_size + while True: + data = self.istream_read(recv_size) + if not data: + break + buffers.append(data) + return "".join(buffers) + else: + # Read until size bytes or EOF seen, whichever comes first + buf_len = len(data) + if buf_len >= size: + self.buffer = data[size:] + return data[:size] + buffers = [] + if data: + buffers.append(data) + self.buffer = "" + while True: + left = size - buf_len + recv_size = max(self.buffer_size, left) + data = self.istream_read(recv_size) + if not data: + break + buffers.append(data) + n = len(data) + if n >= left: + self.buffer = data[left:] + buffers[-1] = data[:left] + break + buf_len += n + return "".join(buffers) + + def readline(self, size=-1): + data = self.buffer + if size < 0: + # Read until \n or EOF, whichever comes first + nl = data.find('\n') + if nl >= 0: + nl += 1 + self.buffer = data[nl:] + return data[:nl] + buffers = [] + if data: + buffers.append(data) + self.buffer = "" + while True: + data = self.istream_read(self.buffer_size) + if not data: + break + buffers.append(data) + nl = data.find('\n') + if nl >= 0: + nl += 1 + self.buffer = data[nl:] + buffers[-1] = data[:nl] + break + return "".join(buffers) + else: + # Read until size bytes or \n or EOF seen, whichever comes first + nl = data.find('\n', 0, size) + if nl >= 0: + nl += 1 + self.buffer = data[nl:] + return data[:nl] + buf_len = len(data) + if buf_len >= size: + self.buffer = data[size:] + return data[:size] + buffers = [] + if data: + buffers.append(data) + self.buffer = "" + while True: + data = self.istream_read(self.buffer_size) + if not data: + break + buffers.append(data) + left = size - buf_len + nl = data.find('\n', 0, left) + if nl >= 0: + nl += 1 + self.buffer = data[nl:] + buffers[-1] = data[:nl] + break + n = len(data) + if n >= left: + self.buffer = data[left:] + buffers[-1] = data[:left] + break + buf_len += n + return "".join(buffers) + + def readlines(self, sizehint=0): + total = 0 + list = [] + while True: + line = self.readline() + if not line: + break + list.append(line) + total += len(line) + if sizehint and total >= sizehint: + break + return list + + # Iterator protocols + + def __iter__(self): + return self + + def next(self): + line = self.readline() + if not line: + raise StopIteration + return line diff --git a/src/main/resources/PythonLibs/modjy/modjy_log.py b/src/main/resources/PythonLibs/modjy/modjy_log.py new file mode 100644 index 0000000000000000000000000000000000000000..9931e340b558096474f70f151c28a6cd9005dff3 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_log.py @@ -0,0 +1,80 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +import java + +import sys + +DEBUG = 'debug' +INFO = 'info' +WARN = 'warn' +ERROR = 'error' +FATAL = 'fatal' + +levels_dict = {} +ix = 0 +for level in [DEBUG, INFO, WARN, ERROR, FATAL, ]: + levels_dict[level]=ix + ix += 1 + +class modjy_logger: + + def __init__(self, context): + self.log_ctx = context + self.format_str = "%(lvl)s:\t%(msg)s" + self.log_level = levels_dict[DEBUG] + + def _log(self, level, level_str, msg, exc): + if level >= self.log_level: + msg = self.format_str % {'lvl': level_str, 'msg': msg, } + if exc: +# java.lang.System.err.println(msg, exc) + self.log_ctx.log(msg, exc) + else: +# java.lang.System.err.println(msg) + self.log_ctx.log(msg) + + def debug(self, msg, exc=None): + self._log(0, DEBUG, msg, exc) + + def info(self, msg, exc=None): + self._log(1, INFO, msg, exc) + + def warn(self, msg, exc=None): + self._log(2, WARN, msg, exc) + + def error(self, msg, exc=None): + self._log(3, ERROR, msg, exc) + + def fatal(self, msg, exc=None): + self._log(4, FATAL, msg, exc) + + def set_log_level(self, level_string): + try: + self.log_level = levels_dict[level_string] + except KeyError: + raise BadParameter("Invalid log level: '%s'" % level_string) + + def set_log_format(self, format_string): + # BUG! Format string never actually used in this function. + try: + self._log(debug, "This is a log formatting test", None) + except KeyError: + raise BadParameter("Bad format string: '%s'" % format_string) diff --git a/src/main/resources/PythonLibs/modjy/modjy_params.py b/src/main/resources/PythonLibs/modjy/modjy_params.py new file mode 100644 index 0000000000000000000000000000000000000000..b6c400c5578020391d0820c83aa406115dc51184 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_params.py @@ -0,0 +1,84 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +from UserDict import UserDict + +BOOLEAN = ('boolean', int) +INTEGER = ('integer', int) +FLOAT = ('float', float) +STRING = ('string', None) + +modjy_servlet_params = { + + 'multithread': (BOOLEAN, 1), + 'cache_callables': (BOOLEAN, 1), + 'reload_on_mod': (BOOLEAN, 0), + + 'app_import_name': (STRING, None), + + 'app_directory': (STRING, None), + 'app_filename': (STRING, 'application.py'), + 'app_callable_name': (STRING, 'handler'), + 'callable_query_name': (STRING, None), + + 'exc_handler': (STRING, 'standard'), + + 'log_level': (STRING, 'info'), + + 'packages': (STRING, None), + 'classdirs': (STRING, None), + 'extdirs': (STRING, None), + + 'initial_env': (STRING, None), +} + +class modjy_param_mgr(UserDict): + + def __init__(self, param_types): + UserDict.__init__(self) + self.param_types = param_types + for pname in self.param_types.keys(): + typ, default = self.param_types[pname] + self.__setitem__(pname, default) + + def __getitem__(self, name): + return self._get_defaulted_value(name) + + def __setitem__(self, name, value): + self.data[name] = self._convert_value(name, value) + + def _convert_value(self, name, value): + if self.param_types.has_key(name): + typ, default = self.param_types[name] + typ_str, typ_func = typ + if typ_func: + try: + return typ_func(value) + except ValueError: + raise BadParameter("Illegal value for %s parameter '%s': %s" % (typ_str, name, value) ) + return value + + def _get_defaulted_value(self, name): + if self.data.has_key(name): + return self.data[name] + if self.param_types.has_key(name): + typ, default = self.param_types[name] + return default + raise KeyError(name) diff --git a/src/main/resources/PythonLibs/modjy/modjy_publish.py b/src/main/resources/PythonLibs/modjy/modjy_publish.py new file mode 100644 index 0000000000000000000000000000000000000000..adb3b1ad14286b06b5012b364337c5457c0193d1 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_publish.py @@ -0,0 +1,143 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +import sys +import synchronize + +from java.io import File + +from modjy_exceptions import * + +class modjy_publisher: + + def init_publisher(self): + self.cache = None + if self.params['app_directory']: + self.app_directory = self.expand_relative_path(self.params['app_directory']) + else: + self.app_directory = self.servlet_context.getRealPath('/') + self.params['app_directory'] = self.app_directory + if self.app_directory is not None and not self.app_directory in sys.path: + sys.path.append(self.app_directory) + + def map_uri(self, req, environ): + source_uri = '%s%s%s' % (self.app_directory, File.separator, self.params['app_filename']) + callable_name = self.params['app_callable_name'] + if self.params['callable_query_name']: + query_string = req.getQueryString() + if query_string: + for name_val in query_string.split('&'): + if name_val.find('=') != -1: + name, value = name_val.split('=', 1) + else: + name, value = name_val, '' + if name == self.params['callable_query_name']: + callable_name = value + else: + callable_name = '' + return source_uri, callable_name + + def get_app_object(self, req, environ): + environ["SCRIPT_NAME"] = "%s%s" % (req.getContextPath(), req.getServletPath()) + path_info = req.getPathInfo() or "" + environ["PATH_INFO"] = path_info + environ["PATH_TRANSLATED"] = File(self.app_directory, path_info).getPath() + + if self.params['app_import_name']: + return self.get_app_object_importable(self.params['app_import_name']) + else: + if self.cache is None: + self.cache = {} + return self.get_app_object_old_style(req, environ) + + get_app_object = synchronize.make_synchronized(get_app_object) + + def get_app_object_importable(self, importable_name): + self.log.debug("Attempting to import application callable '%s'\n" % (importable_name, )) + # Under the importable mechanism, the cache contains a single object + if self.cache is None: + application, instantiable, method_name = self.load_importable(importable_name.strip()) + if instantiable and self.params['cache_callables']: + application = application() + self.cache = application, instantiable, method_name + application, instantiable, method_name = self.cache + self.log.debug("Application is " + str(application)) + if instantiable and not self.params['cache_callables']: + application = application() + self.log.debug("Instantiated application is " + str(application)) + if method_name is not None: + if not hasattr(application, method_name): + self.log.fatal("Attribute error application callable '%s' as no method '%s'" % (application, method_name)) + self.raise_exc(ApplicationNotFound, "Attribute error application callable '%s' as no method '%s'" % (application, method_name)) + application = getattr(application, method_name) + self.log.debug("Application method is " + str(application)) + return application + + def load_importable(self, name): + try: + instantiable = False ; method_name = None + importable_name = name + if name.find('()') != -1: + instantiable = True + importable_name, method_name = name.split('()') + if method_name.startswith('.'): + method_name = method_name[1:] + if not method_name: + method_name = None + module_path, from_name = importable_name.rsplit('.', 1) + imported = __import__(module_path, globals(), locals(), [from_name]) + imported = getattr(imported, from_name) + return imported, instantiable, method_name + except (ImportError, AttributeError), aix: + self.log.fatal("Import error import application callable '%s': %s\n" % (name, str(aix))) + self.raise_exc(ApplicationNotFound, "Failed to import app callable '%s': %s" % (name, str(aix))) + + def get_app_object_old_style(self, req, environ): + source_uri, callable_name = self.map_uri(req, environ) + source_filename = source_uri + if not self.params['cache_callables']: + self.log.debug("Caching of callables disabled") + return self.load_object(source_filename, callable_name) + if not self.cache.has_key( (source_filename, callable_name) ): + self.log.debug("Callable object not in cache: %s#%s" % (source_filename, callable_name) ) + return self.load_object(source_filename, callable_name) + app_callable, last_mod = self.cache.get( (source_filename, callable_name) ) + self.log.debug("Callable object was in cache: %s#%s" % (source_filename, callable_name) ) + if self.params['reload_on_mod']: + f = File(source_filename) + if f.lastModified() > last_mod: + self.log.info("Source file '%s' has been modified: reloading" % source_filename) + return self.load_object(source_filename, callable_name) + return app_callable + + def load_object(self, path, callable_name): + try: + app_ns = {} ; execfile(path, app_ns) + app_callable = app_ns[callable_name] + f = File(path) + self.cache[ (path, callable_name) ] = (app_callable, f.lastModified()) + return app_callable + except IOError, ioe: + self.raise_exc(ApplicationNotFound, "Application filename not found: %s" % path) + except KeyError, k: + self.raise_exc(NoCallable, "No callable named '%s' in %s" % (callable_name, path)) + except Exception, x: + self.raise_exc(NoCallable, "Error loading jython callable '%s': %s" % (callable_name, str(x)) ) + diff --git a/src/main/resources/PythonLibs/modjy/modjy_response.py b/src/main/resources/PythonLibs/modjy/modjy_response.py new file mode 100644 index 0000000000000000000000000000000000000000..52c9bc096aa203e7b80f31afa60dc72d0b76f273 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_response.py @@ -0,0 +1,113 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +import types + +from java.lang import System + +from modjy_exceptions import * +from modjy_write import write_object + +# From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 + +hop_by_hop_headers = { + 'connection': None, + 'keep-alive': None, + 'proxy-authenticate': None, + 'proxy-authorization': None, + 'te': None, + 'trailers': None, + 'transfer-encoding': None, + 'upgrade': None, +} + +class start_response_object: + + def __init__(self, req, resp): + self.http_req = req + self.http_resp = resp + self.write_callable = None + self.called = 0 + self.content_length = None + + # I'm doing the parameters this way to facilitate porting back to java + def __call__(self, *args, **keywords): + if len(args) < 2 or len(args) > 3: + raise BadArgument("Start response callback requires either two or three arguments: got %s" % str(args)) + if len(args) == 3: + exc_info = args[2] + try: + try: + self.http_resp.reset() + except IllegalStateException, isx: + raise exc_info[0], exc_info[1], exc_info[2] + finally: + exc_info = None + else: + if self.called > 0: + raise StartResponseCalledTwice("Start response callback may only be called once, without exception information.") + status_str = args[0] + headers_list = args[1] + if not isinstance(status_str, types.StringType): + raise BadArgument("Start response callback requires string as first argument") + if not isinstance(headers_list, types.ListType): + raise BadArgument("Start response callback requires list as second argument") + try: + status_code, status_message_str = status_str.split(" ", 1) + self.http_resp.setStatus(int(status_code)) + except ValueError: + raise BadArgument("Status string must be of the form '<int> <string>'") + self.make_write_object() + try: + for header_name, header_value in headers_list: + header_name_lower = header_name.lower() + if hop_by_hop_headers.has_key(header_name_lower): + raise HopByHopHeaderSet("Under WSGI, it is illegal to set hop-by-hop headers, i.e. '%s'" % header_name) + if header_name_lower == "content-length": + try: + self.set_content_length(int(header_value)) + except ValueError, v: + raise BadArgument("Content-Length header value must be a string containing an integer, not '%s'" % header_value) + else: + final_value = header_value.encode('latin-1') + # Here would be the place to check for control characters, whitespace, etc + self.http_resp.addHeader(header_name, final_value) + except (AttributeError, TypeError), t: + raise BadArgument("Start response callback headers must contain a list of (<string>,<string>) tuples") + except UnicodeError, u: + raise BadArgument("Encoding error: header values may only contain latin-1 characters, not '%s'" % repr(header_value)) + except ValueError, v: + raise BadArgument("Headers list must contain 2-tuples") + self.called += 1 + return self.write_callable + + def set_content_length(self, length): + if self.write_callable.num_writes == 0: + self.content_length = length + self.http_resp.setContentLength(length) + else: + raise ResponseCommitted("Cannot set content-length: response is already commited.") + + def make_write_object(self): + try: + self.write_callable = write_object(self.http_resp.getOutputStream()) + except IOException, iox: + raise IOError(iox) + return self.write_callable diff --git a/src/main/resources/PythonLibs/modjy/modjy_write.py b/src/main/resources/PythonLibs/modjy/modjy_write.py new file mode 100644 index 0000000000000000000000000000000000000000..e3d105c02cf128b215db261b5bc2cb4ee13159c9 --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_write.py @@ -0,0 +1,43 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +import types + +from modjy_exceptions import * + +class write_object: + + def __init__(self, ostream): + self.ostream = ostream + self.num_writes = 0 + + def __call__(self, *args, **keywords): + if len(args) != 1 or not isinstance(args[0], types.StringTypes): + raise NonStringOutput("Invocation of write callable requires exactly one string argument") + try: + self.ostream.write(args[0]) # Jython implicitly converts the (binary) string to a byte array + # WSGI requires that all output be flushed before returning to the application + # According to the java docs: " The flush method of OutputStream does nothing." + # Still, leave it in place for now: it's in the right place should this + # code ever be ported to another platform. + self.ostream.flush() + self.num_writes += 1 + except Exception, x: + raise ModjyIOException(x) diff --git a/src/main/resources/PythonLibs/modjy/modjy_wsgi.py b/src/main/resources/PythonLibs/modjy/modjy_wsgi.py new file mode 100644 index 0000000000000000000000000000000000000000..9788ce2e85bb31ec6afe00b415962e64f64c312a --- /dev/null +++ b/src/main/resources/PythonLibs/modjy/modjy_wsgi.py @@ -0,0 +1,157 @@ +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +from java.lang import System + +try: + from org.python.core.util import FileUtil + create_py_file = FileUtil.wrap +except ImportError: + from org.python.core import PyFile + create_py_file = PyFile + +from modjy_exceptions import * +from modjy_input import modjy_input_object + +server_name = "modjy" +server_param_prefix = "%s.param" % server_name +j2ee_ns_prefix = "j2ee" + +cgi_var_char_encoding = "iso-8859-1" + +class modjy_wsgi: + + # + # WSGI constants + # + + empty_pystring = u"" + wsgi_version = (1,0) + + # + # Container-specific constants + # + + modjy_version = (0, 25, 3) + + def set_string_envvar(self, dict, name, value): + if value is None: + value = self.empty_pystring + value = value.encode(cgi_var_char_encoding) + dict[name] = value + + def set_string_envvar_optional(self, dict, name, value, default_value): + if value != default_value: + self.set_string_envvar(dict, name, value) + + def set_int_envvar(self, dict, name, value, default_value): + if value == default_value: + value = self.empty_pystring + else: + value = unicode(value) + self.set_string_envvar(dict, name, value) + + def set_container_specific_wsgi_vars(self, req, resp, dict, params): + dict["%s.version" % server_name] = self.modjy_version + for pname in params.keys(): + dict["%s.%s" % (server_param_prefix, pname)] = params[pname] + + def set_j2ee_specific_wsgi_vars(self, dict, j2ee_ns): + for p in j2ee_ns.keys(): + dict["%s.%s" % (j2ee_ns_prefix, p)] = j2ee_ns[p] + + def set_required_cgi_environ (self, req, resp, dict): + self.set_string_envvar(dict, "REQUEST_METHOD", req.getMethod()) + self.set_string_envvar(dict, "QUERY_STRING", req.getQueryString()) + self.set_string_envvar(dict, "CONTENT_TYPE", req.getContentType()) + self.set_int_envvar(dict, "CONTENT_LENGTH", req.getContentLength(), -1) + self.set_string_envvar(dict, "SERVER_NAME", req.getLocalName()) + self.set_int_envvar(dict, "SERVER_PORT", req.getLocalPort(), 0) + + def set_other_cgi_environ (self, req, resp, dict): + if req.isSecure(): + self.set_string_envvar(dict, "HTTPS", 'on') + else: + self.set_string_envvar(dict, "HTTPS", 'off') + self.set_string_envvar(dict, "SERVER_PROTOCOL", req.getProtocol()) + self.set_string_envvar(dict, "REMOTE_HOST", req.getRemoteHost()) + self.set_string_envvar(dict, "REMOTE_ADDR", req.getRemoteAddr()) + self.set_int_envvar(dict, "REMOTE_PORT", req.getRemotePort(), -1) + self.set_string_envvar_optional(dict, "AUTH_TYPE", req.getAuthType(), None) + self.set_string_envvar_optional(dict, "REMOTE_USER", req.getRemoteUser(), None) + + def set_http_header_environ(self, req, resp, dict): + header_name_enum = req.getHeaderNames() + while header_name_enum.hasMoreElements(): + curr_header_name = header_name_enum.nextElement() + values = None + values_enum = req.getHeaders(curr_header_name) + while values_enum.hasMoreElements(): + next_value = values_enum.nextElement().encode(cgi_var_char_encoding) + if values is None: + values = next_value + else: + if isinstance(values, list): + values.append(next_value) + else: + values = [values] + dict["HTTP_%s" % str(curr_header_name).replace('-', '_').upper()] = values + + def set_required_wsgi_vars(self, req, resp, dict): + dict["wsgi.version"] = self.wsgi_version + dict["wsgi.url_scheme"] = req.getScheme() + dict["wsgi.multithread"] = \ + int(dict["%s.cache_callables" % server_param_prefix]) \ + and \ + int(dict["%s.multithread" % server_param_prefix]) + dict["wsgi.multiprocess"] = self.wsgi_multiprocess = 0 + dict["wsgi.run_once"] = not(dict["%s.cache_callables" % server_param_prefix]) + + def set_wsgi_streams(self, req, resp, dict): + try: + dict["wsgi.input"] = modjy_input_object(req.getInputStream()) + dict["wsgi.errors"] = create_py_file(System.err) + except IOException, iox: + raise ModjyIOException(iox) + + def set_wsgi_classes(self, req, resp, dict): + # dict["wsgi.file_wrapper"] = modjy_file_wrapper + pass + + def set_user_specified_environment(self, req, resp, wsgi_environ, params): + if not params.has_key('initial_env') or not params['initial_env']: + return + user_env_string = params['initial_env'] + for l in user_env_string.split('\n'): + l = l.strip() + if l: + name, value = l.split(':', 1) + wsgi_environ[name.strip()] = value.strip() + + def set_wsgi_environment(self, req, resp, wsgi_environ, params, j2ee_ns): + self.set_container_specific_wsgi_vars(req, resp, wsgi_environ, params) + self.set_j2ee_specific_wsgi_vars(wsgi_environ, j2ee_ns) + self.set_required_cgi_environ(req, resp, wsgi_environ) + self.set_other_cgi_environ(req, resp, wsgi_environ) + self.set_http_header_environ(req, resp, wsgi_environ) + self.set_required_wsgi_vars(req, resp, wsgi_environ) + self.set_wsgi_streams(req, resp, wsgi_environ) + self.set_wsgi_classes(req, resp, wsgi_environ) + self.set_user_specified_environment(req, resp, wsgi_environ, params) diff --git a/src/main/resources/PythonLibs/multifile.py b/src/main/resources/PythonLibs/multifile.py new file mode 100644 index 0000000000000000000000000000000000000000..35b0200c248adc9988588afa3747582fb4c285e7 --- /dev/null +++ b/src/main/resources/PythonLibs/multifile.py @@ -0,0 +1,162 @@ +"""A readline()-style interface to the parts of a multipart message. + +The MultiFile class makes each part of a multipart message "feel" like +an ordinary file, as long as you use fp.readline(). Allows recursive +use, for nested multipart messages. Probably best used together +with module mimetools. + +Suggested use: + +real_fp = open(...) +fp = MultiFile(real_fp) + +"read some lines from fp" +fp.push(separator) +while 1: + "read lines from fp until it returns an empty string" (A) + if not fp.next(): break +fp.pop() +"read remaining lines from fp until it returns an empty string" + +The latter sequence may be used recursively at (A). +It is also allowed to use multiple push()...pop() sequences. + +If seekable is given as 0, the class code will not do the bookkeeping +it normally attempts in order to make seeks relative to the beginning of the +current file part. This may be useful when using MultiFile with a non- +seekable stream object. +""" +from warnings import warn +warn("the multifile module has been deprecated since Python 2.5", + DeprecationWarning, stacklevel=2) +del warn + +__all__ = ["MultiFile","Error"] + +class Error(Exception): + pass + +class MultiFile: + + seekable = 0 + + def __init__(self, fp, seekable=1): + self.fp = fp + self.stack = [] + self.level = 0 + self.last = 0 + if seekable: + self.seekable = 1 + self.start = self.fp.tell() + self.posstack = [] + + def tell(self): + if self.level > 0: + return self.lastpos + return self.fp.tell() - self.start + + def seek(self, pos, whence=0): + here = self.tell() + if whence: + if whence == 1: + pos = pos + here + elif whence == 2: + if self.level > 0: + pos = pos + self.lastpos + else: + raise Error, "can't use whence=2 yet" + if not 0 <= pos <= here or \ + self.level > 0 and pos > self.lastpos: + raise Error, 'bad MultiFile.seek() call' + self.fp.seek(pos + self.start) + self.level = 0 + self.last = 0 + + def readline(self): + if self.level > 0: + return '' + line = self.fp.readline() + # Real EOF? + if not line: + self.level = len(self.stack) + self.last = (self.level > 0) + if self.last: + raise Error, 'sudden EOF in MultiFile.readline()' + return '' + assert self.level == 0 + # Fast check to see if this is just data + if self.is_data(line): + return line + else: + # Ignore trailing whitespace on marker lines + marker = line.rstrip() + # No? OK, try to match a boundary. + # Return the line (unstripped) if we don't. + for i, sep in enumerate(reversed(self.stack)): + if marker == self.section_divider(sep): + self.last = 0 + break + elif marker == self.end_marker(sep): + self.last = 1 + break + else: + return line + # We only get here if we see a section divider or EOM line + if self.seekable: + self.lastpos = self.tell() - len(line) + self.level = i+1 + if self.level > 1: + raise Error,'Missing endmarker in MultiFile.readline()' + return '' + + def readlines(self): + list = [] + while 1: + line = self.readline() + if not line: break + list.append(line) + return list + + def read(self): # Note: no size argument -- read until EOF only! + return ''.join(self.readlines()) + + def next(self): + while self.readline(): pass + if self.level > 1 or self.last: + return 0 + self.level = 0 + self.last = 0 + if self.seekable: + self.start = self.fp.tell() + return 1 + + def push(self, sep): + if self.level > 0: + raise Error, 'bad MultiFile.push() call' + self.stack.append(sep) + if self.seekable: + self.posstack.append(self.start) + self.start = self.fp.tell() + + def pop(self): + if self.stack == []: + raise Error, 'bad MultiFile.pop() call' + if self.level <= 1: + self.last = 0 + else: + abslastpos = self.lastpos + self.start + self.level = max(0, self.level - 1) + self.stack.pop() + if self.seekable: + self.start = self.posstack.pop() + if self.level > 0: + self.lastpos = abslastpos - self.start + + def is_data(self, line): + return line[:2] != '--' + + def section_divider(self, str): + return "--" + str + + def end_marker(self, str): + return "--" + str + "--" diff --git a/src/main/resources/PythonLibs/mutex.py b/src/main/resources/PythonLibs/mutex.py new file mode 100644 index 0000000000000000000000000000000000000000..f8acba4a35f93301bea1c528fb3286dc2384b33d --- /dev/null +++ b/src/main/resources/PythonLibs/mutex.py @@ -0,0 +1,55 @@ +"""Mutual exclusion -- for use with module sched + +A mutex has two pieces of state -- a 'locked' bit and a queue. +When the mutex is not locked, the queue is empty. +Otherwise, the queue contains 0 or more (function, argument) pairs +representing functions (or methods) waiting to acquire the lock. +When the mutex is unlocked while the queue is not empty, +the first queue entry is removed and its function(argument) pair called, +implying it now has the lock. + +Of course, no multi-threading is implied -- hence the funny interface +for lock, where a function is called once the lock is aquired. +""" +from warnings import warnpy3k +warnpy3k("the mutex module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +from collections import deque + +class mutex: + def __init__(self): + """Create a new mutex -- initially unlocked.""" + self.locked = False + self.queue = deque() + + def test(self): + """Test the locked bit of the mutex.""" + return self.locked + + def testandset(self): + """Atomic test-and-set -- grab the lock if it is not set, + return True if it succeeded.""" + if not self.locked: + self.locked = True + return True + else: + return False + + def lock(self, function, argument): + """Lock a mutex, call the function with supplied argument + when it is acquired. If the mutex is already locked, place + function and argument in the queue.""" + if self.testandset(): + function(argument) + else: + self.queue.append((function, argument)) + + def unlock(self): + """Unlock a mutex. If the queue is not empty, call the next + function with its argument.""" + if self.queue: + function, argument = self.queue.popleft() + function(argument) + else: + self.locked = False diff --git a/src/main/resources/PythonLibs/netrc.py b/src/main/resources/PythonLibs/netrc.py new file mode 100644 index 0000000000000000000000000000000000000000..370ad2c88d06f480f2c55435f7b3218adea67e77 --- /dev/null +++ b/src/main/resources/PythonLibs/netrc.py @@ -0,0 +1,119 @@ +"""An object-oriented interface to .netrc files.""" + +# Module and documentation by Eric S. Raymond, 21 Dec 1998 + +from __future__ import with_statement +import os, shlex + +__all__ = ["netrc", "NetrcParseError"] + + +class NetrcParseError(Exception): + """Exception raised on syntax errors in the .netrc file.""" + def __init__(self, msg, filename=None, lineno=None): + self.filename = filename + self.lineno = lineno + self.msg = msg + Exception.__init__(self, msg) + + def __str__(self): + return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno) + + +class netrc: + def __init__(self, file=None): + if file is None: + try: + file = os.path.join(os.environ['HOME'], ".netrc") + except KeyError: + raise IOError("Could not find .netrc: $HOME is not set") + self.hosts = {} + self.macros = {} + with open(file) as fp: + self._parse(file, fp) + + def _parse(self, file, fp): + lexer = shlex.shlex(fp) + lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" + lexer.commenters = lexer.commenters.replace('#', '') + while 1: + # Look for a machine, default, or macdef top-level keyword + toplevel = tt = lexer.get_token() + if not tt: + break + elif tt[0] == '#': + fp.readline(); + continue; + elif tt == 'machine': + entryname = lexer.get_token() + elif tt == 'default': + entryname = 'default' + elif tt == 'macdef': # Just skip to end of macdefs + entryname = lexer.get_token() + self.macros[entryname] = [] + lexer.whitespace = ' \t' + while 1: + line = lexer.instream.readline() + if not line or line == '\012': + lexer.whitespace = ' \t\r\n' + break + self.macros[entryname].append(line) + continue + else: + raise NetrcParseError( + "bad toplevel token %r" % tt, file, lexer.lineno) + + # We're looking at start of an entry for a named machine or default. + login = '' + account = password = None + self.hosts[entryname] = {} + while 1: + tt = lexer.get_token() + if (tt=='' or tt == 'machine' or + tt == 'default' or tt =='macdef'): + if password: + self.hosts[entryname] = (login, account, password) + lexer.push_token(tt) + break + else: + raise NetrcParseError( + "malformed %s entry %s terminated by %s" + % (toplevel, entryname, repr(tt)), + file, lexer.lineno) + elif tt == 'login' or tt == 'user': + login = lexer.get_token() + elif tt == 'account': + account = lexer.get_token() + elif tt == 'password': + password = lexer.get_token() + else: + raise NetrcParseError("bad follower token %r" % tt, + file, lexer.lineno) + + def authenticators(self, host): + """Return a (user, account, password) tuple for given host.""" + if host in self.hosts: + return self.hosts[host] + elif 'default' in self.hosts: + return self.hosts['default'] + else: + return None + + def __repr__(self): + """Dump the class data in the format of a .netrc file.""" + rep = "" + for host in self.hosts.keys(): + attrs = self.hosts[host] + rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n" + if attrs[1]: + rep = rep + "account " + repr(attrs[1]) + rep = rep + "\tpassword " + repr(attrs[2]) + "\n" + for macro in self.macros.keys(): + rep = rep + "macdef " + macro + "\n" + for line in self.macros[macro]: + rep = rep + line + rep = rep + "\n" + return rep + +if __name__ == '__main__': + print netrc() diff --git a/src/main/resources/PythonLibs/new.py b/src/main/resources/PythonLibs/new.py new file mode 100644 index 0000000000000000000000000000000000000000..c9048e55dfa8a50bbd3bc8c5294cbca3c79c5b5b --- /dev/null +++ b/src/main/resources/PythonLibs/new.py @@ -0,0 +1,19 @@ +"""Create new objects of various types. Deprecated. + +This module is no longer required except for backward compatibility. +Objects of most types can now be created by calling the type object. +""" +from warnings import warnpy3k +warnpy3k("The 'new' module has been removed in Python 3.0; use the 'types' " + "module instead.", stacklevel=2) +del warnpy3k + +from types import ClassType as classobj +from types import FunctionType as function +from types import InstanceType as instance +from types import MethodType as instancemethod +from types import ModuleType as module + +# XXX: Jython can't really create a code object like CPython does +# (according to test.test_new) +from org.python.core import PyBytecode as code diff --git a/src/main/resources/PythonLibs/nntplib.py b/src/main/resources/PythonLibs/nntplib.py new file mode 100644 index 0000000000000000000000000000000000000000..2dc82a90ae175f4de21504bae8b97098b073dcde --- /dev/null +++ b/src/main/resources/PythonLibs/nntplib.py @@ -0,0 +1,627 @@ +"""An NNTP client class based on RFC 977: Network News Transfer Protocol. + +Example: + +>>> from nntplib import NNTP +>>> s = NNTP('news') +>>> resp, count, first, last, name = s.group('comp.lang.python') +>>> print 'Group', name, 'has', count, 'articles, range', first, 'to', last +Group comp.lang.python has 51 articles, range 5770 to 5821 +>>> resp, subs = s.xhdr('subject', first + '-' + last) +>>> resp = s.quit() +>>> + +Here 'resp' is the server response line. +Error responses are turned into exceptions. + +To post an article from a file: +>>> f = open(filename, 'r') # file containing article, including header +>>> resp = s.post(f) +>>> + +For descriptions of all methods, read the comments in the code below. +Note that all arguments and return values representing article numbers +are strings, not numbers, since they are rarely used for calculations. +""" + +# RFC 977 by Brian Kantor and Phil Lapsley. +# xover, xgtitle, xpath, date methods by Kevan Heydon + + +# Imports +import re +import socket + +__all__ = ["NNTP","NNTPReplyError","NNTPTemporaryError", + "NNTPPermanentError","NNTPProtocolError","NNTPDataError", + "error_reply","error_temp","error_perm","error_proto", + "error_data",] + +# Exceptions raised when an error or invalid response is received +class NNTPError(Exception): + """Base class for all nntplib exceptions""" + def __init__(self, *args): + Exception.__init__(self, *args) + try: + self.response = args[0] + except IndexError: + self.response = 'No response given' + +class NNTPReplyError(NNTPError): + """Unexpected [123]xx reply""" + pass + +class NNTPTemporaryError(NNTPError): + """4xx errors""" + pass + +class NNTPPermanentError(NNTPError): + """5xx errors""" + pass + +class NNTPProtocolError(NNTPError): + """Response does not begin with [1-5]""" + pass + +class NNTPDataError(NNTPError): + """Error in response data""" + pass + +# for backwards compatibility +error_reply = NNTPReplyError +error_temp = NNTPTemporaryError +error_perm = NNTPPermanentError +error_proto = NNTPProtocolError +error_data = NNTPDataError + + + +# Standard port used by NNTP servers +NNTP_PORT = 119 + + +# Response numbers that are followed by additional text (e.g. article) +LONGRESP = ['100', '215', '220', '221', '222', '224', '230', '231', '282'] + + +# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF) +CRLF = '\r\n' + + + +# The class itself +class NNTP: + def __init__(self, host, port=NNTP_PORT, user=None, password=None, + readermode=None, usenetrc=True): + """Initialize an instance. Arguments: + - host: hostname to connect to + - port: port to connect to (default the standard NNTP port) + - user: username to authenticate with + - password: password to use with username + - readermode: if true, send 'mode reader' command after + connecting. + + readermode is sometimes necessary if you are connecting to an + NNTP server on the local machine and intend to call + reader-specific commands, such as `group'. If you get + unexpected NNTPPermanentErrors, you might need to set + readermode. + """ + self.host = host + self.port = port + self.sock = socket.create_connection((host, port)) + self.file = self.sock.makefile('rb') + self.debugging = 0 + self.welcome = self.getresp() + + # 'mode reader' is sometimes necessary to enable 'reader' mode. + # However, the order in which 'mode reader' and 'authinfo' need to + # arrive differs between some NNTP servers. Try to send + # 'mode reader', and if it fails with an authorization failed + # error, try again after sending authinfo. + readermode_afterauth = 0 + if readermode: + try: + self.welcome = self.shortcmd('mode reader') + except NNTPPermanentError: + # error 500, probably 'not implemented' + pass + except NNTPTemporaryError, e: + if user and e.response[:3] == '480': + # Need authorization before 'mode reader' + readermode_afterauth = 1 + else: + raise + # If no login/password was specified, try to get them from ~/.netrc + # Presume that if .netc has an entry, NNRP authentication is required. + try: + if usenetrc and not user: + import netrc + credentials = netrc.netrc() + auth = credentials.authenticators(host) + if auth: + user = auth[0] + password = auth[2] + except IOError: + pass + # Perform NNRP authentication if needed. + if user: + resp = self.shortcmd('authinfo user '+user) + if resp[:3] == '381': + if not password: + raise NNTPReplyError(resp) + else: + resp = self.shortcmd( + 'authinfo pass '+password) + if resp[:3] != '281': + raise NNTPPermanentError(resp) + if readermode_afterauth: + try: + self.welcome = self.shortcmd('mode reader') + except NNTPPermanentError: + # error 500, probably 'not implemented' + pass + + + # Get the welcome message from the server + # (this is read and squirreled away by __init__()). + # If the response code is 200, posting is allowed; + # if it 201, posting is not allowed + + def getwelcome(self): + """Get the welcome message from the server + (this is read and squirreled away by __init__()). + If the response code is 200, posting is allowed; + if it 201, posting is not allowed.""" + + if self.debugging: print '*welcome*', repr(self.welcome) + return self.welcome + + def set_debuglevel(self, level): + """Set the debugging level. Argument 'level' means: + 0: no debugging output (default) + 1: print commands and responses but not body text etc. + 2: also print raw lines read and sent before stripping CR/LF""" + + self.debugging = level + debug = set_debuglevel + + def putline(self, line): + """Internal: send one line to the server, appending CRLF.""" + line = line + CRLF + if self.debugging > 1: print '*put*', repr(line) + self.sock.sendall(line) + + def putcmd(self, line): + """Internal: send one command to the server (through putline()).""" + if self.debugging: print '*cmd*', repr(line) + self.putline(line) + + def getline(self): + """Internal: return one line from the server, stripping CRLF. + Raise EOFError if the connection is closed.""" + line = self.file.readline() + if self.debugging > 1: + print '*get*', repr(line) + if not line: raise EOFError + if line[-2:] == CRLF: line = line[:-2] + elif line[-1:] in CRLF: line = line[:-1] + return line + + def getresp(self): + """Internal: get a response from the server. + Raise various errors if the response indicates an error.""" + resp = self.getline() + if self.debugging: print '*resp*', repr(resp) + c = resp[:1] + if c == '4': + raise NNTPTemporaryError(resp) + if c == '5': + raise NNTPPermanentError(resp) + if c not in '123': + raise NNTPProtocolError(resp) + return resp + + def getlongresp(self, file=None): + """Internal: get a response plus following text from the server. + Raise various errors if the response indicates an error.""" + + openedFile = None + try: + # If a string was passed then open a file with that name + if isinstance(file, str): + openedFile = file = open(file, "w") + + resp = self.getresp() + if resp[:3] not in LONGRESP: + raise NNTPReplyError(resp) + list = [] + while 1: + line = self.getline() + if line == '.': + break + if line[:2] == '..': + line = line[1:] + if file: + file.write(line + "\n") + else: + list.append(line) + finally: + # If this method created the file, then it must close it + if openedFile: + openedFile.close() + + return resp, list + + def shortcmd(self, line): + """Internal: send a command and get the response.""" + self.putcmd(line) + return self.getresp() + + def longcmd(self, line, file=None): + """Internal: send a command and get the response plus following text.""" + self.putcmd(line) + return self.getlongresp(file) + + def newgroups(self, date, time, file=None): + """Process a NEWGROUPS command. Arguments: + - date: string 'yymmdd' indicating the date + - time: string 'hhmmss' indicating the time + Return: + - resp: server response if successful + - list: list of newsgroup names""" + + return self.longcmd('NEWGROUPS ' + date + ' ' + time, file) + + def newnews(self, group, date, time, file=None): + """Process a NEWNEWS command. Arguments: + - group: group name or '*' + - date: string 'yymmdd' indicating the date + - time: string 'hhmmss' indicating the time + Return: + - resp: server response if successful + - list: list of message ids""" + + cmd = 'NEWNEWS ' + group + ' ' + date + ' ' + time + return self.longcmd(cmd, file) + + def list(self, file=None): + """Process a LIST command. Return: + - resp: server response if successful + - list: list of (group, last, first, flag) (strings)""" + + resp, list = self.longcmd('LIST', file) + for i in range(len(list)): + # Parse lines into "group last first flag" + list[i] = tuple(list[i].split()) + return resp, list + + def description(self, group): + + """Get a description for a single group. If more than one + group matches ('group' is a pattern), return the first. If no + group matches, return an empty string. + + This elides the response code from the server, since it can + only be '215' or '285' (for xgtitle) anyway. If the response + code is needed, use the 'descriptions' method. + + NOTE: This neither checks for a wildcard in 'group' nor does + it check whether the group actually exists.""" + + resp, lines = self.descriptions(group) + if len(lines) == 0: + return "" + else: + return lines[0][1] + + def descriptions(self, group_pattern): + """Get descriptions for a range of groups.""" + line_pat = re.compile("^(?P<group>[^ \t]+)[ \t]+(.*)$") + # Try the more std (acc. to RFC2980) LIST NEWSGROUPS first + resp, raw_lines = self.longcmd('LIST NEWSGROUPS ' + group_pattern) + if resp[:3] != "215": + # Now the deprecated XGTITLE. This either raises an error + # or succeeds with the same output structure as LIST + # NEWSGROUPS. + resp, raw_lines = self.longcmd('XGTITLE ' + group_pattern) + lines = [] + for raw_line in raw_lines: + match = line_pat.search(raw_line.strip()) + if match: + lines.append(match.group(1, 2)) + return resp, lines + + def group(self, name): + """Process a GROUP command. Argument: + - group: the group name + Returns: + - resp: server response if successful + - count: number of articles (string) + - first: first article number (string) + - last: last article number (string) + - name: the group name""" + + resp = self.shortcmd('GROUP ' + name) + if resp[:3] != '211': + raise NNTPReplyError(resp) + words = resp.split() + count = first = last = 0 + n = len(words) + if n > 1: + count = words[1] + if n > 2: + first = words[2] + if n > 3: + last = words[3] + if n > 4: + name = words[4].lower() + return resp, count, first, last, name + + def help(self, file=None): + """Process a HELP command. Returns: + - resp: server response if successful + - list: list of strings""" + + return self.longcmd('HELP',file) + + def statparse(self, resp): + """Internal: parse the response of a STAT, NEXT or LAST command.""" + if resp[:2] != '22': + raise NNTPReplyError(resp) + words = resp.split() + nr = 0 + id = '' + n = len(words) + if n > 1: + nr = words[1] + if n > 2: + id = words[2] + return resp, nr, id + + def statcmd(self, line): + """Internal: process a STAT, NEXT or LAST command.""" + resp = self.shortcmd(line) + return self.statparse(resp) + + def stat(self, id): + """Process a STAT command. Argument: + - id: article number or message id + Returns: + - resp: server response if successful + - nr: the article number + - id: the message id""" + + return self.statcmd('STAT ' + id) + + def next(self): + """Process a NEXT command. No arguments. Return as for STAT.""" + return self.statcmd('NEXT') + + def last(self): + """Process a LAST command. No arguments. Return as for STAT.""" + return self.statcmd('LAST') + + def artcmd(self, line, file=None): + """Internal: process a HEAD, BODY or ARTICLE command.""" + resp, list = self.longcmd(line, file) + resp, nr, id = self.statparse(resp) + return resp, nr, id, list + + def head(self, id): + """Process a HEAD command. Argument: + - id: article number or message id + Returns: + - resp: server response if successful + - nr: article number + - id: message id + - list: the lines of the article's header""" + + return self.artcmd('HEAD ' + id) + + def body(self, id, file=None): + """Process a BODY command. Argument: + - id: article number or message id + - file: Filename string or file object to store the article in + Returns: + - resp: server response if successful + - nr: article number + - id: message id + - list: the lines of the article's body or an empty list + if file was used""" + + return self.artcmd('BODY ' + id, file) + + def article(self, id): + """Process an ARTICLE command. Argument: + - id: article number or message id + Returns: + - resp: server response if successful + - nr: article number + - id: message id + - list: the lines of the article""" + + return self.artcmd('ARTICLE ' + id) + + def slave(self): + """Process a SLAVE command. Returns: + - resp: server response if successful""" + + return self.shortcmd('SLAVE') + + def xhdr(self, hdr, str, file=None): + """Process an XHDR command (optional server extension). Arguments: + - hdr: the header type (e.g. 'subject') + - str: an article nr, a message id, or a range nr1-nr2 + Returns: + - resp: server response if successful + - list: list of (nr, value) strings""" + + pat = re.compile('^([0-9]+) ?(.*)\n?') + resp, lines = self.longcmd('XHDR ' + hdr + ' ' + str, file) + for i in range(len(lines)): + line = lines[i] + m = pat.match(line) + if m: + lines[i] = m.group(1, 2) + return resp, lines + + def xover(self, start, end, file=None): + """Process an XOVER command (optional server extension) Arguments: + - start: start of range + - end: end of range + Returns: + - resp: server response if successful + - list: list of (art-nr, subject, poster, date, + id, references, size, lines)""" + + resp, lines = self.longcmd('XOVER ' + start + '-' + end, file) + xover_lines = [] + for line in lines: + elem = line.split("\t") + try: + xover_lines.append((elem[0], + elem[1], + elem[2], + elem[3], + elem[4], + elem[5].split(), + elem[6], + elem[7])) + except IndexError: + raise NNTPDataError(line) + return resp,xover_lines + + def xgtitle(self, group, file=None): + """Process an XGTITLE command (optional server extension) Arguments: + - group: group name wildcard (i.e. news.*) + Returns: + - resp: server response if successful + - list: list of (name,title) strings""" + + line_pat = re.compile("^([^ \t]+)[ \t]+(.*)$") + resp, raw_lines = self.longcmd('XGTITLE ' + group, file) + lines = [] + for raw_line in raw_lines: + match = line_pat.search(raw_line.strip()) + if match: + lines.append(match.group(1, 2)) + return resp, lines + + def xpath(self,id): + """Process an XPATH command (optional server extension) Arguments: + - id: Message id of article + Returns: + resp: server response if successful + path: directory path to article""" + + resp = self.shortcmd("XPATH " + id) + if resp[:3] != '223': + raise NNTPReplyError(resp) + try: + [resp_num, path] = resp.split() + except ValueError: + raise NNTPReplyError(resp) + else: + return resp, path + + def date (self): + """Process the DATE command. Arguments: + None + Returns: + resp: server response if successful + date: Date suitable for newnews/newgroups commands etc. + time: Time suitable for newnews/newgroups commands etc.""" + + resp = self.shortcmd("DATE") + if resp[:3] != '111': + raise NNTPReplyError(resp) + elem = resp.split() + if len(elem) != 2: + raise NNTPDataError(resp) + date = elem[1][2:8] + time = elem[1][-6:] + if len(date) != 6 or len(time) != 6: + raise NNTPDataError(resp) + return resp, date, time + + + def post(self, f): + """Process a POST command. Arguments: + - f: file containing the article + Returns: + - resp: server response if successful""" + + resp = self.shortcmd('POST') + # Raises error_??? if posting is not allowed + if resp[0] != '3': + raise NNTPReplyError(resp) + while 1: + line = f.readline() + if not line: + break + if line[-1] == '\n': + line = line[:-1] + if line[:1] == '.': + line = '.' + line + self.putline(line) + self.putline('.') + return self.getresp() + + def ihave(self, id, f): + """Process an IHAVE command. Arguments: + - id: message-id of the article + - f: file containing the article + Returns: + - resp: server response if successful + Note that if the server refuses the article an exception is raised.""" + + resp = self.shortcmd('IHAVE ' + id) + # Raises error_??? if the server already has it + if resp[0] != '3': + raise NNTPReplyError(resp) + while 1: + line = f.readline() + if not line: + break + if line[-1] == '\n': + line = line[:-1] + if line[:1] == '.': + line = '.' + line + self.putline(line) + self.putline('.') + return self.getresp() + + def quit(self): + """Process a QUIT command and close the socket. Returns: + - resp: server response if successful""" + + resp = self.shortcmd('QUIT') + self.file.close() + self.sock.close() + del self.file, self.sock + return resp + + +# Test retrieval when run as a script. +# Assumption: if there's a local news server, it's called 'news'. +# Assumption: if user queries a remote news server, it's named +# in the environment variable NNTPSERVER (used by slrn and kin) +# and we want readermode off. +if __name__ == '__main__': + import os + newshost = 'news' and os.environ["NNTPSERVER"] + if newshost.find('.') == -1: + mode = 'readermode' + else: + mode = None + s = NNTP(newshost, readermode=mode) + resp, count, first, last, name = s.group('comp.lang.python') + print resp + print 'Group', name, 'has', count, 'articles, range', first, 'to', last + resp, subs = s.xhdr('subject', first + '-' + last) + print resp + for item in subs: + print "%7s %s" % item + resp = s.quit() + print resp diff --git a/src/main/resources/PythonLibs/ntpath.py b/src/main/resources/PythonLibs/ntpath.py new file mode 100644 index 0000000000000000000000000000000000000000..762ad22e80ad4d5e034868a231eb2a50c0c1eff2 --- /dev/null +++ b/src/main/resources/PythonLibs/ntpath.py @@ -0,0 +1,532 @@ +# Module 'ntpath' -- common operations on WinNT/Win95 pathnames +"""Common pathname manipulations, WindowsNT/95 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 * + +__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(a, *p): + """Join two or more pathname components, inserting "\\" as needed. + If any component is an absolute path, all previous path components + will be discarded.""" + path = a + for b in p: + b_wins = 0 # set to 1 iff b makes path irrelevant + if path == "": + b_wins = 1 + + elif isabs(b): + # This probably wipes out path so far. However, it's more + # complicated if path begins with a drive letter: + # 1. join('c:', '/a') == 'c:/a' + # 2. join('c:/', '/a') == 'c:/a' + # But + # 3. join('c:/a', '/b') == '/b' + # 4. join('c:', 'd:/') = 'd:/' + # 5. join('c:/', 'd:/') = 'd:/' + if path[1:2] != ":" or b[1:2] == ":": + # Path doesn't start with a drive letter, or cases 4 and 5. + b_wins = 1 + + # Else path has a drive letter, and b doesn't but is absolute. + elif len(path) > 3 or (len(path) == 3 and + path[-1] not in "/\\"): + # case 3 + b_wins = 1 + + if b_wins: + path = b + else: + # Join, and ensure there's a separator. + assert len(path) > 0 + if path[-1] in "/\\": + if b and b[0] in "/\\": + path += b[1:] + else: + path += b + elif path[-1] == ":": + path += b + elif b: + if b[0] in "/\\": + path += b + else: + path += "\\" + b + else: + # path is not empty and does not end with a backslash, + # but b is empty; since, e.g., split('a/') produces + # ('a', ''), it's best if join() adds a backslash in + # this case. + path += '\\' + + return 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 +def splitdrive(p): + """Split a pathname into drive and path specifiers. Returns a 2-tuple +"(drive,path)"; either part may be empty""" + if p[1:2] == ':': + return p[0:2], p[2:] + 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 p[1:2] == ':': + return '', p # Drive letter present + firstTwo = p[0:2] + if firstTwo == '//' or firstTwo == '\\\\': + # is a UNC path: + # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter + # \\machine\mountpoint\directories... + # directory ^^^^^^^^^^^^^^^ + normp = normcase(p) + index = normp.find('\\', 2) + if index == -1: + ##raise RuntimeError, 'illegal UNC path: "' + p + '"' + return ("", p) + index = normp.find('\\', index + 1) + if index == -1: + index = len(p) + return p[:index], p[index:] + 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 verifed 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 + '_-' + 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 + 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] + if var in os.environ: + res = res + os.environ[var] + else: + 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] + if var in os.environ: + res = res + os.environ[var] + else: + 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] + if var in os.environ: + res = res + os.environ[var] + else: + 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 + import java.io.File + from org.python.core.Py import newString + + 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) + if not splitunc(path)[0] and not splitdrive(path)[0]: + # cwd lacks a UNC mount point, so it should have a drive + # letter (but lacks one): determine it + canon_path = newString(java.io.File(path).getCanonicalPath()) + drive = splitdrive(canon_path)[0] + path = join(drive, 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) diff --git a/src/main/resources/PythonLibs/nturl2path.py b/src/main/resources/PythonLibs/nturl2path.py new file mode 100644 index 0000000000000000000000000000000000000000..10ea27280789f5a6bcfc7a2fb6c94ab6b9df5645 --- /dev/null +++ b/src/main/resources/PythonLibs/nturl2path.py @@ -0,0 +1,66 @@ +"""Convert a NT pathname to a file URL and vice versa.""" + +def url2pathname(url): + """OS-specific conversion from a relative URL of the 'file' scheme + to a file system path; not recommended for general use.""" + # e.g. + # ///C|/foo/bar/spam.foo + # becomes + # C:\foo\bar\spam.foo + import string, urllib + # Windows itself uses ":" even in URLs. + url = url.replace(':', '|') + if not '|' in url: + # No drive specifier, just convert slashes + if url[:4] == '////': + # path is something like ////host/path/on/remote/host + # convert this to \\host\path\on\remote\host + # (notice halving of slashes at the start of the path) + url = url[2:] + components = url.split('/') + # make sure not to convert quoted slashes :-) + return urllib.unquote('\\'.join(components)) + comp = url.split('|') + if len(comp) != 2 or comp[0][-1] not in string.ascii_letters: + error = 'Bad URL: ' + url + raise IOError, error + drive = comp[0][-1].upper() + path = drive + ':' + components = comp[1].split('/') + for comp in components: + if comp: + path = path + '\\' + urllib.unquote(comp) + # Issue #11474: url like '/C|/' should convert into 'C:\\' + if path.endswith(':') and url.endswith('/'): + path += '\\' + return path + +def pathname2url(p): + """OS-specific conversion from a file system path to a relative URL + of the 'file' scheme; not recommended for general use.""" + # e.g. + # C:\foo\bar\spam.foo + # becomes + # ///C|/foo/bar/spam.foo + import urllib + if not ':' in p: + # No drive specifier, just convert slashes and quote the name + if p[:2] == '\\\\': + # path is something like \\host\path\on\remote\host + # convert this to ////host/path/on/remote/host + # (notice doubling of slashes at the start of the path) + p = '\\\\' + p + components = p.split('\\') + return urllib.quote('/'.join(components)) + comp = p.split(':') + if len(comp) != 2 or len(comp[0]) > 1: + error = 'Bad path: ' + p + raise IOError, error + + drive = urllib.quote(comp[0].upper()) + components = comp[1].split('\\') + path = '///' + drive + ':' + for comp in components: + if comp: + path = path + '/' + urllib.quote(comp) + return path diff --git a/src/main/resources/PythonLibs/numbers.py b/src/main/resources/PythonLibs/numbers.py new file mode 100644 index 0000000000000000000000000000000000000000..bdc6dd65213b967b88537d386961bb9389de6902 --- /dev/null +++ b/src/main/resources/PythonLibs/numbers.py @@ -0,0 +1,391 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141. + +TODO: Fill out more detailed documentation on the operators.""" + +from __future__ import division +from abc import ABCMeta, abstractmethod, abstractproperty + +__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] + +class Number(object): + """All numbers inherit from this class. + + If you just want to check if an argument x is a number, without + caring what kind, use isinstance(x, Number). + """ + __metaclass__ = ABCMeta + __slots__ = () + + # Concrete numeric types must provide their own hash implementation + __hash__ = None + + +## Notes on Decimal +## ---------------- +## Decimal has all of the methods specified by the Real abc, but it should +## not be registered as a Real because decimals do not interoperate with +## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But, +## abstract reals are expected to interoperate (i.e. R1 + R2 should be +## expected to work if R1 and R2 are both Reals). + +class Complex(Number): + """Complex defines the operations that work on the builtin complex type. + + In short, those are: a conversion to complex, .real, .imag, +, -, + *, /, abs(), .conjugate, ==, and !=. + + If it is given heterogenous arguments, and doesn't have special + knowledge about them, it should fall back to the builtin complex + type as described below. + """ + + __slots__ = () + + @abstractmethod + def __complex__(self): + """Return a builtin complex instance. Called for complex(self).""" + + # Will be __bool__ in 3.0. + def __nonzero__(self): + """True if self != 0. Called for bool(self).""" + return self != 0 + + @abstractproperty + def real(self): + """Retrieve the real component of this number. + + This should subclass Real. + """ + raise NotImplementedError + + @abstractproperty + def imag(self): + """Retrieve the imaginary component of this number. + + This should subclass Real. + """ + raise NotImplementedError + + @abstractmethod + def __add__(self, other): + """self + other""" + raise NotImplementedError + + @abstractmethod + def __radd__(self, other): + """other + self""" + raise NotImplementedError + + @abstractmethod + def __neg__(self): + """-self""" + raise NotImplementedError + + @abstractmethod + def __pos__(self): + """+self""" + raise NotImplementedError + + def __sub__(self, other): + """self - other""" + return self + -other + + def __rsub__(self, other): + """other - self""" + return -self + other + + @abstractmethod + def __mul__(self, other): + """self * other""" + raise NotImplementedError + + @abstractmethod + def __rmul__(self, other): + """other * self""" + raise NotImplementedError + + @abstractmethod + def __div__(self, other): + """self / other without __future__ division + + May promote to float. + """ + raise NotImplementedError + + @abstractmethod + def __rdiv__(self, other): + """other / self without __future__ division""" + raise NotImplementedError + + @abstractmethod + def __truediv__(self, other): + """self / other with __future__ division. + + Should promote to float when necessary. + """ + raise NotImplementedError + + @abstractmethod + def __rtruediv__(self, other): + """other / self with __future__ division""" + raise NotImplementedError + + @abstractmethod + def __pow__(self, exponent): + """self**exponent; should promote to float or complex when necessary.""" + raise NotImplementedError + + @abstractmethod + def __rpow__(self, base): + """base ** self""" + raise NotImplementedError + + @abstractmethod + def __abs__(self): + """Returns the Real distance from 0. Called for abs(self).""" + raise NotImplementedError + + @abstractmethod + def conjugate(self): + """(x+y*i).conjugate() returns (x-y*i).""" + raise NotImplementedError + + @abstractmethod + def __eq__(self, other): + """self == other""" + raise NotImplementedError + + def __ne__(self, other): + """self != other""" + # The default __ne__ doesn't negate __eq__ until 3.0. + return not (self == other) + +Complex.register(complex) + + +class Real(Complex): + """To Complex, Real adds the operations that work on real numbers. + + In short, those are: a conversion to float, trunc(), divmod, + %, <, <=, >, and >=. + + Real also provides defaults for the derived operations. + """ + + __slots__ = () + + @abstractmethod + def __float__(self): + """Any Real can be converted to a native float object. + + Called for float(self).""" + raise NotImplementedError + + @abstractmethod + def __trunc__(self): + """trunc(self): Truncates self to an Integral. + + Returns an Integral i such that: + * i>0 iff self>0; + * abs(i) <= abs(self); + * for any Integral j satisfying the first two conditions, + abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. + i.e. "truncate towards 0". + """ + raise NotImplementedError + + def __divmod__(self, other): + """divmod(self, other): The pair (self // other, self % other). + + Sometimes this can be computed faster than the pair of + operations. + """ + return (self // other, self % other) + + def __rdivmod__(self, other): + """divmod(other, self): The pair (self // other, self % other). + + Sometimes this can be computed faster than the pair of + operations. + """ + return (other // self, other % self) + + @abstractmethod + def __floordiv__(self, other): + """self // other: The floor() of self/other.""" + raise NotImplementedError + + @abstractmethod + def __rfloordiv__(self, other): + """other // self: The floor() of other/self.""" + raise NotImplementedError + + @abstractmethod + def __mod__(self, other): + """self % other""" + raise NotImplementedError + + @abstractmethod + def __rmod__(self, other): + """other % self""" + raise NotImplementedError + + @abstractmethod + def __lt__(self, other): + """self < other + + < on Reals defines a total ordering, except perhaps for NaN.""" + raise NotImplementedError + + @abstractmethod + def __le__(self, other): + """self <= other""" + raise NotImplementedError + + # Concrete implementations of Complex abstract methods. + def __complex__(self): + """complex(self) == complex(float(self), 0)""" + return complex(float(self)) + + @property + def real(self): + """Real numbers are their real component.""" + return +self + + @property + def imag(self): + """Real numbers have no imaginary component.""" + return 0 + + def conjugate(self): + """Conjugate is a no-op for Reals.""" + return +self + +Real.register(float) + + +class Rational(Real): + """.numerator and .denominator should be in lowest terms.""" + + __slots__ = () + + @abstractproperty + def numerator(self): + raise NotImplementedError + + @abstractproperty + def denominator(self): + raise NotImplementedError + + # Concrete implementation of Real's conversion to float. + def __float__(self): + """float(self) = self.numerator / self.denominator + + It's important that this conversion use the integer's "true" + division rather than casting one side to float before dividing + so that ratios of huge integers convert without overflowing. + + """ + return self.numerator / self.denominator + + +class Integral(Rational): + """Integral adds a conversion to long and the bit-string operations.""" + + __slots__ = () + + @abstractmethod + def __long__(self): + """long(self)""" + raise NotImplementedError + + def __index__(self): + """Called whenever an index is needed, such as in slicing""" + return long(self) + + @abstractmethod + def __pow__(self, exponent, modulus=None): + """self ** exponent % modulus, but maybe faster. + + Accept the modulus argument if you want to support the + 3-argument version of pow(). Raise a TypeError if exponent < 0 + or any argument isn't Integral. Otherwise, just implement the + 2-argument version described in Complex. + """ + raise NotImplementedError + + @abstractmethod + def __lshift__(self, other): + """self << other""" + raise NotImplementedError + + @abstractmethod + def __rlshift__(self, other): + """other << self""" + raise NotImplementedError + + @abstractmethod + def __rshift__(self, other): + """self >> other""" + raise NotImplementedError + + @abstractmethod + def __rrshift__(self, other): + """other >> self""" + raise NotImplementedError + + @abstractmethod + def __and__(self, other): + """self & other""" + raise NotImplementedError + + @abstractmethod + def __rand__(self, other): + """other & self""" + raise NotImplementedError + + @abstractmethod + def __xor__(self, other): + """self ^ other""" + raise NotImplementedError + + @abstractmethod + def __rxor__(self, other): + """other ^ self""" + raise NotImplementedError + + @abstractmethod + def __or__(self, other): + """self | other""" + raise NotImplementedError + + @abstractmethod + def __ror__(self, other): + """other | self""" + raise NotImplementedError + + @abstractmethod + def __invert__(self): + """~self""" + raise NotImplementedError + + # Concrete implementations of Rational and Real abstract methods. + def __float__(self): + """float(self) == float(long(self))""" + return float(long(self)) + + @property + def numerator(self): + """Integers are their own numerators.""" + return +self + + @property + def denominator(self): + """Integers have a denominator of 1.""" + return 1 + +Integral.register(int) +Integral.register(long) diff --git a/src/main/resources/PythonLibs/opcode.py b/src/main/resources/PythonLibs/opcode.py new file mode 100644 index 0000000000000000000000000000000000000000..e403365b6a26818d22eab123f840b88a3a4e1fde --- /dev/null +++ b/src/main/resources/PythonLibs/opcode.py @@ -0,0 +1,192 @@ + +""" +opcode module - potentially shared between dis and other modules which +operate on bytecodes (e.g. peephole optimizers). +""" + +__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs", + "haslocal", "hascompare", "hasfree", "opname", "opmap", + "HAVE_ARGUMENT", "EXTENDED_ARG"] + +cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', + 'is not', 'exception match', 'BAD') + +hasconst = [] +hasname = [] +hasjrel = [] +hasjabs = [] +haslocal = [] +hascompare = [] +hasfree = [] + +opmap = {} +opname = [''] * 256 +for op in range(256): opname[op] = '<%r>' % (op,) +del op + +def def_op(name, op): + opname[op] = name + opmap[name] = op + +def name_op(name, op): + def_op(name, op) + hasname.append(op) + +def jrel_op(name, op): + def_op(name, op) + hasjrel.append(op) + +def jabs_op(name, op): + def_op(name, op) + hasjabs.append(op) + +# Instruction opcodes for compiled code +# Blank lines correspond to available opcodes + +def_op('STOP_CODE', 0) +def_op('POP_TOP', 1) +def_op('ROT_TWO', 2) +def_op('ROT_THREE', 3) +def_op('DUP_TOP', 4) +def_op('ROT_FOUR', 5) + +def_op('NOP', 9) +def_op('UNARY_POSITIVE', 10) +def_op('UNARY_NEGATIVE', 11) +def_op('UNARY_NOT', 12) +def_op('UNARY_CONVERT', 13) + +def_op('UNARY_INVERT', 15) + +def_op('BINARY_POWER', 19) +def_op('BINARY_MULTIPLY', 20) +def_op('BINARY_DIVIDE', 21) +def_op('BINARY_MODULO', 22) +def_op('BINARY_ADD', 23) +def_op('BINARY_SUBTRACT', 24) +def_op('BINARY_SUBSCR', 25) +def_op('BINARY_FLOOR_DIVIDE', 26) +def_op('BINARY_TRUE_DIVIDE', 27) +def_op('INPLACE_FLOOR_DIVIDE', 28) +def_op('INPLACE_TRUE_DIVIDE', 29) +def_op('SLICE+0', 30) +def_op('SLICE+1', 31) +def_op('SLICE+2', 32) +def_op('SLICE+3', 33) + +def_op('STORE_SLICE+0', 40) +def_op('STORE_SLICE+1', 41) +def_op('STORE_SLICE+2', 42) +def_op('STORE_SLICE+3', 43) + +def_op('DELETE_SLICE+0', 50) +def_op('DELETE_SLICE+1', 51) +def_op('DELETE_SLICE+2', 52) +def_op('DELETE_SLICE+3', 53) + +def_op('STORE_MAP', 54) +def_op('INPLACE_ADD', 55) +def_op('INPLACE_SUBTRACT', 56) +def_op('INPLACE_MULTIPLY', 57) +def_op('INPLACE_DIVIDE', 58) +def_op('INPLACE_MODULO', 59) +def_op('STORE_SUBSCR', 60) +def_op('DELETE_SUBSCR', 61) +def_op('BINARY_LSHIFT', 62) +def_op('BINARY_RSHIFT', 63) +def_op('BINARY_AND', 64) +def_op('BINARY_XOR', 65) +def_op('BINARY_OR', 66) +def_op('INPLACE_POWER', 67) +def_op('GET_ITER', 68) + +def_op('PRINT_EXPR', 70) +def_op('PRINT_ITEM', 71) +def_op('PRINT_NEWLINE', 72) +def_op('PRINT_ITEM_TO', 73) +def_op('PRINT_NEWLINE_TO', 74) +def_op('INPLACE_LSHIFT', 75) +def_op('INPLACE_RSHIFT', 76) +def_op('INPLACE_AND', 77) +def_op('INPLACE_XOR', 78) +def_op('INPLACE_OR', 79) +def_op('BREAK_LOOP', 80) +def_op('WITH_CLEANUP', 81) +def_op('LOAD_LOCALS', 82) +def_op('RETURN_VALUE', 83) +def_op('IMPORT_STAR', 84) +def_op('EXEC_STMT', 85) +def_op('YIELD_VALUE', 86) +def_op('POP_BLOCK', 87) +def_op('END_FINALLY', 88) +def_op('BUILD_CLASS', 89) + +HAVE_ARGUMENT = 90 # Opcodes from here have an argument: + +name_op('STORE_NAME', 90) # Index in name list +name_op('DELETE_NAME', 91) # "" +def_op('UNPACK_SEQUENCE', 92) # Number of tuple items +jrel_op('FOR_ITER', 93) +def_op('LIST_APPEND', 94) +name_op('STORE_ATTR', 95) # Index in name list +name_op('DELETE_ATTR', 96) # "" +name_op('STORE_GLOBAL', 97) # "" +name_op('DELETE_GLOBAL', 98) # "" +def_op('DUP_TOPX', 99) # number of items to duplicate +def_op('LOAD_CONST', 100) # Index in const list +hasconst.append(100) +name_op('LOAD_NAME', 101) # Index in name list +def_op('BUILD_TUPLE', 102) # Number of tuple items +def_op('BUILD_LIST', 103) # Number of list items +def_op('BUILD_SET', 104) # Number of set items +def_op('BUILD_MAP', 105) # Number of dict entries (upto 255) +name_op('LOAD_ATTR', 106) # Index in name list +def_op('COMPARE_OP', 107) # Comparison operator +hascompare.append(107) +name_op('IMPORT_NAME', 108) # Index in name list +name_op('IMPORT_FROM', 109) # Index in name list +jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip +jabs_op('JUMP_IF_FALSE_OR_POP', 111) # Target byte offset from beginning of code +jabs_op('JUMP_IF_TRUE_OR_POP', 112) # "" +jabs_op('JUMP_ABSOLUTE', 113) # "" +jabs_op('POP_JUMP_IF_FALSE', 114) # "" +jabs_op('POP_JUMP_IF_TRUE', 115) # "" + +name_op('LOAD_GLOBAL', 116) # Index in name list + +jabs_op('CONTINUE_LOOP', 119) # Target address +jrel_op('SETUP_LOOP', 120) # Distance to target address +jrel_op('SETUP_EXCEPT', 121) # "" +jrel_op('SETUP_FINALLY', 122) # "" + +def_op('LOAD_FAST', 124) # Local variable number +haslocal.append(124) +def_op('STORE_FAST', 125) # Local variable number +haslocal.append(125) +def_op('DELETE_FAST', 126) # Local variable number +haslocal.append(126) + +def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) +def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8) +def_op('MAKE_FUNCTION', 132) # Number of args with default values +def_op('BUILD_SLICE', 133) # Number of items +def_op('MAKE_CLOSURE', 134) +def_op('LOAD_CLOSURE', 135) +hasfree.append(135) +def_op('LOAD_DEREF', 136) +hasfree.append(136) +def_op('STORE_DEREF', 137) +hasfree.append(137) + +def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8) +def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8) +def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8) + +jrel_op('SETUP_WITH', 143) + +def_op('EXTENDED_ARG', 145) +EXTENDED_ARG = 145 +def_op('SET_ADD', 146) +def_op('MAP_ADD', 147) + +del def_op, name_op, jrel_op, jabs_op diff --git a/src/main/resources/PythonLibs/optparse.py b/src/main/resources/PythonLibs/optparse.py new file mode 100644 index 0000000000000000000000000000000000000000..731a2bb5edf8541dd1b8a7bc1eae7ae3e7c945eb --- /dev/null +++ b/src/main/resources/PythonLibs/optparse.py @@ -0,0 +1,1703 @@ +"""A powerful, extensible, and easy-to-use option parser. + +By Greg Ward <gward@python.net> + +Originally distributed as Optik. + +For support, use the optik-users@lists.sourceforge.net mailing list +(http://lists.sourceforge.net/lists/listinfo/optik-users). + +Simple usage example: + + from optparse import OptionParser + + parser = OptionParser() + parser.add_option("-f", "--file", dest="filename", + help="write report to FILE", metavar="FILE") + parser.add_option("-q", "--quiet", + action="store_false", dest="verbose", default=True, + help="don't print status messages to stdout") + + (options, args) = parser.parse_args() +""" + +__version__ = "1.5.3" + +__all__ = ['Option', + 'make_option', + 'SUPPRESS_HELP', + 'SUPPRESS_USAGE', + 'Values', + 'OptionContainer', + 'OptionGroup', + 'OptionParser', + 'HelpFormatter', + 'IndentedHelpFormatter', + 'TitledHelpFormatter', + 'OptParseError', + 'OptionError', + 'OptionConflictError', + 'OptionValueError', + 'BadOptionError'] + +__copyright__ = """ +Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved. +Copyright (c) 2002-2006 Python Software Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +import sys, os +import types +import textwrap + +def _repr(self): + return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self) + + +# This file was generated from: +# Id: option_parser.py 527 2006-07-23 15:21:30Z greg +# Id: option.py 522 2006-06-11 16:22:03Z gward +# Id: help.py 527 2006-07-23 15:21:30Z greg +# Id: errors.py 509 2006-04-20 00:58:24Z gward + +try: + from gettext import gettext +except ImportError: + def gettext(message): + return message +_ = gettext + + +class OptParseError (Exception): + def __init__(self, msg): + self.msg = msg + + def __str__(self): + return self.msg + + +class OptionError (OptParseError): + """ + Raised if an Option instance is created with invalid or + inconsistent arguments. + """ + + def __init__(self, msg, option): + self.msg = msg + self.option_id = str(option) + + def __str__(self): + if self.option_id: + return "option %s: %s" % (self.option_id, self.msg) + else: + return self.msg + +class OptionConflictError (OptionError): + """ + Raised if conflicting options are added to an OptionParser. + """ + +class OptionValueError (OptParseError): + """ + Raised if an invalid option value is encountered on the command + line. + """ + +class BadOptionError (OptParseError): + """ + Raised if an invalid option is seen on the command line. + """ + def __init__(self, opt_str): + self.opt_str = opt_str + + def __str__(self): + return _("no such option: %s") % self.opt_str + +class AmbiguousOptionError (BadOptionError): + """ + Raised if an ambiguous option is seen on the command line. + """ + def __init__(self, opt_str, possibilities): + BadOptionError.__init__(self, opt_str) + self.possibilities = possibilities + + def __str__(self): + return (_("ambiguous option: %s (%s?)") + % (self.opt_str, ", ".join(self.possibilities))) + + +class HelpFormatter: + + """ + Abstract base class for formatting option help. OptionParser + instances should use one of the HelpFormatter subclasses for + formatting help; by default IndentedHelpFormatter is used. + + Instance attributes: + parser : OptionParser + the controlling OptionParser instance + indent_increment : int + the number of columns to indent per nesting level + max_help_position : int + the maximum starting column for option help text + help_position : int + the calculated starting column for option help text; + initially the same as the maximum + width : int + total number of columns for output (pass None to constructor for + this value to be taken from the $COLUMNS environment variable) + level : int + current indentation level + current_indent : int + current indentation level (in columns) + help_width : int + number of columns available for option help text (calculated) + default_tag : str + text to replace with each option's default value, "%default" + by default. Set to false value to disable default value expansion. + option_strings : { Option : str } + maps Option instances to the snippet of help text explaining + the syntax of that option, e.g. "-h, --help" or + "-fFILE, --file=FILE" + _short_opt_fmt : str + format string controlling how short options with values are + printed in help text. Must be either "%s%s" ("-fFILE") or + "%s %s" ("-f FILE"), because those are the two syntaxes that + Optik supports. + _long_opt_fmt : str + similar but for long options; must be either "%s %s" ("--file FILE") + or "%s=%s" ("--file=FILE"). + """ + + NO_DEFAULT_VALUE = "none" + + def __init__(self, + indent_increment, + max_help_position, + width, + short_first): + self.parser = None + self.indent_increment = indent_increment + self.help_position = self.max_help_position = max_help_position + if width is None: + try: + width = int(os.environ['COLUMNS']) + except (KeyError, ValueError): + width = 80 + width -= 2 + self.width = width + self.current_indent = 0 + self.level = 0 + self.help_width = None # computed later + self.short_first = short_first + self.default_tag = "%default" + self.option_strings = {} + self._short_opt_fmt = "%s %s" + self._long_opt_fmt = "%s=%s" + + def set_parser(self, parser): + self.parser = parser + + def set_short_opt_delimiter(self, delim): + if delim not in ("", " "): + raise ValueError( + "invalid metavar delimiter for short options: %r" % delim) + self._short_opt_fmt = "%s" + delim + "%s" + + def set_long_opt_delimiter(self, delim): + if delim not in ("=", " "): + raise ValueError( + "invalid metavar delimiter for long options: %r" % delim) + self._long_opt_fmt = "%s" + delim + "%s" + + def indent(self): + self.current_indent += self.indent_increment + self.level += 1 + + def dedent(self): + self.current_indent -= self.indent_increment + assert self.current_indent >= 0, "Indent decreased below 0." + self.level -= 1 + + def format_usage(self, usage): + raise NotImplementedError, "subclasses must implement" + + def format_heading(self, heading): + raise NotImplementedError, "subclasses must implement" + + def _format_text(self, text): + """ + Format a paragraph of free-form text for inclusion in the + help output at the current indentation level. + """ + text_width = self.width - self.current_indent + indent = " "*self.current_indent + return textwrap.fill(text, + text_width, + initial_indent=indent, + subsequent_indent=indent) + + def format_description(self, description): + if description: + return self._format_text(description) + "\n" + else: + return "" + + def format_epilog(self, epilog): + if epilog: + return "\n" + self._format_text(epilog) + "\n" + else: + return "" + + + def expand_default(self, option): + if self.parser is None or not self.default_tag: + return option.help + + default_value = self.parser.defaults.get(option.dest) + if default_value is NO_DEFAULT or default_value is None: + default_value = self.NO_DEFAULT_VALUE + + return option.help.replace(self.default_tag, str(default_value)) + + def format_option(self, option): + # The help for each option consists of two parts: + # * the opt strings and metavars + # eg. ("-x", or "-fFILENAME, --file=FILENAME") + # * the user-supplied help string + # eg. ("turn on expert mode", "read data from FILENAME") + # + # If possible, we write both of these on the same line: + # -x turn on expert mode + # + # But if the opt string list is too long, we put the help + # string on a second line, indented to the same column it would + # start in if it fit on the first line. + # -fFILENAME, --file=FILENAME + # read data from FILENAME + result = [] + opts = self.option_strings[option] + opt_width = self.help_position - self.current_indent - 2 + if len(opts) > opt_width: + opts = "%*s%s\n" % (self.current_indent, "", opts) + indent_first = self.help_position + else: # start help on same line as opts + opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts) + indent_first = 0 + result.append(opts) + if option.help: + help_text = self.expand_default(option) + help_lines = textwrap.wrap(help_text, self.help_width) + result.append("%*s%s\n" % (indent_first, "", help_lines[0])) + result.extend(["%*s%s\n" % (self.help_position, "", line) + for line in help_lines[1:]]) + elif opts[-1] != "\n": + result.append("\n") + return "".join(result) + + def store_option_strings(self, parser): + self.indent() + max_len = 0 + for opt in parser.option_list: + strings = self.format_option_strings(opt) + self.option_strings[opt] = strings + max_len = max(max_len, len(strings) + self.current_indent) + self.indent() + for group in parser.option_groups: + for opt in group.option_list: + strings = self.format_option_strings(opt) + self.option_strings[opt] = strings + max_len = max(max_len, len(strings) + self.current_indent) + self.dedent() + self.dedent() + self.help_position = min(max_len + 2, self.max_help_position) + self.help_width = self.width - self.help_position + + def format_option_strings(self, option): + """Return a comma-separated list of option strings & metavariables.""" + if option.takes_value(): + metavar = option.metavar or option.dest.upper() + short_opts = [self._short_opt_fmt % (sopt, metavar) + for sopt in option._short_opts] + long_opts = [self._long_opt_fmt % (lopt, metavar) + for lopt in option._long_opts] + else: + short_opts = option._short_opts + long_opts = option._long_opts + + if self.short_first: + opts = short_opts + long_opts + else: + opts = long_opts + short_opts + + return ", ".join(opts) + +class IndentedHelpFormatter (HelpFormatter): + """Format help with indented section bodies. + """ + + def __init__(self, + indent_increment=2, + max_help_position=24, + width=None, + short_first=1): + HelpFormatter.__init__( + self, indent_increment, max_help_position, width, short_first) + + def format_usage(self, usage): + return _("Usage: %s\n") % usage + + def format_heading(self, heading): + return "%*s%s:\n" % (self.current_indent, "", heading) + + +class TitledHelpFormatter (HelpFormatter): + """Format help with underlined section headers. + """ + + def __init__(self, + indent_increment=0, + max_help_position=24, + width=None, + short_first=0): + HelpFormatter.__init__ ( + self, indent_increment, max_help_position, width, short_first) + + def format_usage(self, usage): + return "%s %s\n" % (self.format_heading(_("Usage")), usage) + + def format_heading(self, heading): + return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading)) + + +def _parse_num(val, type): + if val[:2].lower() == "0x": # hexadecimal + radix = 16 + elif val[:2].lower() == "0b": # binary + radix = 2 + val = val[2:] or "0" # have to remove "0b" prefix + elif val[:1] == "0": # octal + radix = 8 + else: # decimal + radix = 10 + + return type(val, radix) + +def _parse_int(val): + return _parse_num(val, int) + +def _parse_long(val): + return _parse_num(val, long) + +_builtin_cvt = { "int" : (_parse_int, _("integer")), + "long" : (_parse_long, _("long integer")), + "float" : (float, _("floating-point")), + "complex" : (complex, _("complex")) } + +def check_builtin(option, opt, value): + (cvt, what) = _builtin_cvt[option.type] + try: + return cvt(value) + except ValueError: + raise OptionValueError( + _("option %s: invalid %s value: %r") % (opt, what, value)) + +def check_choice(option, opt, value): + if value in option.choices: + return value + else: + choices = ", ".join(map(repr, option.choices)) + raise OptionValueError( + _("option %s: invalid choice: %r (choose from %s)") + % (opt, value, choices)) + +# Not supplying a default is different from a default of None, +# so we need an explicit "not supplied" value. +NO_DEFAULT = ("NO", "DEFAULT") + + +class Option: + """ + Instance attributes: + _short_opts : [string] + _long_opts : [string] + + action : string + type : string + dest : string + default : any + nargs : int + const : any + choices : [string] + callback : function + callback_args : (any*) + callback_kwargs : { string : any } + help : string + metavar : string + """ + + # The list of instance attributes that may be set through + # keyword args to the constructor. + ATTRS = ['action', + 'type', + 'dest', + 'default', + 'nargs', + 'const', + 'choices', + 'callback', + 'callback_args', + 'callback_kwargs', + 'help', + 'metavar'] + + # The set of actions allowed by option parsers. Explicitly listed + # here so the constructor can validate its arguments. + ACTIONS = ("store", + "store_const", + "store_true", + "store_false", + "append", + "append_const", + "count", + "callback", + "help", + "version") + + # The set of actions that involve storing a value somewhere; + # also listed just for constructor argument validation. (If + # the action is one of these, there must be a destination.) + STORE_ACTIONS = ("store", + "store_const", + "store_true", + "store_false", + "append", + "append_const", + "count") + + # The set of actions for which it makes sense to supply a value + # type, ie. which may consume an argument from the command line. + TYPED_ACTIONS = ("store", + "append", + "callback") + + # The set of actions which *require* a value type, ie. that + # always consume an argument from the command line. + ALWAYS_TYPED_ACTIONS = ("store", + "append") + + # The set of actions which take a 'const' attribute. + CONST_ACTIONS = ("store_const", + "append_const") + + # The set of known types for option parsers. Again, listed here for + # constructor argument validation. + TYPES = ("string", "int", "long", "float", "complex", "choice") + + # Dictionary of argument checking functions, which convert and + # validate option arguments according to the option type. + # + # Signature of checking functions is: + # check(option : Option, opt : string, value : string) -> any + # where + # option is the Option instance calling the checker + # opt is the actual option seen on the command-line + # (eg. "-a", "--file") + # value is the option argument seen on the command-line + # + # The return value should be in the appropriate Python type + # for option.type -- eg. an integer if option.type == "int". + # + # If no checker is defined for a type, arguments will be + # unchecked and remain strings. + TYPE_CHECKER = { "int" : check_builtin, + "long" : check_builtin, + "float" : check_builtin, + "complex": check_builtin, + "choice" : check_choice, + } + + + # CHECK_METHODS is a list of unbound method objects; they are called + # by the constructor, in order, after all attributes are + # initialized. The list is created and filled in later, after all + # the methods are actually defined. (I just put it here because I + # like to define and document all class attributes in the same + # place.) Subclasses that add another _check_*() method should + # define their own CHECK_METHODS list that adds their check method + # to those from this class. + CHECK_METHODS = None + + + # -- Constructor/initialization methods ---------------------------- + + def __init__(self, *opts, **attrs): + # Set _short_opts, _long_opts attrs from 'opts' tuple. + # Have to be set now, in case no option strings are supplied. + self._short_opts = [] + self._long_opts = [] + opts = self._check_opt_strings(opts) + self._set_opt_strings(opts) + + # Set all other attrs (action, type, etc.) from 'attrs' dict + self._set_attrs(attrs) + + # Check all the attributes we just set. There are lots of + # complicated interdependencies, but luckily they can be farmed + # out to the _check_*() methods listed in CHECK_METHODS -- which + # could be handy for subclasses! The one thing these all share + # is that they raise OptionError if they discover a problem. + for checker in self.CHECK_METHODS: + checker(self) + + def _check_opt_strings(self, opts): + # Filter out None because early versions of Optik had exactly + # one short option and one long option, either of which + # could be None. + opts = filter(None, opts) + if not opts: + raise TypeError("at least one option string must be supplied") + return opts + + def _set_opt_strings(self, opts): + for opt in opts: + if len(opt) < 2: + raise OptionError( + "invalid option string %r: " + "must be at least two characters long" % opt, self) + elif len(opt) == 2: + if not (opt[0] == "-" and opt[1] != "-"): + raise OptionError( + "invalid short option string %r: " + "must be of the form -x, (x any non-dash char)" % opt, + self) + self._short_opts.append(opt) + else: + if not (opt[0:2] == "--" and opt[2] != "-"): + raise OptionError( + "invalid long option string %r: " + "must start with --, followed by non-dash" % opt, + self) + self._long_opts.append(opt) + + def _set_attrs(self, attrs): + for attr in self.ATTRS: + if attr in attrs: + setattr(self, attr, attrs[attr]) + del attrs[attr] + else: + if attr == 'default': + setattr(self, attr, NO_DEFAULT) + else: + setattr(self, attr, None) + if attrs: + attrs = attrs.keys() + attrs.sort() + raise OptionError( + "invalid keyword arguments: %s" % ", ".join(attrs), + self) + + + # -- Constructor validation methods -------------------------------- + + def _check_action(self): + if self.action is None: + self.action = "store" + elif self.action not in self.ACTIONS: + raise OptionError("invalid action: %r" % self.action, self) + + def _check_type(self): + if self.type is None: + if self.action in self.ALWAYS_TYPED_ACTIONS: + if self.choices is not None: + # The "choices" attribute implies "choice" type. + self.type = "choice" + else: + # No type given? "string" is the most sensible default. + self.type = "string" + else: + # Allow type objects or builtin type conversion functions + # (int, str, etc.) as an alternative to their names. (The + # complicated check of __builtin__ is only necessary for + # Python 2.1 and earlier, and is short-circuited by the + # first check on modern Pythons.) + import __builtin__ + if ( type(self.type) is types.TypeType or + (hasattr(self.type, "__name__") and + getattr(__builtin__, self.type.__name__, None) is self.type) ): + self.type = self.type.__name__ + + if self.type == "str": + self.type = "string" + + if self.type not in self.TYPES: + raise OptionError("invalid option type: %r" % self.type, self) + if self.action not in self.TYPED_ACTIONS: + raise OptionError( + "must not supply a type for action %r" % self.action, self) + + def _check_choice(self): + if self.type == "choice": + if self.choices is None: + raise OptionError( + "must supply a list of choices for type 'choice'", self) + elif type(self.choices) not in (types.TupleType, types.ListType): + raise OptionError( + "choices must be a list of strings ('%s' supplied)" + % str(type(self.choices)).split("'")[1], self) + elif self.choices is not None: + raise OptionError( + "must not supply choices for type %r" % self.type, self) + + def _check_dest(self): + # No destination given, and we need one for this action. The + # self.type check is for callbacks that take a value. + takes_value = (self.action in self.STORE_ACTIONS or + self.type is not None) + if self.dest is None and takes_value: + + # Glean a destination from the first long option string, + # or from the first short option string if no long options. + if self._long_opts: + # eg. "--foo-bar" -> "foo_bar" + self.dest = self._long_opts[0][2:].replace('-', '_') + else: + self.dest = self._short_opts[0][1] + + def _check_const(self): + if self.action not in self.CONST_ACTIONS and self.const is not None: + raise OptionError( + "'const' must not be supplied for action %r" % self.action, + self) + + def _check_nargs(self): + if self.action in self.TYPED_ACTIONS: + if self.nargs is None: + self.nargs = 1 + elif self.nargs is not None: + raise OptionError( + "'nargs' must not be supplied for action %r" % self.action, + self) + + def _check_callback(self): + if self.action == "callback": + if not hasattr(self.callback, '__call__'): + raise OptionError( + "callback not callable: %r" % self.callback, self) + if (self.callback_args is not None and + type(self.callback_args) is not types.TupleType): + raise OptionError( + "callback_args, if supplied, must be a tuple: not %r" + % self.callback_args, self) + if (self.callback_kwargs is not None and + type(self.callback_kwargs) is not types.DictType): + raise OptionError( + "callback_kwargs, if supplied, must be a dict: not %r" + % self.callback_kwargs, self) + else: + if self.callback is not None: + raise OptionError( + "callback supplied (%r) for non-callback option" + % self.callback, self) + if self.callback_args is not None: + raise OptionError( + "callback_args supplied for non-callback option", self) + if self.callback_kwargs is not None: + raise OptionError( + "callback_kwargs supplied for non-callback option", self) + + + CHECK_METHODS = [_check_action, + _check_type, + _check_choice, + _check_dest, + _check_const, + _check_nargs, + _check_callback] + + + # -- Miscellaneous methods ----------------------------------------- + + def __str__(self): + return "/".join(self._short_opts + self._long_opts) + + __repr__ = _repr + + def takes_value(self): + return self.type is not None + + def get_opt_string(self): + if self._long_opts: + return self._long_opts[0] + else: + return self._short_opts[0] + + + # -- Processing methods -------------------------------------------- + + def check_value(self, opt, value): + checker = self.TYPE_CHECKER.get(self.type) + if checker is None: + return value + else: + return checker(self, opt, value) + + def convert_value(self, opt, value): + if value is not None: + if self.nargs == 1: + return self.check_value(opt, value) + else: + return tuple([self.check_value(opt, v) for v in value]) + + def process(self, opt, value, values, parser): + + # First, convert the value(s) to the right type. Howl if any + # value(s) are bogus. + value = self.convert_value(opt, value) + + # And then take whatever action is expected of us. + # This is a separate method to make life easier for + # subclasses to add new actions. + return self.take_action( + self.action, self.dest, opt, value, values, parser) + + def take_action(self, action, dest, opt, value, values, parser): + if action == "store": + setattr(values, dest, value) + elif action == "store_const": + setattr(values, dest, self.const) + elif action == "store_true": + setattr(values, dest, True) + elif action == "store_false": + setattr(values, dest, False) + elif action == "append": + values.ensure_value(dest, []).append(value) + elif action == "append_const": + values.ensure_value(dest, []).append(self.const) + elif action == "count": + setattr(values, dest, values.ensure_value(dest, 0) + 1) + elif action == "callback": + args = self.callback_args or () + kwargs = self.callback_kwargs or {} + self.callback(self, opt, value, parser, *args, **kwargs) + elif action == "help": + parser.print_help() + parser.exit() + elif action == "version": + parser.print_version() + parser.exit() + else: + raise ValueError("unknown action %r" % self.action) + + return 1 + +# class Option + + +SUPPRESS_HELP = "SUPPRESS"+"HELP" +SUPPRESS_USAGE = "SUPPRESS"+"USAGE" + +try: + basestring +except NameError: + def isbasestring(x): + return isinstance(x, (types.StringType, types.UnicodeType)) +else: + def isbasestring(x): + return isinstance(x, basestring) + +class Values: + + def __init__(self, defaults=None): + if defaults: + for (attr, val) in defaults.items(): + setattr(self, attr, val) + + def __str__(self): + return str(self.__dict__) + + __repr__ = _repr + + def __cmp__(self, other): + if isinstance(other, Values): + return cmp(self.__dict__, other.__dict__) + elif isinstance(other, types.DictType): + return cmp(self.__dict__, other) + else: + return -1 + + def _update_careful(self, dict): + """ + Update the option values from an arbitrary dictionary, but only + use keys from dict that already have a corresponding attribute + in self. Any keys in dict without a corresponding attribute + are silently ignored. + """ + for attr in dir(self): + if attr in dict: + dval = dict[attr] + if dval is not None: + setattr(self, attr, dval) + + def _update_loose(self, dict): + """ + Update the option values from an arbitrary dictionary, + using all keys from the dictionary regardless of whether + they have a corresponding attribute in self or not. + """ + self.__dict__.update(dict) + + def _update(self, dict, mode): + if mode == "careful": + self._update_careful(dict) + elif mode == "loose": + self._update_loose(dict) + else: + raise ValueError, "invalid update mode: %r" % mode + + def read_module(self, modname, mode="careful"): + __import__(modname) + mod = sys.modules[modname] + self._update(vars(mod), mode) + + def read_file(self, filename, mode="careful"): + vars = {} + execfile(filename, vars) + self._update(vars, mode) + + def ensure_value(self, attr, value): + if not hasattr(self, attr) or getattr(self, attr) is None: + setattr(self, attr, value) + return getattr(self, attr) + + +class OptionContainer: + + """ + Abstract base class. + + Class attributes: + standard_option_list : [Option] + list of standard options that will be accepted by all instances + of this parser class (intended to be overridden by subclasses). + + Instance attributes: + option_list : [Option] + the list of Option objects contained by this OptionContainer + _short_opt : { string : Option } + dictionary mapping short option strings, eg. "-f" or "-X", + to the Option instances that implement them. If an Option + has multiple short option strings, it will appears in this + dictionary multiple times. [1] + _long_opt : { string : Option } + dictionary mapping long option strings, eg. "--file" or + "--exclude", to the Option instances that implement them. + Again, a given Option can occur multiple times in this + dictionary. [1] + defaults : { string : any } + dictionary mapping option destination names to default + values for each destination [1] + + [1] These mappings are common to (shared by) all components of the + controlling OptionParser, where they are initially created. + + """ + + def __init__(self, option_class, conflict_handler, description): + # Initialize the option list and related data structures. + # This method must be provided by subclasses, and it must + # initialize at least the following instance attributes: + # option_list, _short_opt, _long_opt, defaults. + self._create_option_list() + + self.option_class = option_class + self.set_conflict_handler(conflict_handler) + self.set_description(description) + + def _create_option_mappings(self): + # For use by OptionParser constructor -- create the master + # option mappings used by this OptionParser and all + # OptionGroups that it owns. + self._short_opt = {} # single letter -> Option instance + self._long_opt = {} # long option -> Option instance + self.defaults = {} # maps option dest -> default value + + + def _share_option_mappings(self, parser): + # For use by OptionGroup constructor -- use shared option + # mappings from the OptionParser that owns this OptionGroup. + self._short_opt = parser._short_opt + self._long_opt = parser._long_opt + self.defaults = parser.defaults + + def set_conflict_handler(self, handler): + if handler not in ("error", "resolve"): + raise ValueError, "invalid conflict_resolution value %r" % handler + self.conflict_handler = handler + + def set_description(self, description): + self.description = description + + def get_description(self): + return self.description + + + def destroy(self): + """see OptionParser.destroy().""" + del self._short_opt + del self._long_opt + del self.defaults + + + # -- Option-adding methods ----------------------------------------- + + def _check_conflict(self, option): + conflict_opts = [] + for opt in option._short_opts: + if opt in self._short_opt: + conflict_opts.append((opt, self._short_opt[opt])) + for opt in option._long_opts: + if opt in self._long_opt: + conflict_opts.append((opt, self._long_opt[opt])) + + if conflict_opts: + handler = self.conflict_handler + if handler == "error": + raise OptionConflictError( + "conflicting option string(s): %s" + % ", ".join([co[0] for co in conflict_opts]), + option) + elif handler == "resolve": + for (opt, c_option) in conflict_opts: + if opt.startswith("--"): + c_option._long_opts.remove(opt) + del self._long_opt[opt] + else: + c_option._short_opts.remove(opt) + del self._short_opt[opt] + if not (c_option._short_opts or c_option._long_opts): + c_option.container.option_list.remove(c_option) + + def add_option(self, *args, **kwargs): + """add_option(Option) + add_option(opt_str, ..., kwarg=val, ...) + """ + if type(args[0]) in types.StringTypes: + option = self.option_class(*args, **kwargs) + elif len(args) == 1 and not kwargs: + option = args[0] + if not isinstance(option, Option): + raise TypeError, "not an Option instance: %r" % option + else: + raise TypeError, "invalid arguments" + + self._check_conflict(option) + + self.option_list.append(option) + option.container = self + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + if option.dest is not None: # option has a dest, we need a default + if option.default is not NO_DEFAULT: + self.defaults[option.dest] = option.default + elif option.dest not in self.defaults: + self.defaults[option.dest] = None + + return option + + def add_options(self, option_list): + for option in option_list: + self.add_option(option) + + # -- Option query/removal methods ---------------------------------- + + def get_option(self, opt_str): + return (self._short_opt.get(opt_str) or + self._long_opt.get(opt_str)) + + def has_option(self, opt_str): + return (opt_str in self._short_opt or + opt_str in self._long_opt) + + def remove_option(self, opt_str): + option = self._short_opt.get(opt_str) + if option is None: + option = self._long_opt.get(opt_str) + if option is None: + raise ValueError("no such option %r" % opt_str) + + for opt in option._short_opts: + del self._short_opt[opt] + for opt in option._long_opts: + del self._long_opt[opt] + option.container.option_list.remove(option) + + + # -- Help-formatting methods --------------------------------------- + + def format_option_help(self, formatter): + if not self.option_list: + return "" + result = [] + for option in self.option_list: + if not option.help is SUPPRESS_HELP: + result.append(formatter.format_option(option)) + return "".join(result) + + def format_description(self, formatter): + return formatter.format_description(self.get_description()) + + def format_help(self, formatter): + result = [] + if self.description: + result.append(self.format_description(formatter)) + if self.option_list: + result.append(self.format_option_help(formatter)) + return "\n".join(result) + + +class OptionGroup (OptionContainer): + + def __init__(self, parser, title, description=None): + self.parser = parser + OptionContainer.__init__( + self, parser.option_class, parser.conflict_handler, description) + self.title = title + + def _create_option_list(self): + self.option_list = [] + self._share_option_mappings(self.parser) + + def set_title(self, title): + self.title = title + + def destroy(self): + """see OptionParser.destroy().""" + OptionContainer.destroy(self) + del self.option_list + + # -- Help-formatting methods --------------------------------------- + + def format_help(self, formatter): + result = formatter.format_heading(self.title) + formatter.indent() + result += OptionContainer.format_help(self, formatter) + formatter.dedent() + return result + + +class OptionParser (OptionContainer): + + """ + Class attributes: + standard_option_list : [Option] + list of standard options that will be accepted by all instances + of this parser class (intended to be overridden by subclasses). + + Instance attributes: + usage : string + a usage string for your program. Before it is displayed + to the user, "%prog" will be expanded to the name of + your program (self.prog or os.path.basename(sys.argv[0])). + prog : string + the name of the current program (to override + os.path.basename(sys.argv[0])). + description : string + A paragraph of text giving a brief overview of your program. + optparse reformats this paragraph to fit the current terminal + width and prints it when the user requests help (after usage, + but before the list of options). + epilog : string + paragraph of help text to print after option help + + option_groups : [OptionGroup] + list of option groups in this parser (option groups are + irrelevant for parsing the command-line, but very useful + for generating help) + + allow_interspersed_args : bool = true + if true, positional arguments may be interspersed with options. + Assuming -a and -b each take a single argument, the command-line + -ablah foo bar -bboo baz + will be interpreted the same as + -ablah -bboo -- foo bar baz + If this flag were false, that command line would be interpreted as + -ablah -- foo bar -bboo baz + -- ie. we stop processing options as soon as we see the first + non-option argument. (This is the tradition followed by + Python's getopt module, Perl's Getopt::Std, and other argument- + parsing libraries, but it is generally annoying to users.) + + process_default_values : bool = true + if true, option default values are processed similarly to option + values from the command line: that is, they are passed to the + type-checking function for the option's type (as long as the + default value is a string). (This really only matters if you + have defined custom types; see SF bug #955889.) Set it to false + to restore the behaviour of Optik 1.4.1 and earlier. + + rargs : [string] + the argument list currently being parsed. Only set when + parse_args() is active, and continually trimmed down as + we consume arguments. Mainly there for the benefit of + callback options. + largs : [string] + the list of leftover arguments that we have skipped while + parsing options. If allow_interspersed_args is false, this + list is always empty. + values : Values + the set of option values currently being accumulated. Only + set when parse_args() is active. Also mainly for callbacks. + + Because of the 'rargs', 'largs', and 'values' attributes, + OptionParser is not thread-safe. If, for some perverse reason, you + need to parse command-line arguments simultaneously in different + threads, use different OptionParser instances. + + """ + + standard_option_list = [] + + def __init__(self, + usage=None, + option_list=None, + option_class=Option, + version=None, + conflict_handler="error", + description=None, + formatter=None, + add_help_option=True, + prog=None, + epilog=None): + OptionContainer.__init__( + self, option_class, conflict_handler, description) + self.set_usage(usage) + self.prog = prog + self.version = version + self.allow_interspersed_args = True + self.process_default_values = True + if formatter is None: + formatter = IndentedHelpFormatter() + self.formatter = formatter + self.formatter.set_parser(self) + self.epilog = epilog + + # Populate the option list; initial sources are the + # standard_option_list class attribute, the 'option_list' + # argument, and (if applicable) the _add_version_option() and + # _add_help_option() methods. + self._populate_option_list(option_list, + add_help=add_help_option) + + self._init_parsing_state() + + + def destroy(self): + """ + Declare that you are done with this OptionParser. This cleans up + reference cycles so the OptionParser (and all objects referenced by + it) can be garbage-collected promptly. After calling destroy(), the + OptionParser is unusable. + """ + OptionContainer.destroy(self) + for group in self.option_groups: + group.destroy() + del self.option_list + del self.option_groups + del self.formatter + + + # -- Private methods ----------------------------------------------- + # (used by our or OptionContainer's constructor) + + def _create_option_list(self): + self.option_list = [] + self.option_groups = [] + self._create_option_mappings() + + def _add_help_option(self): + self.add_option("-h", "--help", + action="help", + help=_("show this help message and exit")) + + def _add_version_option(self): + self.add_option("--version", + action="version", + help=_("show program's version number and exit")) + + def _populate_option_list(self, option_list, add_help=True): + if self.standard_option_list: + self.add_options(self.standard_option_list) + if option_list: + self.add_options(option_list) + if self.version: + self._add_version_option() + if add_help: + self._add_help_option() + + def _init_parsing_state(self): + # These are set in parse_args() for the convenience of callbacks. + self.rargs = None + self.largs = None + self.values = None + + + # -- Simple modifier methods --------------------------------------- + + def set_usage(self, usage): + if usage is None: + self.usage = _("%prog [options]") + elif usage is SUPPRESS_USAGE: + self.usage = None + # For backwards compatibility with Optik 1.3 and earlier. + elif usage.lower().startswith("usage: "): + self.usage = usage[7:] + else: + self.usage = usage + + def enable_interspersed_args(self): + """Set parsing to not stop on the first non-option, allowing + interspersing switches with command arguments. This is the + default behavior. See also disable_interspersed_args() and the + class documentation description of the attribute + allow_interspersed_args.""" + self.allow_interspersed_args = True + + def disable_interspersed_args(self): + """Set parsing to stop on the first non-option. Use this if + you have a command processor which runs another command that + has options of its own and you want to make sure these options + don't get confused. + """ + self.allow_interspersed_args = False + + def set_process_default_values(self, process): + self.process_default_values = process + + def set_default(self, dest, value): + self.defaults[dest] = value + + def set_defaults(self, **kwargs): + self.defaults.update(kwargs) + + def _get_all_options(self): + options = self.option_list[:] + for group in self.option_groups: + options.extend(group.option_list) + return options + + def get_default_values(self): + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return Values(self.defaults) + + defaults = self.defaults.copy() + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isbasestring(default): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + + return Values(defaults) + + + # -- OptionGroup methods ------------------------------------------- + + def add_option_group(self, *args, **kwargs): + # XXX lots of overlap with OptionContainer.add_option() + if type(args[0]) is types.StringType: + group = OptionGroup(self, *args, **kwargs) + elif len(args) == 1 and not kwargs: + group = args[0] + if not isinstance(group, OptionGroup): + raise TypeError, "not an OptionGroup instance: %r" % group + if group.parser is not self: + raise ValueError, "invalid OptionGroup (wrong parser)" + else: + raise TypeError, "invalid arguments" + + self.option_groups.append(group) + return group + + def get_option_group(self, opt_str): + option = (self._short_opt.get(opt_str) or + self._long_opt.get(opt_str)) + if option and option.container is not self: + return option.container + return None + + + # -- Option-parsing methods ---------------------------------------- + + def _get_args(self, args): + if args is None: + return sys.argv[1:] + else: + return args[:] # don't modify caller's list + + def parse_args(self, args=None, values=None): + """ + parse_args(args : [string] = sys.argv[1:], + values : Values = None) + -> (values : Values, args : [string]) + + Parse the command-line options found in 'args' (default: + sys.argv[1:]). Any errors result in a call to 'error()', which + by default prints the usage message to stderr and calls + sys.exit() with an error message. On success returns a pair + (values, args) where 'values' is an Values instance (with all + your option values) and 'args' is the list of arguments left + over after parsing options. + """ + rargs = self._get_args(args) + if values is None: + values = self.get_default_values() + + # Store the halves of the argument list as attributes for the + # convenience of callbacks: + # rargs + # the rest of the command-line (the "r" stands for + # "remaining" or "right-hand") + # largs + # the leftover arguments -- ie. what's left after removing + # options and their arguments (the "l" stands for "leftover" + # or "left-hand") + self.rargs = rargs + self.largs = largs = [] + self.values = values + + try: + stop = self._process_args(largs, rargs, values) + except (BadOptionError, OptionValueError), err: + self.error(str(err)) + + args = largs + rargs + return self.check_values(values, args) + + def check_values(self, values, args): + """ + check_values(values : Values, args : [string]) + -> (values : Values, args : [string]) + + Check that the supplied option values and leftover arguments are + valid. Returns the option values and leftover arguments + (possibly adjusted, possibly completely new -- whatever you + like). Default implementation just returns the passed-in + values; subclasses may override as desired. + """ + return (values, args) + + def _process_args(self, largs, rargs, values): + """_process_args(largs : [string], + rargs : [string], + values : Values) + + Process command-line arguments and populate 'values', consuming + options and arguments from 'rargs'. If 'allow_interspersed_args' is + false, stop at the first non-option argument. If true, accumulate any + interspersed non-option arguments in 'largs'. + """ + while rargs: + arg = rargs[0] + # We handle bare "--" explicitly, and bare "-" is handled by the + # standard arg handler since the short arg case ensures that the + # len of the opt string is greater than 1. + if arg == "--": + del rargs[0] + return + elif arg[0:2] == "--": + # process a single long option (possibly with value(s)) + self._process_long_opt(rargs, values) + elif arg[:1] == "-" and len(arg) > 1: + # process a cluster of short options (possibly with + # value(s) for the last one only) + self._process_short_opts(rargs, values) + elif self.allow_interspersed_args: + largs.append(arg) + del rargs[0] + else: + return # stop now, leave this arg in rargs + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt(self, opt): + """_match_long_opt(opt : string) -> string + + Determine which long option string 'opt' matches, ie. which one + it is an unambiguous abbrevation for. Raises BadOptionError if + 'opt' doesn't unambiguously match any long option string. + """ + return _match_abbrev(opt, self._long_opt) + + def _process_long_opt(self, rargs, values): + arg = rargs.pop(0) + + # Value explicitly attached to arg? Pretend it's the next + # argument. + if "=" in arg: + (opt, next_arg) = arg.split("=", 1) + rargs.insert(0, next_arg) + had_explicit_value = True + else: + opt = arg + had_explicit_value = False + + opt = self._match_long_opt(opt) + option = self._long_opt[opt] + if option.takes_value(): + nargs = option.nargs + if len(rargs) < nargs: + if nargs == 1: + self.error(_("%s option requires an argument") % opt) + else: + self.error(_("%s option requires %d arguments") + % (opt, nargs)) + elif nargs == 1: + value = rargs.pop(0) + else: + value = tuple(rargs[0:nargs]) + del rargs[0:nargs] + + elif had_explicit_value: + self.error(_("%s option does not take a value") % opt) + + else: + value = None + + option.process(opt, value, values, self) + + def _process_short_opts(self, rargs, values): + arg = rargs.pop(0) + stop = False + i = 1 + for ch in arg[1:]: + opt = "-" + ch + option = self._short_opt.get(opt) + i += 1 # we have consumed a character + + if not option: + raise BadOptionError(opt) + if option.takes_value(): + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + rargs.insert(0, arg[i:]) + stop = True + + nargs = option.nargs + if len(rargs) < nargs: + if nargs == 1: + self.error(_("%s option requires an argument") % opt) + else: + self.error(_("%s option requires %d arguments") + % (opt, nargs)) + elif nargs == 1: + value = rargs.pop(0) + else: + value = tuple(rargs[0:nargs]) + del rargs[0:nargs] + + else: # option doesn't take a value + value = None + + option.process(opt, value, values, self) + + if stop: + break + + + # -- Feedback methods ---------------------------------------------- + + def get_prog_name(self): + if self.prog is None: + return os.path.basename(sys.argv[0]) + else: + return self.prog + + def expand_prog_name(self, s): + return s.replace("%prog", self.get_prog_name()) + + def get_description(self): + return self.expand_prog_name(self.description) + + def exit(self, status=0, msg=None): + if msg: + sys.stderr.write(msg) + sys.exit(status) + + def error(self, msg): + """error(msg : string) + + Print a usage message incorporating 'msg' to stderr and exit. + If you override this in a subclass, it should not return -- it + should either exit or raise an exception. + """ + self.print_usage(sys.stderr) + self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg)) + + def get_usage(self): + if self.usage: + return self.formatter.format_usage( + self.expand_prog_name(self.usage)) + else: + return "" + + def print_usage(self, file=None): + """print_usage(file : file = stdout) + + Print the usage message for the current program (self.usage) to + 'file' (default stdout). Any occurrence of the string "%prog" in + self.usage is replaced with the name of the current program + (basename of sys.argv[0]). Does nothing if self.usage is empty + or not defined. + """ + if self.usage: + print >>file, self.get_usage() + + def get_version(self): + if self.version: + return self.expand_prog_name(self.version) + else: + return "" + + def print_version(self, file=None): + """print_version(file : file = stdout) + + Print the version message for this program (self.version) to + 'file' (default stdout). As with print_usage(), any occurrence + of "%prog" in self.version is replaced by the current program's + name. Does nothing if self.version is empty or undefined. + """ + if self.version: + print >>file, self.get_version() + + def format_option_help(self, formatter=None): + if formatter is None: + formatter = self.formatter + formatter.store_option_strings(self) + result = [] + result.append(formatter.format_heading(_("Options"))) + formatter.indent() + if self.option_list: + result.append(OptionContainer.format_option_help(self, formatter)) + result.append("\n") + for group in self.option_groups: + result.append(group.format_help(formatter)) + result.append("\n") + formatter.dedent() + # Drop the last "\n", or the header if no options or option groups: + return "".join(result[:-1]) + + def format_epilog(self, formatter): + return formatter.format_epilog(self.epilog) + + def format_help(self, formatter=None): + if formatter is None: + formatter = self.formatter + result = [] + if self.usage: + result.append(self.get_usage() + "\n") + if self.description: + result.append(self.format_description(formatter) + "\n") + result.append(self.format_option_help(formatter)) + result.append(self.format_epilog(formatter)) + return "".join(result) + + # used by test suite + def _get_encoding(self, file): + encoding = getattr(file, "encoding", None) + if not encoding: + encoding = sys.getdefaultencoding() + return encoding + + def print_help(self, file=None): + """print_help(file : file = stdout) + + Print an extended help message, listing all options and any + help text provided with them, to 'file' (default stdout). + """ + if file is None: + file = sys.stdout + encoding = self._get_encoding(file) + file.write(self.format_help().encode(encoding, "replace")) + +# class OptionParser + + +def _match_abbrev(s, wordmap): + """_match_abbrev(s : string, wordmap : {string : Option}) -> string + + Return the string key in 'wordmap' for which 's' is an unambiguous + abbreviation. If 's' is found to be ambiguous or doesn't match any of + 'words', raise BadOptionError. + """ + # Is there an exact match? + if s in wordmap: + return s + else: + # Isolate all words with s as a prefix. + possibilities = [word for word in wordmap.keys() + if word.startswith(s)] + # No exact match, so there had better be just one possibility. + if len(possibilities) == 1: + return possibilities[0] + elif not possibilities: + raise BadOptionError(s) + else: + # More than one possible completion: ambiguous prefix. + possibilities.sort() + raise AmbiguousOptionError(s, possibilities) + + +# Some day, there might be many Option classes. As of Optik 1.3, the +# preferred way to instantiate Options is indirectly, via make_option(), +# which will become a factory function when there are many Option +# classes. +make_option = Option diff --git a/src/main/resources/PythonLibs/os.py b/src/main/resources/PythonLibs/os.py new file mode 100644 index 0000000000000000000000000000000000000000..f2561e88d798fa6d5ea133052c3b949e47819956 --- /dev/null +++ b/src/main/resources/PythonLibs/os.py @@ -0,0 +1,721 @@ +r"""OS routines for Mac, NT, or Posix depending on what system we're on. + +This exports: + - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc. + - os.path is one of the modules posixpath, or ntpath + - os.name is '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] != '_'] + +name = 'java' +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 'ibmi' in _names: + _name = 'ibmi' + linesep = '\n' + from ibmi import * + try: + from ibmi import _exit + except ImportError: + pass + import posixpath as path + + import ibmi + __all__.extend(_get_exports_list(ibmi)) + del ibmi + +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=0777): + """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, 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 way 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. + + 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 + """ + + from os.path import join, isdir, islink + + # 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, 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: + path = join(top, name) + if followlinks or not islink(path): + for x in walk(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 _exists(name): + # CPython eval's the name, whereas looking in __all__ works for + # Jython and is much faster + return name in __all__ + +if _exists('execv'): + + 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): + """execp(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, 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: + # 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 + import UserDict + + # 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): + self.data[key.upper()] = item + def __getitem__(self, key): + return self.data[key.upper()] + def __delitem__(self, key): + del self.data[key.upper()] + 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) + + 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") + +# 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 sys.platform.startswith('java') or _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 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 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 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") + +if not _exists("urandom"): + def urandom(n): + """urandom(n) -> str + + Return a string of n random bytes suitable for cryptographic use. + + """ + try: + _urandomfd = open("/dev/urandom", O_RDONLY) + except (OSError, IOError): + raise NotImplementedError("/dev/urandom (or equivalent) not found") + bytes = "" + while len(bytes) < n: + bytes += read(_urandomfd, n - len(bytes)) + close(_urandomfd) + return bytes + +# Supply os.popen() +def popen(cmd, mode='r', bufsize=-1): + """popen(command [, mode='r' [, bufsize]]) -> pipe + + Open a pipe to/from a command returning a file object. + """ + if not isinstance(cmd, (str, unicode)): + raise TypeError('invalid cmd type (%s, expected string)' % type(cmd)) + if mode not in ('r', 'w'): + raise ValueError("invalid mode %r" % mode) + import subprocess + if mode == 'r': + proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, + stdout=subprocess.PIPE) + fp = proc.stdout + elif mode == 'w': + proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, + stdin=subprocess.PIPE) + fp = proc.stdin + # files from subprocess are in binary mode but popen needs text mode + fp = fdopen(fp.fileno(), mode, bufsize) + return _wrap_close(fp, proc) + +# Helper for popen() -- a proxy for a file whose close waits for the process +class _wrap_close(object): + def __init__(self, stream, proc): + self._stream = stream + self._proc = proc + def close(self): + self._stream.close() + returncode = self._proc.wait() + if returncode == 0: + return None + if _name == 'nt': + return returncode + else: + return returncode + def __getattr__(self, name): + return getattr(self._stream, name) + def __iter__(self): + return iter(self._stream) diff --git a/src/main/resources/PythonLibs/pawt/__init__.py b/src/main/resources/PythonLibs/pawt/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..c621f40d4a5db67ddbf56ac9b7b2e1da3bcb1b4c --- /dev/null +++ b/src/main/resources/PythonLibs/pawt/__init__.py @@ -0,0 +1,35 @@ +import sys +from java import awt + +def test(panel, size=None, name='AWT Tester'): + f = awt.Frame(name, windowClosing=lambda event: sys.exit(0)) + if hasattr(panel, 'init'): + panel.init() + + f.add('Center', panel) + f.pack() + if size is not None: + f.setSize(apply(awt.Dimension, size)) + f.setVisible(1) + return f + +class GridBag: + def __init__(self, frame, **defaults): + self.frame = frame + self.gridbag = awt.GridBagLayout() + self.defaults = defaults + frame.setLayout(self.gridbag) + + def addRow(self, widget, **kw): + kw['gridwidth'] = 'REMAINDER' + apply(self.add, (widget, ), kw) + + def add(self, widget, **kw): + constraints = awt.GridBagConstraints() + + for key, value in self.defaults.items()+kw.items(): + if isinstance(value, type('')): + value = getattr(awt.GridBagConstraints, value) + setattr(constraints, key, value) + self.gridbag.setConstraints(widget, constraints) + self.frame.add(widget) diff --git a/src/main/resources/PythonLibs/pawt/colors.py b/src/main/resources/PythonLibs/pawt/colors.py new file mode 100644 index 0000000000000000000000000000000000000000..a20948e046c20180ed67cdaa405b2f3292141662 --- /dev/null +++ b/src/main/resources/PythonLibs/pawt/colors.py @@ -0,0 +1,144 @@ +from java.awt import Color + +aliceblue = Color(240, 248, 255) +antiquewhite = Color(250, 235, 215) +aqua = Color(0, 255, 255) +aquamarine = Color(127, 255, 212) +azure = Color(240, 255, 255) +beige = Color(245, 245, 220) +bisque = Color(255, 228, 196) +black = Color(0, 0, 0) +blanchedalmond = Color(255, 235, 205) +blue = Color(0, 0, 255) +blueviolet = Color(138, 43, 226) +brown = Color(165, 42, 42) +burlywood = Color(222, 184, 135) +cadetblue = Color(95, 158, 160) +chartreuse = Color(127, 255, 0) +chocolate = Color(210, 105, 30) +coral = Color(255, 127, 80) +cornflowerblue = Color(100, 149, 237) +cornsilk = Color(255, 248, 220) +crimson = Color(220, 20, 60) +cyan = Color(0, 255, 255) +darkblue = Color(0, 0, 139) +darkcyan = Color(0, 139, 139) +darkgoldenrod = Color(184, 134, 11) +darkgray = Color(169, 169, 169) +darkgreen = Color(0, 100, 0) +darkkhaki = Color(189, 183, 107) +darkmagenta = Color(139, 0, 139) +darkolivegreen = Color(85, 107, 47) +darkorange = Color(255, 140, 0) +darkorchid = Color(153, 50, 204) +darkred = Color(139, 0, 0) +darksalmon = Color(233, 150, 122) +darkseagreen = Color(143, 188, 143) +darkslateblue = Color(72, 61, 139) +darkslategray = Color(47, 79, 79) +darkturquoise = Color(0, 206, 209) +darkviolet = Color(148, 0, 211) +deeppink = Color(255, 20, 147) +deepskyblue = Color(0, 191, 255) +dimgray = Color(105, 105, 105) +dodgerblue = Color(30, 144, 255) +firebrick = Color(178, 34, 34) +floralwhite = Color(255, 250, 240) +forestgreen = Color(34, 139, 34) +fuchsia = Color(255, 0, 255) +gainsboro = Color(220, 220, 220) +ghostwhite = Color(248, 248, 255) +gold = Color(255, 215, 0) +goldenrod = Color(218, 165, 32) +gray = Color(128, 128, 128) +green = Color(0, 128, 0) +greenyellow = Color(173, 255, 47) +honeydew = Color(240, 255, 240) +hotpink = Color(255, 105, 180) +indianred = Color(205, 92, 92) +indigo = Color(75, 0, 130) +ivory = Color(255, 255, 240) +khaki = Color(240, 230, 140) +lavender = Color(230, 230, 250) +lavenderblush = Color(255, 240, 245) +lawngreen = Color(124, 252, 0) +lemonchiffon = Color(255, 250, 205) +lightblue = Color(173, 216, 230) +lightcoral = Color(240, 128, 128) +lightcyan = Color(224, 255, 255) +lightgoldenrodyellow = Color(250, 250, 210) +lightgreen = Color(144, 238, 144) +lightgrey = Color(211, 211, 211) +lightpink = Color(255, 182, 193) +lightsalmon = Color(255, 160, 122) +lightseagreen = Color(32, 178, 170) +lightskyblue = Color(135, 206, 250) +lightslategray = Color(119, 136, 153) +lightsteelblue = Color(176, 196, 222) +lightyellow = Color(255, 255, 224) +lime = Color(0, 255, 0) +limegreen = Color(50, 205, 50) +linen = Color(250, 240, 230) +magenta = Color(255, 0, 255) +maroon = Color(128, 0, 0) +mediumaquamarine = Color(102, 205, 170) +mediumblue = Color(0, 0, 205) +mediumorchid = Color(186, 85, 211) +mediumpurple = Color(147, 112, 219) +mediumseagreen = Color(60, 179, 113) +mediumslateblue = Color(123, 104, 238) +mediumspringgreen = Color(0, 250, 154) +mediumturquoise = Color(72, 209, 204) +mediumvioletred = Color(199, 21, 133) +midnightblue = Color(25, 25, 112) +mintcream = Color(245, 255, 250) +mistyrose = Color(255, 228, 225) +moccasin = Color(255, 228, 181) +navajowhite = Color(255, 222, 173) +navy = Color(0, 0, 128) +oldlace = Color(253, 245, 230) +olive = Color(128, 128, 0) +olivedrab = Color(107, 142, 35) +orange = Color(255, 165, 0) +orangered = Color(255, 69, 0) +orchid = Color(218, 112, 214) +palegoldenrod = Color(238, 232, 170) +palegreen = Color(152, 251, 152) +paleturquoise = Color(175, 238, 238) +palevioletred = Color(219, 112, 147) +papayawhip = Color(255, 239, 213) +peachpuff = Color(255, 218, 185) +peru = Color(205, 133, 63) +pink = Color(255, 192, 203) +plum = Color(221, 160, 221) +powderblue = Color(176, 224, 230) +purple = Color(128, 0, 128) +red = Color(255, 0, 0) +rosybrown = Color(188, 143, 143) +royalblue = Color(65, 105, 225) +saddlebrown = Color(139, 69, 19) +salmon = Color(250, 128, 114) +sandybrown = Color(244, 164, 96) +seagreen = Color(46, 139, 87) +seashell = Color(255, 245, 238) +sienna = Color(160, 82, 45) +silver = Color(192, 192, 192) +skyblue = Color(135, 206, 235) +slateblue = Color(106, 90, 205) +slategray = Color(112, 128, 144) +snow = Color(255, 250, 250) +springgreen = Color(0, 255, 127) +steelblue = Color(70, 130, 180) +tan = Color(210, 180, 140) +teal = Color(0, 128, 128) +thistle = Color(216, 191, 216) +tomato = Color(255, 99, 71) +turquoise = Color(64, 224, 208) +violet = Color(238, 130, 238) +wheat = Color(245, 222, 179) +white = Color(255, 255, 255) +whitesmoke = Color(245, 245, 245) +yellow = Color(255, 255, 0) +yellowgreen = Color(154, 205, 50) + +del Color diff --git a/src/main/resources/PythonLibs/pawt/swing.py b/src/main/resources/PythonLibs/pawt/swing.py new file mode 100644 index 0000000000000000000000000000000000000000..5c255df6a2a95c3d98bc15043a2deb19fbfa021b --- /dev/null +++ b/src/main/resources/PythonLibs/pawt/swing.py @@ -0,0 +1,24 @@ +""" +No longer needed, but keeping for backwards compatibility. +""" +from javax import swing +import sys + +def test(panel, size=None, name='Swing Tester'): + f = swing.JFrame(name, windowClosing=lambda event: sys.exit(0)) + if hasattr(panel, 'init'): + panel.init() + + f.contentPane.add(panel) + f.pack() + if size is not None: + from java import awt + f.setSize(apply(awt.Dimension, size)) + f.setVisible(1) + return f + +if swing is not None: + import pawt, sys + pawt.swing = swing + sys.modules['pawt.swing'] = swing + swing.__dict__['test'] = test diff --git a/src/main/resources/PythonLibs/pdb.py b/src/main/resources/PythonLibs/pdb.py new file mode 100644 index 0000000000000000000000000000000000000000..5468d3fcaff88c22d0be9d14e34f89c18a30a303 --- /dev/null +++ b/src/main/resources/PythonLibs/pdb.py @@ -0,0 +1,1338 @@ +#! /usr/bin/env python + +"""A Python debugger.""" + +# (See pdb.doc for documentation.) + +import sys +import linecache +import cmd +import bdb +from repr import Repr +import os +import re +import pprint +import traceback + + +class Restart(Exception): + """Causes a debugger to be restarted for the debugged python program.""" + pass + +# Create a custom safe Repr instance and increase its maxstring. +# The default of 30 truncates error messages too easily. +_repr = Repr() +_repr.maxstring = 200 +_saferepr = _repr.repr + +__all__ = ["run", "pm", "Pdb", "runeval", "runctx", "runcall", "set_trace", + "post_mortem", "help"] + +def find_function(funcname, filename): + cre = re.compile(r'def\s+%s\s*[(]' % re.escape(funcname)) + try: + fp = open(filename) + except IOError: + return None + # consumer of this info expects the first line to be 1 + lineno = 1 + answer = None + while 1: + line = fp.readline() + if line == '': + break + if cre.match(line): + answer = funcname, filename, lineno + break + lineno = lineno + 1 + fp.close() + return answer + + +# Interaction prompt line will separate file and call info from code +# text using value of line_prefix string. A newline and arrow may +# be to your liking. You can set it once pdb is imported using the +# command "pdb.line_prefix = '\n% '". +# line_prefix = ': ' # Use this to get the old situation back +line_prefix = '\n-> ' # Probably a better default + +class Pdb(bdb.Bdb, cmd.Cmd): + + def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None): + bdb.Bdb.__init__(self, skip=skip) + cmd.Cmd.__init__(self, completekey, stdin, stdout) + if stdout: + self.use_rawinput = 0 + self.prompt = '(Pdb) ' + self.aliases = {} + self.mainpyfile = '' + self._wait_for_mainpyfile = 0 + # Try to load readline if it exists + try: + import readline + except ImportError: + pass + + # Read $HOME/.pdbrc and ./.pdbrc + self.rcLines = [] + if 'HOME' in os.environ: + envHome = os.environ['HOME'] + try: + rcFile = open(os.path.join(envHome, ".pdbrc")) + except IOError: + pass + else: + for line in rcFile.readlines(): + self.rcLines.append(line) + rcFile.close() + try: + rcFile = open(".pdbrc") + except IOError: + pass + else: + for line in rcFile.readlines(): + self.rcLines.append(line) + rcFile.close() + + self.commands = {} # associates a command list to breakpoint numbers + self.commands_doprompt = {} # for each bp num, tells if the prompt + # must be disp. after execing the cmd list + self.commands_silent = {} # for each bp num, tells if the stack trace + # must be disp. after execing the cmd list + self.commands_defining = False # True while in the process of defining + # a command list + self.commands_bnum = None # The breakpoint number for which we are + # defining a list + + def reset(self): + bdb.Bdb.reset(self) + self.forget() + + def forget(self): + self.lineno = None + self.stack = [] + self.curindex = 0 + self.curframe = None + + def setup(self, f, t): + self.forget() + self.stack, self.curindex = self.get_stack(f, t) + self.curframe = self.stack[self.curindex][0] + # The f_locals dictionary is updated from the actual frame + # locals whenever the .f_locals accessor is called, so we + # cache it here to ensure that modifications are not overwritten. + self.curframe_locals = self.curframe.f_locals + self.execRcLines() + + # Can be executed earlier than 'setup' if desired + def execRcLines(self): + if self.rcLines: + # Make local copy because of recursion + rcLines = self.rcLines + # executed only once + self.rcLines = [] + for line in rcLines: + line = line[:-1] + if len(line) > 0 and line[0] != '#': + self.onecmd(line) + + # Override Bdb methods + + def user_call(self, frame, argument_list): + """This method is called when there is the remote possibility + that we ever need to stop in this function.""" + if self._wait_for_mainpyfile: + return + if self.stop_here(frame): + print >>self.stdout, '--Call--' + self.interaction(frame, None) + + def user_line(self, frame): + """This function is called when we stop or break at this line.""" + if self._wait_for_mainpyfile: + if (self.mainpyfile != self.canonic(frame.f_code.co_filename) + or frame.f_lineno<= 0): + return + self._wait_for_mainpyfile = 0 + if self.bp_commands(frame): + self.interaction(frame, None) + + def bp_commands(self,frame): + """Call every command that was set for the current active breakpoint + (if there is one). + + Returns True if the normal interaction function must be called, + False otherwise.""" + # self.currentbp is set in bdb in Bdb.break_here if a breakpoint was hit + if getattr(self, "currentbp", False) and \ + self.currentbp in self.commands: + currentbp = self.currentbp + self.currentbp = 0 + lastcmd_back = self.lastcmd + self.setup(frame, None) + for line in self.commands[currentbp]: + self.onecmd(line) + self.lastcmd = lastcmd_back + if not self.commands_silent[currentbp]: + self.print_stack_entry(self.stack[self.curindex]) + if self.commands_doprompt[currentbp]: + self.cmdloop() + self.forget() + return + return 1 + + def user_return(self, frame, return_value): + """This function is called when a return trap is set here.""" + if self._wait_for_mainpyfile: + return + frame.f_locals['__return__'] = return_value + print >>self.stdout, '--Return--' + self.interaction(frame, None) + + def user_exception(self, frame, exc_info): + """This function is called if an exception occurs, + but only if we are to stop at or just below this level.""" + if self._wait_for_mainpyfile: + return + exc_type, exc_value, exc_traceback = exc_info + frame.f_locals['__exception__'] = exc_type, exc_value + if type(exc_type) == type(''): + exc_type_name = exc_type + else: exc_type_name = exc_type.__name__ + print >>self.stdout, exc_type_name + ':', _saferepr(exc_value) + self.interaction(frame, exc_traceback) + + # General interaction function + + def interaction(self, frame, traceback): + self.setup(frame, traceback) + self.print_stack_entry(self.stack[self.curindex]) + self.cmdloop() + self.forget() + + def displayhook(self, obj): + """Custom displayhook for the exec in default(), which prevents + assignment of the _ variable in the builtins. + """ + # reproduce the behavior of the standard displayhook, not printing None + if obj is not None: + print repr(obj) + + def default(self, line): + if line[:1] == '!': line = line[1:] + locals = self.curframe_locals + globals = self.curframe.f_globals + try: + code = compile(line + '\n', '<stdin>', 'single') + save_stdout = sys.stdout + save_stdin = sys.stdin + save_displayhook = sys.displayhook + try: + sys.stdin = self.stdin + sys.stdout = self.stdout + sys.displayhook = self.displayhook + exec code in globals, locals + finally: + sys.stdout = save_stdout + sys.stdin = save_stdin + sys.displayhook = save_displayhook + except: + t, v = sys.exc_info()[:2] + if type(t) == type(''): + exc_type_name = t + else: exc_type_name = t.__name__ + print >>self.stdout, '***', exc_type_name + ':', v + + def precmd(self, line): + """Handle alias expansion and ';;' separator.""" + if not line.strip(): + return line + args = line.split() + while args[0] in self.aliases: + line = self.aliases[args[0]] + ii = 1 + for tmpArg in args[1:]: + line = line.replace("%" + str(ii), + tmpArg) + ii = ii + 1 + line = line.replace("%*", ' '.join(args[1:])) + args = line.split() + # split into ';;' separated commands + # unless it's an alias command + if args[0] != 'alias': + marker = line.find(';;') + if marker >= 0: + # queue up everything after marker + next = line[marker+2:].lstrip() + self.cmdqueue.append(next) + line = line[:marker].rstrip() + return line + + def onecmd(self, line): + """Interpret the argument as though it had been typed in response + to the prompt. + + Checks whether this line is typed at the normal prompt or in + a breakpoint command list definition. + """ + if not self.commands_defining: + return cmd.Cmd.onecmd(self, line) + else: + return self.handle_command_def(line) + + def handle_command_def(self,line): + """Handles one command line during command list definition.""" + cmd, arg, line = self.parseline(line) + if not cmd: + return + if cmd == 'silent': + self.commands_silent[self.commands_bnum] = True + return # continue to handle other cmd def in the cmd list + elif cmd == 'end': + self.cmdqueue = [] + return 1 # end of cmd list + cmdlist = self.commands[self.commands_bnum] + if arg: + cmdlist.append(cmd+' '+arg) + else: + cmdlist.append(cmd) + # Determine if we must stop + try: + func = getattr(self, 'do_' + cmd) + except AttributeError: + func = self.default + # one of the resuming commands + if func.func_name in self.commands_resuming: + self.commands_doprompt[self.commands_bnum] = False + self.cmdqueue = [] + return 1 + return + + # Command definitions, called by cmdloop() + # The argument is the remaining string on the command line + # Return true to exit from the command loop + + do_h = cmd.Cmd.do_help + + def do_commands(self, arg): + """Defines a list of commands associated to a breakpoint. + + Those commands will be executed whenever the breakpoint causes + the program to stop execution.""" + if not arg: + bnum = len(bdb.Breakpoint.bpbynumber)-1 + else: + try: + bnum = int(arg) + except: + print >>self.stdout, "Usage : commands [bnum]\n ..." \ + "\n end" + return + self.commands_bnum = bnum + self.commands[bnum] = [] + self.commands_doprompt[bnum] = True + self.commands_silent[bnum] = False + prompt_back = self.prompt + self.prompt = '(com) ' + self.commands_defining = True + try: + self.cmdloop() + finally: + self.commands_defining = False + self.prompt = prompt_back + + def do_break(self, arg, temporary = 0): + # break [ ([filename:]lineno | function) [, "condition"] ] + if not arg: + if self.breaks: # There's at least one + print >>self.stdout, "Num Type Disp Enb Where" + for bp in bdb.Breakpoint.bpbynumber: + if bp: + bp.bpprint(self.stdout) + return + # parse arguments; comma has lowest precedence + # and cannot occur in filename + filename = None + lineno = None + cond = None + comma = arg.find(',') + if comma > 0: + # parse stuff after comma: "condition" + cond = arg[comma+1:].lstrip() + arg = arg[:comma].rstrip() + # parse stuff before comma: [filename:]lineno | function + colon = arg.rfind(':') + funcname = None + if colon >= 0: + filename = arg[:colon].rstrip() + f = self.lookupmodule(filename) + if not f: + print >>self.stdout, '*** ', repr(filename), + print >>self.stdout, 'not found from sys.path' + return + else: + filename = f + arg = arg[colon+1:].lstrip() + try: + lineno = int(arg) + except ValueError, msg: + print >>self.stdout, '*** Bad lineno:', arg + return + else: + # no colon; can be lineno or function + try: + lineno = int(arg) + except ValueError: + try: + func = eval(arg, + self.curframe.f_globals, + self.curframe_locals) + except: + func = arg + try: + if hasattr(func, 'im_func'): + func = func.im_func + code = func.func_code + #use co_name to identify the bkpt (function names + #could be aliased, but co_name is invariant) + funcname = code.co_name + lineno = code.co_firstlineno + filename = code.co_filename + except: + # last thing to try + (ok, filename, ln) = self.lineinfo(arg) + if not ok: + print >>self.stdout, '*** The specified object', + print >>self.stdout, repr(arg), + print >>self.stdout, 'is not a function' + print >>self.stdout, 'or was not found along sys.path.' + return + funcname = ok # ok contains a function name + lineno = int(ln) + if not filename: + filename = self.defaultFile() + # Check for reasonable breakpoint + line = self.checkline(filename, lineno) + if line: + # now set the break point + err = self.set_break(filename, line, temporary, cond, funcname) + if err: print >>self.stdout, '***', err + else: + bp = self.get_breaks(filename, line)[-1] + print >>self.stdout, "Breakpoint %d at %s:%d" % (bp.number, + bp.file, + bp.line) + + # To be overridden in derived debuggers + def defaultFile(self): + """Produce a reasonable default.""" + filename = self.curframe.f_code.co_filename + if filename == '<string>' and self.mainpyfile: + filename = self.mainpyfile + return filename + + do_b = do_break + + def do_tbreak(self, arg): + self.do_break(arg, 1) + + def lineinfo(self, identifier): + failed = (None, None, None) + # Input is identifier, may be in single quotes + idstring = identifier.split("'") + if len(idstring) == 1: + # not in single quotes + id = idstring[0].strip() + elif len(idstring) == 3: + # quoted + id = idstring[1].strip() + else: + return failed + if id == '': return failed + parts = id.split('.') + # Protection for derived debuggers + if parts[0] == 'self': + del parts[0] + if len(parts) == 0: + return failed + # Best first guess at file to look at + fname = self.defaultFile() + if len(parts) == 1: + item = parts[0] + else: + # More than one part. + # First is module, second is method/class + f = self.lookupmodule(parts[0]) + if f: + fname = f + item = parts[1] + answer = find_function(item, fname) + return answer or failed + + def checkline(self, filename, lineno): + """Check whether specified line seems to be executable. + + Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank + line or EOF). Warning: testing is not comprehensive. + """ + # this method should be callable before starting debugging, so default + # to "no globals" if there is no current frame + globs = self.curframe.f_globals if hasattr(self, 'curframe') else None + line = linecache.getline(filename, lineno, globs) + if not line: + print >>self.stdout, 'End of file' + return 0 + line = line.strip() + # Don't allow setting breakpoint at a blank line + if (not line or (line[0] == '#') or + (line[:3] == '"""') or line[:3] == "'''"): + print >>self.stdout, '*** Blank or comment' + return 0 + return lineno + + def do_enable(self, arg): + args = arg.split() + for i in args: + try: + i = int(i) + except ValueError: + print >>self.stdout, 'Breakpoint index %r is not a number' % i + continue + + if not (0 <= i < len(bdb.Breakpoint.bpbynumber)): + print >>self.stdout, 'No breakpoint numbered', i + continue + + bp = bdb.Breakpoint.bpbynumber[i] + if bp: + bp.enable() + + def do_disable(self, arg): + args = arg.split() + for i in args: + try: + i = int(i) + except ValueError: + print >>self.stdout, 'Breakpoint index %r is not a number' % i + continue + + if not (0 <= i < len(bdb.Breakpoint.bpbynumber)): + print >>self.stdout, 'No breakpoint numbered', i + continue + + bp = bdb.Breakpoint.bpbynumber[i] + if bp: + bp.disable() + + def do_condition(self, arg): + # arg is breakpoint number and condition + args = arg.split(' ', 1) + try: + bpnum = int(args[0].strip()) + except ValueError: + # something went wrong + print >>self.stdout, \ + 'Breakpoint index %r is not a number' % args[0] + return + try: + cond = args[1] + except: + cond = None + try: + bp = bdb.Breakpoint.bpbynumber[bpnum] + except IndexError: + print >>self.stdout, 'Breakpoint index %r is not valid' % args[0] + return + if bp: + bp.cond = cond + if not cond: + print >>self.stdout, 'Breakpoint', bpnum, + print >>self.stdout, 'is now unconditional.' + + def do_ignore(self,arg): + """arg is bp number followed by ignore count.""" + args = arg.split() + try: + bpnum = int(args[0].strip()) + except ValueError: + # something went wrong + print >>self.stdout, \ + 'Breakpoint index %r is not a number' % args[0] + return + try: + count = int(args[1].strip()) + except: + count = 0 + try: + bp = bdb.Breakpoint.bpbynumber[bpnum] + except IndexError: + print >>self.stdout, 'Breakpoint index %r is not valid' % args[0] + return + if bp: + bp.ignore = count + if count > 0: + reply = 'Will ignore next ' + if count > 1: + reply = reply + '%d crossings' % count + else: + reply = reply + '1 crossing' + print >>self.stdout, reply + ' of breakpoint %d.' % bpnum + else: + print >>self.stdout, 'Will stop next time breakpoint', + print >>self.stdout, bpnum, 'is reached.' + + def do_clear(self, arg): + """Three possibilities, tried in this order: + clear -> clear all breaks, ask for confirmation + clear file:lineno -> clear all breaks at file:lineno + clear bpno bpno ... -> clear breakpoints by number""" + if not arg: + try: + reply = raw_input('Clear all breaks? ') + except EOFError: + reply = 'no' + reply = reply.strip().lower() + if reply in ('y', 'yes'): + self.clear_all_breaks() + return + if ':' in arg: + # Make sure it works for "clear C:\foo\bar.py:12" + i = arg.rfind(':') + filename = arg[:i] + arg = arg[i+1:] + try: + lineno = int(arg) + except ValueError: + err = "Invalid line number (%s)" % arg + else: + err = self.clear_break(filename, lineno) + if err: print >>self.stdout, '***', err + return + numberlist = arg.split() + for i in numberlist: + try: + i = int(i) + except ValueError: + print >>self.stdout, 'Breakpoint index %r is not a number' % i + continue + + if not (0 <= i < len(bdb.Breakpoint.bpbynumber)): + print >>self.stdout, 'No breakpoint numbered', i + continue + err = self.clear_bpbynumber(i) + if err: + print >>self.stdout, '***', err + else: + print >>self.stdout, 'Deleted breakpoint', i + do_cl = do_clear # 'c' is already an abbreviation for 'continue' + + def do_where(self, arg): + self.print_stack_trace() + do_w = do_where + do_bt = do_where + + def do_up(self, arg): + if self.curindex == 0: + print >>self.stdout, '*** Oldest frame' + else: + self.curindex = self.curindex - 1 + self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals + self.print_stack_entry(self.stack[self.curindex]) + self.lineno = None + do_u = do_up + + def do_down(self, arg): + if self.curindex + 1 == len(self.stack): + print >>self.stdout, '*** Newest frame' + else: + self.curindex = self.curindex + 1 + self.curframe = self.stack[self.curindex][0] + self.curframe_locals = self.curframe.f_locals + self.print_stack_entry(self.stack[self.curindex]) + self.lineno = None + do_d = do_down + + def do_until(self, arg): + self.set_until(self.curframe) + return 1 + do_unt = do_until + + def do_step(self, arg): + self.set_step() + return 1 + do_s = do_step + + def do_next(self, arg): + self.set_next(self.curframe) + return 1 + do_n = do_next + + def do_run(self, arg): + """Restart program by raising an exception to be caught in the main + debugger loop. If arguments were given, set them in sys.argv.""" + if arg: + import shlex + argv0 = sys.argv[0:1] + sys.argv = shlex.split(arg) + sys.argv[:0] = argv0 + raise Restart + + do_restart = do_run + + def do_return(self, arg): + self.set_return(self.curframe) + return 1 + do_r = do_return + + def do_continue(self, arg): + self.set_continue() + return 1 + do_c = do_cont = do_continue + + def do_jump(self, arg): + if self.curindex + 1 != len(self.stack): + print >>self.stdout, "*** You can only jump within the bottom frame" + return + try: + arg = int(arg) + except ValueError: + print >>self.stdout, "*** The 'jump' command requires a line number." + else: + try: + # Do the jump, fix up our copy of the stack, and display the + # new position + self.curframe.f_lineno = arg + self.stack[self.curindex] = self.stack[self.curindex][0], arg + self.print_stack_entry(self.stack[self.curindex]) + except ValueError, e: + print >>self.stdout, '*** Jump failed:', e + do_j = do_jump + + def do_debug(self, arg): + sys.settrace(None) + globals = self.curframe.f_globals + locals = self.curframe_locals + p = Pdb(self.completekey, self.stdin, self.stdout) + p.prompt = "(%s) " % self.prompt.strip() + print >>self.stdout, "ENTERING RECURSIVE DEBUGGER" + sys.call_tracing(p.run, (arg, globals, locals)) + print >>self.stdout, "LEAVING RECURSIVE DEBUGGER" + sys.settrace(self.trace_dispatch) + self.lastcmd = p.lastcmd + + def do_quit(self, arg): + self._user_requested_quit = 1 + self.set_quit() + return 1 + + do_q = do_quit + do_exit = do_quit + + def do_EOF(self, arg): + print >>self.stdout + self._user_requested_quit = 1 + self.set_quit() + return 1 + + def do_args(self, arg): + co = self.curframe.f_code + dict = self.curframe_locals + n = co.co_argcount + if co.co_flags & 4: n = n+1 + if co.co_flags & 8: n = n+1 + for i in range(n): + name = co.co_varnames[i] + print >>self.stdout, name, '=', + if name in dict: print >>self.stdout, dict[name] + else: print >>self.stdout, "*** undefined ***" + do_a = do_args + + def do_retval(self, arg): + if '__return__' in self.curframe_locals: + print >>self.stdout, self.curframe_locals['__return__'] + else: + print >>self.stdout, '*** Not yet returned!' + do_rv = do_retval + + def _getval(self, arg): + try: + return eval(arg, self.curframe.f_globals, + self.curframe_locals) + except: + t, v = sys.exc_info()[:2] + if isinstance(t, str): + exc_type_name = t + else: exc_type_name = t.__name__ + print >>self.stdout, '***', exc_type_name + ':', repr(v) + raise + + def do_p(self, arg): + try: + print >>self.stdout, repr(self._getval(arg)) + except: + pass + + def do_pp(self, arg): + try: + pprint.pprint(self._getval(arg), self.stdout) + except: + pass + + def do_list(self, arg): + self.lastcmd = 'list' + last = None + if arg: + try: + x = eval(arg, {}, {}) + if type(x) == type(()): + first, last = x + first = int(first) + last = int(last) + if last < first: + # Assume it's a count + last = first + last + else: + first = max(1, int(x) - 5) + except: + print >>self.stdout, '*** Error in argument:', repr(arg) + return + elif self.lineno is None: + first = max(1, self.curframe.f_lineno - 5) + else: + first = self.lineno + 1 + if last is None: + last = first + 10 + filename = self.curframe.f_code.co_filename + breaklist = self.get_file_breaks(filename) + try: + for lineno in range(first, last+1): + line = linecache.getline(filename, lineno, + self.curframe.f_globals) + if not line: + print >>self.stdout, '[EOF]' + break + else: + s = repr(lineno).rjust(3) + if len(s) < 4: s = s + ' ' + if lineno in breaklist: s = s + 'B' + else: s = s + ' ' + if lineno == self.curframe.f_lineno: + s = s + '->' + print >>self.stdout, s + '\t' + line, + self.lineno = lineno + except KeyboardInterrupt: + pass + do_l = do_list + + def do_whatis(self, arg): + try: + value = eval(arg, self.curframe.f_globals, + self.curframe_locals) + except: + t, v = sys.exc_info()[:2] + if type(t) == type(''): + exc_type_name = t + else: exc_type_name = t.__name__ + print >>self.stdout, '***', exc_type_name + ':', repr(v) + return + code = None + # Is it a function? + try: code = value.func_code + except: pass + if code: + print >>self.stdout, 'Function', code.co_name + return + # Is it an instance method? + try: code = value.im_func.func_code + except: pass + if code: + print >>self.stdout, 'Method', code.co_name + return + # None of the above... + print >>self.stdout, type(value) + + def do_alias(self, arg): + args = arg.split() + if len(args) == 0: + keys = self.aliases.keys() + keys.sort() + for alias in keys: + print >>self.stdout, "%s = %s" % (alias, self.aliases[alias]) + return + if args[0] in self.aliases and len(args) == 1: + print >>self.stdout, "%s = %s" % (args[0], self.aliases[args[0]]) + else: + self.aliases[args[0]] = ' '.join(args[1:]) + + def do_unalias(self, arg): + args = arg.split() + if len(args) == 0: return + if args[0] in self.aliases: + del self.aliases[args[0]] + + #list of all the commands making the program resume execution. + commands_resuming = ['do_continue', 'do_step', 'do_next', 'do_return', + 'do_quit', 'do_jump'] + + # Print a traceback starting at the top stack frame. + # The most recently entered frame is printed last; + # this is different from dbx and gdb, but consistent with + # the Python interpreter's stack trace. + # It is also consistent with the up/down commands (which are + # compatible with dbx and gdb: up moves towards 'main()' + # and down moves towards the most recent stack frame). + + def print_stack_trace(self): + try: + for frame_lineno in self.stack: + self.print_stack_entry(frame_lineno) + except KeyboardInterrupt: + pass + + def print_stack_entry(self, frame_lineno, prompt_prefix=line_prefix): + frame, lineno = frame_lineno + if frame is self.curframe: + print >>self.stdout, '>', + else: + print >>self.stdout, ' ', + print >>self.stdout, self.format_stack_entry(frame_lineno, + prompt_prefix) + + + # Help methods (derived from pdb.doc) + + def help_help(self): + self.help_h() + + def help_h(self): + print >>self.stdout, """h(elp) +Without argument, print the list of available commands. +With a command name as argument, print help about that command +"help pdb" pipes the full documentation file to the $PAGER +"help exec" gives help on the ! command""" + + def help_where(self): + self.help_w() + + def help_w(self): + print >>self.stdout, """w(here) +Print a stack trace, with the most recent frame at the bottom. +An arrow indicates the "current frame", which determines the +context of most commands. 'bt' is an alias for this command.""" + + help_bt = help_w + + def help_down(self): + self.help_d() + + def help_d(self): + print >>self.stdout, """d(own) +Move the current frame one level down in the stack trace +(to a newer frame).""" + + def help_up(self): + self.help_u() + + def help_u(self): + print >>self.stdout, """u(p) +Move the current frame one level up in the stack trace +(to an older frame).""" + + def help_break(self): + self.help_b() + + def help_b(self): + print >>self.stdout, """b(reak) ([file:]lineno | function) [, condition] +With a line number argument, set a break there in the current +file. With a function name, set a break at first executable line +of that function. Without argument, list all breaks. If a second +argument is present, it is a string specifying an expression +which must evaluate to true before the breakpoint is honored. + +The line number may be prefixed with a filename and a colon, +to specify a breakpoint in another file (probably one that +hasn't been loaded yet). The file is searched for on sys.path; +the .py suffix may be omitted.""" + + def help_clear(self): + self.help_cl() + + def help_cl(self): + print >>self.stdout, "cl(ear) filename:lineno" + print >>self.stdout, """cl(ear) [bpnumber [bpnumber...]] +With a space separated list of breakpoint numbers, clear +those breakpoints. Without argument, clear all breaks (but +first ask confirmation). With a filename:lineno argument, +clear all breaks at that line in that file. + +Note that the argument is different from previous versions of +the debugger (in python distributions 1.5.1 and before) where +a linenumber was used instead of either filename:lineno or +breakpoint numbers.""" + + def help_tbreak(self): + print >>self.stdout, """tbreak same arguments as break, but breakpoint +is removed when first hit.""" + + def help_enable(self): + print >>self.stdout, """enable bpnumber [bpnumber ...] +Enables the breakpoints given as a space separated list of +bp numbers.""" + + def help_disable(self): + print >>self.stdout, """disable bpnumber [bpnumber ...] +Disables the breakpoints given as a space separated list of +bp numbers.""" + + def help_ignore(self): + print >>self.stdout, """ignore bpnumber count +Sets the ignore count for the given breakpoint number. A breakpoint +becomes active when the ignore count is zero. When non-zero, the +count is decremented each time the breakpoint is reached and the +breakpoint is not disabled and any associated condition evaluates +to true.""" + + def help_condition(self): + print >>self.stdout, """condition bpnumber str_condition +str_condition is a string specifying an expression which +must evaluate to true before the breakpoint is honored. +If str_condition is absent, any existing condition is removed; +i.e., the breakpoint is made unconditional.""" + + def help_step(self): + self.help_s() + + def help_s(self): + print >>self.stdout, """s(tep) +Execute the current line, stop at the first possible occasion +(either in a function that is called or in the current function).""" + + def help_until(self): + self.help_unt() + + def help_unt(self): + print """unt(il) +Continue execution until the line with a number greater than the current +one is reached or until the current frame returns""" + + def help_next(self): + self.help_n() + + def help_n(self): + print >>self.stdout, """n(ext) +Continue execution until the next line in the current function +is reached or it returns.""" + + def help_return(self): + self.help_r() + + def help_r(self): + print >>self.stdout, """r(eturn) +Continue execution until the current function returns.""" + + def help_continue(self): + self.help_c() + + def help_cont(self): + self.help_c() + + def help_c(self): + print >>self.stdout, """c(ont(inue)) +Continue execution, only stop when a breakpoint is encountered.""" + + def help_jump(self): + self.help_j() + + def help_j(self): + print >>self.stdout, """j(ump) lineno +Set the next line that will be executed.""" + + def help_debug(self): + print >>self.stdout, """debug code +Enter a recursive debugger that steps through the code argument +(which is an arbitrary expression or statement to be executed +in the current environment).""" + + def help_list(self): + self.help_l() + + def help_l(self): + print >>self.stdout, """l(ist) [first [,last]] +List source code for the current file. +Without arguments, list 11 lines around the current line +or continue the previous listing. +With one argument, list 11 lines starting at that line. +With two arguments, list the given range; +if the second argument is less than the first, it is a count.""" + + def help_args(self): + self.help_a() + + def help_a(self): + print >>self.stdout, """a(rgs) +Print the arguments of the current function.""" + + def help_p(self): + print >>self.stdout, """p expression +Print the value of the expression.""" + + def help_pp(self): + print >>self.stdout, """pp expression +Pretty-print the value of the expression.""" + + def help_exec(self): + print >>self.stdout, """(!) statement +Execute the (one-line) statement in the context of +the current stack frame. +The exclamation point can be omitted unless the first word +of the statement resembles a debugger command. +To assign to a global variable you must always prefix the +command with a 'global' command, e.g.: +(Pdb) global list_options; list_options = ['-l'] +(Pdb)""" + + def help_run(self): + print """run [args...] +Restart the debugged python program. If a string is supplied, it is +splitted with "shlex" and the result is used as the new sys.argv. +History, breakpoints, actions and debugger options are preserved. +"restart" is an alias for "run".""" + + help_restart = help_run + + def help_quit(self): + self.help_q() + + def help_q(self): + print >>self.stdout, """q(uit) or exit - Quit from the debugger. +The program being executed is aborted.""" + + help_exit = help_q + + def help_whatis(self): + print >>self.stdout, """whatis arg +Prints the type of the argument.""" + + def help_EOF(self): + print >>self.stdout, """EOF +Handles the receipt of EOF as a command.""" + + def help_alias(self): + print >>self.stdout, """alias [name [command [parameter parameter ...]]] +Creates an alias called 'name' the executes 'command'. The command +must *not* be enclosed in quotes. Replaceable parameters are +indicated by %1, %2, and so on, while %* is replaced by all the +parameters. If no command is given, the current alias for name +is shown. If no name is given, all aliases are listed. + +Aliases may be nested and can contain anything that can be +legally typed at the pdb prompt. Note! You *can* override +internal pdb commands with aliases! Those internal commands +are then hidden until the alias is removed. Aliasing is recursively +applied to the first word of the command line; all other words +in the line are left alone. + +Some useful aliases (especially when placed in the .pdbrc file) are: + +#Print instance variables (usage "pi classInst") +alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k] + +#Print instance variables in self +alias ps pi self +""" + + def help_unalias(self): + print >>self.stdout, """unalias name +Deletes the specified alias.""" + + def help_commands(self): + print >>self.stdout, """commands [bpnumber] +(com) ... +(com) end +(Pdb) + +Specify a list of commands for breakpoint number bpnumber. The +commands themselves appear on the following lines. Type a line +containing just 'end' to terminate the commands. + +To remove all commands from a breakpoint, type commands and +follow it immediately with end; that is, give no commands. + +With no bpnumber argument, commands refers to the last +breakpoint set. + +You can use breakpoint commands to start your program up again. +Simply use the continue command, or step, or any other +command that resumes execution. + +Specifying any command resuming execution (currently continue, +step, next, return, jump, quit and their abbreviations) terminates +the command list (as if that command was immediately followed by end). +This is because any time you resume execution +(even with a simple next or step), you may encounter +another breakpoint--which could have its own command list, leading to +ambiguities about which list to execute. + + If you use the 'silent' command in the command list, the +usual message about stopping at a breakpoint is not printed. This may +be desirable for breakpoints that are to print a specific message and +then continue. If none of the other commands print anything, you +see no sign that the breakpoint was reached. +""" + + def help_pdb(self): + help() + + def lookupmodule(self, filename): + """Helper function for break/clear parsing -- may be overridden. + + lookupmodule() translates (possibly incomplete) file or module name + into an absolute file name. + """ + if os.path.isabs(filename) and os.path.exists(filename): + return filename + f = os.path.join(sys.path[0], filename) + if os.path.exists(f) and self.canonic(f) == self.mainpyfile: + return f + root, ext = os.path.splitext(filename) + if ext == '': + filename = filename + '.py' + if os.path.isabs(filename): + return filename + for dirname in sys.path: + while os.path.islink(dirname): + dirname = os.readlink(dirname) + fullname = os.path.join(dirname, filename) + if os.path.exists(fullname): + return fullname + return None + + def _runscript(self, filename): + # The script has to run in __main__ namespace (or imports from + # __main__ will break). + # + # So we clear up the __main__ and set several special variables + # (this gets rid of pdb's globals and cleans old variables on restarts). + import __main__ + __main__.__dict__.clear() + __main__.__dict__.update({"__name__" : "__main__", + "__file__" : filename, + "__builtins__": __builtins__, + }) + + # When bdb sets tracing, a number of call and line events happens + # BEFORE debugger even reaches user's code (and the exact sequence of + # events depends on python version). So we take special measures to + # avoid stopping before we reach the main script (see user_line and + # user_call for details). + self._wait_for_mainpyfile = 1 + self.mainpyfile = self.canonic(filename) + self._user_requested_quit = 0 + statement = 'execfile(%r)' % filename + self.run(statement) + +# Simplified interface + +def run(statement, globals=None, locals=None): + Pdb().run(statement, globals, locals) + +def runeval(expression, globals=None, locals=None): + return Pdb().runeval(expression, globals, locals) + +def runctx(statement, globals, locals): + # B/W compatibility + run(statement, globals, locals) + +def runcall(*args, **kwds): + return Pdb().runcall(*args, **kwds) + +def set_trace(): + Pdb().set_trace(sys._getframe().f_back) + +# Post-Mortem interface + +def post_mortem(t=None): + # handling the default + if t is None: + # sys.exc_info() returns (type, value, traceback) if an exception is + # being handled, otherwise it returns None + t = sys.exc_info()[2] + if t is None: + raise ValueError("A valid traceback must be passed if no " + "exception is being handled") + + p = Pdb() + p.reset() + p.interaction(None, t) + +def pm(): + post_mortem(sys.last_traceback) + + +# Main program for testing + +TESTCMD = 'import x; x.main()' + +def test(): + run(TESTCMD) + +# print help +def help(): + for dirname in sys.path: + fullname = os.path.join(dirname, 'pdb.doc') + if os.path.exists(fullname): + sts = os.system('${PAGER-more} '+fullname) + if sts: print '*** Pager exit status:', sts + break + else: + print 'Sorry, can\'t find the help file "pdb.doc"', + print 'along the Python search path' + +def main(): + if not sys.argv[1:] or sys.argv[1] in ("--help", "-h"): + print "usage: pdb.py scriptfile [arg] ..." + sys.exit(2) + + mainpyfile = sys.argv[1] # Get script filename + if not os.path.exists(mainpyfile): + print 'Error:', mainpyfile, 'does not exist' + sys.exit(1) + + del sys.argv[0] # Hide "pdb.py" from argument list + + # Replace pdb's dir with script's dir in front of module search path. + sys.path[0] = os.path.dirname(mainpyfile) + + # Note on saving/restoring sys.argv: it's a good idea when sys.argv was + # modified by the script being debugged. It's a bad idea when it was + # changed by the user from the command line. There is a "restart" command + # which allows explicit specification of command line arguments. + pdb = Pdb() + while True: + try: + pdb._runscript(mainpyfile) + if pdb._user_requested_quit: + break + print "The program finished and will be restarted" + except Restart: + print "Restarting", mainpyfile, "with arguments:" + print "\t" + " ".join(sys.argv[1:]) + except SystemExit: + # In most cases SystemExit does not warrant a post-mortem session. + print "The program exited via sys.exit(). Exit status: ", + print sys.exc_info()[1] + except: + traceback.print_exc() + print "Uncaught exception. Entering post mortem debugging" + print "Running 'cont' or 'step' will restart the program" + t = sys.exc_info()[2] + pdb.interaction(None, t) + print "Post mortem debugger finished. The " + mainpyfile + \ + " will be restarted" + + +# When invoked as main program, invoke the debugger on a script +if __name__ == '__main__': + import pdb + pdb.main() diff --git a/src/main/resources/PythonLibs/pickle.py b/src/main/resources/PythonLibs/pickle.py new file mode 100644 index 0000000000000000000000000000000000000000..5b95cbaca76027a5f01590b7c6ae39d90671b40e --- /dev/null +++ b/src/main/resources/PythonLibs/pickle.py @@ -0,0 +1,1391 @@ +"""Create portable serialized representations of Python objects. + +See module cPickle for a (much) faster implementation. +See module copy_reg for a mechanism for registering custom picklers. +See module pickletools source for extensive comments. + +Classes: + + Pickler + Unpickler + +Functions: + + dump(object, file) + dumps(object) -> string + load(file) -> object + loads(string) -> object + +Misc variables: + + __version__ + format_version + compatible_formats + +""" + +__version__ = "$Revision: 72223 $" # Code version + +from types import * +from copy_reg import dispatch_table +from copy_reg import _extension_registry, _inverted_registry, _extension_cache +import marshal +import sys +import struct +import re + +__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler", + "Unpickler", "dump", "dumps", "load", "loads"] + +# These are purely informational; no code uses these. +format_version = "2.0" # File format version we write +compatible_formats = ["1.0", # Original protocol 0 + "1.1", # Protocol 0 with INST added + "1.2", # Original protocol 1 + "1.3", # Protocol 1 with BINFLOAT added + "2.0", # Protocol 2 + ] # Old format versions we can read + +# Keep in synch with cPickle. This is the highest protocol number we +# know how to read. +HIGHEST_PROTOCOL = 2 + +# Why use struct.pack() for pickling but marshal.loads() for +# unpickling? struct.pack() is 40% faster than marshal.dumps(), but +# marshal.loads() is twice as fast as struct.unpack()! +mloads = marshal.loads + +class PickleError(Exception): + """A common base class for the other pickling exceptions.""" + pass + +class PicklingError(PickleError): + """This exception is raised when an unpicklable object is passed to the + dump() method. + + """ + pass + +class UnpicklingError(PickleError): + """This exception is raised when there is a problem unpickling an object, + such as a security violation. + + Note that other exceptions may also be raised during unpickling, including + (but not necessarily limited to) AttributeError, EOFError, ImportError, + and IndexError. + + """ + pass + +# An instance of _Stop is raised by Unpickler.load_stop() in response to +# the STOP opcode, passing the object that is the result of unpickling. +class _Stop(Exception): + def __init__(self, value): + self.value = value + +# Jython has PyStringMap; it's a dict subclass with string keys +try: + from org.python.core import PyStringMap +except ImportError: + PyStringMap = None + +# UnicodeType may or may not be exported (normally imported from types) +try: + UnicodeType +except NameError: + UnicodeType = None + +# Pickle opcodes. See pickletools.py for extensive docs. The listing +# here is in kind-of alphabetical order of 1-character pickle code. +# pickletools groups them by purpose. + +MARK = '(' # push special markobject on stack +STOP = '.' # every pickle ends with STOP +POP = '0' # discard topmost stack item +POP_MARK = '1' # discard stack top through topmost markobject +DUP = '2' # duplicate top stack item +FLOAT = 'F' # push float object; decimal string argument +INT = 'I' # push integer or bool; decimal string argument +BININT = 'J' # push four-byte signed int +BININT1 = 'K' # push 1-byte unsigned int +LONG = 'L' # push long; decimal string argument +BININT2 = 'M' # push 2-byte unsigned int +NONE = 'N' # push None +PERSID = 'P' # push persistent object; id is taken from string arg +BINPERSID = 'Q' # " " " ; " " " " stack +REDUCE = 'R' # apply callable to argtuple, both on stack +STRING = 'S' # push string; NL-terminated string argument +BINSTRING = 'T' # push string; counted binary string argument +SHORT_BINSTRING = 'U' # " " ; " " " " < 256 bytes +UNICODE = 'V' # push Unicode string; raw-unicode-escaped'd argument +BINUNICODE = 'X' # " " " ; counted UTF-8 string argument +APPEND = 'a' # append stack top to list below it +BUILD = 'b' # call __setstate__ or __dict__.update() +GLOBAL = 'c' # push self.find_class(modname, name); 2 string args +DICT = 'd' # build a dict from stack items +EMPTY_DICT = '}' # push empty dict +APPENDS = 'e' # extend list on stack by topmost stack slice +GET = 'g' # push item from memo on stack; index is string arg +BINGET = 'h' # " " " " " " ; " " 1-byte arg +INST = 'i' # build & push class instance +LONG_BINGET = 'j' # push item from memo on stack; index is 4-byte arg +LIST = 'l' # build list from topmost stack items +EMPTY_LIST = ']' # push empty list +OBJ = 'o' # build & push class instance +PUT = 'p' # store stack top in memo; index is string arg +BINPUT = 'q' # " " " " " ; " " 1-byte arg +LONG_BINPUT = 'r' # " " " " " ; " " 4-byte arg +SETITEM = 's' # add key+value pair to dict +TUPLE = 't' # build tuple from topmost stack items +EMPTY_TUPLE = ')' # push empty tuple +SETITEMS = 'u' # modify dict by adding topmost key+value pairs +BINFLOAT = 'G' # push float; arg is 8-byte float encoding + +TRUE = 'I01\n' # not an opcode; see INT docs in pickletools.py +FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py + +# Protocol 2 + +PROTO = '\x80' # identify pickle protocol +NEWOBJ = '\x81' # build object by applying cls.__new__ to argtuple +EXT1 = '\x82' # push object from extension registry; 1-byte index +EXT2 = '\x83' # ditto, but 2-byte index +EXT4 = '\x84' # ditto, but 4-byte index +TUPLE1 = '\x85' # build 1-tuple from stack top +TUPLE2 = '\x86' # build 2-tuple from two topmost stack items +TUPLE3 = '\x87' # build 3-tuple from three topmost stack items +NEWTRUE = '\x88' # push True +NEWFALSE = '\x89' # push False +LONG1 = '\x8a' # push long from < 256 bytes +LONG4 = '\x8b' # push really big long + +_tuplesize2code = [EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3] + + +__all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) +del x + + +# Pickling machinery + +class Pickler: + + def __init__(self, file, protocol=None): + """This takes a file-like object for writing a pickle data stream. + + The optional protocol argument tells the pickler to use the + given protocol; supported protocols are 0, 1, 2. The default + protocol is 0, to be backwards compatible. (Protocol 0 is the + only protocol that can be written to a file opened in text + mode and read back successfully. When using a protocol higher + than 0, make sure the file is opened in binary mode, both when + pickling and unpickling.) + + Protocol 1 is more efficient than protocol 0; protocol 2 is + more efficient than protocol 1. + + Specifying a negative protocol version selects the highest + protocol version supported. The higher the protocol used, the + more recent the version of Python needed to read the pickle + produced. + + The file parameter must have a write() method that accepts a single + string argument. It can thus be an open file object, a StringIO + object, or any other custom object that meets this interface. + + """ + if protocol is None: + protocol = 0 + if protocol < 0: + protocol = HIGHEST_PROTOCOL + elif not 0 <= protocol <= HIGHEST_PROTOCOL: + raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL) + self.write = file.write + self.memo = {} + self.proto = int(protocol) + self.bin = protocol >= 1 + self.fast = 0 + + def clear_memo(self): + """Clears the pickler's "memo". + + The memo is the data structure that remembers which objects the + pickler has already seen, so that shared or recursive objects are + pickled by reference and not by value. This method is useful when + re-using picklers. + + """ + self.memo.clear() + + def dump(self, obj): + """Write a pickled representation of obj to the open file.""" + if self.proto >= 2: + self.write(PROTO + chr(self.proto)) + self.save(obj) + self.write(STOP) + + def memoize(self, obj): + """Store an object in the memo.""" + + # The Pickler memo is a dictionary mapping object ids to 2-tuples + # that contain the Unpickler memo key and the object being memoized. + # The memo key is written to the pickle and will become + # the key in the Unpickler's memo. The object is stored in the + # Pickler memo so that transient objects are kept alive during + # pickling. + + # The use of the Unpickler memo length as the memo key is just a + # convention. The only requirement is that the memo values be unique. + # But there appears no advantage to any other scheme, and this + # scheme allows the Unpickler memo to be implemented as a plain (but + # growable) array, indexed by memo key. + if self.fast: + return + assert id(obj) not in self.memo + memo_len = len(self.memo) + self.write(self.put(memo_len)) + self.memo[id(obj)] = memo_len, obj + + # Return a PUT (BINPUT, LONG_BINPUT) opcode string, with argument i. + def put(self, i, pack=struct.pack): + if self.bin: + if i < 256: + return BINPUT + chr(i) + else: + return LONG_BINPUT + pack("<i", i) + + return PUT + repr(i) + '\n' + + # Return a GET (BINGET, LONG_BINGET) opcode string, with argument i. + def get(self, i, pack=struct.pack): + if self.bin: + if i < 256: + return BINGET + chr(i) + else: + return LONG_BINGET + pack("<i", i) + + return GET + repr(i) + '\n' + + def save(self, obj): + # Check for persistent id (defined by a subclass) + pid = self.persistent_id(obj) + if pid: + self.save_pers(pid) + return + + # Check the memo + x = self.memo.get(id(obj)) + if x: + self.write(self.get(x[0])) + return + + # Check the type dispatch table + t = type(obj) + f = self.dispatch.get(t) + if f: + f(self, obj) # Call unbound method with explicit self + return + + # Check copy_reg.dispatch_table + reduce = dispatch_table.get(t) + if reduce: + rv = reduce(obj) + else: + # Check for a class with a custom metaclass; treat as regular class + try: + issc = issubclass(t, TypeType) + except TypeError: # t is not a class (old Boost; see SF #502085) + issc = 0 + if issc: + self.save_global(obj) + return + + # Check for a __reduce_ex__ method, fall back to __reduce__ + reduce = getattr(obj, "__reduce_ex__", None) + if reduce: + rv = reduce(self.proto) + else: + reduce = getattr(obj, "__reduce__", None) + if reduce: + rv = reduce() + else: + raise PicklingError("Can't pickle %r object: %r" % + (t.__name__, obj)) + + # Check for string returned by reduce(), meaning "save as global" + if type(rv) is StringType: + self.save_global(obj, rv) + return + + # Assert that reduce() returned a tuple + if type(rv) is not TupleType: + raise PicklingError("%s must return string or tuple" % reduce) + + # Assert that it returned an appropriately sized tuple + l = len(rv) + if not (2 <= l <= 5): + raise PicklingError("Tuple returned by %s must have " + "two to five elements" % reduce) + + # Save the reduce() output and finally memoize the object + self.save_reduce(obj=obj, *rv) + + def persistent_id(self, obj): + # This exists so a subclass can override it + return None + + def save_pers(self, pid): + # Save a persistent id reference + if self.bin: + self.save(pid) + self.write(BINPERSID) + else: + self.write(PERSID + str(pid) + '\n') + + def save_reduce(self, func, args, state=None, + listitems=None, dictitems=None, obj=None): + # This API is called by some subclasses + + # Assert that args is a tuple or None + if not isinstance(args, TupleType): + raise PicklingError("args from reduce() should be a tuple") + + # Assert that func is callable + if not hasattr(func, '__call__'): + raise PicklingError("func from reduce should be callable") + + save = self.save + write = self.write + + # Protocol 2 special case: if func's name is __newobj__, use NEWOBJ + if self.proto >= 2 and getattr(func, "__name__", "") == "__newobj__": + # A __reduce__ implementation can direct protocol 2 to + # use the more efficient NEWOBJ opcode, while still + # allowing protocol 0 and 1 to work normally. For this to + # work, the function returned by __reduce__ should be + # called __newobj__, and its first argument should be a + # new-style class. The implementation for __newobj__ + # should be as follows, although pickle has no way to + # verify this: + # + # def __newobj__(cls, *args): + # return cls.__new__(cls, *args) + # + # Protocols 0 and 1 will pickle a reference to __newobj__, + # while protocol 2 (and above) will pickle a reference to + # cls, the remaining args tuple, and the NEWOBJ code, + # which calls cls.__new__(cls, *args) at unpickling time + # (see load_newobj below). If __reduce__ returns a + # three-tuple, the state from the third tuple item will be + # pickled regardless of the protocol, calling __setstate__ + # at unpickling time (see load_build below). + # + # Note that no standard __newobj__ implementation exists; + # you have to provide your own. This is to enforce + # compatibility with Python 2.2 (pickles written using + # protocol 0 or 1 in Python 2.3 should be unpicklable by + # Python 2.2). + cls = args[0] + if not hasattr(cls, "__new__"): + raise PicklingError( + "args[0] from __newobj__ args has no __new__") + if obj is not None and cls is not obj.__class__: + raise PicklingError( + "args[0] from __newobj__ args has the wrong class") + args = args[1:] + save(cls) + save(args) + write(NEWOBJ) + else: + save(func) + save(args) + write(REDUCE) + + if obj is not None: + self.memoize(obj) + + # More new special cases (that work with older protocols as + # well): when __reduce__ returns a tuple with 4 or 5 items, + # the 4th and 5th item should be iterators that provide list + # items and dict items (as (key, value) tuples), or None. + + if listitems is not None: + self._batch_appends(listitems) + + if dictitems is not None: + self._batch_setitems(dictitems) + + if state is not None: + save(state) + write(BUILD) + + # Methods below this point are dispatched through the dispatch table + + dispatch = {} + + def save_none(self, obj): + self.write(NONE) + dispatch[NoneType] = save_none + + def save_bool(self, obj): + if self.proto >= 2: + self.write(obj and NEWTRUE or NEWFALSE) + else: + self.write(obj and TRUE or FALSE) + dispatch[bool] = save_bool + + def save_int(self, obj, pack=struct.pack): + if self.bin: + # If the int is small enough to fit in a signed 4-byte 2's-comp + # format, we can store it more efficiently than the general + # case. + # First one- and two-byte unsigned ints: + if obj >= 0: + if obj <= 0xff: + self.write(BININT1 + chr(obj)) + return + if obj <= 0xffff: + self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8)) + return + # Next check for 4-byte signed ints: + high_bits = obj >> 31 # note that Python shift sign-extends + if high_bits == 0 or high_bits == -1: + # All high bits are copies of bit 2**31, so the value + # fits in a 4-byte signed int. + self.write(BININT + pack("<i", obj)) + return + # Text pickle, or int too big to fit in signed 4-byte format. + self.write(INT + repr(obj) + '\n') + dispatch[IntType] = save_int + + def save_long(self, obj, pack=struct.pack): + if self.proto >= 2: + bytes = encode_long(obj) + n = len(bytes) + if n < 256: + self.write(LONG1 + chr(n) + bytes) + else: + self.write(LONG4 + pack("<i", n) + bytes) + return + self.write(LONG + repr(obj) + '\n') + dispatch[LongType] = save_long + + def save_float(self, obj, pack=struct.pack): + if self.bin: + self.write(BINFLOAT + pack('>d', obj)) + else: + self.write(FLOAT + repr(obj) + '\n') + dispatch[FloatType] = save_float + + def save_string(self, obj, pack=struct.pack): + if self.bin: + n = len(obj) + if n < 256: + self.write(SHORT_BINSTRING + chr(n) + obj) + else: + self.write(BINSTRING + pack("<i", n) + obj) + else: + self.write(STRING + repr(obj) + '\n') + self.memoize(obj) + dispatch[StringType] = save_string + + def save_unicode(self, obj, pack=struct.pack): + if self.bin: + encoding = obj.encode('utf-8') + n = len(encoding) + self.write(BINUNICODE + pack("<i", n) + encoding) + else: + obj = obj.replace("\\", "\\u005c") + obj = obj.replace("\n", "\\u000a") + self.write(UNICODE + obj.encode('raw-unicode-escape') + '\n') + self.memoize(obj) + dispatch[UnicodeType] = save_unicode + + if StringType is UnicodeType: + # This is true for Jython + def save_string(self, obj, pack=struct.pack): + unicode = obj.isunicode() + + if self.bin: + if unicode: + obj = obj.encode("utf-8") + l = len(obj) + if l < 256 and not unicode: + self.write(SHORT_BINSTRING + chr(l) + obj) + else: + s = pack("<i", l) + if unicode: + self.write(BINUNICODE + s + obj) + else: + self.write(BINSTRING + s + obj) + else: + if unicode: + obj = obj.replace("\\", "\\u005c") + obj = obj.replace("\n", "\\u000a") + obj = obj.encode('raw-unicode-escape') + self.write(UNICODE + obj + '\n') + else: + self.write(STRING + repr(obj) + '\n') + self.memoize(obj) + dispatch[StringType] = save_string + + def save_tuple(self, obj): + write = self.write + proto = self.proto + + n = len(obj) + if n == 0: + if proto: + write(EMPTY_TUPLE) + else: + write(MARK + TUPLE) + return + + save = self.save + memo = self.memo + if n <= 3 and proto >= 2: + for element in obj: + save(element) + # Subtle. Same as in the big comment below. + if id(obj) in memo: + get = self.get(memo[id(obj)][0]) + write(POP * n + get) + else: + write(_tuplesize2code[n]) + self.memoize(obj) + return + + # proto 0 or proto 1 and tuple isn't empty, or proto > 1 and tuple + # has more than 3 elements. + write(MARK) + for element in obj: + save(element) + + if id(obj) in memo: + # Subtle. d was not in memo when we entered save_tuple(), so + # the process of saving the tuple's elements must have saved + # the tuple itself: the tuple is recursive. The proper action + # now is to throw away everything we put on the stack, and + # simply GET the tuple (it's already constructed). This check + # could have been done in the "for element" loop instead, but + # recursive tuples are a rare thing. + get = self.get(memo[id(obj)][0]) + if proto: + write(POP_MARK + get) + else: # proto 0 -- POP_MARK not available + write(POP * (n+1) + get) + return + + # No recursion. + self.write(TUPLE) + self.memoize(obj) + + dispatch[TupleType] = save_tuple + + # save_empty_tuple() isn't used by anything in Python 2.3. However, I + # found a Pickler subclass in Zope3 that calls it, so it's not harmless + # to remove it. + def save_empty_tuple(self, obj): + self.write(EMPTY_TUPLE) + + def save_list(self, obj): + write = self.write + + if self.bin: + write(EMPTY_LIST) + else: # proto 0 -- can't use EMPTY_LIST + write(MARK + LIST) + + self.memoize(obj) + self._batch_appends(iter(obj)) + + dispatch[ListType] = save_list + + # Keep in synch with cPickle's BATCHSIZE. Nothing will break if it gets + # out of synch, though. + _BATCHSIZE = 1000 + + def _batch_appends(self, items): + # Helper to batch up APPENDS sequences + save = self.save + write = self.write + + if not self.bin: + for x in items: + save(x) + write(APPEND) + return + + r = xrange(self._BATCHSIZE) + while items is not None: + tmp = [] + for i in r: + try: + x = items.next() + tmp.append(x) + except StopIteration: + items = None + break + n = len(tmp) + if n > 1: + write(MARK) + for x in tmp: + save(x) + write(APPENDS) + elif n: + save(tmp[0]) + write(APPEND) + # else tmp is empty, and we're done + + def save_dict(self, obj): + write = self.write + + if self.bin: + write(EMPTY_DICT) + else: # proto 0 -- can't use EMPTY_DICT + write(MARK + DICT) + + self.memoize(obj) + self._batch_setitems(obj.iteritems()) + + dispatch[DictionaryType] = save_dict + if not PyStringMap is None: + dispatch[PyStringMap] = save_dict + + def _batch_setitems(self, items): + # Helper to batch up SETITEMS sequences; proto >= 1 only + save = self.save + write = self.write + + if not self.bin: + for k, v in items: + save(k) + save(v) + write(SETITEM) + return + + r = xrange(self._BATCHSIZE) + while items is not None: + tmp = [] + for i in r: + try: + tmp.append(items.next()) + except StopIteration: + items = None + break + n = len(tmp) + if n > 1: + write(MARK) + for k, v in tmp: + save(k) + save(v) + write(SETITEMS) + elif n: + k, v = tmp[0] + save(k) + save(v) + write(SETITEM) + # else tmp is empty, and we're done + + def save_inst(self, obj): + cls = obj.__class__ + + memo = self.memo + write = self.write + save = self.save + + if hasattr(obj, '__getinitargs__'): + args = obj.__getinitargs__() + len(args) # XXX Assert it's a sequence + _keep_alive(args, memo) + else: + args = () + + write(MARK) + + if self.bin: + save(cls) + for arg in args: + save(arg) + write(OBJ) + else: + for arg in args: + save(arg) + write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') + + self.memoize(obj) + + try: + getstate = obj.__getstate__ + except AttributeError: + stuff = obj.__dict__ + else: + stuff = getstate() + _keep_alive(stuff, memo) + save(stuff) + write(BUILD) + + dispatch[InstanceType] = save_inst + + def save_global(self, obj, name=None, pack=struct.pack): + write = self.write + memo = self.memo + + if name is None: + name = obj.__name__ + + module = getattr(obj, "__module__", None) + if module is None: + module = whichmodule(obj, name) + + try: + __import__(module) + mod = sys.modules[module] + klass = getattr(mod, name) + except (ImportError, KeyError, AttributeError): + raise PicklingError( + "Can't pickle %r: it's not found as %s.%s" % + (obj, module, name)) + else: + if klass is not obj: + raise PicklingError( + "Can't pickle %r: it's not the same object as %s.%s" % + (obj, module, name)) + + if self.proto >= 2: + code = _extension_registry.get((module, name)) + if code: + assert code > 0 + if code <= 0xff: + write(EXT1 + chr(code)) + elif code <= 0xffff: + write("%c%c%c" % (EXT2, code&0xff, code>>8)) + else: + write(EXT4 + pack("<i", code)) + return + + write(GLOBAL + module + '\n' + name + '\n') + self.memoize(obj) + + dispatch[ClassType] = save_global + dispatch[FunctionType] = save_global + dispatch[BuiltinFunctionType] = save_global + dispatch[TypeType] = save_global + +# Pickling helpers + +def _keep_alive(x, memo): + """Keeps a reference to the object x in the memo. + + Because we remember objects by their id, we have + to assure that possibly temporary objects are kept + alive by referencing them. + We store a reference at the id of the memo, which should + normally not be used unless someone tries to deepcopy + the memo itself... + """ + try: + memo[id(memo)].append(x) + except KeyError: + # aha, this is the first one :-) + memo[id(memo)]=[x] + + +# A cache for whichmodule(), mapping a function object to the name of +# the module in which the function was found. + +classmap = {} # called classmap for backwards compatibility + +def whichmodule(func, funcname): + """Figure out the module in which a function occurs. + + Search sys.modules for the module. + Cache in classmap. + Return a module name. + If the function cannot be found, return "__main__". + """ + # Python functions should always get an __module__ from their globals. + mod = getattr(func, "__module__", None) + if mod is not None: + return mod + if func in classmap: + return classmap[func] + + for name, module in sys.modules.items(): + if module is None: + continue # skip dummy package entries + if name != '__main__' and getattr(module, funcname, None) is func: + break + else: + name = '__main__' + classmap[func] = name + return name + + +# Unpickling machinery + +class Unpickler: + + def __init__(self, file): + """This takes a file-like object for reading a pickle data stream. + + The protocol version of the pickle is detected automatically, so no + proto argument is needed. + + The file-like object must have two methods, a read() method that + takes an integer argument, and a readline() method that requires no + arguments. Both methods should return a string. Thus file-like + object can be a file object opened for reading, a StringIO object, + or any other custom object that meets this interface. + """ + self.readline = file.readline + self.read = file.read + self.memo = {} + + def load(self): + """Read a pickled object representation from the open file. + + Return the reconstituted object hierarchy specified in the file. + """ + self.mark = object() # any new unique object + self.stack = [] + self.append = self.stack.append + read = self.read + dispatch = self.dispatch + try: + while 1: + key = read(1) + dispatch[key](self) + except _Stop, stopinst: + return stopinst.value + + # Return largest index k such that self.stack[k] is self.mark. + # If the stack doesn't contain a mark, eventually raises IndexError. + # This could be sped by maintaining another stack, of indices at which + # the mark appears. For that matter, the latter stack would suffice, + # and we wouldn't need to push mark objects on self.stack at all. + # Doing so is probably a good thing, though, since if the pickle is + # corrupt (or hostile) we may get a clue from finding self.mark embedded + # in unpickled objects. + def marker(self): + stack = self.stack + mark = self.mark + k = len(stack)-1 + while stack[k] is not mark: k = k-1 + return k + + dispatch = {} + + def load_eof(self): + raise EOFError + dispatch[''] = load_eof + + def load_proto(self): + proto = ord(self.read(1)) + if not 0 <= proto <= 2: + raise ValueError, "unsupported pickle protocol: %d" % proto + dispatch[PROTO] = load_proto + + def load_persid(self): + pid = self.readline()[:-1] + self.append(self.persistent_load(pid)) + dispatch[PERSID] = load_persid + + def load_binpersid(self): + pid = self.stack.pop() + self.append(self.persistent_load(pid)) + dispatch[BINPERSID] = load_binpersid + + def load_none(self): + self.append(None) + dispatch[NONE] = load_none + + def load_false(self): + self.append(False) + dispatch[NEWFALSE] = load_false + + def load_true(self): + self.append(True) + dispatch[NEWTRUE] = load_true + + def load_int(self): + data = self.readline() + if data == FALSE[1:]: + val = False + elif data == TRUE[1:]: + val = True + else: + try: + val = int(data) + except ValueError: + val = long(data) + self.append(val) + dispatch[INT] = load_int + + def load_binint(self): + self.append(mloads('i' + self.read(4))) + dispatch[BININT] = load_binint + + def load_binint1(self): + self.append(ord(self.read(1))) + dispatch[BININT1] = load_binint1 + + def load_binint2(self): + self.append(mloads('i' + self.read(2) + '\000\000')) + dispatch[BININT2] = load_binint2 + + def load_long(self): + self.append(long(self.readline()[:-1], 0)) + dispatch[LONG] = load_long + + def load_long1(self): + n = ord(self.read(1)) + bytes = self.read(n) + self.append(decode_long(bytes)) + dispatch[LONG1] = load_long1 + + def load_long4(self): + n = mloads('i' + self.read(4)) + bytes = self.read(n) + self.append(decode_long(bytes)) + dispatch[LONG4] = load_long4 + + def load_float(self): + self.append(float(self.readline()[:-1])) + dispatch[FLOAT] = load_float + + def load_binfloat(self, unpack=struct.unpack): + self.append(unpack('>d', self.read(8))[0]) + dispatch[BINFLOAT] = load_binfloat + + def load_string(self): + rep = self.readline()[:-1] + for q in "\"'": # double or single quote + if rep.startswith(q): + if not rep.endswith(q): + raise ValueError, "insecure string pickle" + rep = rep[len(q):-len(q)] + break + else: + raise ValueError, "insecure string pickle" + self.append(rep.decode("string-escape")) + dispatch[STRING] = load_string + + def load_binstring(self): + len = mloads('i' + self.read(4)) + self.append(self.read(len)) + dispatch[BINSTRING] = load_binstring + + def load_unicode(self): + self.append(unicode(self.readline()[:-1],'raw-unicode-escape')) + dispatch[UNICODE] = load_unicode + + def load_binunicode(self): + len = mloads('i' + self.read(4)) + self.append(unicode(self.read(len),'utf-8')) + dispatch[BINUNICODE] = load_binunicode + + def load_short_binstring(self): + len = ord(self.read(1)) + self.append(self.read(len)) + dispatch[SHORT_BINSTRING] = load_short_binstring + + def load_tuple(self): + k = self.marker() + self.stack[k:] = [tuple(self.stack[k+1:])] + dispatch[TUPLE] = load_tuple + + def load_empty_tuple(self): + self.stack.append(()) + dispatch[EMPTY_TUPLE] = load_empty_tuple + + def load_tuple1(self): + self.stack[-1] = (self.stack[-1],) + dispatch[TUPLE1] = load_tuple1 + + def load_tuple2(self): + self.stack[-2:] = [(self.stack[-2], self.stack[-1])] + dispatch[TUPLE2] = load_tuple2 + + def load_tuple3(self): + self.stack[-3:] = [(self.stack[-3], self.stack[-2], self.stack[-1])] + dispatch[TUPLE3] = load_tuple3 + + def load_empty_list(self): + self.stack.append([]) + dispatch[EMPTY_LIST] = load_empty_list + + def load_empty_dictionary(self): + self.stack.append({}) + dispatch[EMPTY_DICT] = load_empty_dictionary + + def load_list(self): + k = self.marker() + self.stack[k:] = [self.stack[k+1:]] + dispatch[LIST] = load_list + + def load_dict(self): + k = self.marker() + d = {} + items = self.stack[k+1:] + for i in range(0, len(items), 2): + key = items[i] + value = items[i+1] + d[key] = value + self.stack[k:] = [d] + dispatch[DICT] = load_dict + + # INST and OBJ differ only in how they get a class object. It's not + # only sensible to do the rest in a common routine, the two routines + # previously diverged and grew different bugs. + # klass is the class to instantiate, and k points to the topmost mark + # object, following which are the arguments for klass.__init__. + def _instantiate(self, klass, k): + args = tuple(self.stack[k+1:]) + del self.stack[k:] + instantiated = 0 + if (not args and + type(klass) is ClassType and + not hasattr(klass, "__getinitargs__")): + try: + value = _EmptyClass() + value.__class__ = klass + instantiated = 1 + except RuntimeError: + # In restricted execution, assignment to inst.__class__ is + # prohibited + pass + if not instantiated: + try: + value = klass(*args) + except TypeError, err: + raise TypeError, "in constructor for %s: %s" % ( + klass.__name__, str(err)), sys.exc_info()[2] + self.append(value) + + def load_inst(self): + module = self.readline()[:-1] + name = self.readline()[:-1] + klass = self.find_class(module, name) + self._instantiate(klass, self.marker()) + dispatch[INST] = load_inst + + def load_obj(self): + # Stack is ... markobject classobject arg1 arg2 ... + k = self.marker() + klass = self.stack.pop(k+1) + self._instantiate(klass, k) + dispatch[OBJ] = load_obj + + def load_newobj(self): + args = self.stack.pop() + cls = self.stack[-1] + obj = cls.__new__(cls, *args) + self.stack[-1] = obj + dispatch[NEWOBJ] = load_newobj + + def load_global(self): + module = self.readline()[:-1] + name = self.readline()[:-1] + klass = self.find_class(module, name) + self.append(klass) + dispatch[GLOBAL] = load_global + + def load_ext1(self): + code = ord(self.read(1)) + self.get_extension(code) + dispatch[EXT1] = load_ext1 + + def load_ext2(self): + code = mloads('i' + self.read(2) + '\000\000') + self.get_extension(code) + dispatch[EXT2] = load_ext2 + + def load_ext4(self): + code = mloads('i' + self.read(4)) + self.get_extension(code) + dispatch[EXT4] = load_ext4 + + def get_extension(self, code): + nil = [] + obj = _extension_cache.get(code, nil) + if obj is not nil: + self.append(obj) + return + key = _inverted_registry.get(code) + if not key: + raise ValueError("unregistered extension code %d" % code) + obj = self.find_class(*key) + _extension_cache[code] = obj + self.append(obj) + + def find_class(self, module, name): + # Subclasses may override this + __import__(module) + mod = sys.modules[module] + klass = getattr(mod, name) + return klass + + def load_reduce(self): + stack = self.stack + args = stack.pop() + func = stack[-1] + value = func(*args) + stack[-1] = value + dispatch[REDUCE] = load_reduce + + def load_pop(self): + del self.stack[-1] + dispatch[POP] = load_pop + + def load_pop_mark(self): + k = self.marker() + del self.stack[k:] + dispatch[POP_MARK] = load_pop_mark + + def load_dup(self): + self.append(self.stack[-1]) + dispatch[DUP] = load_dup + + def load_get(self): + self.append(self.memo[self.readline()[:-1]]) + dispatch[GET] = load_get + + def load_binget(self): + i = ord(self.read(1)) + self.append(self.memo[repr(i)]) + dispatch[BINGET] = load_binget + + def load_long_binget(self): + i = mloads('i' + self.read(4)) + self.append(self.memo[repr(i)]) + dispatch[LONG_BINGET] = load_long_binget + + def load_put(self): + self.memo[self.readline()[:-1]] = self.stack[-1] + dispatch[PUT] = load_put + + def load_binput(self): + i = ord(self.read(1)) + self.memo[repr(i)] = self.stack[-1] + dispatch[BINPUT] = load_binput + + def load_long_binput(self): + i = mloads('i' + self.read(4)) + self.memo[repr(i)] = self.stack[-1] + dispatch[LONG_BINPUT] = load_long_binput + + def load_append(self): + stack = self.stack + value = stack.pop() + list = stack[-1] + list.append(value) + dispatch[APPEND] = load_append + + def load_appends(self): + stack = self.stack + mark = self.marker() + list = stack[mark - 1] + list.extend(stack[mark + 1:]) + del stack[mark:] + dispatch[APPENDS] = load_appends + + def load_setitem(self): + stack = self.stack + value = stack.pop() + key = stack.pop() + dict = stack[-1] + dict[key] = value + dispatch[SETITEM] = load_setitem + + def load_setitems(self): + stack = self.stack + mark = self.marker() + dict = stack[mark - 1] + for i in range(mark + 1, len(stack), 2): + dict[stack[i]] = stack[i + 1] + + del stack[mark:] + dispatch[SETITEMS] = load_setitems + + def load_build(self): + stack = self.stack + state = stack.pop() + inst = stack[-1] + setstate = getattr(inst, "__setstate__", None) + if setstate: + setstate(state) + return + slotstate = None + if isinstance(state, tuple) and len(state) == 2: + state, slotstate = state + if state: + try: + d = inst.__dict__ + try: + for k, v in state.iteritems(): + d[intern(k)] = v + # keys in state don't have to be strings + # don't blow up, but don't go out of our way + except TypeError: + d.update(state) + + except RuntimeError: + # XXX In restricted execution, the instance's __dict__ + # is not accessible. Use the old way of unpickling + # the instance variables. This is a semantic + # difference when unpickling in restricted + # vs. unrestricted modes. + # Note, however, that cPickle has never tried to do the + # .update() business, and always uses + # PyObject_SetItem(inst.__dict__, key, value) in a + # loop over state.items(). + for k, v in state.items(): + setattr(inst, k, v) + if slotstate: + for k, v in slotstate.items(): + setattr(inst, k, v) + dispatch[BUILD] = load_build + + def load_mark(self): + self.append(self.mark) + dispatch[MARK] = load_mark + + def load_stop(self): + value = self.stack.pop() + raise _Stop(value) + dispatch[STOP] = load_stop + +# Helper class for load_inst/load_obj + +class _EmptyClass: + pass + +# Encode/decode longs in linear time. + +import binascii as _binascii + +def encode_long(x): + r"""Encode a long to a two's complement little-endian binary string. + Note that 0L is a special case, returning an empty string, to save a + byte in the LONG1 pickling context. + + >>> encode_long(0L) + '' + >>> encode_long(255L) + '\xff\x00' + >>> encode_long(32767L) + '\xff\x7f' + >>> encode_long(-256L) + '\x00\xff' + >>> encode_long(-32768L) + '\x00\x80' + >>> encode_long(-128L) + '\x80' + >>> encode_long(127L) + '\x7f' + >>> + """ + + if x == 0: + return '' + if x > 0: + ashex = hex(x) + assert ashex.startswith("0x") + njunkchars = 2 + ashex.endswith('L') + nibbles = len(ashex) - njunkchars + if nibbles & 1: + # need an even # of nibbles for unhexlify + ashex = "0x0" + ashex[2:] + elif int(ashex[2], 16) >= 8: + # "looks negative", so need a byte of sign bits + ashex = "0x00" + ashex[2:] + else: + # Build the 256's-complement: (1L << nbytes) + x. The trick is + # to find the number of bytes in linear time (although that should + # really be a constant-time task). + ashex = hex(-x) + assert ashex.startswith("0x") + njunkchars = 2 + ashex.endswith('L') + nibbles = len(ashex) - njunkchars + if nibbles & 1: + # Extend to a full byte. + nibbles += 1 + nbits = nibbles * 4 + x += 1L << nbits + assert x > 0 + ashex = hex(x) + njunkchars = 2 + ashex.endswith('L') + newnibbles = len(ashex) - njunkchars + if newnibbles < nibbles: + ashex = "0x" + "0" * (nibbles - newnibbles) + ashex[2:] + if int(ashex[2], 16) < 8: + # "looks positive", so need a byte of sign bits + ashex = "0xff" + ashex[2:] + + if ashex.endswith('L'): + ashex = ashex[2:-1] + else: + ashex = ashex[2:] + assert len(ashex) & 1 == 0, (x, ashex) + binary = _binascii.unhexlify(ashex) + return binary[::-1] + +def decode_long(data): + r"""Decode a long from a two's complement little-endian binary string. + + >>> decode_long('') + 0L + >>> decode_long("\xff\x00") + 255L + >>> decode_long("\xff\x7f") + 32767L + >>> decode_long("\x00\xff") + -256L + >>> decode_long("\x00\x80") + -32768L + >>> decode_long("\x80") + -128L + >>> decode_long("\x7f") + 127L + """ + + nbytes = len(data) + if nbytes == 0: + return 0L + ashex = _binascii.hexlify(data[::-1]) + n = long(ashex, 16) # quadratic time before Python 2.3; linear now + if data[-1] >= '\x80': + n -= 1L << (nbytes * 8) + return n + +# Shorthands + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +def dump(obj, file, protocol=None): + Pickler(file, protocol).dump(obj) + +def dumps(obj, protocol=None): + file = StringIO() + Pickler(file, protocol).dump(obj) + return file.getvalue() + +def load(file): + return Unpickler(file).load() + +def loads(str): + file = StringIO(str) + return Unpickler(file).load() + +# Doctest + +def _test(): + import doctest + return doctest.testmod() + +if __name__ == "__main__": + _test() diff --git a/src/main/resources/PythonLibs/pickletools.py b/src/main/resources/PythonLibs/pickletools.py new file mode 100644 index 0000000000000000000000000000000000000000..d717728d417811a7943ee05a5c536d420b691010 --- /dev/null +++ b/src/main/resources/PythonLibs/pickletools.py @@ -0,0 +1,2274 @@ +'''"Executable documentation" for the pickle module. + +Extensive comments about the pickle protocols and pickle-machine opcodes +can be found here. Some functions meant for external use: + +genops(pickle) + Generate all the opcodes in a pickle, as (opcode, arg, position) triples. + +dis(pickle, out=None, memo=None, indentlevel=4) + Print a symbolic disassembly of a pickle. +''' + +__all__ = ['dis', 'genops', 'optimize'] + +# Other ideas: +# +# - A pickle verifier: read a pickle and check it exhaustively for +# well-formedness. dis() does a lot of this already. +# +# - A protocol identifier: examine a pickle and return its protocol number +# (== the highest .proto attr value among all the opcodes in the pickle). +# dis() already prints this info at the end. +# +# - A pickle optimizer: for example, tuple-building code is sometimes more +# elaborate than necessary, catering for the possibility that the tuple +# is recursive. Or lots of times a PUT is generated that's never accessed +# by a later GET. + + +""" +"A pickle" is a program for a virtual pickle machine (PM, but more accurately +called an unpickling machine). It's a sequence of opcodes, interpreted by the +PM, building an arbitrarily complex Python object. + +For the most part, the PM is very simple: there are no looping, testing, or +conditional instructions, no arithmetic and no function calls. Opcodes are +executed once each, from first to last, until a STOP opcode is reached. + +The PM has two data areas, "the stack" and "the memo". + +Many opcodes push Python objects onto the stack; e.g., INT pushes a Python +integer object on the stack, whose value is gotten from a decimal string +literal immediately following the INT opcode in the pickle bytestream. Other +opcodes take Python objects off the stack. The result of unpickling is +whatever object is left on the stack when the final STOP opcode is executed. + +The memo is simply an array of objects, or it can be implemented as a dict +mapping little integers to objects. The memo serves as the PM's "long term +memory", and the little integers indexing the memo are akin to variable +names. Some opcodes pop a stack object into the memo at a given index, +and others push a memo object at a given index onto the stack again. + +At heart, that's all the PM has. Subtleties arise for these reasons: + ++ Object identity. Objects can be arbitrarily complex, and subobjects + may be shared (for example, the list [a, a] refers to the same object a + twice). It can be vital that unpickling recreate an isomorphic object + graph, faithfully reproducing sharing. + ++ Recursive objects. For example, after "L = []; L.append(L)", L is a + list, and L[0] is the same list. This is related to the object identity + point, and some sequences of pickle opcodes are subtle in order to + get the right result in all cases. + ++ Things pickle doesn't know everything about. Examples of things pickle + does know everything about are Python's builtin scalar and container + types, like ints and tuples. They generally have opcodes dedicated to + them. For things like module references and instances of user-defined + classes, pickle's knowledge is limited. Historically, many enhancements + have been made to the pickle protocol in order to do a better (faster, + and/or more compact) job on those. + ++ Backward compatibility and micro-optimization. As explained below, + pickle opcodes never go away, not even when better ways to do a thing + get invented. The repertoire of the PM just keeps growing over time. + For example, protocol 0 had two opcodes for building Python integers (INT + and LONG), protocol 1 added three more for more-efficient pickling of short + integers, and protocol 2 added two more for more-efficient pickling of + long integers (before protocol 2, the only ways to pickle a Python long + took time quadratic in the number of digits, for both pickling and + unpickling). "Opcode bloat" isn't so much a subtlety as a source of + wearying complication. + + +Pickle protocols: + +For compatibility, the meaning of a pickle opcode never changes. Instead new +pickle opcodes get added, and each version's unpickler can handle all the +pickle opcodes in all protocol versions to date. So old pickles continue to +be readable forever. The pickler can generally be told to restrict itself to +the subset of opcodes available under previous protocol versions too, so that +users can create pickles under the current version readable by older +versions. However, a pickle does not contain its version number embedded +within it. If an older unpickler tries to read a pickle using a later +protocol, the result is most likely an exception due to seeing an unknown (in +the older unpickler) opcode. + +The original pickle used what's now called "protocol 0", and what was called +"text mode" before Python 2.3. The entire pickle bytestream is made up of +printable 7-bit ASCII characters, plus the newline character, in protocol 0. +That's why it was called text mode. Protocol 0 is small and elegant, but +sometimes painfully inefficient. + +The second major set of additions is now called "protocol 1", and was called +"binary mode" before Python 2.3. This added many opcodes with arguments +consisting of arbitrary bytes, including NUL bytes and unprintable "high bit" +bytes. Binary mode pickles can be substantially smaller than equivalent +text mode pickles, and sometimes faster too; e.g., BININT represents a 4-byte +int as 4 bytes following the opcode, which is cheaper to unpickle than the +(perhaps) 11-character decimal string attached to INT. Protocol 1 also added +a number of opcodes that operate on many stack elements at once (like APPENDS +and SETITEMS), and "shortcut" opcodes (like EMPTY_DICT and EMPTY_TUPLE). + +The third major set of additions came in Python 2.3, and is called "protocol +2". This added: + +- A better way to pickle instances of new-style classes (NEWOBJ). + +- A way for a pickle to identify its protocol (PROTO). + +- Time- and space- efficient pickling of long ints (LONG{1,4}). + +- Shortcuts for small tuples (TUPLE{1,2,3}}. + +- Dedicated opcodes for bools (NEWTRUE, NEWFALSE). + +- The "extension registry", a vector of popular objects that can be pushed + efficiently by index (EXT{1,2,4}). This is akin to the memo and GET, but + the registry contents are predefined (there's nothing akin to the memo's + PUT). + +Another independent change with Python 2.3 is the abandonment of any +pretense that it might be safe to load pickles received from untrusted +parties -- no sufficient security analysis has been done to guarantee +this and there isn't a use case that warrants the expense of such an +analysis. + +To this end, all tests for __safe_for_unpickling__ or for +copy_reg.safe_constructors are removed from the unpickling code. +References to these variables in the descriptions below are to be seen +as describing unpickling in Python 2.2 and before. +""" + +# Meta-rule: Descriptions are stored in instances of descriptor objects, +# with plain constructors. No meta-language is defined from which +# descriptors could be constructed. If you want, e.g., XML, write a little +# program to generate XML from the objects. + +############################################################################## +# Some pickle opcodes have an argument, following the opcode in the +# bytestream. An argument is of a specific type, described by an instance +# of ArgumentDescriptor. These are not to be confused with arguments taken +# off the stack -- ArgumentDescriptor applies only to arguments embedded in +# the opcode stream, immediately following an opcode. + +# Represents the number of bytes consumed by an argument delimited by the +# next newline character. +UP_TO_NEWLINE = -1 + +# Represents the number of bytes consumed by a two-argument opcode where +# the first argument gives the number of bytes in the second argument. +TAKEN_FROM_ARGUMENT1 = -2 # num bytes is 1-byte unsigned int +TAKEN_FROM_ARGUMENT4 = -3 # num bytes is 4-byte signed little-endian int + +class ArgumentDescriptor(object): + __slots__ = ( + # name of descriptor record, also a module global name; a string + 'name', + + # length of argument, in bytes; an int; UP_TO_NEWLINE and + # TAKEN_FROM_ARGUMENT{1,4} are negative values for variable-length + # cases + 'n', + + # a function taking a file-like object, reading this kind of argument + # from the object at the current position, advancing the current + # position by n bytes, and returning the value of the argument + 'reader', + + # human-readable docs for this arg descriptor; a string + 'doc', + ) + + def __init__(self, name, n, reader, doc): + assert isinstance(name, str) + self.name = name + + assert isinstance(n, int) and (n >= 0 or + n in (UP_TO_NEWLINE, + TAKEN_FROM_ARGUMENT1, + TAKEN_FROM_ARGUMENT4)) + self.n = n + + self.reader = reader + + assert isinstance(doc, str) + self.doc = doc + +from struct import unpack as _unpack + +def read_uint1(f): + r""" + >>> import StringIO + >>> read_uint1(StringIO.StringIO('\xff')) + 255 + """ + + data = f.read(1) + if data: + return ord(data) + raise ValueError("not enough data in stream to read uint1") + +uint1 = ArgumentDescriptor( + name='uint1', + n=1, + reader=read_uint1, + doc="One-byte unsigned integer.") + + +def read_uint2(f): + r""" + >>> import StringIO + >>> read_uint2(StringIO.StringIO('\xff\x00')) + 255 + >>> read_uint2(StringIO.StringIO('\xff\xff')) + 65535 + """ + + data = f.read(2) + if len(data) == 2: + return _unpack("<H", data)[0] + raise ValueError("not enough data in stream to read uint2") + +uint2 = ArgumentDescriptor( + name='uint2', + n=2, + reader=read_uint2, + doc="Two-byte unsigned integer, little-endian.") + + +def read_int4(f): + r""" + >>> import StringIO + >>> read_int4(StringIO.StringIO('\xff\x00\x00\x00')) + 255 + >>> read_int4(StringIO.StringIO('\x00\x00\x00\x80')) == -(2**31) + True + """ + + data = f.read(4) + if len(data) == 4: + return _unpack("<i", data)[0] + raise ValueError("not enough data in stream to read int4") + +int4 = ArgumentDescriptor( + name='int4', + n=4, + reader=read_int4, + doc="Four-byte signed integer, little-endian, 2's complement.") + + +def read_stringnl(f, decode=True, stripquotes=True): + r""" + >>> import StringIO + >>> read_stringnl(StringIO.StringIO("'abcd'\nefg\n")) + 'abcd' + + >>> read_stringnl(StringIO.StringIO("\n")) + Traceback (most recent call last): + ... + ValueError: no string quotes around '' + + >>> read_stringnl(StringIO.StringIO("\n"), stripquotes=False) + '' + + >>> read_stringnl(StringIO.StringIO("''\n")) + '' + + >>> read_stringnl(StringIO.StringIO('"abcd"')) + Traceback (most recent call last): + ... + ValueError: no newline found when trying to read stringnl + + Embedded escapes are undone in the result. + >>> read_stringnl(StringIO.StringIO(r"'a\n\\b\x00c\td'" + "\n'e'")) + 'a\n\\b\x00c\td' + """ + + data = f.readline() + if not data.endswith('\n'): + raise ValueError("no newline found when trying to read stringnl") + data = data[:-1] # lose the newline + + if stripquotes: + for q in "'\"": + if data.startswith(q): + if not data.endswith(q): + raise ValueError("strinq quote %r not found at both " + "ends of %r" % (q, data)) + data = data[1:-1] + break + else: + raise ValueError("no string quotes around %r" % data) + + # I'm not sure when 'string_escape' was added to the std codecs; it's + # crazy not to use it if it's there. + if decode: + data = data.decode('string_escape') + return data + +stringnl = ArgumentDescriptor( + name='stringnl', + n=UP_TO_NEWLINE, + reader=read_stringnl, + doc="""A newline-terminated string. + + This is a repr-style string, with embedded escapes, and + bracketing quotes. + """) + +def read_stringnl_noescape(f): + return read_stringnl(f, decode=False, stripquotes=False) + +stringnl_noescape = ArgumentDescriptor( + name='stringnl_noescape', + n=UP_TO_NEWLINE, + reader=read_stringnl_noescape, + doc="""A newline-terminated string. + + This is a str-style string, without embedded escapes, + or bracketing quotes. It should consist solely of + printable ASCII characters. + """) + +def read_stringnl_noescape_pair(f): + r""" + >>> import StringIO + >>> read_stringnl_noescape_pair(StringIO.StringIO("Queue\nEmpty\njunk")) + 'Queue Empty' + """ + + return "%s %s" % (read_stringnl_noescape(f), read_stringnl_noescape(f)) + +stringnl_noescape_pair = ArgumentDescriptor( + name='stringnl_noescape_pair', + n=UP_TO_NEWLINE, + reader=read_stringnl_noescape_pair, + doc="""A pair of newline-terminated strings. + + These are str-style strings, without embedded + escapes, or bracketing quotes. They should + consist solely of printable ASCII characters. + The pair is returned as a single string, with + a single blank separating the two strings. + """) + +def read_string4(f): + r""" + >>> import StringIO + >>> read_string4(StringIO.StringIO("\x00\x00\x00\x00abc")) + '' + >>> read_string4(StringIO.StringIO("\x03\x00\x00\x00abcdef")) + 'abc' + >>> read_string4(StringIO.StringIO("\x00\x00\x00\x03abcdef")) + Traceback (most recent call last): + ... + ValueError: expected 50331648 bytes in a string4, but only 6 remain + """ + + n = read_int4(f) + if n < 0: + raise ValueError("string4 byte count < 0: %d" % n) + data = f.read(n) + if len(data) == n: + return data + raise ValueError("expected %d bytes in a string4, but only %d remain" % + (n, len(data))) + +string4 = ArgumentDescriptor( + name="string4", + n=TAKEN_FROM_ARGUMENT4, + reader=read_string4, + doc="""A counted string. + + The first argument is a 4-byte little-endian signed int giving + the number of bytes in the string, and the second argument is + that many bytes. + """) + + +def read_string1(f): + r""" + >>> import StringIO + >>> read_string1(StringIO.StringIO("\x00")) + '' + >>> read_string1(StringIO.StringIO("\x03abcdef")) + 'abc' + """ + + n = read_uint1(f) + assert n >= 0 + data = f.read(n) + if len(data) == n: + return data + raise ValueError("expected %d bytes in a string1, but only %d remain" % + (n, len(data))) + +string1 = ArgumentDescriptor( + name="string1", + n=TAKEN_FROM_ARGUMENT1, + reader=read_string1, + doc="""A counted string. + + The first argument is a 1-byte unsigned int giving the number + of bytes in the string, and the second argument is that many + bytes. + """) + + +def read_unicodestringnl(f): + r""" + >>> import StringIO + >>> read_unicodestringnl(StringIO.StringIO("abc\uabcd\njunk")) + u'abc\uabcd' + """ + + data = f.readline() + if not data.endswith('\n'): + raise ValueError("no newline found when trying to read " + "unicodestringnl") + data = data[:-1] # lose the newline + return unicode(data, 'raw-unicode-escape') + +unicodestringnl = ArgumentDescriptor( + name='unicodestringnl', + n=UP_TO_NEWLINE, + reader=read_unicodestringnl, + doc="""A newline-terminated Unicode string. + + This is raw-unicode-escape encoded, so consists of + printable ASCII characters, and may contain embedded + escape sequences. + """) + +def read_unicodestring4(f): + r""" + >>> import StringIO + >>> s = u'abcd\uabcd' + >>> enc = s.encode('utf-8') + >>> enc + 'abcd\xea\xaf\x8d' + >>> n = chr(len(enc)) + chr(0) * 3 # little-endian 4-byte length + >>> t = read_unicodestring4(StringIO.StringIO(n + enc + 'junk')) + >>> s == t + True + + >>> read_unicodestring4(StringIO.StringIO(n + enc[:-1])) + Traceback (most recent call last): + ... + ValueError: expected 7 bytes in a unicodestring4, but only 6 remain + """ + + n = read_int4(f) + if n < 0: + raise ValueError("unicodestring4 byte count < 0: %d" % n) + data = f.read(n) + if len(data) == n: + return unicode(data, 'utf-8') + raise ValueError("expected %d bytes in a unicodestring4, but only %d " + "remain" % (n, len(data))) + +unicodestring4 = ArgumentDescriptor( + name="unicodestring4", + n=TAKEN_FROM_ARGUMENT4, + reader=read_unicodestring4, + doc="""A counted Unicode string. + + The first argument is a 4-byte little-endian signed int + giving the number of bytes in the string, and the second + argument-- the UTF-8 encoding of the Unicode string -- + contains that many bytes. + """) + + +def read_decimalnl_short(f): + r""" + >>> import StringIO + >>> read_decimalnl_short(StringIO.StringIO("1234\n56")) + 1234 + + >>> read_decimalnl_short(StringIO.StringIO("1234L\n56")) + Traceback (most recent call last): + ... + ValueError: trailing 'L' not allowed in '1234L' + """ + + s = read_stringnl(f, decode=False, stripquotes=False) + if s.endswith("L"): + raise ValueError("trailing 'L' not allowed in %r" % s) + + # It's not necessarily true that the result fits in a Python short int: + # the pickle may have been written on a 64-bit box. There's also a hack + # for True and False here. + if s == "00": + return False + elif s == "01": + return True + + try: + return int(s) + except OverflowError: + return long(s) + +def read_decimalnl_long(f): + r""" + >>> import StringIO + + >>> read_decimalnl_long(StringIO.StringIO("1234\n56")) + Traceback (most recent call last): + ... + ValueError: trailing 'L' required in '1234' + + Someday the trailing 'L' will probably go away from this output. + + >>> read_decimalnl_long(StringIO.StringIO("1234L\n56")) + 1234L + + >>> read_decimalnl_long(StringIO.StringIO("123456789012345678901234L\n6")) + 123456789012345678901234L + """ + + s = read_stringnl(f, decode=False, stripquotes=False) + if not s.endswith("L"): + raise ValueError("trailing 'L' required in %r" % s) + return long(s) + + +decimalnl_short = ArgumentDescriptor( + name='decimalnl_short', + n=UP_TO_NEWLINE, + reader=read_decimalnl_short, + doc="""A newline-terminated decimal integer literal. + + This never has a trailing 'L', and the integer fit + in a short Python int on the box where the pickle + was written -- but there's no guarantee it will fit + in a short Python int on the box where the pickle + is read. + """) + +decimalnl_long = ArgumentDescriptor( + name='decimalnl_long', + n=UP_TO_NEWLINE, + reader=read_decimalnl_long, + doc="""A newline-terminated decimal integer literal. + + This has a trailing 'L', and can represent integers + of any size. + """) + + +def read_floatnl(f): + r""" + >>> import StringIO + >>> read_floatnl(StringIO.StringIO("-1.25\n6")) + -1.25 + """ + s = read_stringnl(f, decode=False, stripquotes=False) + return float(s) + +floatnl = ArgumentDescriptor( + name='floatnl', + n=UP_TO_NEWLINE, + reader=read_floatnl, + doc="""A newline-terminated decimal floating literal. + + In general this requires 17 significant digits for roundtrip + identity, and pickling then unpickling infinities, NaNs, and + minus zero doesn't work across boxes, or on some boxes even + on itself (e.g., Windows can't read the strings it produces + for infinities or NaNs). + """) + +def read_float8(f): + r""" + >>> import StringIO, struct + >>> raw = struct.pack(">d", -1.25) + >>> raw + '\xbf\xf4\x00\x00\x00\x00\x00\x00' + >>> read_float8(StringIO.StringIO(raw + "\n")) + -1.25 + """ + + data = f.read(8) + if len(data) == 8: + return _unpack(">d", data)[0] + raise ValueError("not enough data in stream to read float8") + + +float8 = ArgumentDescriptor( + name='float8', + n=8, + reader=read_float8, + doc="""An 8-byte binary representation of a float, big-endian. + + The format is unique to Python, and shared with the struct + module (format string '>d') "in theory" (the struct and cPickle + implementations don't share the code -- they should). It's + strongly related to the IEEE-754 double format, and, in normal + cases, is in fact identical to the big-endian 754 double format. + On other boxes the dynamic range is limited to that of a 754 + double, and "add a half and chop" rounding is used to reduce + the precision to 53 bits. However, even on a 754 box, + infinities, NaNs, and minus zero may not be handled correctly + (may not survive roundtrip pickling intact). + """) + +# Protocol 2 formats + +from pickle import decode_long + +def read_long1(f): + r""" + >>> import StringIO + >>> read_long1(StringIO.StringIO("\x00")) + 0L + >>> read_long1(StringIO.StringIO("\x02\xff\x00")) + 255L + >>> read_long1(StringIO.StringIO("\x02\xff\x7f")) + 32767L + >>> read_long1(StringIO.StringIO("\x02\x00\xff")) + -256L + >>> read_long1(StringIO.StringIO("\x02\x00\x80")) + -32768L + """ + + n = read_uint1(f) + data = f.read(n) + if len(data) != n: + raise ValueError("not enough data in stream to read long1") + return decode_long(data) + +long1 = ArgumentDescriptor( + name="long1", + n=TAKEN_FROM_ARGUMENT1, + reader=read_long1, + doc="""A binary long, little-endian, using 1-byte size. + + This first reads one byte as an unsigned size, then reads that + many bytes and interprets them as a little-endian 2's-complement long. + If the size is 0, that's taken as a shortcut for the long 0L. + """) + +def read_long4(f): + r""" + >>> import StringIO + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\xff\x00")) + 255L + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\xff\x7f")) + 32767L + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\xff")) + -256L + >>> read_long4(StringIO.StringIO("\x02\x00\x00\x00\x00\x80")) + -32768L + >>> read_long1(StringIO.StringIO("\x00\x00\x00\x00")) + 0L + """ + + n = read_int4(f) + if n < 0: + raise ValueError("long4 byte count < 0: %d" % n) + data = f.read(n) + if len(data) != n: + raise ValueError("not enough data in stream to read long4") + return decode_long(data) + +long4 = ArgumentDescriptor( + name="long4", + n=TAKEN_FROM_ARGUMENT4, + reader=read_long4, + doc="""A binary representation of a long, little-endian. + + This first reads four bytes as a signed size (but requires the + size to be >= 0), then reads that many bytes and interprets them + as a little-endian 2's-complement long. If the size is 0, that's taken + as a shortcut for the long 0L, although LONG1 should really be used + then instead (and in any case where # of bytes < 256). + """) + + +############################################################################## +# Object descriptors. The stack used by the pickle machine holds objects, +# and in the stack_before and stack_after attributes of OpcodeInfo +# descriptors we need names to describe the various types of objects that can +# appear on the stack. + +class StackObject(object): + __slots__ = ( + # name of descriptor record, for info only + 'name', + + # type of object, or tuple of type objects (meaning the object can + # be of any type in the tuple) + 'obtype', + + # human-readable docs for this kind of stack object; a string + 'doc', + ) + + def __init__(self, name, obtype, doc): + assert isinstance(name, str) + self.name = name + + assert isinstance(obtype, type) or isinstance(obtype, tuple) + if isinstance(obtype, tuple): + for contained in obtype: + assert isinstance(contained, type) + self.obtype = obtype + + assert isinstance(doc, str) + self.doc = doc + + def __repr__(self): + return self.name + + +pyint = StackObject( + name='int', + obtype=int, + doc="A short (as opposed to long) Python integer object.") + +pylong = StackObject( + name='long', + obtype=long, + doc="A long (as opposed to short) Python integer object.") + +pyinteger_or_bool = StackObject( + name='int_or_bool', + obtype=(int, long, bool), + doc="A Python integer object (short or long), or " + "a Python bool.") + +pybool = StackObject( + name='bool', + obtype=(bool,), + doc="A Python bool object.") + +pyfloat = StackObject( + name='float', + obtype=float, + doc="A Python float object.") + +pystring = StackObject( + name='str', + obtype=str, + doc="A Python string object.") + +pyunicode = StackObject( + name='unicode', + obtype=unicode, + doc="A Python Unicode string object.") + +pynone = StackObject( + name="None", + obtype=type(None), + doc="The Python None object.") + +pytuple = StackObject( + name="tuple", + obtype=tuple, + doc="A Python tuple object.") + +pylist = StackObject( + name="list", + obtype=list, + doc="A Python list object.") + +pydict = StackObject( + name="dict", + obtype=dict, + doc="A Python dict object.") + +anyobject = StackObject( + name='any', + obtype=object, + doc="Any kind of object whatsoever.") + +markobject = StackObject( + name="mark", + obtype=StackObject, + doc="""'The mark' is a unique object. + + Opcodes that operate on a variable number of objects + generally don't embed the count of objects in the opcode, + or pull it off the stack. Instead the MARK opcode is used + to push a special marker object on the stack, and then + some other opcodes grab all the objects from the top of + the stack down to (but not including) the topmost marker + object. + """) + +stackslice = StackObject( + name="stackslice", + obtype=StackObject, + doc="""An object representing a contiguous slice of the stack. + + This is used in conjuction with markobject, to represent all + of the stack following the topmost markobject. For example, + the POP_MARK opcode changes the stack from + + [..., markobject, stackslice] + to + [...] + + No matter how many object are on the stack after the topmost + markobject, POP_MARK gets rid of all of them (including the + topmost markobject too). + """) + +############################################################################## +# Descriptors for pickle opcodes. + +class OpcodeInfo(object): + + __slots__ = ( + # symbolic name of opcode; a string + 'name', + + # the code used in a bytestream to represent the opcode; a + # one-character string + 'code', + + # If the opcode has an argument embedded in the byte string, an + # instance of ArgumentDescriptor specifying its type. Note that + # arg.reader(s) can be used to read and decode the argument from + # the bytestream s, and arg.doc documents the format of the raw + # argument bytes. If the opcode doesn't have an argument embedded + # in the bytestream, arg should be None. + 'arg', + + # what the stack looks like before this opcode runs; a list + 'stack_before', + + # what the stack looks like after this opcode runs; a list + 'stack_after', + + # the protocol number in which this opcode was introduced; an int + 'proto', + + # human-readable docs for this opcode; a string + 'doc', + ) + + def __init__(self, name, code, arg, + stack_before, stack_after, proto, doc): + assert isinstance(name, str) + self.name = name + + assert isinstance(code, str) + assert len(code) == 1 + self.code = code + + assert arg is None or isinstance(arg, ArgumentDescriptor) + self.arg = arg + + assert isinstance(stack_before, list) + for x in stack_before: + assert isinstance(x, StackObject) + self.stack_before = stack_before + + assert isinstance(stack_after, list) + for x in stack_after: + assert isinstance(x, StackObject) + self.stack_after = stack_after + + assert isinstance(proto, int) and 0 <= proto <= 2 + self.proto = proto + + assert isinstance(doc, str) + self.doc = doc + +I = OpcodeInfo +opcodes = [ + + # Ways to spell integers. + + I(name='INT', + code='I', + arg=decimalnl_short, + stack_before=[], + stack_after=[pyinteger_or_bool], + proto=0, + doc="""Push an integer or bool. + + The argument is a newline-terminated decimal literal string. + + The intent may have been that this always fit in a short Python int, + but INT can be generated in pickles written on a 64-bit box that + require a Python long on a 32-bit box. The difference between this + and LONG then is that INT skips a trailing 'L', and produces a short + int whenever possible. + + Another difference is due to that, when bool was introduced as a + distinct type in 2.3, builtin names True and False were also added to + 2.2.2, mapping to ints 1 and 0. For compatibility in both directions, + True gets pickled as INT + "I01\\n", and False as INT + "I00\\n". + Leading zeroes are never produced for a genuine integer. The 2.3 + (and later) unpicklers special-case these and return bool instead; + earlier unpicklers ignore the leading "0" and return the int. + """), + + I(name='BININT', + code='J', + arg=int4, + stack_before=[], + stack_after=[pyint], + proto=1, + doc="""Push a four-byte signed integer. + + This handles the full range of Python (short) integers on a 32-bit + box, directly as binary bytes (1 for the opcode and 4 for the integer). + If the integer is non-negative and fits in 1 or 2 bytes, pickling via + BININT1 or BININT2 saves space. + """), + + I(name='BININT1', + code='K', + arg=uint1, + stack_before=[], + stack_after=[pyint], + proto=1, + doc="""Push a one-byte unsigned integer. + + This is a space optimization for pickling very small non-negative ints, + in range(256). + """), + + I(name='BININT2', + code='M', + arg=uint2, + stack_before=[], + stack_after=[pyint], + proto=1, + doc="""Push a two-byte unsigned integer. + + This is a space optimization for pickling small positive ints, in + range(256, 2**16). Integers in range(256) can also be pickled via + BININT2, but BININT1 instead saves a byte. + """), + + I(name='LONG', + code='L', + arg=decimalnl_long, + stack_before=[], + stack_after=[pylong], + proto=0, + doc="""Push a long integer. + + The same as INT, except that the literal ends with 'L', and always + unpickles to a Python long. There doesn't seem a real purpose to the + trailing 'L'. + + Note that LONG takes time quadratic in the number of digits when + unpickling (this is simply due to the nature of decimal->binary + conversion). Proto 2 added linear-time (in C; still quadratic-time + in Python) LONG1 and LONG4 opcodes. + """), + + I(name="LONG1", + code='\x8a', + arg=long1, + stack_before=[], + stack_after=[pylong], + proto=2, + doc="""Long integer using one-byte length. + + A more efficient encoding of a Python long; the long1 encoding + says it all."""), + + I(name="LONG4", + code='\x8b', + arg=long4, + stack_before=[], + stack_after=[pylong], + proto=2, + doc="""Long integer using found-byte length. + + A more efficient encoding of a Python long; the long4 encoding + says it all."""), + + # Ways to spell strings (8-bit, not Unicode). + + I(name='STRING', + code='S', + arg=stringnl, + stack_before=[], + stack_after=[pystring], + proto=0, + doc="""Push a Python string object. + + The argument is a repr-style string, with bracketing quote characters, + and perhaps embedded escapes. The argument extends until the next + newline character. + """), + + I(name='BINSTRING', + code='T', + arg=string4, + stack_before=[], + stack_after=[pystring], + proto=1, + doc="""Push a Python string object. + + There are two arguments: the first is a 4-byte little-endian signed int + giving the number of bytes in the string, and the second is that many + bytes, which are taken literally as the string content. + """), + + I(name='SHORT_BINSTRING', + code='U', + arg=string1, + stack_before=[], + stack_after=[pystring], + proto=1, + doc="""Push a Python string object. + + There are two arguments: the first is a 1-byte unsigned int giving + the number of bytes in the string, and the second is that many bytes, + which are taken literally as the string content. + """), + + # Ways to spell None. + + I(name='NONE', + code='N', + arg=None, + stack_before=[], + stack_after=[pynone], + proto=0, + doc="Push None on the stack."), + + # Ways to spell bools, starting with proto 2. See INT for how this was + # done before proto 2. + + I(name='NEWTRUE', + code='\x88', + arg=None, + stack_before=[], + stack_after=[pybool], + proto=2, + doc="""True. + + Push True onto the stack."""), + + I(name='NEWFALSE', + code='\x89', + arg=None, + stack_before=[], + stack_after=[pybool], + proto=2, + doc="""True. + + Push False onto the stack."""), + + # Ways to spell Unicode strings. + + I(name='UNICODE', + code='V', + arg=unicodestringnl, + stack_before=[], + stack_after=[pyunicode], + proto=0, # this may be pure-text, but it's a later addition + doc="""Push a Python Unicode string object. + + The argument is a raw-unicode-escape encoding of a Unicode string, + and so may contain embedded escape sequences. The argument extends + until the next newline character. + """), + + I(name='BINUNICODE', + code='X', + arg=unicodestring4, + stack_before=[], + stack_after=[pyunicode], + proto=1, + doc="""Push a Python Unicode string object. + + There are two arguments: the first is a 4-byte little-endian signed int + giving the number of bytes in the string. The second is that many + bytes, and is the UTF-8 encoding of the Unicode string. + """), + + # Ways to spell floats. + + I(name='FLOAT', + code='F', + arg=floatnl, + stack_before=[], + stack_after=[pyfloat], + proto=0, + doc="""Newline-terminated decimal float literal. + + The argument is repr(a_float), and in general requires 17 significant + digits for roundtrip conversion to be an identity (this is so for + IEEE-754 double precision values, which is what Python float maps to + on most boxes). + + In general, FLOAT cannot be used to transport infinities, NaNs, or + minus zero across boxes (or even on a single box, if the platform C + library can't read the strings it produces for such things -- Windows + is like that), but may do less damage than BINFLOAT on boxes with + greater precision or dynamic range than IEEE-754 double. + """), + + I(name='BINFLOAT', + code='G', + arg=float8, + stack_before=[], + stack_after=[pyfloat], + proto=1, + doc="""Float stored in binary form, with 8 bytes of data. + + This generally requires less than half the space of FLOAT encoding. + In general, BINFLOAT cannot be used to transport infinities, NaNs, or + minus zero, raises an exception if the exponent exceeds the range of + an IEEE-754 double, and retains no more than 53 bits of precision (if + there are more than that, "add a half and chop" rounding is used to + cut it back to 53 significant bits). + """), + + # Ways to build lists. + + I(name='EMPTY_LIST', + code=']', + arg=None, + stack_before=[], + stack_after=[pylist], + proto=1, + doc="Push an empty list."), + + I(name='APPEND', + code='a', + arg=None, + stack_before=[pylist, anyobject], + stack_after=[pylist], + proto=0, + doc="""Append an object to a list. + + Stack before: ... pylist anyobject + Stack after: ... pylist+[anyobject] + + although pylist is really extended in-place. + """), + + I(name='APPENDS', + code='e', + arg=None, + stack_before=[pylist, markobject, stackslice], + stack_after=[pylist], + proto=1, + doc="""Extend a list by a slice of stack objects. + + Stack before: ... pylist markobject stackslice + Stack after: ... pylist+stackslice + + although pylist is really extended in-place. + """), + + I(name='LIST', + code='l', + arg=None, + stack_before=[markobject, stackslice], + stack_after=[pylist], + proto=0, + doc="""Build a list out of the topmost stack slice, after markobject. + + All the stack entries following the topmost markobject are placed into + a single Python list, which single list object replaces all of the + stack from the topmost markobject onward. For example, + + Stack before: ... markobject 1 2 3 'abc' + Stack after: ... [1, 2, 3, 'abc'] + """), + + # Ways to build tuples. + + I(name='EMPTY_TUPLE', + code=')', + arg=None, + stack_before=[], + stack_after=[pytuple], + proto=1, + doc="Push an empty tuple."), + + I(name='TUPLE', + code='t', + arg=None, + stack_before=[markobject, stackslice], + stack_after=[pytuple], + proto=0, + doc="""Build a tuple out of the topmost stack slice, after markobject. + + All the stack entries following the topmost markobject are placed into + a single Python tuple, which single tuple object replaces all of the + stack from the topmost markobject onward. For example, + + Stack before: ... markobject 1 2 3 'abc' + Stack after: ... (1, 2, 3, 'abc') + """), + + I(name='TUPLE1', + code='\x85', + arg=None, + stack_before=[anyobject], + stack_after=[pytuple], + proto=2, + doc="""Build a one-tuple out of the topmost item on the stack. + + This code pops one value off the stack and pushes a tuple of + length 1 whose one item is that value back onto it. In other + words: + + stack[-1] = tuple(stack[-1:]) + """), + + I(name='TUPLE2', + code='\x86', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[pytuple], + proto=2, + doc="""Build a two-tuple out of the top two items on the stack. + + This code pops two values off the stack and pushes a tuple of + length 2 whose items are those values back onto it. In other + words: + + stack[-2:] = [tuple(stack[-2:])] + """), + + I(name='TUPLE3', + code='\x87', + arg=None, + stack_before=[anyobject, anyobject, anyobject], + stack_after=[pytuple], + proto=2, + doc="""Build a three-tuple out of the top three items on the stack. + + This code pops three values off the stack and pushes a tuple of + length 3 whose items are those values back onto it. In other + words: + + stack[-3:] = [tuple(stack[-3:])] + """), + + # Ways to build dicts. + + I(name='EMPTY_DICT', + code='}', + arg=None, + stack_before=[], + stack_after=[pydict], + proto=1, + doc="Push an empty dict."), + + I(name='DICT', + code='d', + arg=None, + stack_before=[markobject, stackslice], + stack_after=[pydict], + proto=0, + doc="""Build a dict out of the topmost stack slice, after markobject. + + All the stack entries following the topmost markobject are placed into + a single Python dict, which single dict object replaces all of the + stack from the topmost markobject onward. The stack slice alternates + key, value, key, value, .... For example, + + Stack before: ... markobject 1 2 3 'abc' + Stack after: ... {1: 2, 3: 'abc'} + """), + + I(name='SETITEM', + code='s', + arg=None, + stack_before=[pydict, anyobject, anyobject], + stack_after=[pydict], + proto=0, + doc="""Add a key+value pair to an existing dict. + + Stack before: ... pydict key value + Stack after: ... pydict + + where pydict has been modified via pydict[key] = value. + """), + + I(name='SETITEMS', + code='u', + arg=None, + stack_before=[pydict, markobject, stackslice], + stack_after=[pydict], + proto=1, + doc="""Add an arbitrary number of key+value pairs to an existing dict. + + The slice of the stack following the topmost markobject is taken as + an alternating sequence of keys and values, added to the dict + immediately under the topmost markobject. Everything at and after the + topmost markobject is popped, leaving the mutated dict at the top + of the stack. + + Stack before: ... pydict markobject key_1 value_1 ... key_n value_n + Stack after: ... pydict + + where pydict has been modified via pydict[key_i] = value_i for i in + 1, 2, ..., n, and in that order. + """), + + # Stack manipulation. + + I(name='POP', + code='0', + arg=None, + stack_before=[anyobject], + stack_after=[], + proto=0, + doc="Discard the top stack item, shrinking the stack by one item."), + + I(name='DUP', + code='2', + arg=None, + stack_before=[anyobject], + stack_after=[anyobject, anyobject], + proto=0, + doc="Push the top stack item onto the stack again, duplicating it."), + + I(name='MARK', + code='(', + arg=None, + stack_before=[], + stack_after=[markobject], + proto=0, + doc="""Push markobject onto the stack. + + markobject is a unique object, used by other opcodes to identify a + region of the stack containing a variable number of objects for them + to work on. See markobject.doc for more detail. + """), + + I(name='POP_MARK', + code='1', + arg=None, + stack_before=[markobject, stackslice], + stack_after=[], + proto=1, + doc="""Pop all the stack objects at and above the topmost markobject. + + When an opcode using a variable number of stack objects is done, + POP_MARK is used to remove those objects, and to remove the markobject + that delimited their starting position on the stack. + """), + + # Memo manipulation. There are really only two operations (get and put), + # each in all-text, "short binary", and "long binary" flavors. + + I(name='GET', + code='g', + arg=decimalnl_short, + stack_before=[], + stack_after=[anyobject], + proto=0, + doc="""Read an object from the memo and push it on the stack. + + The index of the memo object to push is given by the newline-terminated + decimal string following. BINGET and LONG_BINGET are space-optimized + versions. + """), + + I(name='BINGET', + code='h', + arg=uint1, + stack_before=[], + stack_after=[anyobject], + proto=1, + doc="""Read an object from the memo and push it on the stack. + + The index of the memo object to push is given by the 1-byte unsigned + integer following. + """), + + I(name='LONG_BINGET', + code='j', + arg=int4, + stack_before=[], + stack_after=[anyobject], + proto=1, + doc="""Read an object from the memo and push it on the stack. + + The index of the memo object to push is given by the 4-byte signed + little-endian integer following. + """), + + I(name='PUT', + code='p', + arg=decimalnl_short, + stack_before=[], + stack_after=[], + proto=0, + doc="""Store the stack top into the memo. The stack is not popped. + + The index of the memo location to write into is given by the newline- + terminated decimal string following. BINPUT and LONG_BINPUT are + space-optimized versions. + """), + + I(name='BINPUT', + code='q', + arg=uint1, + stack_before=[], + stack_after=[], + proto=1, + doc="""Store the stack top into the memo. The stack is not popped. + + The index of the memo location to write into is given by the 1-byte + unsigned integer following. + """), + + I(name='LONG_BINPUT', + code='r', + arg=int4, + stack_before=[], + stack_after=[], + proto=1, + doc="""Store the stack top into the memo. The stack is not popped. + + The index of the memo location to write into is given by the 4-byte + signed little-endian integer following. + """), + + # Access the extension registry (predefined objects). Akin to the GET + # family. + + I(name='EXT1', + code='\x82', + arg=uint1, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + This code and the similar EXT2 and EXT4 allow using a registry + of popular objects that are pickled by name, typically classes. + It is envisioned that through a global negotiation and + registration process, third parties can set up a mapping between + ints and object names. + + In order to guarantee pickle interchangeability, the extension + code registry ought to be global, although a range of codes may + be reserved for private use. + + EXT1 has a 1-byte integer argument. This is used to index into the + extension registry, and the object at that index is pushed on the stack. + """), + + I(name='EXT2', + code='\x83', + arg=uint2, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + See EXT1. EXT2 has a two-byte integer argument. + """), + + I(name='EXT4', + code='\x84', + arg=int4, + stack_before=[], + stack_after=[anyobject], + proto=2, + doc="""Extension code. + + See EXT1. EXT4 has a four-byte integer argument. + """), + + # Push a class object, or module function, on the stack, via its module + # and name. + + I(name='GLOBAL', + code='c', + arg=stringnl_noescape_pair, + stack_before=[], + stack_after=[anyobject], + proto=0, + doc="""Push a global object (module.attr) on the stack. + + Two newline-terminated strings follow the GLOBAL opcode. The first is + taken as a module name, and the second as a class name. The class + object module.class is pushed on the stack. More accurately, the + object returned by self.find_class(module, class) is pushed on the + stack, so unpickling subclasses can override this form of lookup. + """), + + # Ways to build objects of classes pickle doesn't know about directly + # (user-defined classes). I despair of documenting this accurately + # and comprehensibly -- you really have to read the pickle code to + # find all the special cases. + + I(name='REDUCE', + code='R', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[anyobject], + proto=0, + doc="""Push an object built from a callable and an argument tuple. + + The opcode is named to remind of the __reduce__() method. + + Stack before: ... callable pytuple + Stack after: ... callable(*pytuple) + + The callable and the argument tuple are the first two items returned + by a __reduce__ method. Applying the callable to the argtuple is + supposed to reproduce the original object, or at least get it started. + If the __reduce__ method returns a 3-tuple, the last component is an + argument to be passed to the object's __setstate__, and then the REDUCE + opcode is followed by code to create setstate's argument, and then a + BUILD opcode to apply __setstate__ to that argument. + + If type(callable) is not ClassType, REDUCE complains unless the + callable has been registered with the copy_reg module's + safe_constructors dict, or the callable has a magic + '__safe_for_unpickling__' attribute with a true value. I'm not sure + why it does this, but I've sure seen this complaint often enough when + I didn't want to <wink>. + """), + + I(name='BUILD', + code='b', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[anyobject], + proto=0, + doc="""Finish building an object, via __setstate__ or dict update. + + Stack before: ... anyobject argument + Stack after: ... anyobject + + where anyobject may have been mutated, as follows: + + If the object has a __setstate__ method, + + anyobject.__setstate__(argument) + + is called. + + Else the argument must be a dict, the object must have a __dict__, and + the object is updated via + + anyobject.__dict__.update(argument) + + This may raise RuntimeError in restricted execution mode (which + disallows access to __dict__ directly); in that case, the object + is updated instead via + + for k, v in argument.items(): + anyobject[k] = v + """), + + I(name='INST', + code='i', + arg=stringnl_noescape_pair, + stack_before=[markobject, stackslice], + stack_after=[anyobject], + proto=0, + doc="""Build a class instance. + + This is the protocol 0 version of protocol 1's OBJ opcode. + INST is followed by two newline-terminated strings, giving a + module and class name, just as for the GLOBAL opcode (and see + GLOBAL for more details about that). self.find_class(module, name) + is used to get a class object. + + In addition, all the objects on the stack following the topmost + markobject are gathered into a tuple and popped (along with the + topmost markobject), just as for the TUPLE opcode. + + Now it gets complicated. If all of these are true: + + + The argtuple is empty (markobject was at the top of the stack + at the start). + + + It's an old-style class object (the type of the class object is + ClassType). + + + The class object does not have a __getinitargs__ attribute. + + then we want to create an old-style class instance without invoking + its __init__() method (pickle has waffled on this over the years; not + calling __init__() is current wisdom). In this case, an instance of + an old-style dummy class is created, and then we try to rebind its + __class__ attribute to the desired class object. If this succeeds, + the new instance object is pushed on the stack, and we're done. In + restricted execution mode it can fail (assignment to __class__ is + disallowed), and I'm not really sure what happens then -- it looks + like the code ends up calling the class object's __init__ anyway, + via falling into the next case. + + Else (the argtuple is not empty, it's not an old-style class object, + or the class object does have a __getinitargs__ attribute), the code + first insists that the class object have a __safe_for_unpickling__ + attribute. Unlike as for the __safe_for_unpickling__ check in REDUCE, + it doesn't matter whether this attribute has a true or false value, it + only matters whether it exists (XXX this is a bug; cPickle + requires the attribute to be true). If __safe_for_unpickling__ + doesn't exist, UnpicklingError is raised. + + Else (the class object does have a __safe_for_unpickling__ attr), + the class object obtained from INST's arguments is applied to the + argtuple obtained from the stack, and the resulting instance object + is pushed on the stack. + + NOTE: checks for __safe_for_unpickling__ went away in Python 2.3. + """), + + I(name='OBJ', + code='o', + arg=None, + stack_before=[markobject, anyobject, stackslice], + stack_after=[anyobject], + proto=1, + doc="""Build a class instance. + + This is the protocol 1 version of protocol 0's INST opcode, and is + very much like it. The major difference is that the class object + is taken off the stack, allowing it to be retrieved from the memo + repeatedly if several instances of the same class are created. This + can be much more efficient (in both time and space) than repeatedly + embedding the module and class names in INST opcodes. + + Unlike INST, OBJ takes no arguments from the opcode stream. Instead + the class object is taken off the stack, immediately above the + topmost markobject: + + Stack before: ... markobject classobject stackslice + Stack after: ... new_instance_object + + As for INST, the remainder of the stack above the markobject is + gathered into an argument tuple, and then the logic seems identical, + except that no __safe_for_unpickling__ check is done (XXX this is + a bug; cPickle does test __safe_for_unpickling__). See INST for + the gory details. + + NOTE: In Python 2.3, INST and OBJ are identical except for how they + get the class object. That was always the intent; the implementations + had diverged for accidental reasons. + """), + + I(name='NEWOBJ', + code='\x81', + arg=None, + stack_before=[anyobject, anyobject], + stack_after=[anyobject], + proto=2, + doc="""Build an object instance. + + The stack before should be thought of as containing a class + object followed by an argument tuple (the tuple being the stack + top). Call these cls and args. They are popped off the stack, + and the value returned by cls.__new__(cls, *args) is pushed back + onto the stack. + """), + + # Machine control. + + I(name='PROTO', + code='\x80', + arg=uint1, + stack_before=[], + stack_after=[], + proto=2, + doc="""Protocol version indicator. + + For protocol 2 and above, a pickle must start with this opcode. + The argument is the protocol version, an int in range(2, 256). + """), + + I(name='STOP', + code='.', + arg=None, + stack_before=[anyobject], + stack_after=[], + proto=0, + doc="""Stop the unpickling machine. + + Every pickle ends with this opcode. The object at the top of the stack + is popped, and that's the result of unpickling. The stack should be + empty then. + """), + + # Ways to deal with persistent IDs. + + I(name='PERSID', + code='P', + arg=stringnl_noescape, + stack_before=[], + stack_after=[anyobject], + proto=0, + doc="""Push an object identified by a persistent ID. + + The pickle module doesn't define what a persistent ID means. PERSID's + argument is a newline-terminated str-style (no embedded escapes, no + bracketing quote characters) string, which *is* "the persistent ID". + The unpickler passes this string to self.persistent_load(). Whatever + object that returns is pushed on the stack. There is no implementation + of persistent_load() in Python's unpickler: it must be supplied by an + unpickler subclass. + """), + + I(name='BINPERSID', + code='Q', + arg=None, + stack_before=[anyobject], + stack_after=[anyobject], + proto=1, + doc="""Push an object identified by a persistent ID. + + Like PERSID, except the persistent ID is popped off the stack (instead + of being a string embedded in the opcode bytestream). The persistent + ID is passed to self.persistent_load(), and whatever object that + returns is pushed on the stack. See PERSID for more detail. + """), +] +del I + +# Verify uniqueness of .name and .code members. +name2i = {} +code2i = {} + +for i, d in enumerate(opcodes): + if d.name in name2i: + raise ValueError("repeated name %r at indices %d and %d" % + (d.name, name2i[d.name], i)) + if d.code in code2i: + raise ValueError("repeated code %r at indices %d and %d" % + (d.code, code2i[d.code], i)) + + name2i[d.name] = i + code2i[d.code] = i + +del name2i, code2i, i, d + +############################################################################## +# Build a code2op dict, mapping opcode characters to OpcodeInfo records. +# Also ensure we've got the same stuff as pickle.py, although the +# introspection here is dicey. + +code2op = {} +for d in opcodes: + code2op[d.code] = d +del d + +def assure_pickle_consistency(verbose=False): + import pickle, re + + copy = code2op.copy() + for name in pickle.__all__: + if not re.match("[A-Z][A-Z0-9_]+$", name): + if verbose: + print "skipping %r: it doesn't look like an opcode name" % name + continue + picklecode = getattr(pickle, name) + if not isinstance(picklecode, str) or len(picklecode) != 1: + if verbose: + print ("skipping %r: value %r doesn't look like a pickle " + "code" % (name, picklecode)) + continue + if picklecode in copy: + if verbose: + print "checking name %r w/ code %r for consistency" % ( + name, picklecode) + d = copy[picklecode] + if d.name != name: + raise ValueError("for pickle code %r, pickle.py uses name %r " + "but we're using name %r" % (picklecode, + name, + d.name)) + # Forget this one. Any left over in copy at the end are a problem + # of a different kind. + del copy[picklecode] + else: + raise ValueError("pickle.py appears to have a pickle opcode with " + "name %r and code %r, but we don't" % + (name, picklecode)) + if copy: + msg = ["we appear to have pickle opcodes that pickle.py doesn't have:"] + for code, d in copy.items(): + msg.append(" name %r with code %r" % (d.name, code)) + raise ValueError("\n".join(msg)) + +assure_pickle_consistency() +del assure_pickle_consistency + +############################################################################## +# A pickle opcode generator. + +def genops(pickle): + """Generate all the opcodes in a pickle. + + 'pickle' is a file-like object, or string, containing the pickle. + + Each opcode in the pickle is generated, from the current pickle position, + stopping after a STOP opcode is delivered. A triple is generated for + each opcode: + + opcode, arg, pos + + opcode is an OpcodeInfo record, describing the current opcode. + + If the opcode has an argument embedded in the pickle, arg is its decoded + value, as a Python object. If the opcode doesn't have an argument, arg + is None. + + If the pickle has a tell() method, pos was the value of pickle.tell() + before reading the current opcode. If the pickle is a string object, + it's wrapped in a StringIO object, and the latter's tell() result is + used. Else (the pickle doesn't have a tell(), and it's not obvious how + to query its current position) pos is None. + """ + + import cStringIO as StringIO + + if isinstance(pickle, str): + pickle = StringIO.StringIO(pickle) + + if hasattr(pickle, "tell"): + getpos = pickle.tell + else: + getpos = lambda: None + + while True: + pos = getpos() + code = pickle.read(1) + opcode = code2op.get(code) + if opcode is None: + if code == "": + raise ValueError("pickle exhausted before seeing STOP") + else: + raise ValueError("at position %s, opcode %r unknown" % ( + pos is None and "<unknown>" or pos, + code)) + if opcode.arg is None: + arg = None + else: + arg = opcode.arg.reader(pickle) + yield opcode, arg, pos + if code == '.': + assert opcode.name == 'STOP' + break + +############################################################################## +# A pickle optimizer. + +def optimize(p): + 'Optimize a pickle string by removing unused PUT opcodes' + gets = set() # set of args used by a GET opcode + puts = [] # (arg, startpos, stoppos) for the PUT opcodes + prevpos = None # set to pos if previous opcode was a PUT + for opcode, arg, pos in genops(p): + if prevpos is not None: + puts.append((prevarg, prevpos, pos)) + prevpos = None + if 'PUT' in opcode.name: + prevarg, prevpos = arg, pos + elif 'GET' in opcode.name: + gets.add(arg) + + # Copy the pickle string except for PUTS without a corresponding GET + s = [] + i = 0 + for arg, start, stop in puts: + j = stop if (arg in gets) else start + s.append(p[i:j]) + i = stop + s.append(p[i:]) + return ''.join(s) + +############################################################################## +# A symbolic pickle disassembler. + +def dis(pickle, out=None, memo=None, indentlevel=4): + """Produce a symbolic disassembly of a pickle. + + 'pickle' is a file-like object, or string, containing a (at least one) + pickle. The pickle is disassembled from the current position, through + the first STOP opcode encountered. + + Optional arg 'out' is a file-like object to which the disassembly is + printed. It defaults to sys.stdout. + + Optional arg 'memo' is a Python dict, used as the pickle's memo. It + may be mutated by dis(), if the pickle contains PUT or BINPUT opcodes. + Passing the same memo object to another dis() call then allows disassembly + to proceed across multiple pickles that were all created by the same + pickler with the same memo. Ordinarily you don't need to worry about this. + + Optional arg indentlevel is the number of blanks by which to indent + a new MARK level. It defaults to 4. + + In addition to printing the disassembly, some sanity checks are made: + + + All embedded opcode arguments "make sense". + + + Explicit and implicit pop operations have enough items on the stack. + + + When an opcode implicitly refers to a markobject, a markobject is + actually on the stack. + + + A memo entry isn't referenced before it's defined. + + + The markobject isn't stored in the memo. + + + A memo entry isn't redefined. + """ + + # Most of the hair here is for sanity checks, but most of it is needed + # anyway to detect when a protocol 0 POP takes a MARK off the stack + # (which in turn is needed to indent MARK blocks correctly). + + stack = [] # crude emulation of unpickler stack + if memo is None: + memo = {} # crude emulation of unpicker memo + maxproto = -1 # max protocol number seen + markstack = [] # bytecode positions of MARK opcodes + indentchunk = ' ' * indentlevel + errormsg = None + for opcode, arg, pos in genops(pickle): + if pos is not None: + print >> out, "%5d:" % pos, + + line = "%-4s %s%s" % (repr(opcode.code)[1:-1], + indentchunk * len(markstack), + opcode.name) + + maxproto = max(maxproto, opcode.proto) + before = opcode.stack_before # don't mutate + after = opcode.stack_after # don't mutate + numtopop = len(before) + + # See whether a MARK should be popped. + markmsg = None + if markobject in before or (opcode.name == "POP" and + stack and + stack[-1] is markobject): + assert markobject not in after + if __debug__: + if markobject in before: + assert before[-1] is stackslice + if markstack: + markpos = markstack.pop() + if markpos is None: + markmsg = "(MARK at unknown opcode offset)" + else: + markmsg = "(MARK at %d)" % markpos + # Pop everything at and after the topmost markobject. + while stack[-1] is not markobject: + stack.pop() + stack.pop() + # Stop later code from popping too much. + try: + numtopop = before.index(markobject) + except ValueError: + assert opcode.name == "POP" + numtopop = 0 + else: + errormsg = markmsg = "no MARK exists on stack" + + # Check for correct memo usage. + if opcode.name in ("PUT", "BINPUT", "LONG_BINPUT"): + assert arg is not None + if arg in memo: + errormsg = "memo key %r already defined" % arg + elif not stack: + errormsg = "stack is empty -- can't store into memo" + elif stack[-1] is markobject: + errormsg = "can't store markobject in the memo" + else: + memo[arg] = stack[-1] + + elif opcode.name in ("GET", "BINGET", "LONG_BINGET"): + if arg in memo: + assert len(after) == 1 + after = [memo[arg]] # for better stack emulation + else: + errormsg = "memo key %r has never been stored into" % arg + + if arg is not None or markmsg: + # make a mild effort to align arguments + line += ' ' * (10 - len(opcode.name)) + if arg is not None: + line += ' ' + repr(arg) + if markmsg: + line += ' ' + markmsg + print >> out, line + + if errormsg: + # Note that we delayed complaining until the offending opcode + # was printed. + raise ValueError(errormsg) + + # Emulate the stack effects. + if len(stack) < numtopop: + raise ValueError("tries to pop %d items from stack with " + "only %d items" % (numtopop, len(stack))) + if numtopop: + del stack[-numtopop:] + if markobject in after: + assert markobject not in before + markstack.append(pos) + + stack.extend(after) + + print >> out, "highest protocol among opcodes =", maxproto + if stack: + raise ValueError("stack not empty after STOP: %r" % stack) + +# For use in the doctest, simply as an example of a class to pickle. +class _Example: + def __init__(self, value): + self.value = value + +_dis_test = r""" +>>> import pickle +>>> x = [1, 2, (3, 4), {'abc': u"def"}] +>>> pkl = pickle.dumps(x, 0) +>>> dis(pkl) + 0: ( MARK + 1: l LIST (MARK at 0) + 2: p PUT 0 + 5: I INT 1 + 8: a APPEND + 9: I INT 2 + 12: a APPEND + 13: ( MARK + 14: I INT 3 + 17: I INT 4 + 20: t TUPLE (MARK at 13) + 21: p PUT 1 + 24: a APPEND + 25: ( MARK + 26: d DICT (MARK at 25) + 27: p PUT 2 + 30: S STRING 'abc' + 37: p PUT 3 + 40: V UNICODE u'def' + 45: p PUT 4 + 48: s SETITEM + 49: a APPEND + 50: . STOP +highest protocol among opcodes = 0 + +Try again with a "binary" pickle. + +>>> pkl = pickle.dumps(x, 1) +>>> dis(pkl) + 0: ] EMPTY_LIST + 1: q BINPUT 0 + 3: ( MARK + 4: K BININT1 1 + 6: K BININT1 2 + 8: ( MARK + 9: K BININT1 3 + 11: K BININT1 4 + 13: t TUPLE (MARK at 8) + 14: q BINPUT 1 + 16: } EMPTY_DICT + 17: q BINPUT 2 + 19: U SHORT_BINSTRING 'abc' + 24: q BINPUT 3 + 26: X BINUNICODE u'def' + 34: q BINPUT 4 + 36: s SETITEM + 37: e APPENDS (MARK at 3) + 38: . STOP +highest protocol among opcodes = 1 + +Exercise the INST/OBJ/BUILD family. + +>>> import pickletools +>>> dis(pickle.dumps(pickletools.dis, 0)) + 0: c GLOBAL 'pickletools dis' + 17: p PUT 0 + 20: . STOP +highest protocol among opcodes = 0 + +>>> from pickletools import _Example +>>> x = [_Example(42)] * 2 +>>> dis(pickle.dumps(x, 0)) + 0: ( MARK + 1: l LIST (MARK at 0) + 2: p PUT 0 + 5: ( MARK + 6: i INST 'pickletools _Example' (MARK at 5) + 28: p PUT 1 + 31: ( MARK + 32: d DICT (MARK at 31) + 33: p PUT 2 + 36: S STRING 'value' + 45: p PUT 3 + 48: I INT 42 + 52: s SETITEM + 53: b BUILD + 54: a APPEND + 55: g GET 1 + 58: a APPEND + 59: . STOP +highest protocol among opcodes = 0 + +>>> dis(pickle.dumps(x, 1)) + 0: ] EMPTY_LIST + 1: q BINPUT 0 + 3: ( MARK + 4: ( MARK + 5: c GLOBAL 'pickletools _Example' + 27: q BINPUT 1 + 29: o OBJ (MARK at 4) + 30: q BINPUT 2 + 32: } EMPTY_DICT + 33: q BINPUT 3 + 35: U SHORT_BINSTRING 'value' + 42: q BINPUT 4 + 44: K BININT1 42 + 46: s SETITEM + 47: b BUILD + 48: h BINGET 2 + 50: e APPENDS (MARK at 3) + 51: . STOP +highest protocol among opcodes = 1 + +Try "the canonical" recursive-object test. + +>>> L = [] +>>> T = L, +>>> L.append(T) +>>> L[0] is T +True +>>> T[0] is L +True +>>> L[0][0] is L +True +>>> T[0][0] is T +True +>>> dis(pickle.dumps(L, 0)) + 0: ( MARK + 1: l LIST (MARK at 0) + 2: p PUT 0 + 5: ( MARK + 6: g GET 0 + 9: t TUPLE (MARK at 5) + 10: p PUT 1 + 13: a APPEND + 14: . STOP +highest protocol among opcodes = 0 + +>>> dis(pickle.dumps(L, 1)) + 0: ] EMPTY_LIST + 1: q BINPUT 0 + 3: ( MARK + 4: h BINGET 0 + 6: t TUPLE (MARK at 3) + 7: q BINPUT 1 + 9: a APPEND + 10: . STOP +highest protocol among opcodes = 1 + +Note that, in the protocol 0 pickle of the recursive tuple, the disassembler +has to emulate the stack in order to realize that the POP opcode at 16 gets +rid of the MARK at 0. + +>>> dis(pickle.dumps(T, 0)) + 0: ( MARK + 1: ( MARK + 2: l LIST (MARK at 1) + 3: p PUT 0 + 6: ( MARK + 7: g GET 0 + 10: t TUPLE (MARK at 6) + 11: p PUT 1 + 14: a APPEND + 15: 0 POP + 16: 0 POP (MARK at 0) + 17: g GET 1 + 20: . STOP +highest protocol among opcodes = 0 + +>>> dis(pickle.dumps(T, 1)) + 0: ( MARK + 1: ] EMPTY_LIST + 2: q BINPUT 0 + 4: ( MARK + 5: h BINGET 0 + 7: t TUPLE (MARK at 4) + 8: q BINPUT 1 + 10: a APPEND + 11: 1 POP_MARK (MARK at 0) + 12: h BINGET 1 + 14: . STOP +highest protocol among opcodes = 1 + +Try protocol 2. + +>>> dis(pickle.dumps(L, 2)) + 0: \x80 PROTO 2 + 2: ] EMPTY_LIST + 3: q BINPUT 0 + 5: h BINGET 0 + 7: \x85 TUPLE1 + 8: q BINPUT 1 + 10: a APPEND + 11: . STOP +highest protocol among opcodes = 2 + +>>> dis(pickle.dumps(T, 2)) + 0: \x80 PROTO 2 + 2: ] EMPTY_LIST + 3: q BINPUT 0 + 5: h BINGET 0 + 7: \x85 TUPLE1 + 8: q BINPUT 1 + 10: a APPEND + 11: 0 POP + 12: h BINGET 1 + 14: . STOP +highest protocol among opcodes = 2 +""" + +_memo_test = r""" +>>> import pickle +>>> from StringIO import StringIO +>>> f = StringIO() +>>> p = pickle.Pickler(f, 2) +>>> x = [1, 2, 3] +>>> p.dump(x) +>>> p.dump(x) +>>> f.seek(0) +>>> memo = {} +>>> dis(f, memo=memo) + 0: \x80 PROTO 2 + 2: ] EMPTY_LIST + 3: q BINPUT 0 + 5: ( MARK + 6: K BININT1 1 + 8: K BININT1 2 + 10: K BININT1 3 + 12: e APPENDS (MARK at 5) + 13: . STOP +highest protocol among opcodes = 2 +>>> dis(f, memo=memo) + 14: \x80 PROTO 2 + 16: h BINGET 0 + 18: . STOP +highest protocol among opcodes = 2 +""" + +__test__ = {'disassembler_test': _dis_test, + 'disassembler_memo_test': _memo_test, + } + +def _test(): + import doctest + return doctest.testmod() + +if __name__ == "__main__": + _test() diff --git a/src/main/resources/PythonLibs/pipes.py b/src/main/resources/PythonLibs/pipes.py new file mode 100644 index 0000000000000000000000000000000000000000..26750f6ab88d8f43465710bee33936997bbc1553 --- /dev/null +++ b/src/main/resources/PythonLibs/pipes.py @@ -0,0 +1,278 @@ +"""Conversion pipeline templates. + +The problem: +------------ + +Suppose you have some data that you want to convert to another format, +such as from GIF image format to PPM image format. Maybe the +conversion involves several steps (e.g. piping it through compress or +uuencode). Some of the conversion steps may require that their input +is a disk file, others may be able to read standard input; similar for +their output. The input to the entire conversion may also be read +from a disk file or from an open file, and similar for its output. + +The module lets you construct a pipeline template by sticking one or +more conversion steps together. It will take care of creating and +removing temporary files if they are necessary to hold intermediate +data. You can then use the template to do conversions from many +different sources to many different destinations. The temporary +file names used are different each time the template is used. + +The templates are objects so you can create templates for many +different conversion steps and store them in a dictionary, for +instance. + + +Directions: +----------- + +To create a template: + t = Template() + +To add a conversion step to a template: + t.append(command, kind) +where kind is a string of two characters: the first is '-' if the +command reads its standard input or 'f' if it requires a file; the +second likewise for the output. The command must be valid /bin/sh +syntax. If input or output files are required, they are passed as +$IN and $OUT; otherwise, it must be possible to use the command in +a pipeline. + +To add a conversion step at the beginning: + t.prepend(command, kind) + +To convert a file to another file using a template: + sts = t.copy(infile, outfile) +If infile or outfile are the empty string, standard input is read or +standard output is written, respectively. The return value is the +exit status of the conversion pipeline. + +To open a file for reading or writing through a conversion pipeline: + fp = t.open(file, mode) +where mode is 'r' to read the file, or 'w' to write it -- just like +for the built-in function open() or for os.popen(). + +To create a new template object initialized to a given one: + t2 = t.clone() +""" # ' + + +import re +import os +import tempfile +import string + +__all__ = ["Template"] + +# Conversion step kinds + +FILEIN_FILEOUT = 'ff' # Must read & write real files +STDIN_FILEOUT = '-f' # Must write a real file +FILEIN_STDOUT = 'f-' # Must read a real file +STDIN_STDOUT = '--' # Normal pipeline element +SOURCE = '.-' # Must be first, writes stdout +SINK = '-.' # Must be last, reads stdin + +stepkinds = [FILEIN_FILEOUT, STDIN_FILEOUT, FILEIN_STDOUT, STDIN_STDOUT, \ + SOURCE, SINK] + + +class Template: + """Class representing a pipeline template.""" + + def __init__(self): + """Template() returns a fresh pipeline template.""" + self.debugging = 0 + self.reset() + + def __repr__(self): + """t.__repr__() implements repr(t).""" + return '<Template instance, steps=%r>' % (self.steps,) + + def reset(self): + """t.reset() restores a pipeline template to its initial state.""" + self.steps = [] + + def clone(self): + """t.clone() returns a new pipeline template with identical + initial state as the current one.""" + t = Template() + t.steps = self.steps[:] + t.debugging = self.debugging + return t + + def debug(self, flag): + """t.debug(flag) turns debugging on or off.""" + self.debugging = flag + + def append(self, cmd, kind): + """t.append(cmd, kind) adds a new step at the end.""" + if type(cmd) is not type(''): + raise TypeError, \ + 'Template.append: cmd must be a string' + if kind not in stepkinds: + raise ValueError, \ + 'Template.append: bad kind %r' % (kind,) + if kind == SOURCE: + raise ValueError, \ + 'Template.append: SOURCE can only be prepended' + if self.steps and self.steps[-1][1] == SINK: + raise ValueError, \ + 'Template.append: already ends with SINK' + if kind[0] == 'f' and not re.search(r'\$IN\b', cmd): + raise ValueError, \ + 'Template.append: missing $IN in cmd' + if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd): + raise ValueError, \ + 'Template.append: missing $OUT in cmd' + self.steps.append((cmd, kind)) + + def prepend(self, cmd, kind): + """t.prepend(cmd, kind) adds a new step at the front.""" + if type(cmd) is not type(''): + raise TypeError, \ + 'Template.prepend: cmd must be a string' + if kind not in stepkinds: + raise ValueError, \ + 'Template.prepend: bad kind %r' % (kind,) + if kind == SINK: + raise ValueError, \ + 'Template.prepend: SINK can only be appended' + if self.steps and self.steps[0][1] == SOURCE: + raise ValueError, \ + 'Template.prepend: already begins with SOURCE' + if kind[0] == 'f' and not re.search(r'\$IN\b', cmd): + raise ValueError, \ + 'Template.prepend: missing $IN in cmd' + if kind[1] == 'f' and not re.search(r'\$OUT\b', cmd): + raise ValueError, \ + 'Template.prepend: missing $OUT in cmd' + self.steps.insert(0, (cmd, kind)) + + def open(self, file, rw): + """t.open(file, rw) returns a pipe or file object open for + reading or writing; the file is the other end of the pipeline.""" + if rw == 'r': + return self.open_r(file) + if rw == 'w': + return self.open_w(file) + raise ValueError, \ + 'Template.open: rw must be \'r\' or \'w\', not %r' % (rw,) + + def open_r(self, file): + """t.open_r(file) and t.open_w(file) implement + t.open(file, 'r') and t.open(file, 'w') respectively.""" + if not self.steps: + return open(file, 'r') + if self.steps[-1][1] == SINK: + raise ValueError, \ + 'Template.open_r: pipeline ends width SINK' + cmd = self.makepipeline(file, '') + return os.popen(cmd, 'r') + + def open_w(self, file): + if not self.steps: + return open(file, 'w') + if self.steps[0][1] == SOURCE: + raise ValueError, \ + 'Template.open_w: pipeline begins with SOURCE' + cmd = self.makepipeline('', file) + return os.popen(cmd, 'w') + + def copy(self, infile, outfile): + return os.system(self.makepipeline(infile, outfile)) + + def makepipeline(self, infile, outfile): + cmd = makepipeline(infile, self.steps, outfile) + if self.debugging: + print cmd + cmd = 'set -x; ' + cmd + return cmd + + +def makepipeline(infile, steps, outfile): + # Build a list with for each command: + # [input filename or '', command string, kind, output filename or ''] + + list = [] + for cmd, kind in steps: + list.append(['', cmd, kind, '']) + # + # Make sure there is at least one step + # + if not list: + list.append(['', 'cat', '--', '']) + # + # Take care of the input and output ends + # + [cmd, kind] = list[0][1:3] + if kind[0] == 'f' and not infile: + list.insert(0, ['', 'cat', '--', '']) + list[0][0] = infile + # + [cmd, kind] = list[-1][1:3] + if kind[1] == 'f' and not outfile: + list.append(['', 'cat', '--', '']) + list[-1][-1] = outfile + # + # Invent temporary files to connect stages that need files + # + garbage = [] + for i in range(1, len(list)): + lkind = list[i-1][2] + rkind = list[i][2] + if lkind[1] == 'f' or rkind[0] == 'f': + (fd, temp) = tempfile.mkstemp() + os.close(fd) + garbage.append(temp) + list[i-1][-1] = list[i][0] = temp + # + for item in list: + [inf, cmd, kind, outf] = item + if kind[1] == 'f': + cmd = 'OUT=' + quote(outf) + '; ' + cmd + if kind[0] == 'f': + cmd = 'IN=' + quote(inf) + '; ' + cmd + if kind[0] == '-' and inf: + cmd = cmd + ' <' + quote(inf) + if kind[1] == '-' and outf: + cmd = cmd + ' >' + quote(outf) + item[1] = cmd + # + cmdlist = list[0][1] + for item in list[1:]: + [cmd, kind] = item[1:3] + if item[0] == '': + if 'f' in kind: + cmd = '{ ' + cmd + '; }' + cmdlist = cmdlist + ' |\n' + cmd + else: + cmdlist = cmdlist + '\n' + cmd + # + if garbage: + rmcmd = 'rm -f' + for file in garbage: + rmcmd = rmcmd + ' ' + quote(file) + trapcmd = 'trap ' + quote(rmcmd + '; exit') + ' 1 2 3 13 14 15' + cmdlist = trapcmd + '\n' + cmdlist + '\n' + rmcmd + # + return cmdlist + + +# Reliably quote a string as a single argument for /bin/sh + +# Safe unquoted +_safechars = frozenset(string.ascii_letters + string.digits + '@%_-+=:,./') + +def quote(file): + """Return a shell-escaped version of the file string.""" + for c in file: + if c not in _safechars: + break + else: + if not file: + return "''" + return file + # use single quotes, and put single quotes into double quotes + # the string $'b is then quoted as '$'"'"'b' + return "'" + file.replace("'", "'\"'\"'") + "'" diff --git a/src/main/resources/PythonLibs/pkgutil.py b/src/main/resources/PythonLibs/pkgutil.py new file mode 100644 index 0000000000000000000000000000000000000000..681f887429f72d2223bb076e407907b28bbe5fc3 --- /dev/null +++ b/src/main/resources/PythonLibs/pkgutil.py @@ -0,0 +1,595 @@ +"""Utilities to support packages.""" + +# NOTE: This module must remain compatible with Python 2.3, as it is shared +# by setuptools for distribution with Python 2.3 and up. + +import os +import sys +import imp +import os.path +from types import ModuleType +from org.python.core import imp as _imp, BytecodeLoader + +__all__ = [ + 'get_importer', 'iter_importers', 'get_loader', 'find_loader', + 'walk_packages', 'iter_modules', + 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', +] + + +# equivalent to CPythonLib's pkgutil.read_code except that we need +# diff args to pass into our underlying imp implementation, as +# accessed by _imp here + +def read_jython_code(fullname, file, filename): + data = _imp.readCode(filename, file, False) + return BytecodeLoader.makeCode(fullname + "$py", data, filename) + +read_code = read_jython_code + +def simplegeneric(func): + """Make a trivial single-dispatch generic function""" + registry = {} + def wrapper(*args, **kw): + ob = args[0] + try: + cls = ob.__class__ + except AttributeError: + cls = type(ob) + try: + mro = cls.__mro__ + except AttributeError: + try: + class cls(cls, object): + pass + mro = cls.__mro__[1:] + except TypeError: + mro = object, # must be an ExtensionClass or some such :( + for t in mro: + if t in registry: + return registry[t](*args, **kw) + else: + return func(*args, **kw) + try: + wrapper.__name__ = func.__name__ + except (TypeError, AttributeError): + pass # Python 2.3 doesn't allow functions to be renamed + + def register(typ, func=None): + if func is None: + return lambda f: register(typ, f) + registry[typ] = func + return func + + wrapper.__dict__ = func.__dict__ + wrapper.__doc__ = func.__doc__ + wrapper.register = register + return wrapper + + +def walk_packages(path=None, prefix='', onerror=None): + """Yields (module_loader, name, ispkg) for all modules recursively + on path, or, if path is None, all accessible modules. + + 'path' should be either None or a list of paths to look for + modules in. + + 'prefix' is a string to output on the front of every module name + on output. + + Note that this function must import all *packages* (NOT all + modules!) on the given path, in order to access the __path__ + attribute to find submodules. + + 'onerror' is a function which gets called with one argument (the + name of the package which was being imported) if any exception + occurs while trying to import a package. If no onerror function is + supplied, ImportErrors are caught and ignored, while all other + exceptions are propagated, terminating the search. + + Examples: + + # list all modules python can access + walk_packages() + + # list all submodules of ctypes + walk_packages(ctypes.__path__, ctypes.__name__+'.') + """ + + def seen(p, m={}): + if p in m: + return True + m[p] = True + + for importer, name, ispkg in iter_modules(path, prefix): + yield importer, name, ispkg + + if ispkg: + try: + __import__(name) + except ImportError: + if onerror is not None: + onerror(name) + except Exception: + if onerror is not None: + onerror(name) + else: + raise + else: + path = getattr(sys.modules[name], '__path__', None) or [] + + # don't traverse path items we've seen before + path = [p for p in path if not seen(p)] + + for item in walk_packages(path, name+'.', onerror): + yield item + + +def iter_modules(path=None, prefix=''): + """Yields (module_loader, name, ispkg) for all submodules on path, + or, if path is None, all top-level modules on sys.path. + + 'path' should be either None or a list of paths to look for + modules in. + + 'prefix' is a string to output on the front of every module name + on output. + """ + + if path is None: + importers = iter_importers() + else: + importers = map(get_importer, path) + + yielded = {} + for i in importers: + for name, ispkg in iter_importer_modules(i, prefix): + if name not in yielded: + yielded[name] = 1 + yield i, name, ispkg + + +#@simplegeneric +def iter_importer_modules(importer, prefix=''): + if not hasattr(importer, 'iter_modules'): + return [] + return importer.iter_modules(prefix) + +iter_importer_modules = simplegeneric(iter_importer_modules) + + +class ImpImporter: + """PEP 302 Importer that wraps Python's "classic" import algorithm + + ImpImporter(dirname) produces a PEP 302 importer that searches that + directory. ImpImporter(None) produces a PEP 302 importer that searches + the current sys.path, plus any modules that are frozen or built-in. + + Note that ImpImporter does not currently support being used by placement + on sys.meta_path. + """ + + def __init__(self, path=None): + self.path = path + + def find_module(self, fullname, path=None): + # Note: we ignore 'path' argument since it is only used via meta_path + subname = fullname.split(".")[-1] + if subname != fullname and self.path is None: + return None + if self.path is None: + path = None + else: + path = [os.path.realpath(self.path)] + try: + file, filename, etc = imp.find_module(subname, path) + except ImportError: + return None + return ImpLoader(fullname, file, filename, etc) + + def iter_modules(self, prefix=''): + if self.path is None or not os.path.isdir(self.path): + return + + yielded = {} + import inspect + + filenames = os.listdir(self.path) + filenames.sort() # handle packages before same-named modules + + for fn in filenames: + modname = inspect.getmodulename(fn) + if modname=='__init__' or modname in yielded: + continue + + path = os.path.join(self.path, fn) + ispkg = False + + if not modname and os.path.isdir(path) and '.' not in fn: + modname = fn + for fn in os.listdir(path): + subname = inspect.getmodulename(fn) + if subname=='__init__': + ispkg = True + break + else: + continue # not a package + + if modname and '.' not in modname: + yielded[modname] = 1 + yield prefix + modname, ispkg + + +class ImpLoader: + """PEP 302 Loader that wraps Python's "classic" import algorithm + """ + code = source = None + + def __init__(self, fullname, file, filename, etc): + self.file = file + self.filename = filename + self.fullname = fullname + self.etc = etc + + def load_module(self, fullname): + self._reopen() + try: + mod = imp.load_module(fullname, self.file, self.filename, self.etc) + finally: + if self.file: + self.file.close() + # Note: we don't set __loader__ because we want the module to look + # normal; i.e. this is just a wrapper for standard import machinery + return mod + + def get_data(self, pathname): + f = open(pathname, "rb") + try: + return f.read() + finally: + f.close() + + def _reopen(self): + if self.file and self.file.closed: + mod_type = self.etc[2] + if mod_type==imp.PY_SOURCE: + self.file = open(self.filename, 'rU') + elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION): + self.file = open(self.filename, 'rb') + + def _fix_name(self, fullname): + if fullname is None: + fullname = self.fullname + elif fullname != self.fullname: + raise ImportError("Loader for module %s cannot handle " + "module %s" % (self.fullname, fullname)) + return fullname + + def is_package(self, fullname): + fullname = self._fix_name(fullname) + return self.etc[2]==imp.PKG_DIRECTORY + + def get_code(self, fullname=None): + fullname = self._fix_name(fullname) + if self.code is None: + mod_type = self.etc[2] + if mod_type==imp.PY_SOURCE: + source = self.get_source(fullname) + self.code = compile(source, self.filename, 'exec') + elif mod_type==imp.PY_COMPILED: + self._reopen() + try: + self.code = read_jython_code(fullname, self.file, self.filename) + finally: + self.file.close() + elif mod_type==imp.PKG_DIRECTORY: + self.code = self._get_delegate().get_code() + return self.code + + def get_source(self, fullname=None): + fullname = self._fix_name(fullname) + if self.source is None: + mod_type = self.etc[2] + if mod_type==imp.PY_SOURCE: + self._reopen() + try: + self.source = self.file.read() + finally: + self.file.close() + elif mod_type==imp.PY_COMPILED: + if os.path.exists(self.filename[:-1]): + f = open(self.filename[:-1], 'rU') + try: + self.source = f.read() + finally: + f.close() + elif mod_type==imp.PKG_DIRECTORY: + self.source = self._get_delegate().get_source() + return self.source + + + def _get_delegate(self): + return ImpImporter(self.filename).find_module('__init__') + + def get_filename(self, fullname=None): + fullname = self._fix_name(fullname) + mod_type = self.etc[2] + if self.etc[2]==imp.PKG_DIRECTORY: + return self._get_delegate().get_filename() + elif self.etc[2] in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION): + return self.filename + return None + + +try: + import zipimport + from zipimport import zipimporter + + def iter_zipimport_modules(importer, prefix=''): + dirlist = zipimport._zip_directory_cache[importer.archive].keys() + dirlist.sort() + _prefix = importer.prefix + plen = len(_prefix) + yielded = {} + import inspect + for fn in dirlist: + if not fn.startswith(_prefix): + continue + + fn = fn[plen:].split(os.sep) + + if len(fn)==2 and fn[1].startswith('__init__.py'): + if fn[0] not in yielded: + yielded[fn[0]] = 1 + yield fn[0], True + + if len(fn)!=1: + continue + + modname = inspect.getmodulename(fn[0]) + if modname=='__init__': + continue + + if modname and '.' not in modname and modname not in yielded: + yielded[modname] = 1 + yield prefix + modname, False + + iter_importer_modules.register(zipimporter, iter_zipimport_modules) + +except ImportError: + pass + + +def get_importer(path_item): + """Retrieve a PEP 302 importer for the given path item + + The returned importer is cached in sys.path_importer_cache + if it was newly created by a path hook. + + If there is no importer, a wrapper around the basic import + machinery is returned. This wrapper is never inserted into + the importer cache (None is inserted instead). + + The cache (or part of it) can be cleared manually if a + rescan of sys.path_hooks is necessary. + """ + try: + importer = sys.path_importer_cache[path_item] + except KeyError: + for path_hook in sys.path_hooks: + try: + importer = path_hook(path_item) + break + except ImportError: + pass + else: + importer = None + sys.path_importer_cache.setdefault(path_item, importer) + + if importer is None: + try: + importer = ImpImporter(path_item) + except ImportError: + importer = None + return importer + + +def iter_importers(fullname=""): + """Yield PEP 302 importers for the given module name + + If fullname contains a '.', the importers will be for the package + containing fullname, otherwise they will be importers for sys.meta_path, + sys.path, and Python's "classic" import machinery, in that order. If + the named module is in a package, that package is imported as a side + effect of invoking this function. + + Non PEP 302 mechanisms (e.g. the Windows registry) used by the + standard import machinery to find files in alternative locations + are partially supported, but are searched AFTER sys.path. Normally, + these locations are searched BEFORE sys.path, preventing sys.path + entries from shadowing them. + + For this to cause a visible difference in behaviour, there must + be a module or package name that is accessible via both sys.path + and one of the non PEP 302 file system mechanisms. In this case, + the emulation will find the former version, while the builtin + import mechanism will find the latter. + + Items of the following types can be affected by this discrepancy: + imp.C_EXTENSION, imp.PY_SOURCE, imp.PY_COMPILED, imp.PKG_DIRECTORY + """ + if fullname.startswith('.'): + raise ImportError("Relative module names not supported") + if '.' in fullname: + # Get the containing package's __path__ + pkg = '.'.join(fullname.split('.')[:-1]) + if pkg not in sys.modules: + __import__(pkg) + path = getattr(sys.modules[pkg], '__path__', None) or [] + else: + for importer in sys.meta_path: + yield importer + path = sys.path + for item in path: + yield get_importer(item) + if '.' not in fullname: + yield ImpImporter() + +def get_loader(module_or_name): + """Get a PEP 302 "loader" object for module_or_name + + If the module or package is accessible via the normal import + mechanism, a wrapper around the relevant part of that machinery + is returned. Returns None if the module cannot be found or imported. + If the named module is not already imported, its containing package + (if any) is imported, in order to establish the package __path__. + + This function uses iter_importers(), and is thus subject to the same + limitations regarding platform-specific special import locations such + as the Windows registry. + """ + if module_or_name in sys.modules: + module_or_name = sys.modules[module_or_name] + if isinstance(module_or_name, ModuleType): + module = module_or_name + loader = getattr(module, '__loader__', None) + if loader is not None: + return loader + fullname = module.__name__ + elif module_or_name == sys: + # Jython sys is not a real module; fake it here for now since + # making it a module requires a fair amount of decoupling from + # PySystemState + fullname = "sys" + else: + fullname = module_or_name + return find_loader(fullname) + +def find_loader(fullname): + """Find a PEP 302 "loader" object for fullname + + If fullname contains dots, path must be the containing package's __path__. + Returns None if the module cannot be found or imported. This function uses + iter_importers(), and is thus subject to the same limitations regarding + platform-specific special import locations such as the Windows registry. + """ + for importer in iter_importers(fullname): + loader = importer.find_module(fullname) + if loader is not None: + return loader + + return None + + +def extend_path(path, name): + """Extend a package's path. + + Intended use is to place the following code in a package's __init__.py: + + from pkgutil import extend_path + __path__ = extend_path(__path__, __name__) + + This will add to the package's __path__ all subdirectories of + directories on sys.path named after the package. This is useful + if one wants to distribute different parts of a single logical + package as multiple directories. + + It also looks for *.pkg files beginning where * matches the name + argument. This feature is similar to *.pth files (see site.py), + except that it doesn't special-case lines starting with 'import'. + A *.pkg file is trusted at face value: apart from checking for + duplicates, all entries found in a *.pkg file are added to the + path, regardless of whether they are exist the filesystem. (This + is a feature.) + + If the input path is not a list (as is the case for frozen + packages) it is returned unchanged. The input path is not + modified; an extended copy is returned. Items are only appended + to the copy at the end. + + It is assumed that sys.path is a sequence. Items of sys.path that + are not (unicode or 8-bit) strings referring to existing + directories are ignored. Unicode items of sys.path that cause + errors when used as filenames may cause this function to raise an + exception (in line with os.path.isdir() behavior). + """ + + if not isinstance(path, list): + # This could happen e.g. when this is called from inside a + # frozen package. Return the path unchanged in that case. + return path + + pname = os.path.join(*name.split('.')) # Reconstitute as relative path + # Just in case os.extsep != '.' + sname = os.extsep.join(name.split('.')) + sname_pkg = sname + os.extsep + "pkg" + init_py = "__init__" + os.extsep + "py" + + path = path[:] # Start with a copy of the existing path + + for dir in sys.path: + if not isinstance(dir, basestring) or not os.path.isdir(dir): + continue + subdir = os.path.join(dir, pname) + # XXX This may still add duplicate entries to path on + # case-insensitive filesystems + initfile = os.path.join(subdir, init_py) + if subdir not in path and os.path.isfile(initfile): + path.append(subdir) + # XXX Is this the right thing for subpackages like zope.app? + # It looks for a file named "zope.app.pkg" + pkgfile = os.path.join(dir, sname_pkg) + if os.path.isfile(pkgfile): + try: + f = open(pkgfile) + except IOError, msg: + sys.stderr.write("Can't open %s: %s\n" % + (pkgfile, msg)) + else: + try: + for line in f: + line = line.rstrip('\n') + if not line or line.startswith('#'): + continue + path.append(line) # Don't check for existence! + finally: + f.close() + + return path + +def get_data(package, resource): + """Get a resource from a package. + + This is a wrapper round the PEP 302 loader get_data API. The package + argument should be the name of a package, in standard module format + (foo.bar). The resource argument should be in the form of a relative + filename, using '/' as the path separator. The parent directory name '..' + is not allowed, and nor is a rooted name (starting with a '/'). + + The function returns a binary string, which is the contents of the + specified resource. + + For packages located in the filesystem, which have already been imported, + this is the rough equivalent of + + d = os.path.dirname(sys.modules[package].__file__) + data = open(os.path.join(d, resource), 'rb').read() + + If the package cannot be located or loaded, or it uses a PEP 302 loader + which does not support get_data(), then None is returned. + """ + + loader = get_loader(package) + if loader is None or not hasattr(loader, 'get_data'): + return None + mod = sys.modules.get(package) or loader.load_module(package) + if mod is None or not hasattr(mod, '__file__'): + return None + + # Modify the resource name to be compatible with the loader.get_data + # signature - an os.path format "filename" starting with the dirname of + # the package's __file__ + parts = resource.split('/') + parts.insert(0, os.path.dirname(mod.__file__)) + resource_name = os.path.join(*parts) + return loader.get_data(resource_name) diff --git a/src/main/resources/PythonLibs/platform.py b/src/main/resources/PythonLibs/platform.py new file mode 100644 index 0000000000000000000000000000000000000000..855d856e137eaa90fdeded6013509c31a42d3c29 --- /dev/null +++ b/src/main/resources/PythonLibs/platform.py @@ -0,0 +1,1654 @@ +#!/usr/bin/env python + +""" This module tries to retrieve as much platform-identifying data as + possible. It makes this information available via function APIs. + + If called from the command line, it prints the platform + information concatenated as single string to stdout. The output + format is useable as part of a filename. + +""" +# This module is maintained by Marc-Andre Lemburg <mal@egenix.com>. +# If you find problems, please submit bug reports/patches via the +# Python bug tracker (http://bugs.python.org) and assign them to "lemburg". +# +# Note: Please keep this module compatible to Python 1.5.2. +# +# Still needed: +# * more support for WinCE +# * support for MS-DOS (PythonDX ?) +# * support for Amiga and other still unsupported platforms running Python +# * support for additional Linux distributions +# +# Many thanks to all those who helped adding platform-specific +# checks (in no particular order): +# +# Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell, +# Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef +# Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg +# Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark +# Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support), +# Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter +# +# History: +# +# <see CVS and SVN checkin messages for history> +# +# 1.0.7 - added DEV_NULL +# 1.0.6 - added linux_distribution() +# 1.0.5 - fixed Java support to allow running the module on Jython +# 1.0.4 - added IronPython support +# 1.0.3 - added normalization of Windows system name +# 1.0.2 - added more Windows support +# 1.0.1 - reformatted to make doc.py happy +# 1.0.0 - reformatted a bit and checked into Python CVS +# 0.8.0 - added sys.version parser and various new access +# APIs (python_version(), python_compiler(), etc.) +# 0.7.2 - fixed architecture() to use sizeof(pointer) where available +# 0.7.1 - added support for Caldera OpenLinux +# 0.7.0 - some fixes for WinCE; untabified the source file +# 0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and +# vms_lib.getsyi() configured +# 0.6.1 - added code to prevent 'uname -p' on platforms which are +# known not to support it +# 0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k; +# did some cleanup of the interfaces - some APIs have changed +# 0.5.5 - fixed another type in the MacOS code... should have +# used more coffee today ;-) +# 0.5.4 - fixed a few typos in the MacOS code +# 0.5.3 - added experimental MacOS support; added better popen() +# workarounds in _syscmd_ver() -- still not 100% elegant +# though +# 0.5.2 - fixed uname() to return '' instead of 'unknown' in all +# return values (the system uname command tends to return +# 'unknown' instead of just leaving the field emtpy) +# 0.5.1 - included code for slackware dist; added exception handlers +# to cover up situations where platforms don't have os.popen +# (e.g. Mac) or fail on socket.gethostname(); fixed libc +# detection RE +# 0.5.0 - changed the API names referring to system commands to *syscmd*; +# added java_ver(); made syscmd_ver() a private +# API (was system_ver() in previous versions) -- use uname() +# instead; extended the win32_ver() to also return processor +# type information +# 0.4.0 - added win32_ver() and modified the platform() output for WinXX +# 0.3.4 - fixed a bug in _follow_symlinks() +# 0.3.3 - fixed popen() and "file" command invokation bugs +# 0.3.2 - added architecture() API and support for it in platform() +# 0.3.1 - fixed syscmd_ver() RE to support Windows NT +# 0.3.0 - added system alias support +# 0.2.3 - removed 'wince' again... oh well. +# 0.2.2 - added 'wince' to syscmd_ver() supported platforms +# 0.2.1 - added cache logic and changed the platform string format +# 0.2.0 - changed the API to use functions instead of module globals +# since some action take too long to be run on module import +# 0.1.0 - first release +# +# You can always get the latest version of this module at: +# +# http://www.egenix.com/files/python/platform.py +# +# If that URL should fail, try contacting the author. + +__copyright__ = """ + Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:mal@lemburg.com + Copyright (c) 2000-2010, eGenix.com Software GmbH; mailto:info@egenix.com + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee or royalty 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 or portions thereof, including modifications, + that you make. + + EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO + THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE AUTHOR 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 ! + +""" + +__version__ = '1.0.7' + +import sys,string,os,re + +### Globals & Constants +if sys.platform.startswith("java"): + from java.lang import System + from org.python.core.Py import newString + +# Determine the platform's /dev/null device +try: + DEV_NULL = os.devnull +except AttributeError: + # os.devnull was added in Python 2.4, so emulate it for earlier + # Python versions + if sys.platform in ('dos','win32','win16','os2'): + # Use the old CP/M NUL as device name + DEV_NULL = 'NUL' + else: + # Standard Unix uses /dev/null + DEV_NULL = '/dev/null' + +### Platform specific APIs + +_libc_search = re.compile(r'(__libc_init)' + '|' + '(GLIBC_([0-9.]+))' + '|' + '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)') + +def libc_ver(executable=sys.executable,lib='',version='', + + chunksize=2048): + + """ Tries to determine the libc version that the file executable + (which defaults to the Python interpreter) is linked against. + + Returns a tuple of strings (lib,version) which default to the + given parameters in case the lookup fails. + + Note that the function has intimate knowledge of how different + libc versions add symbols to the executable and thus is probably + only useable for executables compiled using gcc. + + The file is read and scanned in chunks of chunksize bytes. + + """ + if hasattr(os.path, 'realpath'): + # Python 2.2 introduced os.path.realpath(); it is used + # here to work around problems with Cygwin not being + # able to open symlinks for reading + executable = os.path.realpath(executable) + f = open(executable,'rb') + binary = f.read(chunksize) + pos = 0 + while 1: + m = _libc_search.search(binary,pos) + if not m: + binary = f.read(chunksize) + if not binary: + break + pos = 0 + continue + libcinit,glibc,glibcversion,so,threads,soversion = m.groups() + if libcinit and not lib: + lib = 'libc' + elif glibc: + if lib != 'glibc': + lib = 'glibc' + version = glibcversion + elif glibcversion > version: + version = glibcversion + elif so: + if lib != 'glibc': + lib = 'libc' + if soversion and soversion > version: + version = soversion + if threads and version[-len(threads):] != threads: + version = version + threads + pos = m.end() + f.close() + return lib,version + +def _dist_try_harder(distname,version,id): + + """ Tries some special tricks to get the distribution + information in case the default method fails. + + Currently supports older SuSE Linux, Caldera OpenLinux and + Slackware Linux distributions. + + """ + if os.path.exists('/var/adm/inst-log/info'): + # SuSE Linux stores distribution information in that file + info = open('/var/adm/inst-log/info').readlines() + distname = 'SuSE' + for line in info: + tv = string.split(line) + if len(tv) == 2: + tag,value = tv + else: + continue + if tag == 'MIN_DIST_VERSION': + version = string.strip(value) + elif tag == 'DIST_IDENT': + values = string.split(value,'-') + id = values[2] + return distname,version,id + + if os.path.exists('/etc/.installed'): + # Caldera OpenLinux has some infos in that file (thanks to Colin Kong) + info = open('/etc/.installed').readlines() + for line in info: + pkg = string.split(line,'-') + if len(pkg) >= 2 and pkg[0] == 'OpenLinux': + # XXX does Caldera support non Intel platforms ? If yes, + # where can we find the needed id ? + return 'OpenLinux',pkg[1],id + + if os.path.isdir('/usr/lib/setup'): + # Check for slackware verson tag file (thanks to Greg Andruk) + verfiles = os.listdir('/usr/lib/setup') + for n in range(len(verfiles)-1, -1, -1): + if verfiles[n][:14] != 'slack-version-': + del verfiles[n] + if verfiles: + verfiles.sort() + distname = 'slackware' + version = verfiles[-1][14:] + return distname,version,id + + return distname,version,id + +_release_filename = re.compile(r'(\w+)[-_](release|version)') +_lsb_release_version = re.compile(r'(.+)' + ' release ' + '([\d.]+)' + '[^(]*(?:\((.+)\))?') +_release_version = re.compile(r'([^0-9]+)' + '(?: release )?' + '([\d.]+)' + '[^(]*(?:\((.+)\))?') + +# See also http://www.novell.com/coolsolutions/feature/11251.html +# and http://linuxmafia.com/faq/Admin/release-files.html +# and http://data.linux-ntfs.org/rpm/whichrpm +# and http://www.die.net/doc/linux/man/man1/lsb_release.1.html + +_supported_dists = ( + 'SuSE', 'debian', 'fedora', 'redhat', 'centos', + 'mandrake', 'mandriva', 'rocks', 'slackware', 'yellowdog', 'gentoo', + 'UnitedLinux', 'turbolinux') + +def _parse_release_file(firstline): + + # Default to empty 'version' and 'id' strings. Both defaults are used + # when 'firstline' is empty. 'id' defaults to empty when an id can not + # be deduced. + version = '' + id = '' + + # Parse the first line + m = _lsb_release_version.match(firstline) + if m is not None: + # LSB format: "distro release x.x (codename)" + return tuple(m.groups()) + + # Pre-LSB format: "distro x.x (codename)" + m = _release_version.match(firstline) + if m is not None: + return tuple(m.groups()) + + # Unkown format... take the first two words + l = string.split(string.strip(firstline)) + if l: + version = l[0] + if len(l) > 1: + id = l[1] + return '', version, id + +def linux_distribution(distname='', version='', id='', + + supported_dists=_supported_dists, + full_distribution_name=1): + + """ Tries to determine the name of the Linux OS distribution name. + + The function first looks for a distribution release file in + /etc and then reverts to _dist_try_harder() in case no + suitable files are found. + + supported_dists may be given to define the set of Linux + distributions to look for. It defaults to a list of currently + supported Linux distributions identified by their release file + name. + + If full_distribution_name is true (default), the full + distribution read from the OS is returned. Otherwise the short + name taken from supported_dists is used. + + Returns a tuple (distname,version,id) which default to the + args given as parameters. + + """ + try: + etc = os.listdir('/etc') + except os.error: + # Probably not a Unix system + return distname,version,id + etc.sort() + for file in etc: + m = _release_filename.match(file) + if m is not None: + _distname,dummy = m.groups() + if _distname in supported_dists: + distname = _distname + break + else: + return _dist_try_harder(distname,version,id) + + # Read the first line + f = open('/etc/'+file, 'r') + firstline = f.readline() + f.close() + _distname, _version, _id = _parse_release_file(firstline) + + if _distname and full_distribution_name: + distname = _distname + if _version: + version = _version + if _id: + id = _id + return distname, version, id + +# To maintain backwards compatibility: + +def dist(distname='',version='',id='', + + supported_dists=_supported_dists): + + """ Tries to determine the name of the Linux OS distribution name. + + The function first looks for a distribution release file in + /etc and then reverts to _dist_try_harder() in case no + suitable files are found. + + Returns a tuple (distname,version,id) which default to the + args given as parameters. + + """ + return linux_distribution(distname, version, id, + supported_dists=supported_dists, + full_distribution_name=0) + +class _popen: + + """ Fairly portable (alternative) popen implementation. + + This is mostly needed in case os.popen() is not available, or + doesn't work as advertised, e.g. in Win9X GUI programs like + PythonWin or IDLE. + + Writing to the pipe is currently not supported. + + """ + tmpfile = '' + pipe = None + bufsize = None + mode = 'r' + + def __init__(self,cmd,mode='r',bufsize=None): + + if mode != 'r': + raise ValueError,'popen()-emulation only supports read mode' + import tempfile + self.tmpfile = tmpfile = tempfile.mktemp() + os.system(cmd + ' > %s' % tmpfile) + self.pipe = open(tmpfile,'rb') + self.bufsize = bufsize + self.mode = mode + + def read(self): + + return self.pipe.read() + + def readlines(self): + + if self.bufsize is not None: + return self.pipe.readlines() + + def close(self, + + remove=os.unlink,error=os.error): + + if self.pipe: + rc = self.pipe.close() + else: + rc = 255 + if self.tmpfile: + try: + remove(self.tmpfile) + except error: + pass + return rc + + # Alias + __del__ = close + +def popen(cmd, mode='r', bufsize=None): + + """ Portable popen() interface. + """ + # Find a working popen implementation preferring win32pipe.popen + # over os.popen over _popen + popen = None + if os.environ.get('OS','') == 'Windows_NT': + # On NT win32pipe should work; on Win9x it hangs due to bugs + # in the MS C lib (see MS KnowledgeBase article Q150956) + try: + import win32pipe + except ImportError: + pass + else: + popen = win32pipe.popen + if popen is None: + if hasattr(os,'popen'): + popen = os.popen + # Check whether it works... it doesn't in GUI programs + # on Windows platforms + if sys.platform == 'win32': # XXX Others too ? + try: + popen('') + except os.error: + popen = _popen + else: + popen = _popen + if bufsize is None: + return popen(cmd,mode) + else: + return popen(cmd,mode,bufsize) + +def _norm_version(version, build=''): + + """ Normalize the version and build strings and return a single + version string using the format major.minor.build (or patchlevel). + """ + l = string.split(version,'.') + if build: + l.append(build) + try: + ints = map(int,l) + except ValueError: + strings = l + else: + strings = map(str,ints) + version = string.join(strings[:3],'.') + return version + +_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' + '.*' + '\[.* ([\d.]+)\])') + +# Examples of VER command output: +# +# Windows 2000: Microsoft Windows 2000 [Version 5.00.2195] +# Windows XP: Microsoft Windows XP [Version 5.1.2600] +# Windows Vista: Microsoft Windows [Version 6.0.6002] +# +# Note that the "Version" string gets localized on different +# Windows versions. + +def _syscmd_ver(system='', release='', version='', + + supported_platforms=('win32','win16','dos','os2')): + + """ Tries to figure out the OS version used and returns + a tuple (system,release,version). + + It uses the "ver" shell command for this which is known + to exists on Windows, DOS and OS/2. XXX Others too ? + + In case this fails, the given parameters are used as + defaults. + + """ + if sys.platform not in supported_platforms: + return system,release,version + + # Try some common cmd strings + for cmd in ('ver','command /c ver','cmd /c ver'): + try: + pipe = popen(cmd) + info = pipe.read() + if pipe.close(): + raise os.error,'command failed' + # XXX How can I suppress shell errors from being written + # to stderr ? + except os.error,why: + #print 'Command %s failed: %s' % (cmd,why) + continue + except IOError,why: + #print 'Command %s failed: %s' % (cmd,why) + continue + else: + break + else: + return system,release,version + + # Parse the output + info = string.strip(info) + m = _ver_output.match(info) + if m is not None: + system,release,version = m.groups() + # Strip trailing dots from version and release + if release[-1] == '.': + release = release[:-1] + if version[-1] == '.': + version = version[:-1] + # Normalize the version and build strings (eliminating additional + # zeros) + version = _norm_version(version) + return system,release,version + +def _win32_getvalue(key,name,default=''): + + """ Read a value for name from the registry key. + + In case this fails, default is returned. + + """ + try: + # Use win32api if available + from win32api import RegQueryValueEx + except ImportError: + # On Python 2.0 and later, emulate using _winreg + import _winreg + RegQueryValueEx = _winreg.QueryValueEx + try: + return RegQueryValueEx(key,name) + except: + return default + +def win32_ver(release='',version='',csd='',ptype=''): + + """ Get additional version information from the Windows Registry + and return a tuple (version,csd,ptype) referring to version + number, CSD level (service pack), and OS type (multi/single + processor). + + As a hint: ptype returns 'Uniprocessor Free' on single + processor NT machines and 'Multiprocessor Free' on multi + processor machines. The 'Free' refers to the OS version being + free of debugging code. It could also state 'Checked' which + means the OS version uses debugging code, i.e. code that + checks arguments, ranges, etc. (Thomas Heller). + + Note: this function works best with Mark Hammond's win32 + package installed, but also on Python 2.3 and later. It + obviously only runs on Win32 compatible platforms. + + """ + # XXX Is there any way to find out the processor type on WinXX ? + # XXX Is win32 available on Windows CE ? + # + # Adapted from code posted by Karl Putland to comp.lang.python. + # + # The mappings between reg. values and release names can be found + # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp + + # Import the needed APIs + try: + import win32api + from win32api import RegQueryValueEx, RegOpenKeyEx, \ + RegCloseKey, GetVersionEx + from win32con import HKEY_LOCAL_MACHINE, VER_PLATFORM_WIN32_NT, \ + VER_PLATFORM_WIN32_WINDOWS, VER_NT_WORKSTATION + except ImportError: + # Emulate the win32api module using Python APIs + try: + sys.getwindowsversion + except AttributeError: + # No emulation possible, so return the defaults... + return release,version,csd,ptype + else: + # Emulation using _winreg (added in Python 2.0) and + # sys.getwindowsversion() (added in Python 2.3) + import _winreg + GetVersionEx = sys.getwindowsversion + RegQueryValueEx = _winreg.QueryValueEx + RegOpenKeyEx = _winreg.OpenKeyEx + RegCloseKey = _winreg.CloseKey + HKEY_LOCAL_MACHINE = _winreg.HKEY_LOCAL_MACHINE + VER_PLATFORM_WIN32_WINDOWS = 1 + VER_PLATFORM_WIN32_NT = 2 + VER_NT_WORKSTATION = 1 + VER_NT_SERVER = 3 + REG_SZ = 1 + + # Find out the registry key and some general version infos + winver = GetVersionEx() + maj,min,buildno,plat,csd = winver + version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF) + if hasattr(winver, "service_pack"): + if winver.service_pack != "": + csd = 'SP%s' % winver.service_pack_major + else: + if csd[:13] == 'Service Pack ': + csd = 'SP' + csd[13:] + + if plat == VER_PLATFORM_WIN32_WINDOWS: + regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion' + # Try to guess the release name + if maj == 4: + if min == 0: + release = '95' + elif min == 10: + release = '98' + elif min == 90: + release = 'Me' + else: + release = 'postMe' + elif maj == 5: + release = '2000' + + elif plat == VER_PLATFORM_WIN32_NT: + regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' + if maj <= 4: + release = 'NT' + elif maj == 5: + if min == 0: + release = '2000' + elif min == 1: + release = 'XP' + elif min == 2: + release = '2003Server' + else: + release = 'post2003' + elif maj == 6: + if hasattr(winver, "product_type"): + product_type = winver.product_type + else: + product_type = VER_NT_WORKSTATION + # Without an OSVERSIONINFOEX capable sys.getwindowsversion(), + # or help from the registry, we cannot properly identify + # non-workstation versions. + try: + key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey) + name, type = RegQueryValueEx(key, "ProductName") + # Discard any type that isn't REG_SZ + if type == REG_SZ and name.find("Server") != -1: + product_type = VER_NT_SERVER + except WindowsError: + # Use default of VER_NT_WORKSTATION + pass + + if min == 0: + if product_type == VER_NT_WORKSTATION: + release = 'Vista' + else: + release = '2008Server' + elif min == 1: + if product_type == VER_NT_WORKSTATION: + release = '7' + else: + release = '2008ServerR2' + elif min == 2: + if product_type == VER_NT_WORKSTATION: + release = '8' + else: + release = '2012Server' + else: + release = 'post2012Server' + + else: + if not release: + # E.g. Win3.1 with win32s + release = '%i.%i' % (maj,min) + return release,version,csd,ptype + + # Open the registry key + try: + keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey) + # Get a value to make sure the key exists... + RegQueryValueEx(keyCurVer, 'SystemRoot') + except: + return release,version,csd,ptype + + # Parse values + #subversion = _win32_getvalue(keyCurVer, + # 'SubVersionNumber', + # ('',1))[0] + #if subversion: + # release = release + subversion # 95a, 95b, etc. + build = _win32_getvalue(keyCurVer, + 'CurrentBuildNumber', + ('',1))[0] + ptype = _win32_getvalue(keyCurVer, + 'CurrentType', + (ptype,1))[0] + + # Normalize version + version = _norm_version(version,build) + + # Close key + RegCloseKey(keyCurVer) + return release,version,csd,ptype + +def _mac_ver_lookup(selectors,default=None): + + from gestalt import gestalt + import MacOS + l = [] + append = l.append + for selector in selectors: + try: + append(gestalt(selector)) + except (RuntimeError, MacOS.Error): + append(default) + return l + +def _bcd2str(bcd): + + return hex(bcd)[2:] + +def _mac_ver_gestalt(): + """ + Thanks to Mark R. Levinson for mailing documentation links and + code examples for this function. Documentation for the + gestalt() API is available online at: + + http://www.rgaros.nl/gestalt/ + """ + # Check whether the version info module is available + try: + import gestalt + import MacOS + except ImportError: + return None + # Get the infos + sysv,sysa = _mac_ver_lookup(('sysv','sysa')) + # Decode the infos + if sysv: + major = (sysv & 0xFF00) >> 8 + minor = (sysv & 0x00F0) >> 4 + patch = (sysv & 0x000F) + + if (major, minor) >= (10, 4): + # the 'sysv' gestald cannot return patchlevels + # higher than 9. Apple introduced 3 new + # gestalt codes in 10.4 to deal with this + # issue (needed because patch levels can + # run higher than 9, such as 10.4.11) + major,minor,patch = _mac_ver_lookup(('sys1','sys2','sys3')) + release = '%i.%i.%i' %(major, minor, patch) + else: + release = '%s.%i.%i' % (_bcd2str(major),minor,patch) + + if sysa: + machine = {0x1: '68k', + 0x2: 'PowerPC', + 0xa: 'i386'}.get(sysa,'') + + versioninfo=('', '', '') + return release,versioninfo,machine + +def _mac_ver_xml(): + fn = '/System/Library/CoreServices/SystemVersion.plist' + if not os.path.exists(fn): + return None + + try: + import plistlib + except ImportError: + return None + + pl = plistlib.readPlist(fn) + release = pl['ProductVersion'] + versioninfo=('', '', '') + machine = os.uname()[4] + if machine in ('ppc', 'Power Macintosh'): + # for compatibility with the gestalt based code + machine = 'PowerPC' + + return release,versioninfo,machine + + +def mac_ver(release='',versioninfo=('','',''),machine=''): + + """ Get MacOS version information and return it as tuple (release, + versioninfo, machine) with versioninfo being a tuple (version, + dev_stage, non_release_version). + + Entries which cannot be determined are set to the paramter values + which default to ''. All tuple entries are strings. + """ + + # First try reading the information from an XML file which should + # always be present + info = _mac_ver_xml() + if info is not None: + return info + + # If that doesn't work for some reason fall back to reading the + # information using gestalt calls. + info = _mac_ver_gestalt() + if info is not None: + return info + + # If that also doesn't work return the default values + return release,versioninfo,machine + +def _java_getprop(name,default): + + try: + value = System.getProperty(name) + if value is None: + return default + return newString(value) + except AttributeError: + return default + +def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): + + """ Version interface for Jython. + + Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being + a tuple (vm_name,vm_release,vm_vendor) and osinfo being a + tuple (os_name,os_version,os_arch). + + Values which cannot be determined are set to the defaults + given as parameters (which all default to ''). + + """ + # Import the needed APIs + try: + import java.lang + except ImportError: + return release,vendor,vminfo,osinfo + + vendor = _java_getprop('java.vendor', vendor) + release = _java_getprop('java.version', release) + vm_name, vm_release, vm_vendor = vminfo + vm_name = _java_getprop('java.vm.name', vm_name) + vm_vendor = _java_getprop('java.vm.vendor', vm_vendor) + vm_release = _java_getprop('java.vm.version', vm_release) + vminfo = vm_name, vm_release, vm_vendor + os_name, os_version, os_arch = osinfo + os_arch = _java_getprop('os.arch', os_arch) + os_name = _java_getprop('os.name', os_name) + os_version = _java_getprop('os.version', os_version) + osinfo = os_name, os_version, os_arch + + return release, vendor, vminfo, osinfo + +### System name aliasing + +def system_alias(system,release,version): + + """ Returns (system,release,version) aliased to common + marketing names used for some systems. + + It also does some reordering of the information in some cases + where it would otherwise cause confusion. + + """ + if system == 'Rhapsody': + # Apple's BSD derivative + # XXX How can we determine the marketing release number ? + return 'MacOS X Server',system+release,version + + elif system == 'SunOS': + # Sun's OS + if release < '5': + # These releases use the old name SunOS + return system,release,version + # Modify release (marketing release = SunOS release - 3) + l = string.split(release,'.') + if l: + try: + major = int(l[0]) + except ValueError: + pass + else: + major = major - 3 + l[0] = str(major) + release = string.join(l,'.') + if release < '6': + system = 'Solaris' + else: + # XXX Whatever the new SunOS marketing name is... + system = 'Solaris' + + elif system == 'IRIX64': + # IRIX reports IRIX64 on platforms with 64-bit support; yet it + # is really a version and not a different platform, since 32-bit + # apps are also supported.. + system = 'IRIX' + if version: + version = version + ' (64bit)' + else: + version = '64bit' + + elif system in ('win32','win16'): + # In case one of the other tricks + system = 'Windows' + + return system,release,version + +### Various internal helpers + +def _platform(*args): + + """ Helper to format the platform string in a filename + compatible format e.g. "system-version-machine". + """ + # Format the platform string + platform = string.join( + map(string.strip, + filter(len, args)), + '-') + + # Cleanup some possible filename obstacles... + replace = string.replace + platform = replace(platform,' ','_') + platform = replace(platform,'/','-') + platform = replace(platform,'\\','-') + platform = replace(platform,':','-') + platform = replace(platform,';','-') + platform = replace(platform,'"','-') + platform = replace(platform,'(','-') + platform = replace(platform,')','-') + + # No need to report 'unknown' information... + platform = replace(platform,'unknown','') + + # Fold '--'s and remove trailing '-' + while 1: + cleaned = replace(platform,'--','-') + if cleaned == platform: + break + platform = cleaned + while platform[-1] == '-': + platform = platform[:-1] + + return platform + +def _node(default=''): + + """ Helper to determine the node name of this machine. + """ + try: + import socket + except ImportError: + # No sockets... + return default + try: + return socket.gethostname() + except socket.error: + # Still not working... + return default + +# os.path.abspath is new in Python 1.5.2: +if not hasattr(os.path,'abspath'): + + def _abspath(path, + + isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd, + normpath=os.path.normpath): + + if not isabs(path): + path = join(getcwd(), path) + return normpath(path) + +else: + + _abspath = os.path.abspath + +def _follow_symlinks(filepath): + + """ In case filepath is a symlink, follow it until a + real file is reached. + """ + filepath = _abspath(filepath) + while os.path.islink(filepath): + filepath = os.path.normpath( + os.path.join(os.path.dirname(filepath),os.readlink(filepath))) + return filepath + +def _syscmd_uname(option,default=''): + + """ Interface to the system's uname command. + """ + if sys.platform in ('dos','win32','win16','os2') or \ + (sys.platform.startswith('java') and os._name == 'nt'): + # XXX Others too ? + return default + try: + f = os.popen('uname %s 2> %s' % (option, DEV_NULL)) + except (AttributeError,os.error): + return default + output = string.strip(f.read()) + rc = f.close() + if not output or rc: + return default + else: + return output + +def _syscmd_file(target,default=''): + + """ Interface to the system's file command. + + The function uses the -b option of the file command to have it + ommit the filename in its output and if possible the -L option + to have the command follow symlinks. It returns default in + case the command should fail. + + """ + + # We do the import here to avoid a bootstrap issue. + # See c73b90b6dadd changeset. + # + # [..] + # ranlib libpython2.7.a + # gcc -o python \ + # Modules/python.o \ + # libpython2.7.a -lsocket -lnsl -ldl -lm + # Traceback (most recent call last): + # File "./setup.py", line 8, in <module> + # from platform import machine as platform_machine + # File "[..]/build/Lib/platform.py", line 116, in <module> + # import sys,string,os,re,subprocess + # File "[..]/build/Lib/subprocess.py", line 429, in <module> + # import select + # ImportError: No module named select + + import subprocess + + if sys.platform in ('dos','win32','win16','os2'): + # XXX Others too ? + return default + target = _follow_symlinks(target) + try: + proc = subprocess.Popen(['file', target], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + + except (AttributeError,os.error): + return default + output = proc.communicate()[0] + rc = proc.wait() + if not output or rc: + return default + else: + return output + +### Information about the used architecture + +# Default values for architecture; non-empty strings override the +# defaults given as parameters +_default_architecture = { + 'win32': ('','WindowsPE'), + 'win16': ('','Windows'), + 'dos': ('','MSDOS'), +} + +_architecture_split = re.compile(r'[\s,]').split + +def architecture(executable=sys.executable,bits='',linkage=''): + + """ Queries the given executable (defaults to the Python interpreter + binary) for various architecture information. + + Returns a tuple (bits,linkage) which contains information about + the bit architecture and the linkage format used for the + executable. Both values are returned as strings. + + Values that cannot be determined are returned as given by the + parameter presets. If bits is given as '', the sizeof(pointer) + (or sizeof(long) on Python version < 1.5.2) is used as + indicator for the supported pointer size. + + The function relies on the system's "file" command to do the + actual work. This is available on most if not all Unix + platforms. On some non-Unix platforms where the "file" command + does not exist and the executable is set to the Python interpreter + binary defaults from _default_architecture are used. + + """ + # Use the sizeof(pointer) as default number of bits if nothing + # else is given as default. + if not bits: + import struct + try: + size = struct.calcsize('P') + except struct.error: + # Older installations can only query longs + size = struct.calcsize('l') + bits = str(size*8) + 'bit' + + # Get data from the 'file' system command + if executable: + output = _syscmd_file(executable, '') + else: + output = '' + + if not output and \ + executable == sys.executable: + # "file" command did not return anything; we'll try to provide + # some sensible defaults then... + if sys.platform in _default_architecture: + b, l = _default_architecture[sys.platform] + if b: + bits = b + if l: + linkage = l + return bits, linkage + + # Split the output into a list of strings omitting the filename + fileout = _architecture_split(output)[1:] + + if 'executable' not in fileout: + # Format not supported + return bits,linkage + + # Bits + if '32-bit' in fileout: + bits = '32bit' + elif 'N32' in fileout: + # On Irix only + bits = 'n32bit' + elif '64-bit' in fileout: + bits = '64bit' + + # Linkage + if 'ELF' in fileout: + linkage = 'ELF' + elif 'PE' in fileout: + # E.g. Windows uses this format + if 'Windows' in fileout: + linkage = 'WindowsPE' + else: + linkage = 'PE' + elif 'COFF' in fileout: + linkage = 'COFF' + elif 'MS-DOS' in fileout: + linkage = 'MSDOS' + else: + # XXX the A.OUT format also falls under this class... + pass + + return bits,linkage + +### Portable uname() interface + +_uname_cache = None + +def uname(): + + """ Fairly portable uname interface. Returns a tuple + of strings (system,node,release,version,machine,processor) + identifying the underlying platform. + + Note that unlike the os.uname function this also returns + possible processor information as an additional tuple entry. + + Entries which cannot be determined are set to ''. + + """ + global _uname_cache + no_os_uname = 0 + + if _uname_cache is not None: + return _uname_cache + + processor = '' + + # Get some infos from the builtin os.uname API... + try: + system,node,release,version,machine = os.uname() + except AttributeError: + no_os_uname = 1 + + if no_os_uname or not filter(None, (system, node, release, version, machine)): + # Hmm, no there is either no uname or uname has returned + #'unknowns'... we'll have to poke around the system then. + if no_os_uname: + system = sys.platform + release = '' + version = '' + node = _node() + machine = '' + + use_syscmd_ver = 1 + + # Try win32_ver() on win32 platforms + if system == 'win32': + release,version,csd,ptype = win32_ver() + if release and version: + use_syscmd_ver = 0 + # Try to use the PROCESSOR_* environment variables + # available on Win XP and later; see + # http://support.microsoft.com/kb/888731 and + # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM + if not machine: + # WOW64 processes mask the native architecture + if "PROCESSOR_ARCHITEW6432" in os.environ: + machine = os.environ.get("PROCESSOR_ARCHITEW6432", '') + else: + machine = os.environ.get('PROCESSOR_ARCHITECTURE', '') + if not processor: + processor = os.environ.get('PROCESSOR_IDENTIFIER', machine) + + # Try the 'ver' system command available on some + # platforms + if use_syscmd_ver: + system,release,version = _syscmd_ver(system) + # Normalize system to what win32_ver() normally returns + # (_syscmd_ver() tends to return the vendor name as well) + if system == 'Microsoft Windows': + system = 'Windows' + elif system == 'Microsoft' and release == 'Windows': + # Under Windows Vista and Windows Server 2008, + # Microsoft changed the output of the ver command. The + # release is no longer printed. This causes the + # system and release to be misidentified. + system = 'Windows' + if '6.0' == version[:3]: + release = 'Vista' + else: + release = '' + + # In case we still don't know anything useful, we'll try to + # help ourselves + if system in ('win32','win16'): + if not version: + if system == 'win32': + version = '32bit' + else: + version = '16bit' + system = 'Windows' + + elif system[:4] == 'java': + release,vendor,vminfo,osinfo = java_ver() + system = 'Java' + version = string.join(vminfo,', ') + if not version: + version = vendor + + # System specific extensions + if system == 'OpenVMS': + # OpenVMS seems to have release and version mixed up + if not release or release == '0': + release = version + version = '' + # Get processor information + try: + import vms_lib + except ImportError: + pass + else: + csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0) + if (cpu_number >= 128): + processor = 'Alpha' + else: + processor = 'VAX' + if not processor: + # Get processor information from the uname system command + processor = _syscmd_uname('-p','') + + #If any unknowns still exist, replace them with ''s, which are more portable + if system == 'unknown': + system = '' + if node == 'unknown': + node = '' + if release == 'unknown': + release = '' + if version == 'unknown': + version = '' + if machine == 'unknown': + machine = '' + if processor == 'unknown': + processor = '' + + # normalize name + if system == 'Microsoft' and release == 'Windows': + system = 'Windows' + release = 'Vista' + + _uname_cache = system,node,release,version,machine,processor + return _uname_cache + +### Direct interfaces to some of the uname() return values + +def system(): + + """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'. + + An empty string is returned if the value cannot be determined. + + """ + return uname()[0] + +def node(): + + """ Returns the computer's network name (which may not be fully + qualified) + + An empty string is returned if the value cannot be determined. + + """ + return uname()[1] + +def release(): + + """ Returns the system's release, e.g. '2.2.0' or 'NT' + + An empty string is returned if the value cannot be determined. + + """ + return uname()[2] + +def version(): + + """ Returns the system's release version, e.g. '#3 on degas' + + An empty string is returned if the value cannot be determined. + + """ + return uname()[3] + +def machine(): + + """ Returns the machine type, e.g. 'i386' + + An empty string is returned if the value cannot be determined. + + """ + return uname()[4] + +def processor(): + + """ Returns the (true) processor name, e.g. 'amdk6' + + An empty string is returned if the value cannot be + determined. Note that many platforms do not provide this + information or simply return the same value as for machine(), + e.g. NetBSD does this. + + """ + return uname()[5] + +### Various APIs for extracting information from sys.version + +_sys_version_parser = re.compile( + r'([\w.+]+)\s*' + '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' + '\[([^\]]+)\]?') + +_jython_sys_version_parser = re.compile( + r'([\d\.]+)') + +_ironpython_sys_version_parser = re.compile( + r'IronPython\s*' + '([\d\.]+)' + '(?: \(([\d\.]+)\))?' + ' on (.NET [\d\.]+)') + +_pypy_sys_version_parser = re.compile( + r'([\w.+]+)\s*' + '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' + '\[PyPy [^\]]+\]?') + +_sys_version_cache = {} + +def _sys_version(sys_version=None): + + """ Returns a parsed version of Python's sys.version as tuple + (name, version, branch, revision, buildno, builddate, compiler) + referring to the Python implementation name, version, branch, + revision, build number, build date/time as string and the compiler + identification string. + + Note that unlike the Python sys.version, the returned value + for the Python version will always include the patchlevel (it + defaults to '.0'). + + The function returns empty strings for tuple entries that + cannot be determined. + + sys_version may be given to parse an alternative version + string, e.g. if the version was read from a different Python + interpreter. + + """ + # Get the Python version + if sys_version is None: + sys_version = sys.version + + # Try the cache first + result = _sys_version_cache.get(sys_version, None) + if result is not None: + return result + + # Parse it + if sys_version[:10] == 'IronPython': + # IronPython + name = 'IronPython' + match = _ironpython_sys_version_parser.match(sys_version) + if match is None: + raise ValueError( + 'failed to parse IronPython sys.version: %s' % + repr(sys_version)) + version, alt_version, compiler = match.groups() + branch = '' + revision = '' + buildno = '' + builddate = '' + + elif sys.platform[:4] == 'java': + # Jython + name = 'Jython' + match = _jython_sys_version_parser.match(sys_version) + if match is None: + raise ValueError( + 'failed to parse Jython sys.version: %s' % + repr(sys_version)) + version, = match.groups() + branch = '' + revision = '' + compiler = sys.platform + buildno = '' + builddate = '' + + elif "PyPy" in sys_version: + # PyPy + name = "PyPy" + match = _pypy_sys_version_parser.match(sys_version) + if match is None: + raise ValueError("failed to parse PyPy sys.version: %s" % + repr(sys_version)) + version, buildno, builddate, buildtime = match.groups() + compiler = "" + + else: + # CPython + match = _sys_version_parser.match(sys_version) + if match is None: + raise ValueError( + 'failed to parse CPython sys.version: %s' % + repr(sys_version)) + version, buildno, builddate, buildtime, compiler = \ + match.groups() + name = 'CPython' + builddate = builddate + ' ' + buildtime + + if hasattr(sys, 'subversion'): + # sys.subversion was added in Python 2.5 + _, branch, revision = sys.subversion + else: + branch = '' + revision = '' + + # Add the patchlevel version if missing + l = string.split(version, '.') + if len(l) == 2: + l.append('0') + version = string.join(l, '.') + + # Build and cache the result + result = (name, version, branch, revision, buildno, builddate, compiler) + _sys_version_cache[sys_version] = result + return result + +def python_implementation(): + + """ Returns a string identifying the Python implementation. + + Currently, the following implementations are identified: + 'CPython' (C implementation of Python), + 'IronPython' (.NET implementation of Python), + 'Jython' (Java implementation of Python), + 'PyPy' (Python implementation of Python). + + """ + return _sys_version()[0] + +def python_version(): + + """ Returns the Python version as string 'major.minor.patchlevel' + + Note that unlike the Python sys.version, the returned value + will always include the patchlevel (it defaults to 0). + + """ + return _sys_version()[1] + +def python_version_tuple(): + + """ Returns the Python version as tuple (major, minor, patchlevel) + of strings. + + Note that unlike the Python sys.version, the returned value + will always include the patchlevel (it defaults to 0). + + """ + return tuple(string.split(_sys_version()[1], '.')) + +def python_branch(): + + """ Returns a string identifying the Python implementation + branch. + + For CPython this is the Subversion branch from which the + Python binary was built. + + If not available, an empty string is returned. + + """ + + return _sys_version()[2] + +def python_revision(): + + """ Returns a string identifying the Python implementation + revision. + + For CPython this is the Subversion revision from which the + Python binary was built. + + If not available, an empty string is returned. + + """ + return _sys_version()[3] + +def python_build(): + + """ Returns a tuple (buildno, builddate) stating the Python + build number and date as strings. + + """ + return _sys_version()[4:6] + +def python_compiler(): + + """ Returns a string identifying the compiler used for compiling + Python. + + """ + return _sys_version()[6] + +### The Opus Magnum of platform strings :-) + +_platform_cache = {} + +def platform(aliased=0, terse=0): + + """ Returns a single string identifying the underlying platform + with as much useful information as possible (but no more :). + + The output is intended to be human readable rather than + machine parseable. It may look different on different + platforms and this is intended. + + If "aliased" is true, the function will use aliases for + various platforms that report system names which differ from + their common names, e.g. SunOS will be reported as + Solaris. The system_alias() function is used to implement + this. + + Setting terse to true causes the function to return only the + absolute minimum information needed to identify the platform. + + """ + result = _platform_cache.get((aliased, terse), None) + if result is not None: + return result + + # Get uname information and then apply platform specific cosmetics + # to it... + system,node,release,version,machine,processor = uname() + if machine == processor: + processor = '' + if aliased: + system,release,version = system_alias(system,release,version) + + if system == 'Windows': + # MS platforms + rel,vers,csd,ptype = win32_ver(version) + if terse: + platform = _platform(system,release) + else: + platform = _platform(system,release,version,csd) + + elif system in ('Linux',): + # Linux based systems + distname,distversion,distid = dist('') + if distname and not terse: + platform = _platform(system,release,machine,processor, + 'with', + distname,distversion,distid) + else: + # If the distribution name is unknown check for libc vs. glibc + libcname,libcversion = libc_ver(sys.executable) + platform = _platform(system,release,machine,processor, + 'with', + libcname+libcversion) + elif system == 'Java': + # Java platforms + r,v,vminfo,(os_name,os_version,os_arch) = java_ver() + if terse or not os_name: + platform = _platform(system,release,version) + else: + platform = _platform(system,release,version, + 'on', + os_name,os_version,os_arch) + + elif system == 'MacOS': + # MacOS platforms + if terse: + platform = _platform(system,release) + else: + platform = _platform(system,release,machine) + + else: + # Generic handler + if terse: + platform = _platform(system,release) + else: + bits,linkage = architecture(sys.executable) + platform = _platform(system,release,machine,processor,bits,linkage) + + _platform_cache[(aliased, terse)] = platform + return platform + +### Command line interface + +if __name__ == '__main__': + # Default is to print the aliased verbose platform string + terse = ('terse' in sys.argv or '--terse' in sys.argv) + aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv) + print platform(aliased,terse) + sys.exit(0) diff --git a/src/main/resources/PythonLibs/plistlib.py b/src/main/resources/PythonLibs/plistlib.py new file mode 100644 index 0000000000000000000000000000000000000000..51944eecb0f01c7bc27b6600e6f33a58272fd0b1 --- /dev/null +++ b/src/main/resources/PythonLibs/plistlib.py @@ -0,0 +1,474 @@ +r"""plistlib.py -- a tool to generate and parse MacOSX .plist files. + +The PropertyList (.plist) file format is a simple XML pickle supporting +basic object types, like dictionaries, lists, numbers and strings. +Usually the top level object is a dictionary. + +To write out a plist file, use the writePlist(rootObject, pathOrFile) +function. 'rootObject' is the top level object, 'pathOrFile' is a +filename or a (writable) file object. + +To parse a plist from a file, use the readPlist(pathOrFile) function, +with a file name or a (readable) file object as the only argument. It +returns the top level object (again, usually a dictionary). + +To work with plist data in strings, you can use readPlistFromString() +and writePlistToString(). + +Values can be strings, integers, floats, booleans, tuples, lists, +dictionaries, Data or datetime.datetime objects. String values (including +dictionary keys) may be unicode strings -- they will be written out as +UTF-8. + +The <data> plist type is supported through the Data class. This is a +thin wrapper around a Python string. + +Generate Plist example: + + pl = dict( + aString="Doodah", + aList=["A", "B", 12, 32.1, [1, 2, 3]], + aFloat=0.1, + anInt=728, + aDict=dict( + anotherString="<hello & hi there!>", + aUnicodeValue=u'M\xe4ssig, Ma\xdf', + aTrueValue=True, + aFalseValue=False, + ), + someData=Data("<binary gunk>"), + someMoreData=Data("<lots of binary gunk>" * 10), + aDate=datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), + ) + # unicode keys are possible, but a little awkward to use: + pl[u'\xc5benraa'] = "That was a unicode key." + writePlist(pl, fileName) + +Parse Plist example: + + pl = readPlist(pathOrFile) + print pl["aKey"] +""" + + +__all__ = [ + "readPlist", "writePlist", "readPlistFromString", "writePlistToString", + "readPlistFromResource", "writePlistToResource", + "Plist", "Data", "Dict" +] +# Note: the Plist and Dict classes have been deprecated. + +import binascii +import datetime +from cStringIO import StringIO +import re +import warnings + + +def readPlist(pathOrFile): + """Read a .plist file. 'pathOrFile' may either be a file name or a + (readable) file object. Return the unpacked root object (which + usually is a dictionary). + """ + didOpen = 0 + if isinstance(pathOrFile, (str, unicode)): + pathOrFile = open(pathOrFile) + didOpen = 1 + p = PlistParser() + rootObject = p.parse(pathOrFile) + if didOpen: + pathOrFile.close() + return rootObject + + +def writePlist(rootObject, pathOrFile): + """Write 'rootObject' to a .plist file. 'pathOrFile' may either be a + file name or a (writable) file object. + """ + didOpen = 0 + if isinstance(pathOrFile, (str, unicode)): + pathOrFile = open(pathOrFile, "w") + didOpen = 1 + writer = PlistWriter(pathOrFile) + writer.writeln("<plist version=\"1.0\">") + writer.writeValue(rootObject) + writer.writeln("</plist>") + if didOpen: + pathOrFile.close() + + +def readPlistFromString(data): + """Read a plist data from a string. Return the root object. + """ + return readPlist(StringIO(data)) + + +def writePlistToString(rootObject): + """Return 'rootObject' as a plist-formatted string. + """ + f = StringIO() + writePlist(rootObject, f) + return f.getvalue() + + +def readPlistFromResource(path, restype='plst', resid=0): + """Read plst resource from the resource fork of path. + """ + warnings.warnpy3k("In 3.x, readPlistFromResource is removed.", + stacklevel=2) + from Carbon.File import FSRef, FSGetResourceForkName + from Carbon.Files import fsRdPerm + from Carbon import Res + fsRef = FSRef(path) + resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdPerm) + Res.UseResFile(resNum) + plistData = Res.Get1Resource(restype, resid).data + Res.CloseResFile(resNum) + return readPlistFromString(plistData) + + +def writePlistToResource(rootObject, path, restype='plst', resid=0): + """Write 'rootObject' as a plst resource to the resource fork of path. + """ + warnings.warnpy3k("In 3.x, writePlistToResource is removed.", stacklevel=2) + from Carbon.File import FSRef, FSGetResourceForkName + from Carbon.Files import fsRdWrPerm + from Carbon import Res + plistData = writePlistToString(rootObject) + fsRef = FSRef(path) + resNum = Res.FSOpenResourceFile(fsRef, FSGetResourceForkName(), fsRdWrPerm) + Res.UseResFile(resNum) + try: + Res.Get1Resource(restype, resid).RemoveResource() + except Res.Error: + pass + res = Res.Resource(plistData) + res.AddResource(restype, resid, '') + res.WriteResource() + Res.CloseResFile(resNum) + + +class DumbXMLWriter: + + def __init__(self, file, indentLevel=0, indent="\t"): + self.file = file + self.stack = [] + self.indentLevel = indentLevel + self.indent = indent + + def beginElement(self, element): + self.stack.append(element) + self.writeln("<%s>" % element) + self.indentLevel += 1 + + def endElement(self, element): + assert self.indentLevel > 0 + assert self.stack.pop() == element + self.indentLevel -= 1 + self.writeln("</%s>" % element) + + def simpleElement(self, element, value=None): + if value is not None: + value = _escapeAndEncode(value) + self.writeln("<%s>%s</%s>" % (element, value, element)) + else: + self.writeln("<%s/>" % element) + + def writeln(self, line): + if line: + self.file.write(self.indentLevel * self.indent + line + "\n") + else: + self.file.write("\n") + + +# Contents should conform to a subset of ISO 8601 +# (in particular, YYYY '-' MM '-' DD 'T' HH ':' MM ':' SS 'Z'. Smaller units may be omitted with +# a loss of precision) +_dateParser = re.compile(r"(?P<year>\d\d\d\d)(?:-(?P<month>\d\d)(?:-(?P<day>\d\d)(?:T(?P<hour>\d\d)(?::(?P<minute>\d\d)(?::(?P<second>\d\d))?)?)?)?)?Z") + +def _dateFromString(s): + order = ('year', 'month', 'day', 'hour', 'minute', 'second') + gd = _dateParser.match(s).groupdict() + lst = [] + for key in order: + val = gd[key] + if val is None: + break + lst.append(int(val)) + return datetime.datetime(*lst) + +def _dateToString(d): + return '%04d-%02d-%02dT%02d:%02d:%02dZ' % ( + d.year, d.month, d.day, + d.hour, d.minute, d.second + ) + + +# Regex to find any control chars, except for \t \n and \r +_controlCharPat = re.compile( + r"[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f" + r"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]") + +def _escapeAndEncode(text): + m = _controlCharPat.search(text) + if m is not None: + raise ValueError("strings can't contains control characters; " + "use plistlib.Data instead") + text = text.replace("\r\n", "\n") # convert DOS line endings + text = text.replace("\r", "\n") # convert Mac line endings + text = text.replace("&", "&") # escape '&' + text = text.replace("<", "<") # escape '<' + text = text.replace(">", ">") # escape '>' + return text.encode("utf-8") # encode as UTF-8 + + +PLISTHEADER = """\ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +""" + +class PlistWriter(DumbXMLWriter): + + def __init__(self, file, indentLevel=0, indent="\t", writeHeader=1): + if writeHeader: + file.write(PLISTHEADER) + DumbXMLWriter.__init__(self, file, indentLevel, indent) + + def writeValue(self, value): + if isinstance(value, (str, unicode)): + self.simpleElement("string", value) + elif isinstance(value, bool): + # must switch for bool before int, as bool is a + # subclass of int... + if value: + self.simpleElement("true") + else: + self.simpleElement("false") + elif isinstance(value, (int, long)): + self.simpleElement("integer", "%d" % value) + elif isinstance(value, float): + self.simpleElement("real", repr(value)) + elif isinstance(value, dict): + self.writeDict(value) + elif isinstance(value, Data): + self.writeData(value) + elif isinstance(value, datetime.datetime): + self.simpleElement("date", _dateToString(value)) + elif isinstance(value, (tuple, list)): + self.writeArray(value) + else: + raise TypeError("unsuported type: %s" % type(value)) + + def writeData(self, data): + self.beginElement("data") + self.indentLevel -= 1 + maxlinelength = 76 - len(self.indent.replace("\t", " " * 8) * + self.indentLevel) + for line in data.asBase64(maxlinelength).split("\n"): + if line: + self.writeln(line) + self.indentLevel += 1 + self.endElement("data") + + def writeDict(self, d): + self.beginElement("dict") + items = d.items() + items.sort() + for key, value in items: + if not isinstance(key, (str, unicode)): + raise TypeError("keys must be strings") + self.simpleElement("key", key) + self.writeValue(value) + self.endElement("dict") + + def writeArray(self, array): + self.beginElement("array") + for value in array: + self.writeValue(value) + self.endElement("array") + + +class _InternalDict(dict): + + # This class is needed while Dict is scheduled for deprecation: + # we only need to warn when a *user* instantiates Dict or when + # the "attribute notation for dict keys" is used. + + def __getattr__(self, attr): + try: + value = self[attr] + except KeyError: + raise AttributeError, attr + from warnings import warn + warn("Attribute access from plist dicts is deprecated, use d[key] " + "notation instead", PendingDeprecationWarning, 2) + return value + + def __setattr__(self, attr, value): + from warnings import warn + warn("Attribute access from plist dicts is deprecated, use d[key] " + "notation instead", PendingDeprecationWarning, 2) + self[attr] = value + + def __delattr__(self, attr): + try: + del self[attr] + except KeyError: + raise AttributeError, attr + from warnings import warn + warn("Attribute access from plist dicts is deprecated, use d[key] " + "notation instead", PendingDeprecationWarning, 2) + +class Dict(_InternalDict): + + def __init__(self, **kwargs): + from warnings import warn + warn("The plistlib.Dict class is deprecated, use builtin dict instead", + PendingDeprecationWarning, 2) + super(Dict, self).__init__(**kwargs) + + +class Plist(_InternalDict): + + """This class has been deprecated. Use readPlist() and writePlist() + functions instead, together with regular dict objects. + """ + + def __init__(self, **kwargs): + from warnings import warn + warn("The Plist class is deprecated, use the readPlist() and " + "writePlist() functions instead", PendingDeprecationWarning, 2) + super(Plist, self).__init__(**kwargs) + + def fromFile(cls, pathOrFile): + """Deprecated. Use the readPlist() function instead.""" + rootObject = readPlist(pathOrFile) + plist = cls() + plist.update(rootObject) + return plist + fromFile = classmethod(fromFile) + + def write(self, pathOrFile): + """Deprecated. Use the writePlist() function instead.""" + writePlist(self, pathOrFile) + + +def _encodeBase64(s, maxlinelength=76): + # copied from base64.encodestring(), with added maxlinelength argument + maxbinsize = (maxlinelength//4)*3 + pieces = [] + for i in range(0, len(s), maxbinsize): + chunk = s[i : i + maxbinsize] + pieces.append(binascii.b2a_base64(chunk)) + return "".join(pieces) + +class Data: + + """Wrapper for binary data.""" + + def __init__(self, data): + self.data = data + + def fromBase64(cls, data): + # base64.decodestring just calls binascii.a2b_base64; + # it seems overkill to use both base64 and binascii. + return cls(binascii.a2b_base64(data)) + fromBase64 = classmethod(fromBase64) + + def asBase64(self, maxlinelength=76): + return _encodeBase64(self.data, maxlinelength) + + def __cmp__(self, other): + if isinstance(other, self.__class__): + return cmp(self.data, other.data) + elif isinstance(other, str): + return cmp(self.data, other) + else: + return cmp(id(self), id(other)) + + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, repr(self.data)) + + +class PlistParser: + + def __init__(self): + self.stack = [] + self.currentKey = None + self.root = None + + def parse(self, fileobj): + from xml.parsers.expat import ParserCreate + parser = ParserCreate() + parser.StartElementHandler = self.handleBeginElement + parser.EndElementHandler = self.handleEndElement + parser.CharacterDataHandler = self.handleData + parser.ParseFile(fileobj) + return self.root + + def handleBeginElement(self, element, attrs): + self.data = [] + handler = getattr(self, "begin_" + element, None) + if handler is not None: + handler(attrs) + + def handleEndElement(self, element): + handler = getattr(self, "end_" + element, None) + if handler is not None: + handler() + + def handleData(self, data): + self.data.append(data) + + def addObject(self, value): + if self.currentKey is not None: + self.stack[-1][self.currentKey] = value + self.currentKey = None + elif not self.stack: + # this is the root object + self.root = value + else: + self.stack[-1].append(value) + + def getData(self): + data = "".join(self.data) + try: + data = data.encode("ascii") + except UnicodeError: + pass + self.data = [] + return data + + # element handlers + + def begin_dict(self, attrs): + d = _InternalDict() + self.addObject(d) + self.stack.append(d) + def end_dict(self): + self.stack.pop() + + def end_key(self): + self.currentKey = self.getData() + + def begin_array(self, attrs): + a = [] + self.addObject(a) + self.stack.append(a) + def end_array(self): + self.stack.pop() + + def end_true(self): + self.addObject(True) + def end_false(self): + self.addObject(False) + def end_integer(self): + self.addObject(int(self.getData())) + def end_real(self): + self.addObject(float(self.getData())) + def end_string(self): + self.addObject(self.getData()) + def end_data(self): + self.addObject(Data.fromBase64(self.getData())) + def end_date(self): + self.addObject(_dateFromString(self.getData())) diff --git a/src/main/resources/PythonLibs/popen2.py b/src/main/resources/PythonLibs/popen2.py new file mode 100644 index 0000000000000000000000000000000000000000..88dadafbb43c32e2f4062b014375615fe50d9a8d --- /dev/null +++ b/src/main/resources/PythonLibs/popen2.py @@ -0,0 +1,190 @@ +"""Spawn a command with pipes to its stdin, stdout, and optionally stderr. + +The normal os.popen(cmd, mode) call spawns a shell command and provides a +file interface to just the input or output of the process depending on +whether mode is 'r' or 'w'. This module provides the functions popen2(cmd) +and popen3(cmd) which return two or three pipes to the spawned command. +""" + +import os +import subprocess +import sys + +__all__ = ["popen2", "popen3", "popen4"] + +MAXFD = subprocess.MAXFD +_active = subprocess._active +_cleanup = subprocess._cleanup + +class Popen3: + """Class representing a child process. Normally instances are created + by the factory functions popen2() and popen3().""" + + sts = -1 # Child not completed yet + + def __init__(self, cmd, capturestderr=False, bufsize=-1): + """The parameter 'cmd' is the shell command to execute 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()). The 'capturestderr' flag, if true, specifies + that the object should capture standard error output of the child + process. The default is false. If the 'bufsize' parameter is + specified, it specifies the size of the I/O buffers to/from the child + process.""" + stderr = subprocess.PIPE if capturestderr else None + PIPE = subprocess.PIPE + self._popen = subprocess.Popen(cmd, bufsize=bufsize, + shell=isinstance(cmd, basestring), + stdin=PIPE, stdout=PIPE, stderr=stderr) + self._setup(cmd) + + def _setup(self, cmd): + """Setup the Popen attributes.""" + self.cmd = cmd + self.pid = self._popen.pid + self.tochild = self._popen.stdin + self.fromchild = self._popen.stdout + self.childerr = self._popen.stderr + + def __del__(self): + # XXX: Should let _popen __del__ on its own, but it's a new + # style class: http://bugs.jython.org/issue1057 + if hasattr(self, '_popen'): + self._popen.__del__() + + def poll(self, _deadstate=None): + """Return the exit status of the child process if it has finished, + or -1 if it hasn't finished yet.""" + if self.sts < 0: + result = self._popen.poll(_deadstate) + if result is not None: + self.sts = result + return self.sts + + def wait(self): + """Wait for and return the exit status of the child process.""" + if self.sts < 0: + self.sts = self._popen.wait() + return self.sts + + +class Popen4(Popen3): + childerr = None + + def __init__(self, cmd, bufsize=-1): + PIPE = subprocess.PIPE + self._popen = subprocess.Popen(cmd, bufsize=bufsize, + shell=isinstance(cmd, basestring), + stdin=PIPE, stdout=PIPE, + stderr=subprocess.STDOUT) + self._setup(cmd) + + +if sys.platform[:3] == "win" or sys.platform == "os2emx": + # Some things don't make sense on non-Unix platforms. + del Popen3, Popen4 + + def popen2(cmd, bufsize=-1, mode='t'): + """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_stdout, child_stdin) are returned.""" + w, r = os.popen2(cmd, mode, bufsize) + return r, w + + def popen3(cmd, bufsize=-1, mode='t'): + """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_stdout, child_stdin, child_stderr) are returned.""" + w, r, e = os.popen3(cmd, mode, bufsize) + return r, w, e + + def popen4(cmd, bufsize=-1, mode='t'): + """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_stdout_stderr, child_stdin) are returned.""" + w, r = os.popen4(cmd, mode, bufsize) + return r, w +else: + def popen2(cmd, bufsize=-1, mode='t'): + """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_stdout, child_stdin) are returned.""" + inst = Popen3(cmd, False, bufsize) + return inst.fromchild, inst.tochild + + def popen3(cmd, bufsize=-1, mode='t'): + """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_stdout, child_stdin, child_stderr) are returned.""" + inst = Popen3(cmd, True, bufsize) + return inst.fromchild, inst.tochild, inst.childerr + + def popen4(cmd, bufsize=-1, mode='t'): + """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_stdout_stderr, child_stdin) are returned.""" + inst = Popen4(cmd, bufsize) + return inst.fromchild, inst.tochild + + __all__.extend(["Popen3", "Popen4"]) + +def _test(): + # When the test runs, there shouldn't be any open pipes + _cleanup() + assert not _active, "Active pipes when test starts " + repr([c.cmd for c in _active]) + cmd = "cat" + teststr = "ab cd\n" + if os.name in ("nt", "java"): + cmd = "more" + # "more" doesn't act the same way across Windows flavors, + # sometimes adding an extra newline at the start or the + # end. So we strip whitespace off both ends for comparison. + expected = teststr.strip() + print "testing popen2..." + r, w = popen2(cmd) + w.write(teststr) + w.close() + got = r.read() + if got.strip() != expected: + raise ValueError("wrote %r read %r" % (teststr, got)) + print "testing popen3..." + try: + r, w, e = popen3([cmd]) + except: + r, w, e = popen3(cmd) + w.write(teststr) + w.close() + got = r.read() + if got.strip() != expected: + raise ValueError("wrote %r read %r" % (teststr, got)) + got = e.read() + if got: + raise ValueError("unexpected %r on stderr" % (got,)) + for inst in _active[:]: + inst.wait() + _cleanup() + if _active: + raise ValueError("_active not empty") + print "All OK" + +if __name__ == '__main__': + _test() diff --git a/src/main/resources/PythonLibs/poplib.py b/src/main/resources/PythonLibs/poplib.py new file mode 100644 index 0000000000000000000000000000000000000000..e2b33ef10f499fd75ab1d709b1a3c9d7b4ca4437 --- /dev/null +++ b/src/main/resources/PythonLibs/poplib.py @@ -0,0 +1,417 @@ +"""A POP3 client class. + +Based on the J. Myers POP3 draft, Jan. 96 +""" + +# Author: David Ascher <david_ascher@brown.edu> +# [heavily stealing from nntplib.py] +# Updated: Piers Lauder <piers@cs.su.oz.au> [Jul '97] +# String method conversion and test jig improvements by ESR, February 2001. +# Added the POP3_SSL class. Methods loosely based on IMAP_SSL. Hector Urtubia <urtubia@mrbook.org> Aug 2003 + +# Example (see the test function at the end of this file) + +# Imports + +import re, socket + +__all__ = ["POP3","error_proto"] + +# Exception raised when an error or invalid response is received: + +class error_proto(Exception): pass + +# Standard Port +POP3_PORT = 110 + +# POP SSL PORT +POP3_SSL_PORT = 995 + +# Line terminators (we always output CRLF, but accept any of CRLF, LFCR, LF) +CR = '\r' +LF = '\n' +CRLF = CR+LF + + +class POP3: + + """This class supports both the minimal and optional command sets. + Arguments can be strings or integers (where appropriate) + (e.g.: retr(1) and retr('1') both work equally well. + + Minimal Command Set: + USER name user(name) + PASS string pass_(string) + STAT stat() + LIST [msg] list(msg = None) + RETR msg retr(msg) + DELE msg dele(msg) + NOOP noop() + RSET rset() + QUIT quit() + + Optional Commands (some servers support these): + RPOP name rpop(name) + APOP name digest apop(name, digest) + TOP msg n top(msg, n) + UIDL [msg] uidl(msg = None) + + Raises one exception: 'error_proto'. + + Instantiate with: + POP3(hostname, port=110) + + NB: the POP protocol locks the mailbox from user + authorization until QUIT, so be sure to get in, suck + the messages, and quit, each time you access the + mailbox. + + POP is a line-based protocol, which means large mail + messages consume lots of python cycles reading them + line-by-line. + + If it's available on your mail server, use IMAP4 + instead, it doesn't suffer from the two problems + above. + """ + + + def __init__(self, host, port=POP3_PORT, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + self.host = host + self.port = port + self.sock = socket.create_connection((host, port), timeout) + self.file = self.sock.makefile('rb') + self._debugging = 0 + self.welcome = self._getresp() + + + def _putline(self, line): + if self._debugging > 1: print '*put*', repr(line) + self.sock.sendall('%s%s' % (line, CRLF)) + + + # Internal: send one command to the server (through _putline()) + + def _putcmd(self, line): + if self._debugging: print '*cmd*', repr(line) + self._putline(line) + + + # Internal: return one line from the server, stripping CRLF. + # This is where all the CPU time of this module is consumed. + # Raise error_proto('-ERR EOF') if the connection is closed. + + def _getline(self): + line = self.file.readline() + if self._debugging > 1: print '*get*', repr(line) + if not line: raise error_proto('-ERR EOF') + octets = len(line) + # server can send any combination of CR & LF + # however, 'readline()' returns lines ending in LF + # so only possibilities are ...LF, ...CRLF, CR...LF + if line[-2:] == CRLF: + return line[:-2], octets + if line[0] == CR: + return line[1:-1], octets + return line[:-1], octets + + + # Internal: get a response from the server. + # Raise 'error_proto' if the response doesn't start with '+'. + + def _getresp(self): + resp, o = self._getline() + if self._debugging > 1: print '*resp*', repr(resp) + c = resp[:1] + if c != '+': + raise error_proto(resp) + return resp + + + # Internal: get a response plus following text from the server. + + def _getlongresp(self): + resp = self._getresp() + list = []; octets = 0 + line, o = self._getline() + while line != '.': + if line[:2] == '..': + o = o-1 + line = line[1:] + octets = octets + o + list.append(line) + line, o = self._getline() + return resp, list, octets + + + # Internal: send a command and get the response + + def _shortcmd(self, line): + self._putcmd(line) + return self._getresp() + + + # Internal: send a command and get the response plus following text + + def _longcmd(self, line): + self._putcmd(line) + return self._getlongresp() + + + # These can be useful: + + def getwelcome(self): + return self.welcome + + + def set_debuglevel(self, level): + self._debugging = level + + + # Here are all the POP commands: + + def user(self, user): + """Send user name, return response + + (should indicate password required). + """ + return self._shortcmd('USER %s' % user) + + + def pass_(self, pswd): + """Send password, return response + + (response includes message count, mailbox size). + + NB: mailbox is locked by server from here to 'quit()' + """ + return self._shortcmd('PASS %s' % pswd) + + + def stat(self): + """Get mailbox status. + + Result is tuple of 2 ints (message count, mailbox size) + """ + retval = self._shortcmd('STAT') + rets = retval.split() + if self._debugging: print '*stat*', repr(rets) + numMessages = int(rets[1]) + sizeMessages = int(rets[2]) + return (numMessages, sizeMessages) + + + def list(self, which=None): + """Request listing, return result. + + Result without a message number argument is in form + ['response', ['mesg_num octets', ...], octets]. + + Result when a message number argument is given is a + single response: the "scan listing" for that message. + """ + if which is not None: + return self._shortcmd('LIST %s' % which) + return self._longcmd('LIST') + + + def retr(self, which): + """Retrieve whole message number 'which'. + + Result is in form ['response', ['line', ...], octets]. + """ + return self._longcmd('RETR %s' % which) + + + def dele(self, which): + """Delete message number 'which'. + + Result is 'response'. + """ + return self._shortcmd('DELE %s' % which) + + + def noop(self): + """Does nothing. + + One supposes the response indicates the server is alive. + """ + return self._shortcmd('NOOP') + + + def rset(self): + """Unmark all messages marked for deletion.""" + return self._shortcmd('RSET') + + + def quit(self): + """Signoff: commit changes on server, unlock mailbox, close connection.""" + try: + resp = self._shortcmd('QUIT') + except error_proto, val: + resp = val + self.file.close() + self.sock.close() + del self.file, self.sock + return resp + + #__del__ = quit + + + # optional commands: + + def rpop(self, user): + """Not sure what this does.""" + return self._shortcmd('RPOP %s' % user) + + + timestamp = re.compile(r'\+OK.*(<[^>]+>)') + + def apop(self, user, secret): + """Authorisation + + - only possible if server has supplied a timestamp in initial greeting. + + Args: + user - mailbox user; + secret - secret shared between client and server. + + NB: mailbox is locked by server from here to 'quit()' + """ + m = self.timestamp.match(self.welcome) + if not m: + raise error_proto('-ERR APOP not supported by server') + import hashlib + digest = hashlib.md5(m.group(1)+secret).digest() + digest = ''.join(map(lambda x:'%02x'%ord(x), digest)) + return self._shortcmd('APOP %s %s' % (user, digest)) + + + def top(self, which, howmuch): + """Retrieve message header of message number 'which' + and first 'howmuch' lines of message body. + + Result is in form ['response', ['line', ...], octets]. + """ + return self._longcmd('TOP %s %s' % (which, howmuch)) + + + def uidl(self, which=None): + """Return message digest (unique id) list. + + If 'which', result contains unique id for that message + in the form 'response mesgnum uid', otherwise result is + the list ['response', ['mesgnum uid', ...], octets] + """ + if which is not None: + return self._shortcmd('UIDL %s' % which) + return self._longcmd('UIDL') + +try: + import ssl +except ImportError: + pass +else: + + class POP3_SSL(POP3): + """POP3 client class over SSL connection + + Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None) + + hostname - the hostname of the pop3 over ssl server + port - port number + keyfile - PEM formatted file that countains your private key + certfile - PEM formatted certificate chain file + + See the methods of the parent class POP3 for more documentation. + """ + + def __init__(self, host, port = POP3_SSL_PORT, keyfile = None, certfile = None): + self.host = host + self.port = port + self.keyfile = keyfile + self.certfile = certfile + self.buffer = "" + msg = "getaddrinfo returns an empty list" + self.sock = None + for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + try: + self.sock = socket.socket(af, socktype, proto) + self.sock.connect(sa) + except socket.error, msg: + if self.sock: + self.sock.close() + self.sock = None + continue + break + if not self.sock: + raise socket.error, msg + self.file = self.sock.makefile('rb') + self.sslobj = ssl.wrap_socket(self.sock, self.keyfile, self.certfile) + self._debugging = 0 + self.welcome = self._getresp() + + def _fillBuffer(self): + localbuf = self.sslobj.read() + if len(localbuf) == 0: + raise error_proto('-ERR EOF') + self.buffer += localbuf + + def _getline(self): + line = "" + renewline = re.compile(r'.*?\n') + match = renewline.match(self.buffer) + while not match: + self._fillBuffer() + match = renewline.match(self.buffer) + line = match.group(0) + self.buffer = renewline.sub('' ,self.buffer, 1) + if self._debugging > 1: print '*get*', repr(line) + + octets = len(line) + if line[-2:] == CRLF: + return line[:-2], octets + if line[0] == CR: + return line[1:-1], octets + return line[:-1], octets + + def _putline(self, line): + if self._debugging > 1: print '*put*', repr(line) + line += CRLF + bytes = len(line) + while bytes > 0: + sent = self.sslobj.write(line) + if sent == bytes: + break # avoid copy + line = line[sent:] + bytes = bytes - sent + + def quit(self): + """Signoff: commit changes on server, unlock mailbox, close connection.""" + try: + resp = self._shortcmd('QUIT') + except error_proto, val: + resp = val + self.sock.close() + del self.sslobj, self.sock + return resp + + __all__.append("POP3_SSL") + +if __name__ == "__main__": + import sys + a = POP3(sys.argv[1]) + print a.getwelcome() + a.user(sys.argv[2]) + a.pass_(sys.argv[3]) + a.list() + (numMsgs, totalSize) = a.stat() + for i in range(1, numMsgs + 1): + (header, msg, octets) = a.retr(i) + print "Message %d:" % i + for line in msg: + print ' ' + line + print '-----------------------' + a.quit() diff --git a/src/main/resources/PythonLibs/posixfile.py b/src/main/resources/PythonLibs/posixfile.py new file mode 100644 index 0000000000000000000000000000000000000000..ff2910779bc6511afe41066a600ce53f16545bae --- /dev/null +++ b/src/main/resources/PythonLibs/posixfile.py @@ -0,0 +1,237 @@ +"""Extended file operations available in POSIX. + +f = posixfile.open(filename, [mode, [bufsize]]) + will create a new posixfile object + +f = posixfile.fileopen(fileobject) + will create a posixfile object from a builtin file object + +f.file() + will return the original builtin file object + +f.dup() + will return a new file object based on a new filedescriptor + +f.dup2(fd) + will return a new file object based on the given filedescriptor + +f.flags(mode) + will turn on the associated flag (merge) + mode can contain the following characters: + + (character representing a flag) + a append only flag + c close on exec flag + n no delay flag + s synchronization flag + (modifiers) + ! turn flags 'off' instead of default 'on' + = copy flags 'as is' instead of default 'merge' + ? return a string in which the characters represent the flags + that are set + + note: - the '!' and '=' modifiers are mutually exclusive. + - the '?' modifier will return the status of the flags after they + have been changed by other characters in the mode string + +f.lock(mode [, len [, start [, whence]]]) + will (un)lock a region + mode can contain the following characters: + + (character representing type of lock) + u unlock + r read lock + w write lock + (modifiers) + | wait until the lock can be granted + ? return the first lock conflicting with the requested lock + or 'None' if there is no conflict. The lock returned is in the + format (mode, len, start, whence, pid) where mode is a + character representing the type of lock ('r' or 'w') + + note: - the '?' modifier prevents a region from being locked; it is + query only +""" +import warnings +warnings.warn("The posixfile module is deprecated; " + "fcntl.lockf() provides better locking", DeprecationWarning, 2) + +class _posixfile_: + """File wrapper class that provides extra POSIX file routines.""" + + states = ['open', 'closed'] + + # + # Internal routines + # + def __repr__(self): + file = self._file_ + return "<%s posixfile '%s', mode '%s' at %s>" % \ + (self.states[file.closed], file.name, file.mode, \ + hex(id(self))[2:]) + + # + # Initialization routines + # + def open(self, name, mode='r', bufsize=-1): + import __builtin__ + return self.fileopen(__builtin__.open(name, mode, bufsize)) + + def fileopen(self, file): + import types + if repr(type(file)) != "<type 'file'>": + raise TypeError, 'posixfile.fileopen() arg must be file object' + self._file_ = file + # Copy basic file methods + for maybemethod in dir(file): + if not maybemethod.startswith('_'): + attr = getattr(file, maybemethod) + if isinstance(attr, types.BuiltinMethodType): + setattr(self, maybemethod, attr) + return self + + # + # New methods + # + def file(self): + return self._file_ + + def dup(self): + import posix + + if not hasattr(posix, 'fdopen'): + raise AttributeError, 'dup() method unavailable' + + return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode) + + def dup2(self, fd): + import posix + + if not hasattr(posix, 'fdopen'): + raise AttributeError, 'dup() method unavailable' + + posix.dup2(self._file_.fileno(), fd) + return posix.fdopen(fd, self._file_.mode) + + def flags(self, *which): + import fcntl, os + + if which: + if len(which) > 1: + raise TypeError, 'Too many arguments' + which = which[0] + else: which = '?' + + l_flags = 0 + if 'n' in which: l_flags = l_flags | os.O_NDELAY + if 'a' in which: l_flags = l_flags | os.O_APPEND + if 's' in which: l_flags = l_flags | os.O_SYNC + + file = self._file_ + + if '=' not in which: + cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0) + if '!' in which: l_flags = cur_fl & ~ l_flags + else: l_flags = cur_fl | l_flags + + l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags) + + if 'c' in which: + arg = ('!' not in which) # 0 is don't, 1 is do close on exec + l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg) + + if '?' in which: + which = '' # Return current flags + l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0) + if os.O_APPEND & l_flags: which = which + 'a' + if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1: + which = which + 'c' + if os.O_NDELAY & l_flags: which = which + 'n' + if os.O_SYNC & l_flags: which = which + 's' + return which + + def lock(self, how, *args): + import struct, fcntl + + if 'w' in how: l_type = fcntl.F_WRLCK + elif 'r' in how: l_type = fcntl.F_RDLCK + elif 'u' in how: l_type = fcntl.F_UNLCK + else: raise TypeError, 'no type of lock specified' + + if '|' in how: cmd = fcntl.F_SETLKW + elif '?' in how: cmd = fcntl.F_GETLK + else: cmd = fcntl.F_SETLK + + l_whence = 0 + l_start = 0 + l_len = 0 + + if len(args) == 1: + l_len = args[0] + elif len(args) == 2: + l_len, l_start = args + elif len(args) == 3: + l_len, l_start, l_whence = args + elif len(args) > 3: + raise TypeError, 'too many arguments' + + # Hack by davem@magnet.com to get locking to go on freebsd; + # additions for AIX by Vladimir.Marangozov@imag.fr + import sys, os + if sys.platform in ('netbsd1', + 'openbsd2', + 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', + 'freebsd6', 'freebsd7', 'freebsd8', + 'bsdos2', 'bsdos3', 'bsdos4'): + flock = struct.pack('lxxxxlxxxxlhh', \ + l_start, l_len, os.getpid(), l_type, l_whence) + elif sys.platform in ('aix3', 'aix4'): + flock = struct.pack('hhlllii', \ + l_type, l_whence, l_start, l_len, 0, 0, 0) + else: + flock = struct.pack('hhllhh', \ + l_type, l_whence, l_start, l_len, 0, 0) + + flock = fcntl.fcntl(self._file_.fileno(), cmd, flock) + + if '?' in how: + if sys.platform in ('netbsd1', + 'openbsd2', + 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5', + 'bsdos2', 'bsdos3', 'bsdos4'): + l_start, l_len, l_pid, l_type, l_whence = \ + struct.unpack('lxxxxlxxxxlhh', flock) + elif sys.platform in ('aix3', 'aix4'): + l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \ + struct.unpack('hhlllii', flock) + elif sys.platform == "linux2": + l_type, l_whence, l_start, l_len, l_pid, l_sysid = \ + struct.unpack('hhllhh', flock) + else: + l_type, l_whence, l_start, l_len, l_sysid, l_pid = \ + struct.unpack('hhllhh', flock) + + if l_type != fcntl.F_UNLCK: + if l_type == fcntl.F_RDLCK: + return 'r', l_len, l_start, l_whence, l_pid + else: + return 'w', l_len, l_start, l_whence, l_pid + +def open(name, mode='r', bufsize=-1): + """Public routine to open a file as a posixfile object.""" + return _posixfile_().open(name, mode, bufsize) + +def fileopen(file): + """Public routine to get a posixfile object from a Python file object.""" + return _posixfile_().fileopen(file) + +# +# Constants +# +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + +# +# End of posixfile.py +# diff --git a/src/main/resources/PythonLibs/posixpath.py b/src/main/resources/PythonLibs/posixpath.py new file mode 100644 index 0000000000000000000000000000000000000000..f6c0edda71911e53c5de10054829e6d80481e819 --- /dev/null +++ b/src/main/resources/PythonLibs/posixpath.py @@ -0,0 +1,513 @@ +"""Common operations on Posix pathnames. + +Instead of importing this module directly, import os and refer to +this module as os.path. The "os.path" name is an alias for this +module on Posix systems; on other systems (e.g. Mac, Windows), +os.path provides the same operations in a manner specific to that +platform, and is an alias to another module (e.g. macpath, ntpath). + +Some of this can actually be useful on non-Posix systems too, e.g. +for manipulation of the pathname component of URLs. +""" + +import os +import stat + +__all__ = ["normcase","isabs","join","splitdrive","split","splitext", + "basename","dirname","commonprefix","getsize","getmtime", + "getatime","getctime","islink","exists","lexists","isdir","isfile", + "walk","expanduser","expandvars","normpath","abspath", + "samefile", + "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 = ':' +defpath = ':/bin:/usr/bin' +altsep = None +devnull = '/dev/null' + +# Normalize the case of a pathname. Trivial in Posix, string.lower on Mac. +# On MS-DOS this may also turn slashes into backslashes; however, other +# normalizations (such as optimizing '../' away) are not allowed +# (another function should be defined to do that). + +def normcase(s): + """Normalize case of pathname. Has no effect under Posix""" + return s + + +# Return whether a path is absolute. +# Trivial in Posix, harder on the Mac or MS-DOS. + +def isabs(s): + """Test whether a path is absolute""" + return s.startswith('/') + + +# Join pathnames. +# Ignore the previous parts if a part is absolute. +# Insert a '/' unless the first part is empty or already ends in '/'. + +def join(a, *p): + """Join two or more pathname components, inserting '/' as needed""" + path = a + for b in p: + if b.startswith('/'): + path = b + elif path == '' or path.endswith('/'): + path += b + else: + path += '/' + b + return path + + +# Split a path in head (everything up to the last '/') and tail (the +# rest). If the path ends in '/', tail will be empty. If there is no +# '/' in the path, head will be empty. +# Trailing '/'es are stripped from head unless it is the root. + +def split(p): + """Split a pathname. Returns tuple "(head, tail)" where "tail" is + everything after the final slash. Either part may be empty.""" + i = p.rfind('/') + 1 + head, tail = p[:i], p[i:] + if head and head != '/'*len(head): + head = head.rstrip('/') + return 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): + """Split the extension from a pathname. Extension is everything from the + last dot to the end. Returns "(root, ext)", either part may be empty.""" + i = p.rfind('.') + if i<=p.rfind('/'): + return p, '' + else: + return p[:i], p[i:] + + +# Split a pathname into a drive specification and the rest of the +# path. Useful on DOS/Windows/NT; on Unix, the drive is always empty. + +def splitdrive(p): + """Split a pathname into drive and path. On Posix, drive is always + empty.""" + return '', p + + +# 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] + + +# 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 '' + s1 = min(m) + s2 = max(m) + n = min(len(s1), len(s2)) + for i in xrange(n): + if s1[i] != s2[i]: + return s1[:i] + return s1[:n] + +# Get size, mtime, atime of files. + +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 + +# Is a path a symbolic link? +# This will always return false on systems where os.lstat doesn't exist. + +def islink(path): + """Test whether a path is a symbolic link""" + try: + st = os.lstat(path) + except (os.error, AttributeError): + return False + return stat.S_ISLNK(st.st_mode) + + +# Does a path exist? +# This is false for dangling symbolic links. + +def exists(path): + """Test whether a path exists. Returns False for broken symbolic links""" + try: + st = os.stat(path) + except os.error: + return False + return True + + +# Being true for dangling symbolic links is also useful. + +def lexists(path): + """Test whether a path exists. Returns True for broken symbolic links""" + try: + st = os.lstat(path) + except os.error: + return False + return True + + +# Is a path a directory? +# This follows symbolic links, so both islink() and isdir() can be true +# for the same path. + +def isdir(path): + """Test whether a path is a directory""" + try: + st = os.stat(path) + except os.error: + return False + return stat.S_ISDIR(st.st_mode) + + +# Is a path a regular file? +# This follows symbolic links, so both islink() and isfile() can be true +# for the same path. + +def isfile(path): + """Test whether a path is a regular file""" + try: + st = os.stat(path) + except os.error: + return False + return stat.S_ISREG(st.st_mode) + + +# Are two filenames really pointing to the same file? + +if not os._native_posix: + import java.io.File + import java.io.IOException + from org.python.core.Py import newString + + def samefile(f1, f2): + """Test whether two pathnames reference the same actual file""" + canon1 = newString(java.io.File(_ensure_str(f1)).getCanonicalPath()) + canon2 = newString(java.io.File(_ensure_str(f2)).getCanonicalPath()) + return canon1 == canon2 +else: + 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) + + +# XXX: Jython currently lacks fstat +if hasattr(os, 'fstat'): + # 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) + + __all__.append("sameopenfile") + + +# XXX: Pure Java stat lacks st_ino/st_dev +if os._native_posix: + # 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 + + + # Is a path a mount point? + # (Does this work for all UNIXes? Is it even guaranteed to work by Posix?) + + def ismount(path): + """Test whether a path is a mount point""" + try: + s1 = os.lstat(path) + s2 = os.lstat(join(path, '..')) + except os.error: + return False # It doesn't exist -- so not a mount point :-) + dev1 = s1.st_dev + dev2 = s2.st_dev + if dev1 != dev2: + return True # path/.. on a different device as path + ino1 = s1.st_ino + ino2 = s2.st_ino + if ino1 == ino2: + return True # path/.. is the same i-node as path + return False + + __all__.extend(["samestat", "ismount"]) + + +# 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.""" + + try: + names = os.listdir(top) + except os.error: + return + func(arg, top, names) + for name in names: + name = join(top, name) + try: + st = os.lstat(name) + except os.error: + continue + if stat.S_ISDIR(st.st_mode): + 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 constructions. If user or $HOME is unknown, + do nothing.""" + if not path.startswith('~'): + return path + i = path.find('/', 1) + if i < 0: + i = len(path) + if i == 1: + if 'HOME' not in os.environ: + return path + else: + userhome = os.environ['HOME'] + else: + # XXX: Jython lacks the pwd module: '~user' isn't supported + return path + userhome = userhome.rstrip('/') + return userhome + path[i:] + + +# Expand paths containing shell variable substitutions. +# This expands the forms $variable and ${variable} only. +# Non-existent variables are left unchanged. + +_varprog = None + +def expandvars(path): + """Expand shell variables of form $var and ${var}. Unknown variables + are left unchanged.""" + global _varprog + if '$' not in path: + return path + if not _varprog: + import re + _varprog = re.compile(r'\$(\w+|\{[^}]*\})') + i = 0 + while True: + m = _varprog.search(path, i) + if not m: + break + i, j = m.span(0) + name = m.group(1) + if name.startswith('{') and name.endswith('}'): + name = name[1:-1] + if name in os.environ: + tail = path[j:] + path = path[:i] + os.environ[name] + i = len(path) + path += tail + else: + i = j + return path + + +# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. +# It should be understood that this may change the meaning of the path +# if it contains symbolic links! + +def normpath(path): + """Normalize path, eliminating double slashes, etc.""" + if path == '': + return '.' + initial_slashes = path.startswith('/') + # POSIX allows one or two initial slashes, but treats three or more + # as single slash. + if (initial_slashes and + path.startswith('//') and not path.startswith('///')): + initial_slashes = 2 + comps = path.split('/') + new_comps = [] + for comp in comps: + if comp in ('', '.'): + continue + if (comp != '..' or (not initial_slashes and not new_comps) or + (new_comps and new_comps[-1] == '..')): + new_comps.append(comp) + elif new_comps: + new_comps.pop() + comps = new_comps + path = '/'.join(comps) + if initial_slashes: + path = '/'*initial_slashes + path + return path or '.' + + +def abspath(path): + """Return an absolute path.""" + if not isabs(path): + path = join(os.getcwd(), path) + return normpath(path) + + +# Return a canonical path (i.e. the absolute location of a file on the +# filesystem). + +def realpath(filename): + """Return the canonical path of the specified filename, eliminating any +symbolic links encountered in the path.""" + if isabs(filename): + bits = ['/'] + filename.split('/')[1:] + else: + bits = [''] + filename.split('/') + + for i in range(2, len(bits)+1): + component = join(*bits[0:i]) + # Resolve symbolic links. + if islink(component): + resolved = _resolve_link(component) + if resolved is None: + # Infinite loop -- return original component + rest of the path + return abspath(join(*([component] + bits[i:]))) + else: + newpath = join(*([resolved] + bits[i:])) + return realpath(newpath) + + return abspath(filename) + + +if not os._native_posix: + def _resolve_link(path): + """Internal helper function. Takes a path and follows symlinks + until we either arrive at something that isn't a symlink, or + encounter a path we've seen before (meaning that there's a loop). + """ + try: + return newString(java.io.File(abspath(path)).getCanonicalPath()) + except java.io.IOException: + return None +else: + def _resolve_link(path): + """Internal helper function. Takes a path and follows symlinks + until we either arrive at something that isn't a symlink, or + encounter a path we've seen before (meaning that there's a loop). + """ + paths_seen = [] + while islink(path): + if path in paths_seen: + # Already seen this path, so we must have a symlink loop + return None + paths_seen.append(path) + # Resolve where the link points to + resolved = os.readlink(path) + if not isabs(resolved): + dir = dirname(path) + path = normpath(join(dir, resolved)) + else: + path = normpath(resolved) + return path + +def relpath(path, start=curdir): + """Return a relative version of a path""" + + if not path: + raise ValueError("no path specified") + + start_list = [x for x in abspath(start).split(sep) if x] + path_list = [x for x in abspath(path).split(sep) if x] + + # Work out how much of the filepath is shared by start and path. + i = len(commonprefix([start_list, path_list])) + + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir + return join(*rel_list) +def _ensure_str(obj): + """Ensure obj is a string, otherwise raise a TypeError""" + if isinstance(obj, basestring): + return obj + raise TypeError('coercing to Unicode: need string or buffer, %s found' % \ + _type_name(obj)) + + +def _type_name(obj): + """Determine the appropriate type name of obj for display""" + TPFLAGS_HEAPTYPE = 1 << 9 + type_name = '' + obj_type = type(obj) + is_heap = obj_type.__flags__ & TPFLAGS_HEAPTYPE == TPFLAGS_HEAPTYPE + if not is_heap and obj_type.__module__ != '__builtin__': + type_name = '%s.' % obj_type.__module__ + type_name += obj_type.__name__ + return type_name + +supports_unicode_filenames = False diff --git a/src/main/resources/PythonLibs/pprint.py b/src/main/resources/PythonLibs/pprint.py new file mode 100644 index 0000000000000000000000000000000000000000..910283e60913e3c209d0d9d4ed799796155bad31 --- /dev/null +++ b/src/main/resources/PythonLibs/pprint.py @@ -0,0 +1,350 @@ +# Author: Fred L. Drake, Jr. +# fdrake@acm.org +# +# This is a simple little module I wrote to make life easier. I didn't +# see anything quite like it in the library, though I may have overlooked +# something. I wrote this when I was trying to read some heavily nested +# tuples with fairly non-descriptive content. This is modeled very much +# after Lisp/Scheme - style pretty-printing of lists. If you find it +# useful, thank small children who sleep at night. + +"""Support to pretty-print lists, tuples, & dictionaries recursively. + +Very simple, but useful, especially in debugging data structures. + +Classes +------- + +PrettyPrinter() + Handle pretty-printing operations onto a stream using a configured + set of formatting parameters. + +Functions +--------- + +pformat() + Format a Python object into a pretty-printed representation. + +pprint() + Pretty-print a Python object to a stream [default is sys.stdout]. + +saferepr() + Generate a 'standard' repr()-like value, but protect against recursive + data structures. + +""" + +import sys as _sys +import warnings + +from cStringIO import StringIO as _StringIO + +__all__ = ["pprint","pformat","isreadable","isrecursive","saferepr", + "PrettyPrinter"] + +# cache these for faster access: +_commajoin = ", ".join +_id = id +_len = len +_type = type + + +def pprint(object, stream=None, indent=1, width=80, depth=None): + """Pretty-print a Python object to a stream [default is sys.stdout].""" + printer = PrettyPrinter( + stream=stream, indent=indent, width=width, depth=depth) + printer.pprint(object) + +def pformat(object, indent=1, width=80, depth=None): + """Format a Python object into a pretty-printed representation.""" + return PrettyPrinter(indent=indent, width=width, depth=depth).pformat(object) + +def saferepr(object): + """Version of repr() which can handle recursive data structures.""" + return _safe_repr(object, {}, None, 0)[0] + +def isreadable(object): + """Determine if saferepr(object) is readable by eval().""" + return _safe_repr(object, {}, None, 0)[1] + +def isrecursive(object): + """Determine if object requires a recursive representation.""" + return _safe_repr(object, {}, None, 0)[2] + +def _sorted(iterable): + with warnings.catch_warnings(): + if _sys.py3kwarning: + warnings.filterwarnings("ignore", "comparing unequal types " + "not supported", DeprecationWarning) + return sorted(iterable) + +class PrettyPrinter: + def __init__(self, indent=1, width=80, depth=None, stream=None): + """Handle pretty printing operations onto a stream using a set of + configured parameters. + + indent + Number of spaces to indent for each level of nesting. + + width + Attempted maximum number of columns in the output. + + depth + The maximum depth to print out nested structures. + + stream + The desired output stream. If omitted (or false), the standard + output stream available at construction will be used. + + """ + indent = int(indent) + width = int(width) + assert indent >= 0, "indent must be >= 0" + assert depth is None or depth > 0, "depth must be > 0" + assert width, "width must be != 0" + self._depth = depth + self._indent_per_level = indent + self._width = width + if stream is not None: + self._stream = stream + else: + self._stream = _sys.stdout + + def pprint(self, object): + self._format(object, self._stream, 0, 0, {}, 0) + self._stream.write("\n") + + def pformat(self, object): + sio = _StringIO() + self._format(object, sio, 0, 0, {}, 0) + return sio.getvalue() + + def isrecursive(self, object): + return self.format(object, {}, 0, 0)[2] + + def isreadable(self, object): + s, readable, recursive = self.format(object, {}, 0, 0) + return readable and not recursive + + def _format(self, object, stream, indent, allowance, context, level): + level = level + 1 + objid = _id(object) + if objid in context: + stream.write(_recursion(object)) + self._recursive = True + self._readable = False + return + rep = self._repr(object, context, level - 1) + typ = _type(object) + sepLines = _len(rep) > (self._width - 1 - indent - allowance) + write = stream.write + + if self._depth and level > self._depth: + write(rep) + return + + r = getattr(typ, "__repr__", None) + if issubclass(typ, dict) and r is dict.__repr__: + write('{') + if self._indent_per_level > 1: + write((self._indent_per_level - 1) * ' ') + length = _len(object) + if length: + context[objid] = 1 + indent = indent + self._indent_per_level + items = _sorted(object.items()) + key, ent = items[0] + rep = self._repr(key, context, level) + write(rep) + write(': ') + self._format(ent, stream, indent + _len(rep) + 2, + allowance + 1, context, level) + if length > 1: + for key, ent in items[1:]: + rep = self._repr(key, context, level) + if sepLines: + write(',\n%s%s: ' % (' '*indent, rep)) + else: + write(', %s: ' % rep) + self._format(ent, stream, indent + _len(rep) + 2, + allowance + 1, context, level) + indent = indent - self._indent_per_level + del context[objid] + write('}') + return + + if ((issubclass(typ, list) and r is list.__repr__) or + (issubclass(typ, tuple) and r is tuple.__repr__) or + (issubclass(typ, set) and r is set.__repr__) or + (issubclass(typ, frozenset) and r is frozenset.__repr__) + ): + length = _len(object) + if issubclass(typ, list): + write('[') + endchar = ']' + elif issubclass(typ, set): + if not length: + write('set()') + return + write('set([') + endchar = '])' + object = _sorted(object) + indent += 4 + elif issubclass(typ, frozenset): + if not length: + write('frozenset()') + return + write('frozenset([') + endchar = '])' + object = _sorted(object) + indent += 10 + else: + write('(') + endchar = ')' + if self._indent_per_level > 1 and sepLines: + write((self._indent_per_level - 1) * ' ') + if length: + context[objid] = 1 + indent = indent + self._indent_per_level + self._format(object[0], stream, indent, allowance + 1, + context, level) + if length > 1: + for ent in object[1:]: + if sepLines: + write(',\n' + ' '*indent) + else: + write(', ') + self._format(ent, stream, indent, + allowance + 1, context, level) + indent = indent - self._indent_per_level + del context[objid] + if issubclass(typ, tuple) and length == 1: + write(',') + write(endchar) + return + + write(rep) + + def _repr(self, object, context, level): + repr, readable, recursive = self.format(object, context.copy(), + self._depth, level) + if not readable: + self._readable = False + if recursive: + self._recursive = True + return repr + + def format(self, object, context, maxlevels, level): + """Format object for a specific context, returning a string + and flags indicating whether the representation is 'readable' + and whether the object represents a recursive construct. + """ + return _safe_repr(object, context, maxlevels, level) + + +# Return triple (repr_string, isreadable, isrecursive). + +def _safe_repr(object, context, maxlevels, level): + typ = _type(object) + if typ is str: + if 'locale' not in _sys.modules: + return repr(object), True, False + if "'" in object and '"' not in object: + closure = '"' + quotes = {'"': '\\"'} + else: + closure = "'" + quotes = {"'": "\\'"} + qget = quotes.get + sio = _StringIO() + write = sio.write + for char in object: + if char.isalpha(): + write(char) + else: + write(qget(char, repr(char)[1:-1])) + return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False + + r = getattr(typ, "__repr__", None) + if issubclass(typ, dict) and r is dict.__repr__: + if not object: + return "{}", True, False + objid = _id(object) + if maxlevels and level >= maxlevels: + return "{...}", False, objid in context + if objid in context: + return _recursion(object), False, True + context[objid] = 1 + readable = True + recursive = False + components = [] + append = components.append + level += 1 + saferepr = _safe_repr + for k, v in _sorted(object.items()): + krepr, kreadable, krecur = saferepr(k, context, maxlevels, level) + vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level) + append("%s: %s" % (krepr, vrepr)) + readable = readable and kreadable and vreadable + if krecur or vrecur: + recursive = True + del context[objid] + return "{%s}" % _commajoin(components), readable, recursive + + if (issubclass(typ, list) and r is list.__repr__) or \ + (issubclass(typ, tuple) and r is tuple.__repr__): + if issubclass(typ, list): + if not object: + return "[]", True, False + format = "[%s]" + elif _len(object) == 1: + format = "(%s,)" + else: + if not object: + return "()", True, False + format = "(%s)" + objid = _id(object) + if maxlevels and level >= maxlevels: + return format % "...", False, objid in context + if objid in context: + return _recursion(object), False, True + context[objid] = 1 + readable = True + recursive = False + components = [] + append = components.append + level += 1 + for o in object: + orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level) + append(orepr) + if not oreadable: + readable = False + if orecur: + recursive = True + del context[objid] + return format % _commajoin(components), readable, recursive + + rep = repr(object) + return rep, (rep and not rep.startswith('<')), False + + +def _recursion(object): + return ("<Recursion on %s with id=%s>" + % (_type(object).__name__, _id(object))) + + +def _perfcheck(object=None): + import time + if object is None: + object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000 + p = PrettyPrinter() + t1 = time.time() + _safe_repr(object, {}, None, 0) + t2 = time.time() + p.pformat(object) + t3 = time.time() + print "_safe_repr:", t2 - t1 + print "pformat:", t3 - t2 + +if __name__ == "__main__": + _perfcheck() diff --git a/src/main/resources/PythonLibs/profile.py b/src/main/resources/PythonLibs/profile.py new file mode 100644 index 0000000000000000000000000000000000000000..297aa04cf7cf3f624b8aa7c6d0077c7ee8c8e9e2 --- /dev/null +++ b/src/main/resources/PythonLibs/profile.py @@ -0,0 +1,610 @@ +#! /usr/bin/env python +# +# Class for profiling python code. rev 1.0 6/2/94 +# +# Written by James Roskind +# Based on prior profile module by Sjoerd Mullender... +# which was hacked somewhat by: Guido van Rossum + +"""Class for profiling Python code.""" + +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. + + +import sys +import os +import time +import marshal +from optparse import OptionParser + +__all__ = ["run", "runctx", "help", "Profile"] + +# Sample timer for use with +#i_count = 0 +#def integer_timer(): +# global i_count +# i_count = i_count + 1 +# return i_count +#itimes = integer_timer # replace with C coded timer returning integers + +#************************************************************************** +# The following are the static member functions for the profiler class +# Note that an instance of Profile() is *not* needed to call them. +#************************************************************************** + +def run(statement, filename=None, sort=-1): + """Run statement under profiler optionally saving results in filename + + This function takes a single argument that can be passed to the + "exec" statement, and an optional file name. In all cases this + routine attempts to "exec" its first argument and gather profiling + statistics from the execution. If no file name is present, then this + function automatically prints a simple profiling report, sorted by the + standard name string (file/line/function-name) that is presented in + each line. + """ + prof = Profile() + try: + prof = prof.run(statement) + except SystemExit: + pass + if filename is not None: + prof.dump_stats(filename) + else: + return prof.print_stats(sort) + +def runctx(statement, globals, locals, filename=None, sort=-1): + """Run statement under profiler, supplying your own globals and locals, + optionally saving results in filename. + + statement and filename have the same semantics as profile.run + """ + prof = Profile() + try: + prof = prof.runctx(statement, globals, locals) + except SystemExit: + pass + + if filename is not None: + prof.dump_stats(filename) + else: + return prof.print_stats(sort) + +# Backwards compatibility. +def help(): + print "Documentation for the profile module can be found " + print "in the Python Library Reference, section 'The Python Profiler'." + +if hasattr(os, "times"): + def _get_time_times(timer=os.times): + t = timer() + return t[0] + t[1] + +# Using getrusage(3) is better than clock(3) if available: +# on some systems (e.g. FreeBSD), getrusage has a higher resolution +# Furthermore, on a POSIX system, returns microseconds, which +# wrap around after 36min. +_has_res = 0 +try: + import resource + resgetrusage = lambda: resource.getrusage(resource.RUSAGE_SELF) + def _get_time_resource(timer=resgetrusage): + t = timer() + return t[0] + t[1] + _has_res = 1 +except ImportError: + pass + +class Profile: + """Profiler class. + + self.cur is always a tuple. Each such tuple corresponds to a stack + frame that is currently active (self.cur[-2]). The following are the + definitions of its members. We use this external "parallel stack" to + avoid contaminating the program that we are profiling. (old profiler + used to write into the frames local dictionary!!) Derived classes + can change the definition of some entries, as long as they leave + [-2:] intact (frame and previous tuple). In case an internal error is + detected, the -3 element is used as the function name. + + [ 0] = Time that needs to be charged to the parent frame's function. + It is used so that a function call will not have to access the + timing data for the parent frame. + [ 1] = Total time spent in this frame's function, excluding time in + subfunctions (this latter is tallied in cur[2]). + [ 2] = Total time spent in subfunctions, excluding time executing the + frame's function (this latter is tallied in cur[1]). + [-3] = Name of the function that corresponds to this frame. + [-2] = Actual frame that we correspond to (used to sync exception handling). + [-1] = Our parent 6-tuple (corresponds to frame.f_back). + + Timing data for each function is stored as a 5-tuple in the dictionary + self.timings[]. The index is always the name stored in self.cur[-3]. + The following are the definitions of the members: + + [0] = The number of times this function was called, not counting direct + or indirect recursion, + [1] = Number of times this function appears on the stack, minus one + [2] = Total time spent internal to this function + [3] = Cumulative time that this function was present on the stack. In + non-recursive functions, this is the total execution time from start + to finish of each invocation of a function, including time spent in + all subfunctions. + [4] = A dictionary indicating for each function name, the number of times + it was called by us. + """ + + bias = 0 # calibration constant + + def __init__(self, timer=None, bias=None): + self.timings = {} + self.cur = None + self.cmd = "" + self.c_func_name = "" + + if bias is None: + bias = self.bias + self.bias = bias # Materialize in local dict for lookup speed. + + if not timer: + if _has_res: + self.timer = resgetrusage + self.dispatcher = self.trace_dispatch + self.get_time = _get_time_resource + elif hasattr(time, 'clock'): + self.timer = self.get_time = time.clock + self.dispatcher = self.trace_dispatch_i + elif hasattr(os, 'times'): + self.timer = os.times + self.dispatcher = self.trace_dispatch + self.get_time = _get_time_times + else: + self.timer = self.get_time = time.time + self.dispatcher = self.trace_dispatch_i + else: + self.timer = timer + t = self.timer() # test out timer function + try: + length = len(t) + except TypeError: + self.get_time = timer + self.dispatcher = self.trace_dispatch_i + else: + if length == 2: + self.dispatcher = self.trace_dispatch + else: + self.dispatcher = self.trace_dispatch_l + # This get_time() implementation needs to be defined + # here to capture the passed-in timer in the parameter + # list (for performance). Note that we can't assume + # the timer() result contains two values in all + # cases. + def get_time_timer(timer=timer, sum=sum): + return sum(timer()) + self.get_time = get_time_timer + self.t = self.get_time() + self.simulate_call('profiler') + + # Heavily optimized dispatch routine for os.times() timer + + def trace_dispatch(self, frame, event, arg): + timer = self.timer + t = timer() + t = t[0] + t[1] - self.t - self.bias + + if event == "c_call": + self.c_func_name = arg.__name__ + + if self.dispatch[event](self, frame,t): + t = timer() + self.t = t[0] + t[1] + else: + r = timer() + self.t = r[0] + r[1] - t # put back unrecorded delta + + # Dispatch routine for best timer program (return = scalar, fastest if + # an integer but float works too -- and time.clock() relies on that). + + def trace_dispatch_i(self, frame, event, arg): + timer = self.timer + t = timer() - self.t - self.bias + + if event == "c_call": + self.c_func_name = arg.__name__ + + if self.dispatch[event](self, frame, t): + self.t = timer() + else: + self.t = timer() - t # put back unrecorded delta + + # Dispatch routine for macintosh (timer returns time in ticks of + # 1/60th second) + + def trace_dispatch_mac(self, frame, event, arg): + timer = self.timer + t = timer()/60.0 - self.t - self.bias + + if event == "c_call": + self.c_func_name = arg.__name__ + + if self.dispatch[event](self, frame, t): + self.t = timer()/60.0 + else: + self.t = timer()/60.0 - t # put back unrecorded delta + + # SLOW generic dispatch routine for timer returning lists of numbers + + def trace_dispatch_l(self, frame, event, arg): + get_time = self.get_time + t = get_time() - self.t - self.bias + + if event == "c_call": + self.c_func_name = arg.__name__ + + if self.dispatch[event](self, frame, t): + self.t = get_time() + else: + self.t = get_time() - t # put back unrecorded delta + + # In the event handlers, the first 3 elements of self.cur are unpacked + # into vrbls w/ 3-letter names. The last two characters are meant to be + # mnemonic: + # _pt self.cur[0] "parent time" time to be charged to parent frame + # _it self.cur[1] "internal time" time spent directly in the function + # _et self.cur[2] "external time" time spent in subfunctions + + def trace_dispatch_exception(self, frame, t): + rpt, rit, ret, rfn, rframe, rcur = self.cur + if (rframe is not frame) and rcur: + return self.trace_dispatch_return(rframe, t) + self.cur = rpt, rit+t, ret, rfn, rframe, rcur + return 1 + + + def trace_dispatch_call(self, frame, t): + if self.cur and frame.f_back is not self.cur[-2]: + rpt, rit, ret, rfn, rframe, rcur = self.cur + if not isinstance(rframe, Profile.fake_frame): + assert rframe.f_back is frame.f_back, ("Bad call", rfn, + rframe, rframe.f_back, + frame, frame.f_back) + self.trace_dispatch_return(rframe, 0) + assert (self.cur is None or \ + frame.f_back is self.cur[-2]), ("Bad call", + self.cur[-3]) + fcode = frame.f_code + fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name) + self.cur = (t, 0, 0, fn, frame, self.cur) + timings = self.timings + if fn in timings: + cc, ns, tt, ct, callers = timings[fn] + timings[fn] = cc, ns + 1, tt, ct, callers + else: + timings[fn] = 0, 0, 0, 0, {} + return 1 + + def trace_dispatch_c_call (self, frame, t): + fn = ("", 0, self.c_func_name) + self.cur = (t, 0, 0, fn, frame, self.cur) + timings = self.timings + if fn in timings: + cc, ns, tt, ct, callers = timings[fn] + timings[fn] = cc, ns+1, tt, ct, callers + else: + timings[fn] = 0, 0, 0, 0, {} + return 1 + + def trace_dispatch_return(self, frame, t): + if frame is not self.cur[-2]: + assert frame is self.cur[-2].f_back, ("Bad return", self.cur[-3]) + self.trace_dispatch_return(self.cur[-2], 0) + + # Prefix "r" means part of the Returning or exiting frame. + # Prefix "p" means part of the Previous or Parent or older frame. + + rpt, rit, ret, rfn, frame, rcur = self.cur + rit = rit + t + frame_total = rit + ret + + ppt, pit, pet, pfn, pframe, pcur = rcur + self.cur = ppt, pit + rpt, pet + frame_total, pfn, pframe, pcur + + timings = self.timings + cc, ns, tt, ct, callers = timings[rfn] + if not ns: + # This is the only occurrence of the function on the stack. + # Else this is a (directly or indirectly) recursive call, and + # its cumulative time will get updated when the topmost call to + # it returns. + ct = ct + frame_total + cc = cc + 1 + + if pfn in callers: + callers[pfn] = callers[pfn] + 1 # hack: gather more + # stats such as the amount of time added to ct courtesy + # of this specific call, and the contribution to cc + # courtesy of this call. + else: + callers[pfn] = 1 + + timings[rfn] = cc, ns - 1, tt + rit, ct, callers + + return 1 + + + dispatch = { + "call": trace_dispatch_call, + "exception": trace_dispatch_exception, + "return": trace_dispatch_return, + "c_call": trace_dispatch_c_call, + "c_exception": trace_dispatch_return, # the C function returned + "c_return": trace_dispatch_return, + } + + + # The next few functions play with self.cmd. By carefully preloading + # our parallel stack, we can force the profiled result to include + # an arbitrary string as the name of the calling function. + # We use self.cmd as that string, and the resulting stats look + # very nice :-). + + def set_cmd(self, cmd): + if self.cur[-1]: return # already set + self.cmd = cmd + self.simulate_call(cmd) + + class fake_code: + def __init__(self, filename, line, name): + self.co_filename = filename + self.co_line = line + self.co_name = name + self.co_firstlineno = 0 + + def __repr__(self): + return repr((self.co_filename, self.co_line, self.co_name)) + + class fake_frame: + def __init__(self, code, prior): + self.f_code = code + self.f_back = prior + + def simulate_call(self, name): + code = self.fake_code('profile', 0, name) + if self.cur: + pframe = self.cur[-2] + else: + pframe = None + frame = self.fake_frame(code, pframe) + self.dispatch['call'](self, frame, 0) + + # collect stats from pending stack, including getting final + # timings for self.cmd frame. + + def simulate_cmd_complete(self): + get_time = self.get_time + t = get_time() - self.t + while self.cur[-1]: + # We *can* cause assertion errors here if + # dispatch_trace_return checks for a frame match! + self.dispatch['return'](self, self.cur[-2], t) + t = 0 + self.t = get_time() - t + + + def print_stats(self, sort=-1): + import pstats + pstats.Stats(self).strip_dirs().sort_stats(sort). \ + print_stats() + + def dump_stats(self, file): + f = open(file, 'wb') + self.create_stats() + marshal.dump(self.stats, f) + f.close() + + def create_stats(self): + self.simulate_cmd_complete() + self.snapshot_stats() + + def snapshot_stats(self): + self.stats = {} + for func, (cc, ns, tt, ct, callers) in self.timings.iteritems(): + callers = callers.copy() + nc = 0 + for callcnt in callers.itervalues(): + nc += callcnt + self.stats[func] = cc, nc, tt, ct, callers + + + # The following two methods can be called by clients to use + # a profiler to profile a statement, given as a string. + + def run(self, cmd): + import __main__ + dict = __main__.__dict__ + return self.runctx(cmd, dict, dict) + + def runctx(self, cmd, globals, locals): + self.set_cmd(cmd) + sys.setprofile(self.dispatcher) + try: + exec cmd in globals, locals + finally: + sys.setprofile(None) + return self + + # This method is more useful to profile a single function call. + def runcall(self, func, *args, **kw): + self.set_cmd(repr(func)) + sys.setprofile(self.dispatcher) + try: + return func(*args, **kw) + finally: + sys.setprofile(None) + + + #****************************************************************** + # The following calculates the overhead for using a profiler. The + # problem is that it takes a fair amount of time for the profiler + # to stop the stopwatch (from the time it receives an event). + # Similarly, there is a delay from the time that the profiler + # re-starts the stopwatch before the user's code really gets to + # continue. The following code tries to measure the difference on + # a per-event basis. + # + # Note that this difference is only significant if there are a lot of + # events, and relatively little user code per event. For example, + # code with small functions will typically benefit from having the + # profiler calibrated for the current platform. This *could* be + # done on the fly during init() time, but it is not worth the + # effort. Also note that if too large a value specified, then + # execution time on some functions will actually appear as a + # negative number. It is *normal* for some functions (with very + # low call counts) to have such negative stats, even if the + # calibration figure is "correct." + # + # One alternative to profile-time calibration adjustments (i.e., + # adding in the magic little delta during each event) is to track + # more carefully the number of events (and cumulatively, the number + # of events during sub functions) that are seen. If this were + # done, then the arithmetic could be done after the fact (i.e., at + # display time). Currently, we track only call/return events. + # These values can be deduced by examining the callees and callers + # vectors for each functions. Hence we *can* almost correct the + # internal time figure at print time (note that we currently don't + # track exception event processing counts). Unfortunately, there + # is currently no similar information for cumulative sub-function + # time. It would not be hard to "get all this info" at profiler + # time. Specifically, we would have to extend the tuples to keep + # counts of this in each frame, and then extend the defs of timing + # tuples to include the significant two figures. I'm a bit fearful + # that this additional feature will slow the heavily optimized + # event/time ratio (i.e., the profiler would run slower, fur a very + # low "value added" feature.) + #************************************************************** + + def calibrate(self, m, verbose=0): + if self.__class__ is not Profile: + raise TypeError("Subclasses must override .calibrate().") + + saved_bias = self.bias + self.bias = 0 + try: + return self._calibrate_inner(m, verbose) + finally: + self.bias = saved_bias + + def _calibrate_inner(self, m, verbose): + get_time = self.get_time + + # Set up a test case to be run with and without profiling. Include + # lots of calls, because we're trying to quantify stopwatch overhead. + # Do not raise any exceptions, though, because we want to know + # exactly how many profile events are generated (one call event, + + # one return event, per Python-level call). + + def f1(n): + for i in range(n): + x = 1 + + def f(m, f1=f1): + for i in range(m): + f1(100) + + f(m) # warm up the cache + + # elapsed_noprofile <- time f(m) takes without profiling. + t0 = get_time() + f(m) + t1 = get_time() + elapsed_noprofile = t1 - t0 + if verbose: + print "elapsed time without profiling =", elapsed_noprofile + + # elapsed_profile <- time f(m) takes with profiling. The difference + # is profiling overhead, only some of which the profiler subtracts + # out on its own. + p = Profile() + t0 = get_time() + p.runctx('f(m)', globals(), locals()) + t1 = get_time() + elapsed_profile = t1 - t0 + if verbose: + print "elapsed time with profiling =", elapsed_profile + + # reported_time <- "CPU seconds" the profiler charged to f and f1. + total_calls = 0.0 + reported_time = 0.0 + for (filename, line, funcname), (cc, ns, tt, ct, callers) in \ + p.timings.items(): + if funcname in ("f", "f1"): + total_calls += cc + reported_time += tt + + if verbose: + print "'CPU seconds' profiler reported =", reported_time + print "total # calls =", total_calls + if total_calls != m + 1: + raise ValueError("internal error: total calls = %d" % total_calls) + + # reported_time - elapsed_noprofile = overhead the profiler wasn't + # able to measure. Divide by twice the number of calls (since there + # are two profiler events per call in this test) to get the hidden + # overhead per event. + mean = (reported_time - elapsed_noprofile) / 2.0 / total_calls + if verbose: + print "mean stopwatch overhead per profile event =", mean + return mean + +#**************************************************************************** +def Stats(*args): + print 'Report generating functions are in the "pstats" module\a' + +def main(): + usage = "profile.py [-o output_file_path] [-s sort] scriptfile [arg] ..." + parser = OptionParser(usage=usage) + parser.allow_interspersed_args = False + parser.add_option('-o', '--outfile', dest="outfile", + help="Save stats to <outfile>", default=None) + parser.add_option('-s', '--sort', dest="sort", + help="Sort order when printing to stdout, based on pstats.Stats class", + default=-1) + + if not sys.argv[1:]: + parser.print_usage() + sys.exit(2) + + (options, args) = parser.parse_args() + sys.argv[:] = args + + if len(args) > 0: + progname = args[0] + sys.path.insert(0, os.path.dirname(progname)) + with open(progname, 'rb') as fp: + code = compile(fp.read(), progname, 'exec') + globs = { + '__file__': progname, + '__name__': '__main__', + '__package__': None, + } + runctx(code, globs, None, options.outfile, options.sort) + else: + parser.print_usage() + return parser + +# When invoked as main program, invoke the profiler on a script +if __name__ == '__main__': + main() diff --git a/src/main/resources/PythonLibs/pstats.py b/src/main/resources/PythonLibs/pstats.py new file mode 100644 index 0000000000000000000000000000000000000000..4338994e5d4466607d6ca3f7917cddc3ef88d102 --- /dev/null +++ b/src/main/resources/PythonLibs/pstats.py @@ -0,0 +1,705 @@ +"""Class for printing reports on profiled python code.""" + +# Written by James Roskind +# Based on prior profile module by Sjoerd Mullender... +# which was hacked somewhat by: Guido van Rossum + +# Copyright Disney Enterprises, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific language +# governing permissions and limitations under the License. + + +import sys +import os +import time +import marshal +import re +from functools import cmp_to_key + +__all__ = ["Stats"] + +class Stats: + """This class is used for creating reports from data generated by the + Profile class. It is a "friend" of that class, and imports data either + by direct access to members of Profile class, or by reading in a dictionary + that was emitted (via marshal) from the Profile class. + + The big change from the previous Profiler (in terms of raw functionality) + is that an "add()" method has been provided to combine Stats from + several distinct profile runs. Both the constructor and the add() + method now take arbitrarily many file names as arguments. + + All the print methods now take an argument that indicates how many lines + to print. If the arg is a floating point number between 0 and 1.0, then + it is taken as a decimal percentage of the available lines to be printed + (e.g., .1 means print 10% of all available lines). If it is an integer, + it is taken to mean the number of lines of data that you wish to have + printed. + + The sort_stats() method now processes some additional options (i.e., in + addition to the old -1, 0, 1, or 2). It takes an arbitrary number of + quoted strings to select the sort order. For example sort_stats('time', + 'name') sorts on the major key of 'internal function time', and on the + minor key of 'the name of the function'. Look at the two tables in + sort_stats() and get_sort_arg_defs(self) for more examples. + + All methods return self, so you can string together commands like: + Stats('foo', 'goo').strip_dirs().sort_stats('calls').\ + print_stats(5).print_callers(5) + """ + + def __init__(self, *args, **kwds): + # I can't figure out how to explictly specify a stream keyword arg + # with *args: + # def __init__(self, *args, stream=sys.stdout): ... + # so I use **kwds and sqauwk if something unexpected is passed in. + self.stream = sys.stdout + if "stream" in kwds: + self.stream = kwds["stream"] + del kwds["stream"] + if kwds: + keys = kwds.keys() + keys.sort() + extras = ", ".join(["%s=%s" % (k, kwds[k]) for k in keys]) + raise ValueError, "unrecognized keyword args: %s" % extras + if not len(args): + arg = None + else: + arg = args[0] + args = args[1:] + self.init(arg) + self.add(*args) + + def init(self, arg): + self.all_callees = None # calc only if needed + self.files = [] + self.fcn_list = None + self.total_tt = 0 + self.total_calls = 0 + self.prim_calls = 0 + self.max_name_len = 0 + self.top_level = {} + self.stats = {} + self.sort_arg_dict = {} + self.load_stats(arg) + trouble = 1 + try: + self.get_top_level_stats() + trouble = 0 + finally: + if trouble: + print >> self.stream, "Invalid timing data", + if self.files: print >> self.stream, self.files[-1], + print >> self.stream + + def load_stats(self, arg): + if not arg: self.stats = {} + elif isinstance(arg, basestring): + f = open(arg, 'rb') + self.stats = marshal.load(f) + f.close() + try: + file_stats = os.stat(arg) + arg = time.ctime(file_stats.st_mtime) + " " + arg + except: # in case this is not unix + pass + self.files = [ arg ] + elif hasattr(arg, 'create_stats'): + arg.create_stats() + self.stats = arg.stats + arg.stats = {} + if not self.stats: + raise TypeError("Cannot create or construct a %r object from %r" + % (self.__class__, arg)) + return + + def get_top_level_stats(self): + for func, (cc, nc, tt, ct, callers) in self.stats.items(): + self.total_calls += nc + self.prim_calls += cc + self.total_tt += tt + if ("jprofile", 0, "profiler") in callers: + self.top_level[func] = None + if len(func_std_string(func)) > self.max_name_len: + self.max_name_len = len(func_std_string(func)) + + def add(self, *arg_list): + if not arg_list: return self + if len(arg_list) > 1: self.add(*arg_list[1:]) + other = arg_list[0] + if type(self) != type(other) or self.__class__ != other.__class__: + other = Stats(other) + self.files += other.files + self.total_calls += other.total_calls + self.prim_calls += other.prim_calls + self.total_tt += other.total_tt + for func in other.top_level: + self.top_level[func] = None + + if self.max_name_len < other.max_name_len: + self.max_name_len = other.max_name_len + + self.fcn_list = None + + for func, stat in other.stats.iteritems(): + if func in self.stats: + old_func_stat = self.stats[func] + else: + old_func_stat = (0, 0, 0, 0, {},) + self.stats[func] = add_func_stats(old_func_stat, stat) + return self + + def dump_stats(self, filename): + """Write the profile data to a file we know how to load back.""" + f = file(filename, 'wb') + try: + marshal.dump(self.stats, f) + finally: + f.close() + + # list the tuple indices and directions for sorting, + # along with some printable description + sort_arg_dict_default = { + "calls" : (((1,-1), ), "call count"), + "ncalls" : (((1,-1), ), "call count"), + "cumtime" : (((3,-1), ), "cumulative time"), + "cumulative": (((3,-1), ), "cumulative time"), + "file" : (((4, 1), ), "file name"), + "filename" : (((4, 1), ), "file name"), + "line" : (((5, 1), ), "line number"), + "module" : (((4, 1), ), "file name"), + "name" : (((6, 1), ), "function name"), + "nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"), + "pcalls" : (((0,-1), ), "primitive call count"), + "stdname" : (((7, 1), ), "standard name"), + "time" : (((2,-1), ), "internal time"), + "tottime" : (((2,-1), ), "internal time"), + } + + def get_sort_arg_defs(self): + """Expand all abbreviations that are unique.""" + if not self.sort_arg_dict: + self.sort_arg_dict = dict = {} + bad_list = {} + for word, tup in self.sort_arg_dict_default.iteritems(): + fragment = word + while fragment: + if not fragment: + break + if fragment in dict: + bad_list[fragment] = 0 + break + dict[fragment] = tup + fragment = fragment[:-1] + for word in bad_list: + del dict[word] + return self.sort_arg_dict + + def sort_stats(self, *field): + if not field: + self.fcn_list = 0 + return self + if len(field) == 1 and isinstance(field[0], (int, long)): + # Be compatible with old profiler + field = [ {-1: "stdname", + 0: "calls", + 1: "time", + 2: "cumulative"}[field[0]] ] + + sort_arg_defs = self.get_sort_arg_defs() + sort_tuple = () + self.sort_type = "" + connector = "" + for word in field: + sort_tuple = sort_tuple + sort_arg_defs[word][0] + self.sort_type += connector + sort_arg_defs[word][1] + connector = ", " + + stats_list = [] + for func, (cc, nc, tt, ct, callers) in self.stats.iteritems(): + stats_list.append((cc, nc, tt, ct) + func + + (func_std_string(func), func)) + + stats_list.sort(key=cmp_to_key(TupleComp(sort_tuple).compare)) + + self.fcn_list = fcn_list = [] + for tuple in stats_list: + fcn_list.append(tuple[-1]) + return self + + def reverse_order(self): + if self.fcn_list: + self.fcn_list.reverse() + return self + + def strip_dirs(self): + oldstats = self.stats + self.stats = newstats = {} + max_name_len = 0 + for func, (cc, nc, tt, ct, callers) in oldstats.iteritems(): + newfunc = func_strip_path(func) + if len(func_std_string(newfunc)) > max_name_len: + max_name_len = len(func_std_string(newfunc)) + newcallers = {} + for func2, caller in callers.iteritems(): + newcallers[func_strip_path(func2)] = caller + + if newfunc in newstats: + newstats[newfunc] = add_func_stats( + newstats[newfunc], + (cc, nc, tt, ct, newcallers)) + else: + newstats[newfunc] = (cc, nc, tt, ct, newcallers) + old_top = self.top_level + self.top_level = new_top = {} + for func in old_top: + new_top[func_strip_path(func)] = None + + self.max_name_len = max_name_len + + self.fcn_list = None + self.all_callees = None + return self + + def calc_callees(self): + if self.all_callees: return + self.all_callees = all_callees = {} + for func, (cc, nc, tt, ct, callers) in self.stats.iteritems(): + if not func in all_callees: + all_callees[func] = {} + for func2, caller in callers.iteritems(): + if not func2 in all_callees: + all_callees[func2] = {} + all_callees[func2][func] = caller + return + + #****************************************************************** + # The following functions support actual printing of reports + #****************************************************************** + + # Optional "amount" is either a line count, or a percentage of lines. + + def eval_print_amount(self, sel, list, msg): + new_list = list + if isinstance(sel, basestring): + try: + rex = re.compile(sel) + except re.error: + msg += " <Invalid regular expression %r>\n" % sel + return new_list, msg + new_list = [] + for func in list: + if rex.search(func_std_string(func)): + new_list.append(func) + else: + count = len(list) + if isinstance(sel, float) and 0.0 <= sel < 1.0: + count = int(count * sel + .5) + new_list = list[:count] + elif isinstance(sel, (int, long)) and 0 <= sel < count: + count = sel + new_list = list[:count] + if len(list) != len(new_list): + msg += " List reduced from %r to %r due to restriction <%r>\n" % ( + len(list), len(new_list), sel) + + return new_list, msg + + def get_print_list(self, sel_list): + width = self.max_name_len + if self.fcn_list: + stat_list = self.fcn_list[:] + msg = " Ordered by: " + self.sort_type + '\n' + else: + stat_list = self.stats.keys() + msg = " Random listing order was used\n" + + for selection in sel_list: + stat_list, msg = self.eval_print_amount(selection, stat_list, msg) + + count = len(stat_list) + + if not stat_list: + return 0, stat_list + print >> self.stream, msg + if count < len(self.stats): + width = 0 + for func in stat_list: + if len(func_std_string(func)) > width: + width = len(func_std_string(func)) + return width+2, stat_list + + def print_stats(self, *amount): + for filename in self.files: + print >> self.stream, filename + if self.files: print >> self.stream + indent = ' ' * 8 + for func in self.top_level: + print >> self.stream, indent, func_get_function_name(func) + + print >> self.stream, indent, self.total_calls, "function calls", + if self.total_calls != self.prim_calls: + print >> self.stream, "(%d primitive calls)" % self.prim_calls, + print >> self.stream, "in %.3f seconds" % self.total_tt + print >> self.stream + width, list = self.get_print_list(amount) + if list: + self.print_title() + for func in list: + self.print_line(func) + print >> self.stream + print >> self.stream + return self + + def print_callees(self, *amount): + width, list = self.get_print_list(amount) + if list: + self.calc_callees() + + self.print_call_heading(width, "called...") + for func in list: + if func in self.all_callees: + self.print_call_line(width, func, self.all_callees[func]) + else: + self.print_call_line(width, func, {}) + print >> self.stream + print >> self.stream + return self + + def print_callers(self, *amount): + width, list = self.get_print_list(amount) + if list: + self.print_call_heading(width, "was called by...") + for func in list: + cc, nc, tt, ct, callers = self.stats[func] + self.print_call_line(width, func, callers, "<-") + print >> self.stream + print >> self.stream + return self + + def print_call_heading(self, name_size, column_title): + print >> self.stream, "Function ".ljust(name_size) + column_title + # print sub-header only if we have new-style callers + subheader = False + for cc, nc, tt, ct, callers in self.stats.itervalues(): + if callers: + value = callers.itervalues().next() + subheader = isinstance(value, tuple) + break + if subheader: + print >> self.stream, " "*name_size + " ncalls tottime cumtime" + + def print_call_line(self, name_size, source, call_dict, arrow="->"): + print >> self.stream, func_std_string(source).ljust(name_size) + arrow, + if not call_dict: + print >> self.stream + return + clist = call_dict.keys() + clist.sort() + indent = "" + for func in clist: + name = func_std_string(func) + value = call_dict[func] + if isinstance(value, tuple): + nc, cc, tt, ct = value + if nc != cc: + substats = '%d/%d' % (nc, cc) + else: + substats = '%d' % (nc,) + substats = '%s %s %s %s' % (substats.rjust(7+2*len(indent)), + f8(tt), f8(ct), name) + left_width = name_size + 1 + else: + substats = '%s(%r) %s' % (name, value, f8(self.stats[func][3])) + left_width = name_size + 3 + print >> self.stream, indent*left_width + substats + indent = " " + + def print_title(self): + print >> self.stream, ' ncalls tottime percall cumtime percall', + print >> self.stream, 'filename:lineno(function)' + + def print_line(self, func): # hack : should print percentages + cc, nc, tt, ct, callers = self.stats[func] + c = str(nc) + if nc != cc: + c = c + '/' + str(cc) + print >> self.stream, c.rjust(9), + print >> self.stream, f8(tt), + if nc == 0: + print >> self.stream, ' '*8, + else: + print >> self.stream, f8(float(tt)/nc), + print >> self.stream, f8(ct), + if cc == 0: + print >> self.stream, ' '*8, + else: + print >> self.stream, f8(float(ct)/cc), + print >> self.stream, func_std_string(func) + +class TupleComp: + """This class provides a generic function for comparing any two tuples. + Each instance records a list of tuple-indices (from most significant + to least significant), and sort direction (ascending or decending) for + each tuple-index. The compare functions can then be used as the function + argument to the system sort() function when a list of tuples need to be + sorted in the instances order.""" + + def __init__(self, comp_select_list): + self.comp_select_list = comp_select_list + + def compare (self, left, right): + for index, direction in self.comp_select_list: + l = left[index] + r = right[index] + if l < r: + return -direction + if l > r: + return direction + return 0 + +#************************************************************************** +# func_name is a triple (file:string, line:int, name:string) + +def func_strip_path(func_name): + filename, line, name = func_name + return os.path.basename(filename), line, name + +def func_get_function_name(func): + return func[2] + +def func_std_string(func_name): # match what old profile produced + if func_name[:2] == ('~', 0): + # special case for built-in functions + name = func_name[2] + if name.startswith('<') and name.endswith('>'): + return '{%s}' % name[1:-1] + else: + return name + else: + return "%s:%d(%s)" % func_name + +#************************************************************************** +# The following functions combine statists for pairs functions. +# The bulk of the processing involves correctly handling "call" lists, +# such as callers and callees. +#************************************************************************** + +def add_func_stats(target, source): + """Add together all the stats for two profile entries.""" + cc, nc, tt, ct, callers = source + t_cc, t_nc, t_tt, t_ct, t_callers = target + return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct, + add_callers(t_callers, callers)) + +def add_callers(target, source): + """Combine two caller lists in a single list.""" + new_callers = {} + for func, caller in target.iteritems(): + new_callers[func] = caller + for func, caller in source.iteritems(): + if func in new_callers: + if isinstance(caller, tuple): + # format used by cProfile + new_callers[func] = tuple([i[0] + i[1] for i in + zip(caller, new_callers[func])]) + else: + # format used by profile + new_callers[func] += caller + else: + new_callers[func] = caller + return new_callers + +def count_calls(callers): + """Sum the caller statistics to get total number of calls received.""" + nc = 0 + for calls in callers.itervalues(): + nc += calls + return nc + +#************************************************************************** +# The following functions support printing of reports +#************************************************************************** + +def f8(x): + return "%8.3f" % x + +#************************************************************************** +# Statistics browser added by ESR, April 2001 +#************************************************************************** + +if __name__ == '__main__': + import cmd + try: + import readline + except ImportError: + pass + + class ProfileBrowser(cmd.Cmd): + def __init__(self, profile=None): + cmd.Cmd.__init__(self) + self.prompt = "% " + self.stats = None + self.stream = sys.stdout + if profile is not None: + self.do_read(profile) + + def generic(self, fn, line): + args = line.split() + processed = [] + for term in args: + try: + processed.append(int(term)) + continue + except ValueError: + pass + try: + frac = float(term) + if frac > 1 or frac < 0: + print >> self.stream, "Fraction argument must be in [0, 1]" + continue + processed.append(frac) + continue + except ValueError: + pass + processed.append(term) + if self.stats: + getattr(self.stats, fn)(*processed) + else: + print >> self.stream, "No statistics object is loaded." + return 0 + def generic_help(self): + print >> self.stream, "Arguments may be:" + print >> self.stream, "* An integer maximum number of entries to print." + print >> self.stream, "* A decimal fractional number between 0 and 1, controlling" + print >> self.stream, " what fraction of selected entries to print." + print >> self.stream, "* A regular expression; only entries with function names" + print >> self.stream, " that match it are printed." + + def do_add(self, line): + if self.stats: + self.stats.add(line) + else: + print >> self.stream, "No statistics object is loaded." + return 0 + def help_add(self): + print >> self.stream, "Add profile info from given file to current statistics object." + + def do_callees(self, line): + return self.generic('print_callees', line) + def help_callees(self): + print >> self.stream, "Print callees statistics from the current stat object." + self.generic_help() + + def do_callers(self, line): + return self.generic('print_callers', line) + def help_callers(self): + print >> self.stream, "Print callers statistics from the current stat object." + self.generic_help() + + def do_EOF(self, line): + print >> self.stream, "" + return 1 + def help_EOF(self): + print >> self.stream, "Leave the profile brower." + + def do_quit(self, line): + return 1 + def help_quit(self): + print >> self.stream, "Leave the profile brower." + + def do_read(self, line): + if line: + try: + self.stats = Stats(line) + except IOError, args: + print >> self.stream, args[1] + return + except Exception as err: + print >> self.stream, err.__class__.__name__ + ':', err + return + self.prompt = line + "% " + elif len(self.prompt) > 2: + line = self.prompt[:-2] + self.do_read(line) + else: + print >> self.stream, "No statistics object is current -- cannot reload." + return 0 + def help_read(self): + print >> self.stream, "Read in profile data from a specified file." + print >> self.stream, "Without argument, reload the current file." + + def do_reverse(self, line): + if self.stats: + self.stats.reverse_order() + else: + print >> self.stream, "No statistics object is loaded." + return 0 + def help_reverse(self): + print >> self.stream, "Reverse the sort order of the profiling report." + + def do_sort(self, line): + if not self.stats: + print >> self.stream, "No statistics object is loaded." + return + abbrevs = self.stats.get_sort_arg_defs() + if line and all((x in abbrevs) for x in line.split()): + self.stats.sort_stats(*line.split()) + else: + print >> self.stream, "Valid sort keys (unique prefixes are accepted):" + for (key, value) in Stats.sort_arg_dict_default.iteritems(): + print >> self.stream, "%s -- %s" % (key, value[1]) + return 0 + def help_sort(self): + print >> self.stream, "Sort profile data according to specified keys." + print >> self.stream, "(Typing `sort' without arguments lists valid keys.)" + def complete_sort(self, text, *args): + return [a for a in Stats.sort_arg_dict_default if a.startswith(text)] + + def do_stats(self, line): + return self.generic('print_stats', line) + def help_stats(self): + print >> self.stream, "Print statistics from the current stat object." + self.generic_help() + + def do_strip(self, line): + if self.stats: + self.stats.strip_dirs() + else: + print >> self.stream, "No statistics object is loaded." + def help_strip(self): + print >> self.stream, "Strip leading path information from filenames in the report." + + def help_help(self): + print >> self.stream, "Show help for a given command." + + def postcmd(self, stop, line): + if stop: + return stop + return None + + import sys + if len(sys.argv) > 1: + initprofile = sys.argv[1] + else: + initprofile = None + try: + browser = ProfileBrowser(initprofile) + print >> browser.stream, "Welcome to the profile statistics browser." + browser.cmdloop() + print >> browser.stream, "Goodbye." + except KeyboardInterrupt: + pass + +# That's all, folks. diff --git a/src/main/resources/PythonLibs/pty.py b/src/main/resources/PythonLibs/pty.py new file mode 100644 index 0000000000000000000000000000000000000000..05ff6860c1bcf0c62979c6539a0c63789303ca55 --- /dev/null +++ b/src/main/resources/PythonLibs/pty.py @@ -0,0 +1,180 @@ +"""Pseudo terminal utilities.""" + +# Bugs: No signal handling. Doesn't set slave termios and window size. +# Only tested on Linux. +# See: W. Richard Stevens. 1992. Advanced Programming in the +# UNIX Environment. Chapter 19. +# Author: Steen Lumholt -- with additions by Guido. + +from select import select +import os +import tty + +__all__ = ["openpty","fork","spawn"] + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +CHILD = 0 + +def openpty(): + """openpty() -> (master_fd, slave_fd) + Open a pty master/slave pair, using os.openpty() if possible.""" + + try: + return os.openpty() + except (AttributeError, OSError): + pass + master_fd, slave_name = _open_terminal() + slave_fd = slave_open(slave_name) + return master_fd, slave_fd + +def master_open(): + """master_open() -> (master_fd, slave_name) + Open a pty master and return the fd, and the filename of the slave end. + Deprecated, use openpty() instead.""" + + try: + master_fd, slave_fd = os.openpty() + except (AttributeError, OSError): + pass + else: + slave_name = os.ttyname(slave_fd) + os.close(slave_fd) + return master_fd, slave_name + + return _open_terminal() + +def _open_terminal(): + """Open pty master and return (master_fd, tty_name). + SGI and generic BSD version, for when openpty() fails.""" + try: + import sgi + except ImportError: + pass + else: + try: + tty_name, master_fd = sgi._getpty(os.O_RDWR, 0666, 0) + except IOError, msg: + raise os.error, msg + return master_fd, tty_name + for x in 'pqrstuvwxyzPQRST': + for y in '0123456789abcdef': + pty_name = '/dev/pty' + x + y + try: + fd = os.open(pty_name, os.O_RDWR) + except os.error: + continue + return (fd, '/dev/tty' + x + y) + raise os.error, 'out of pty devices' + +def slave_open(tty_name): + """slave_open(tty_name) -> slave_fd + Open the pty slave and acquire the controlling terminal, returning + opened filedescriptor. + Deprecated, use openpty() instead.""" + + result = os.open(tty_name, os.O_RDWR) + try: + from fcntl import ioctl, I_PUSH + except ImportError: + return result + try: + ioctl(result, I_PUSH, "ptem") + ioctl(result, I_PUSH, "ldterm") + except IOError: + pass + return result + +def fork(): + """fork() -> (pid, master_fd) + Fork and make the child a session leader with a controlling terminal.""" + + try: + pid, fd = os.forkpty() + except (AttributeError, OSError): + pass + else: + if pid == CHILD: + try: + os.setsid() + except OSError: + # os.forkpty() already set us session leader + pass + return pid, fd + + master_fd, slave_fd = openpty() + pid = os.fork() + if pid == CHILD: + # Establish a new session. + os.setsid() + os.close(master_fd) + + # Slave becomes stdin/stdout/stderr of child. + os.dup2(slave_fd, STDIN_FILENO) + os.dup2(slave_fd, STDOUT_FILENO) + os.dup2(slave_fd, STDERR_FILENO) + if (slave_fd > STDERR_FILENO): + os.close (slave_fd) + + # Explicitly open the tty to make it become a controlling tty. + tmp_fd = os.open(os.ttyname(STDOUT_FILENO), os.O_RDWR) + os.close(tmp_fd) + else: + os.close(slave_fd) + + # Parent and child process. + return pid, master_fd + +def _writen(fd, data): + """Write all the data to a descriptor.""" + while data != '': + n = os.write(fd, data) + data = data[n:] + +def _read(fd): + """Default read function.""" + return os.read(fd, 1024) + +def _copy(master_fd, master_read=_read, stdin_read=_read): + """Parent copy loop. + Copies + pty master -> standard output (master_read) + standard input -> pty master (stdin_read)""" + fds = [master_fd, STDIN_FILENO] + while True: + rfds, wfds, xfds = select(fds, [], []) + if master_fd in rfds: + data = master_read(master_fd) + if not data: # Reached EOF. + fds.remove(master_fd) + else: + os.write(STDOUT_FILENO, data) + if STDIN_FILENO in rfds: + data = stdin_read(STDIN_FILENO) + if not data: + fds.remove(STDIN_FILENO) + else: + _writen(master_fd, data) + +def spawn(argv, master_read=_read, stdin_read=_read): + """Create a spawned process.""" + if type(argv) == type(''): + argv = (argv,) + pid, master_fd = fork() + if pid == CHILD: + os.execlp(argv[0], *argv) + try: + mode = tty.tcgetattr(STDIN_FILENO) + tty.setraw(STDIN_FILENO) + restore = 1 + except tty.error: # This is the same as termios.error + restore = 0 + try: + _copy(master_fd, master_read, stdin_read) + except (IOError, OSError): + if restore: + tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode) + + os.close(master_fd) diff --git a/src/main/resources/PythonLibs/pwd.py b/src/main/resources/PythonLibs/pwd.py new file mode 100644 index 0000000000000000000000000000000000000000..f20169a1b3639fc8e4af19aa12d9984b6f0b5949 --- /dev/null +++ b/src/main/resources/PythonLibs/pwd.py @@ -0,0 +1,83 @@ +""" +This module provides access to the Unix password database. + +Password database entries are reported as 7-tuples containing the +following items from the password database (see `<pwd.h>'), in order: +pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell. The +uid and gid items are integers, all others are strings. An exception +is raised if the entry asked for cannot be found. +""" + +__all__ = ['getpwuid', 'getpwnam', 'getpwall'] + +from os import _name, _posix_impl +from org.python.core.Py import newString + +if _name == 'nt': + raise ImportError, 'pwd module not supported on Windows' + +class struct_passwd(tuple): + """ + pwd.struct_passwd: Results from getpw*() routines. + + This object may be accessed either as a tuple of + (pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell) + or via the object attributes as named in the above tuple. + """ + + attrs = ['pw_name', 'pw_passwd', 'pw_uid', 'pw_gid', 'pw_gecos', + 'pw_dir', 'pw_shell'] + + def __new__(cls, pwd): + pwd = (newString(pwd.loginName), newString(pwd.password), int(pwd.UID), + int(pwd.GID), newString(pwd.GECOS), newString(pwd.home), + newString(pwd.shell)) + return tuple.__new__(cls, pwd) + + def __getattr__(self, attr): + try: + return self[self.attrs.index(attr)] + except ValueError: + raise AttributeError + + +def getpwuid(uid): + """ + getpwuid(uid) -> (pw_name,pw_passwd,pw_uid, + pw_gid,pw_gecos,pw_dir,pw_shell) + Return the password database entry for the given numeric user ID. + See pwd.__doc__ for more on password database entries. + """ + entry = _posix_impl.getpwuid(uid) + if not entry: + raise KeyError(uid) + return struct_passwd(entry) + + +def getpwnam(name): + """ + getpwnam(name) -> (pw_name,pw_passwd,pw_uid, + pw_gid,pw_gecos,pw_dir,pw_shell) + Return the password database entry for the given user name. + See pwd.__doc__ for more on password database entries. + """ + entry = _posix_impl.getpwnam(name) + if not entry: + raise KeyError(name) + return struct_passwd(entry) + + +def getpwall(): + """ + getpwall() -> list_of_entries + Return a list of all available password database entries, + in arbitrary order. + See pwd.__doc__ for more on password database entries. + """ + entries = [] + while True: + entry = _posix_impl.getpwent() + if not entry: + break + entries.append(struct_passwd(entry)) + return entries diff --git a/src/main/resources/PythonLibs/py_compile.py b/src/main/resources/PythonLibs/py_compile.py new file mode 100644 index 0000000000000000000000000000000000000000..843196d891a28ce3219d8e220ab20f9f4ff9f1df --- /dev/null +++ b/src/main/resources/PythonLibs/py_compile.py @@ -0,0 +1,128 @@ +"""Routine to "compile" a .py file to a .pyc (or .pyo) file. + +This module has intimate knowledge of the format of .pyc files. +""" + +import _py_compile +import os +import sys +import traceback + +__all__ = ["compile", "main", "PyCompileError"] + + +class PyCompileError(Exception): + """Exception raised when an error occurs while attempting to + compile the file. + + To raise this exception, use + + raise PyCompileError(exc_type,exc_value,file[,msg]) + + where + + exc_type: exception type to be used in error message + type name can be accesses as class variable + 'exc_type_name' + + exc_value: exception value to be used in error message + can be accesses as class variable 'exc_value' + + file: name of file being compiled to be used in error message + can be accesses as class variable 'file' + + msg: string message to be written as error message + If no value is given, a default exception message will be given, + consistent with 'standard' py_compile output. + message (or default) can be accesses as class variable 'msg' + + """ + + def __init__(self, exc_type, exc_value, file, msg=''): + exc_type_name = exc_type.__name__ + if exc_type is SyntaxError: + tbtext = ''.join(traceback.format_exception_only(exc_type, exc_value)) + errmsg = tbtext.replace('File "<string>"', 'File "%s"' % file) + else: + errmsg = "Sorry: %s: %s" % (exc_type_name,exc_value) + + Exception.__init__(self,msg or errmsg,exc_type_name,exc_value,file) + + self.exc_type_name = exc_type_name + self.exc_value = exc_value + self.file = file + self.msg = msg or errmsg + + def __str__(self): + return self.msg + + +def compile(file, cfile=None, dfile=None, doraise=False): + """Byte-compile one Python source file to Python bytecode. + + Arguments: + + file: source filename + cfile: target filename; defaults to source with 'c' or 'o' appended + ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo) + dfile: purported filename; defaults to source (this is the filename + that will show up in error messages) + doraise: flag indicating whether or not an exception should be + raised when a compile error is found. If an exception + occurs and this flag is set to False, a string + indicating the nature of the exception will be printed, + and the function will return to the caller. If an + exception occurs and this flag is set to True, a + PyCompileError exception will be raised. + + Note that it isn't necessary to byte-compile Python modules for + execution efficiency -- Python itself byte-compiles a module when + it is loaded, and if it can, writes out the bytecode to the + corresponding .pyc (or .pyo) file. + + However, if a Python installation is shared between users, it is a + good idea to byte-compile all modules upon installation, since + other users may not be able to write in the source directories, + and thus they won't be able to write the .pyc/.pyo file, and then + they would be byte-compiling every module each time it is loaded. + This can slow down program start-up considerably. + + See compileall.py for a script/module that uses this module to + byte-compile all installed files (or all files in selected + directories). + + """ + try: + _py_compile.compile(file, cfile, dfile) + except Exception,err: + py_exc = PyCompileError(err.__class__,err.args,dfile or file) + if doraise: + raise py_exc + else: + sys.stderr.write(py_exc.msg + '\n') + return + +def main(args=None): + """Compile several source files. + + The files named in 'args' (or on the command line, if 'args' is + not specified) are compiled and the resulting bytecode is cached + in the normal manner. This function does not search a directory + structure to locate source files; it only compiles files named + explicitly. + + """ + if args is None: + args = sys.argv[1:] + rv = 0 + for filename in args: + try: + compile(filename, doraise=True) + except PyCompileError, err: + # return value to indicate at least one failure + rv = 1 + sys.stderr.write(err.msg) + return rv + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/main/resources/PythonLibs/pycimport.py b/src/main/resources/PythonLibs/pycimport.py new file mode 100644 index 0000000000000000000000000000000000000000..bcccaa58d9f8f490dc497db30fa4a698d69d908c --- /dev/null +++ b/src/main/resources/PythonLibs/pycimport.py @@ -0,0 +1,83 @@ +import imp +import os +import sys +from marshal import Unmarshaller + +__debugging__ = False + +def __readPycHeader(file): + def read(): + return ord(file.read(1)) + magic = read() | (read()<<8) + if not ( file.read(1) == '\r' and file.read(1) == '\n' ): + raise TypeError("not valid pyc-file") + mtime = read() | (read()<<8) | (read()<<16) | (read()<<24) + return magic, mtime + +def __makeModule(name, code, path): + module = sys.modules.get(name) + if not module: + module = sys.modules[name] = imp.new_module(name) + module.__file__ = path + exec code in module.__dict__ + return module + +class __Importer(object): + def __init__(self, path): + if __debugging__: print "Importer invoked" + self.__path = path + def find_module(self, fullname, path=None): + if __debugging__: + print "Importer.find_module(fullname=%s, path=%s)" % ( + repr(fullname), repr(path)) + path = fullname.split('.') + filename = path[-1] + path = path[:-1] + pycfile = os.path.join(self.__path, *(path + [filename + '.pyc'])) + pyfile = os.path.join(self.__path, *(path + [filename + '.py'])) + if os.path.exists(pycfile): + f = open(pycfile, 'rb') + try: + magic, mtime = __readPycHeader(f) + except: + return None # abort! not a valid pyc-file + f.close() + if os.path.exists(pyfile): + pytime = os.stat(pyfile).st_mtime + if pytime > mtime: + return None # abort! py-file was newer + return self + else: + return None # abort! pyc-file does not exist + def load_module(self, fullname): + path = fullname.split('.') + path[-1] += '.pyc' + filename = os.path.join(self.__path, *path) + f = open(filename, 'rb') + magic, mtime = __readPycHeader(f) + #code = Unmarshaller(f, magic=magic).load() + code = Unmarshaller(f).load() + if __debugging__: print "Successfully loaded:", fullname + return __makeModule( fullname, code, filename ) + +class __MetaImporter(object): + def __init__(self): + self.__importers = {} + def find_module(self, fullname, path): + if __debugging__: print "MetaImporter.find_module(%s, %s)" % ( + repr(fullname), repr(path)) + for _path in sys.path: + if _path not in self.__importers: + try: + self.__importers[_path] = __Importer(_path) + except: + self.__importers[_path] = None + importer = self.__importers[_path] + if importer is not None: + loader = importer.find_module(fullname, path) + if loader is not None: + return loader + else: + return None + +sys.meta_path.insert(0, __MetaImporter()) diff --git a/src/main/resources/PythonLibs/pyclbr.py b/src/main/resources/PythonLibs/pyclbr.py new file mode 100644 index 0000000000000000000000000000000000000000..b8f71ae6b64843f38a1284316fa98d34627882dd --- /dev/null +++ b/src/main/resources/PythonLibs/pyclbr.py @@ -0,0 +1,344 @@ +"""Parse a Python module and describe its classes and methods. + +Parse enough of a Python file to recognize imports and class and +method definitions, and to find out the superclasses of a class. + +The interface consists of a single function: + readmodule_ex(module [, path]) +where module is the name of a Python module, and path is an optional +list of directories where the module is to be searched. If present, +path is prepended to the system search path sys.path. The return +value is a dictionary. The keys of the dictionary are the names of +the classes defined in the module (including classes that are defined +via the from XXX import YYY construct). The values are class +instances of the class Class defined here. One special key/value pair +is present for packages: the key '__path__' has a list as its value +which contains the package search path. + +A class is described by the class Class in this module. Instances +of this class have the following instance variables: + module -- the module name + name -- the name of the class + super -- a list of super classes (Class instances) + methods -- a dictionary of methods + file -- the file in which the class was defined + lineno -- the line in the file on which the class statement occurred +The dictionary of methods uses the method names as keys and the line +numbers on which the method was defined as values. +If the name of a super class is not recognized, the corresponding +entry in the list of super classes is not a class instance but a +string giving the name of the super class. Since import statements +are recognized and imported modules are scanned as well, this +shouldn't happen often. + +A function is described by the class Function in this module. +Instances of this class have the following instance variables: + module -- the module name + name -- the name of the class + file -- the file in which the class was defined + lineno -- the line in the file on which the class statement occurred +""" + +import sys +import imp +import tokenize +from token import NAME, DEDENT, OP +from operator import itemgetter + +__all__ = ["readmodule", "readmodule_ex", "Class", "Function"] + +_modules = {} # cache of modules we've seen + +# each Python class is represented by an instance of this class +class Class: + '''Class to represent a Python class.''' + def __init__(self, module, name, super, file, lineno): + self.module = module + self.name = name + if super is None: + super = [] + self.super = super + self.methods = {} + self.file = file + self.lineno = lineno + + def _addmethod(self, name, lineno): + self.methods[name] = lineno + +class Function: + '''Class to represent a top-level Python function''' + def __init__(self, module, name, file, lineno): + self.module = module + self.name = name + self.file = file + self.lineno = lineno + +def readmodule(module, path=None): + '''Backwards compatible interface. + + Call readmodule_ex() and then only keep Class objects from the + resulting dictionary.''' + + res = {} + for key, value in _readmodule(module, path or []).items(): + if isinstance(value, Class): + res[key] = value + return res + +def readmodule_ex(module, path=None): + '''Read a module file and return a dictionary of classes. + + Search for MODULE in PATH and sys.path, read and parse the + module and return a dictionary with one entry for each class + found in the module. + ''' + return _readmodule(module, path or []) + +def _readmodule(module, path, inpackage=None): + '''Do the hard work for readmodule[_ex]. + + If INPACKAGE is given, it must be the dotted name of the package in + which we are searching for a submodule, and then PATH must be the + package search path; otherwise, we are searching for a top-level + module, and PATH is combined with sys.path. + ''' + # Compute the full module name (prepending inpackage if set) + if inpackage is not None: + fullmodule = "%s.%s" % (inpackage, module) + else: + fullmodule = module + + # Check in the cache + if fullmodule in _modules: + return _modules[fullmodule] + + # Initialize the dict for this module's contents + dict = {} + + # Check if it is a built-in module; we don't do much for these + if module in sys.builtin_module_names and inpackage is None: + _modules[module] = dict + return dict + + # Check for a dotted module name + i = module.rfind('.') + if i >= 0: + package = module[:i] + submodule = module[i+1:] + parent = _readmodule(package, path, inpackage) + if inpackage is not None: + package = "%s.%s" % (inpackage, package) + if not '__path__' in parent: + raise ImportError('No package named {}'.format(package)) + return _readmodule(submodule, parent['__path__'], package) + + # Search the path for the module + f = None + if inpackage is not None: + f, fname, (_s, _m, ty) = imp.find_module(module, path) + else: + f, fname, (_s, _m, ty) = imp.find_module(module, path + sys.path) + if ty == imp.PKG_DIRECTORY: + dict['__path__'] = [fname] + path = [fname] + path + f, fname, (_s, _m, ty) = imp.find_module('__init__', [fname]) + _modules[fullmodule] = dict + if ty != imp.PY_SOURCE: + # not Python source, can't do anything with this module + f.close() + return dict + + stack = [] # stack of (class, indent) pairs + + g = tokenize.generate_tokens(f.readline) + try: + for tokentype, token, start, _end, _line in g: + if tokentype == DEDENT: + lineno, thisindent = start + # close nested classes and defs + while stack and stack[-1][1] >= thisindent: + del stack[-1] + elif token == 'def': + lineno, thisindent = start + # close previous nested classes and defs + while stack and stack[-1][1] >= thisindent: + del stack[-1] + tokentype, meth_name, start = g.next()[0:3] + if tokentype != NAME: + continue # Syntax error + if stack: + cur_class = stack[-1][0] + if isinstance(cur_class, Class): + # it's a method + cur_class._addmethod(meth_name, lineno) + # else it's a nested def + else: + # it's a function + dict[meth_name] = Function(fullmodule, meth_name, + fname, lineno) + stack.append((None, thisindent)) # Marker for nested fns + elif token == 'class': + lineno, thisindent = start + # close previous nested classes and defs + while stack and stack[-1][1] >= thisindent: + del stack[-1] + tokentype, class_name, start = g.next()[0:3] + if tokentype != NAME: + continue # Syntax error + # parse what follows the class name + tokentype, token, start = g.next()[0:3] + inherit = None + if token == '(': + names = [] # List of superclasses + # there's a list of superclasses + level = 1 + super = [] # Tokens making up current superclass + while True: + tokentype, token, start = g.next()[0:3] + if token in (')', ',') and level == 1: + n = "".join(super) + if n in dict: + # we know this super class + n = dict[n] + else: + c = n.split('.') + if len(c) > 1: + # super class is of the form + # module.class: look in module for + # class + m = c[-2] + c = c[-1] + if m in _modules: + d = _modules[m] + if c in d: + n = d[c] + names.append(n) + super = [] + if token == '(': + level += 1 + elif token == ')': + level -= 1 + if level == 0: + break + elif token == ',' and level == 1: + pass + # only use NAME and OP (== dot) tokens for type name + elif tokentype in (NAME, OP) and level == 1: + super.append(token) + # expressions in the base list are not supported + inherit = names + cur_class = Class(fullmodule, class_name, inherit, + fname, lineno) + if not stack: + dict[class_name] = cur_class + stack.append((cur_class, thisindent)) + elif token == 'import' and start[1] == 0: + modules = _getnamelist(g) + for mod, _mod2 in modules: + try: + # Recursively read the imported module + if inpackage is None: + _readmodule(mod, path) + else: + try: + _readmodule(mod, path, inpackage) + except ImportError: + _readmodule(mod, []) + except: + # If we can't find or parse the imported module, + # too bad -- don't die here. + pass + elif token == 'from' and start[1] == 0: + mod, token = _getname(g) + if not mod or token != "import": + continue + names = _getnamelist(g) + try: + # Recursively read the imported module + d = _readmodule(mod, path, inpackage) + except: + # If we can't find or parse the imported module, + # too bad -- don't die here. + continue + # add any classes that were defined in the imported module + # to our name space if they were mentioned in the list + for n, n2 in names: + if n in d: + dict[n2 or n] = d[n] + elif n == '*': + # don't add names that start with _ + for n in d: + if n[0] != '_': + dict[n] = d[n] + except StopIteration: + pass + + f.close() + return dict + +def _getnamelist(g): + # Helper to get a comma-separated list of dotted names plus 'as' + # clauses. Return a list of pairs (name, name2) where name2 is + # the 'as' name, or None if there is no 'as' clause. + names = [] + while True: + name, token = _getname(g) + if not name: + break + if token == 'as': + name2, token = _getname(g) + else: + name2 = None + names.append((name, name2)) + while token != "," and "\n" not in token: + token = g.next()[1] + if token != ",": + break + return names + +def _getname(g): + # Helper to get a dotted name, return a pair (name, token) where + # name is the dotted name, or None if there was no dotted name, + # and token is the next input token. + parts = [] + tokentype, token = g.next()[0:2] + if tokentype != NAME and token != '*': + return (None, token) + parts.append(token) + while True: + tokentype, token = g.next()[0:2] + if token != '.': + break + tokentype, token = g.next()[0:2] + if tokentype != NAME: + break + parts.append(token) + return (".".join(parts), token) + +def _main(): + # Main program for testing. + import os + mod = sys.argv[1] + if os.path.exists(mod): + path = [os.path.dirname(mod)] + mod = os.path.basename(mod) + if mod.lower().endswith(".py"): + mod = mod[:-3] + else: + path = [] + dict = readmodule_ex(mod, path) + objs = dict.values() + objs.sort(lambda a, b: cmp(getattr(a, 'lineno', 0), + getattr(b, 'lineno', 0))) + for obj in objs: + if isinstance(obj, Class): + print "class", obj.name, obj.super, obj.lineno + methods = sorted(obj.methods.iteritems(), key=itemgetter(1)) + for name, lineno in methods: + if name != "__path__": + print " def", name, lineno + elif isinstance(obj, Function): + print "def", obj.name, obj.lineno + +if __name__ == "__main__": + _main() diff --git a/src/main/resources/PythonLibs/pydoc.py b/src/main/resources/PythonLibs/pydoc.py new file mode 100644 index 0000000000000000000000000000000000000000..265f6b0bf68b3ea17732d39389637d80d6208b1e --- /dev/null +++ b/src/main/resources/PythonLibs/pydoc.py @@ -0,0 +1,2359 @@ +#!/usr/bin/env python +# -*- coding: latin-1 -*- +"""Generate Python documentation in HTML or text for interactive use. + +In the Python interpreter, do "from pydoc import help" to provide online +help. Calling help(thing) on a Python object documents the object. + +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 a given port on the +local machine to generate documentation web pages. + +For platforms without a command line, "pydoc -g" starts the HTTP server +and also pops up a little window for controlling it. + +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 + + http://docs.python.org/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. +""" + +__author__ = "Ka-Ping Yee <ping@lfw.org>" +__date__ = "26 February 2001" + +__version__ = "$Revision: 88564 $" +__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: +# - imp.load_module() cannot be prevented from clobbering existing +# loaded modules, so calling synopsis() on a binary module file +# changes the contents of any existing module with the same name. +# - 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 sys, imp, os, re, types, inspect, __builtin__, pkgutil, warnings +from repr import Repr +from string import expandtabs, find, join, lower, split, strip, rfind, rstrip +from traceback import extract_tb +try: + from collections import deque +except ImportError: + # Python 2.3 compatibility + class deque(list): + def popleft(self): + return self.pop(0) + +# --------------------------------------------------------- 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', '', rstrip(result)) or '' + +def splitdoc(doc): + """Split a doc string into a synopsis line (if any) and the rest.""" + lines = split(strip(doc), '\n') + if len(lines) == 1: + return lines[0], '' + elif len(lines) >= 2 and not rstrip(lines[1]): + return lines[0], join(lines[2:], '\n') + return '', join(lines, '\n') + +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 = join(split(text, pairs[0]), pairs[1]) + 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.ismethod(obj) or inspect.ismethoddescriptor(obj) + +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. + _hidden_names = ('__builtins__', '__doc__', '__file__', '__path__', + '__module__', '__name__', '__slots__', '__package__') + if name in _hidden_names: 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 1 + 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.""" + def fixup(data): + name, kind, cls, value = data + if inspect.isdatadescriptor(value): + kind = 'data descriptor' + return name, kind, cls, value + return map(fixup, inspect.classify_class_attrs(object)) + +# ----------------------------------------------------- module manipulation + +def ispackage(path): + """Guess whether a path refers to a package directory.""" + if os.path.isdir(path): + for ext in ('.py', '.pyc', '.pyo', '$py.class'): + 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 strip(line): + line = file.readline() + if not line: break + line = strip(line) + if line[:4] == 'r"""': line = line[1:] + if line[:3] == '"""': + line = line[3:] + if line[-1:] == '\\': line = line[:-1] + while not strip(line): + line = file.readline() + if not line: break + result = strip(split(line, '"""')[0]) + 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: + info = inspect.getmoduleinfo(filename) + try: + file = open(filename) + except IOError: + # module can't be opened, so skip it + return None + if info and 'b' in info[2]: # binary modules have to be imported + try: module = imp.load_module('__temp__', file, filename, info[1:]) + except: return None + result = (module.__doc__ or '').splitlines()[0] + del sys.modules['__temp__'] + else: # text modules can be directly examined + result = source_synopsis(file) + file.close() + 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): + exc, value, tb = exc_info + self.filename = filename + self.exc = exc + self.value = value + self.tb = tb + + def __str__(self): + exc = self.exc + if type(exc) is types.ClassType: + exc = 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 = imp.get_magic() + file = open(path, 'r') + if file.read(len(magic)) == magic: + kind = imp.PY_COMPILED + else: + kind = imp.PY_SOURCE + file.close() + filename = os.path.basename(path) + name, ext = os.path.splitext(filename) + file = open(path, 'r') + try: + module = imp.load_module(name, file, path, (ext, 'r', kind)) + except: + raise ErrorDuringImport(path, sys.exc_info()) + file.close() + return module + +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: + # Avoid simply calling reload() because it leaves names in + # the currently loaded module lying around if they're not + # defined in the new source file. Instead, remove the + # module from sys.modules and re-import. 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 exc is ImportError and extract_tb(tb)[-1][2]=='safeimport': + # The import error occurred directly in this function, + # which means there is 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 split(path, '.')[1:]: + try: module = getattr(module, part) + except AttributeError: return None + return module + +# ---------------------------------------------------- formatter base class + +class Doc: + 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): + """Return the location of module docs or None""" + + try: + file = inspect.getabsfile(object) + except TypeError: + file = '(built-in)' + + docloc = os.environ.get("PYTHONDOCS", + "http://docs.python.org/library") + basedir = os.path.join(sys.exec_prefix, "lib", + "python"+sys.version[0:3]) + 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://"): + docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__) + else: + docloc = os.path.join(docloc, object.__name__ + ".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, '&', '&', '<', '<', '>', '>') + + def repr(self, object): + return Repr.repr(self, object) + + def repr1(self, x, level): + if hasattr(type(x), '__name__'): + methodname = 'repr_' + join(split(type(x).__name__), '_') + 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> +</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> <br> +<font color="%s" face="helvetica, arial"> <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 ' ') + + def section(self, title, fgcol, bgcol, contents, width=6, + prelude='', marginalia=None, gap=' '): + """Format a section with a heading.""" + if marginalia is None: + marginalia = '<tt>' + ' ' * width + '</tt>' + result = '''<p> +<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section"> +<tr bgcolor="%s"> +<td colspan=3 valign=bottom> <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(expandtabs(text)) + return replace(text, '\n\n', '\n \n', '\n\n', '\n \n', + ' ', ' ', '\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, data): + """Make a link for a module or package to display in an index.""" + name, path, ispackage, shadowed = data + 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> (package)' % name + else: + text = name + return '<a href="%s">%s</a>' % (url, text) + + 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('"', '"') + 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 text[end:end+1] == '(': + results.append(self.namelink(name, methods, funcs, classes)) + elif selfdot: + results.append('self.<strong>%s</strong>' % name) + 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 = split(name, '.') + 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 = path + if sys.platform == 'win32': + import nturl2path + url = nturl2path.pathname2url(path) + filelink = '<a href="file:%s">%s</a>' % (url, path) + except TypeError: + filelink = '(built-in)' + info = [] + if hasattr(object, '__version__'): + version = str(object.__version__) + if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': + version = strip(version[11:-1]) + 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 Docs</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 key_value, s=self: s.modulelink(key_value[1])) + result = result + self.bigsection( + 'Modules', '#ffffff', '#aa55cc', contents) + + if classes: + classlist = map(lambda key_value: key_value[1], 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', join(contents, '<br>\n')) + 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 (hasattr(value, '__call__') 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 = filter(lambda data: visiblename(data[0], obj=object), + classify_class_attrs(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 __builtin__.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 attrs by name. + try: + attrs.sort(key=lambda t: t[0]) + except TypeError: + attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) # 2.3 compat + + # 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> </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 inspect.ismethod(object): + imclass = object.im_class + if cl: + if imclass is not cl: + note = ' from ' + self.classlink(imclass, mod) + else: + if object.im_self is not None: + note = ' method of %s instance' % self.classlink( + object.im_self.__class__, mod) + else: + note = ' unbound %s method' % self.classlink(imclass,mod) + object = object.im_func + + if name == realname: + title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname) + else: + if (cl and realname in cl.__dict__ and + cl.__dict__[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) + if inspect.isfunction(object): + args, varargs, varkw, defaults = inspect.getargspec(object) + argspec = inspect.formatargspec( + args, varargs, varkw, defaults, formatvalue=self.formatvalue) + if realname == '<lambda>': + title = '<strong>%s</strong> <em>lambda</em> ' % name + argspec = argspec[1:-1] # remove parentheses + else: + argspec = '(...)' + + decl = title + 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]): + 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(split(type(x).__name__), '_') + 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(map(lambda ch: ch + '\b' + ch, text), '') + + def indent(self, text, prefix=' '): + """Indent text by prepending a given prefix to each line.""" + if not text: return '' + lines = split(text, '\n') + lines = map(lambda line, prefix=prefix: prefix + line, lines) + if lines: lines[-1] = rstrip(lines[-1]) + return join(lines, '\n') + + def section(self, title, contents): + """Format a section with a given heading.""" + return self.bold(title) + '\n' + rstrip(self.indent(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 = map(lambda c, m=modname: classname(c, m), 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)) + + try: + all = object.__all__ + except AttributeError: + all = None + + try: + file = inspect.getabsfile(object) + except TypeError: + file = '(built-in)' + result = result + self.section('FILE', file) + + docloc = self.getdocloc(object) + if docloc is not None: + result = result + self.section('MODULE DOCS', docloc) + + 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', join(modpkgs, '\n')) + + # 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', join(submodules, '\n')) + + if classes: + classlist = map(lambda key_value: key_value[1], 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', join(contents, '\n')) + + if funcs: + contents = [] + for key, value in funcs: + contents.append(self.document(value, key, name)) + result = result + self.section('FUNCTIONS', join(contents, '\n')) + + if data: + contents = [] + for key, value in data: + contents.append(self.docother(value, key, name, maxlen=70)) + result = result + self.section('DATA', join(contents, '\n')) + + if hasattr(object, '__version__'): + version = str(object.__version__) + if version[:11] == '$' + 'Revision: ' and version[-1:] == '$': + version = strip(version[11:-1]) + 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__)) + 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 (hasattr(value, '__call__') or + inspect.isdatadescriptor(value)): + doc = getdoc(value) + else: + doc = None + push(self.docother(getattr(object, name), + name, mod, maxlen=70, doc=doc) + '\n') + return attrs + + attrs = filter(lambda data: visiblename(data[0], obj=object), + classify_class_attrs(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 __builtin__.object: + attrs = inherited + continue + elif thisclass is object: + tag = "defined here" + else: + tag = "inherited from %s" % classname(thisclass, + object.__module__) + + # Sort attrs by name. + attrs.sort() + + # 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(rstrip(contents), ' | ') + '\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 inspect.ismethod(object): + imclass = object.im_class + if cl: + if imclass is not cl: + note = ' from ' + classname(imclass, mod) + else: + if object.im_self is not None: + note = ' method of %s instance' % classname( + object.im_self.__class__, mod) + else: + note = ' unbound %s method' % classname(imclass,mod) + object = object.im_func + + if name == realname: + title = self.bold(realname) + else: + if (cl and realname in cl.__dict__ and + cl.__dict__[realname] is object): + skipdocs = 1 + title = self.bold(name) + ' = ' + realname + if inspect.isfunction(object): + args, varargs, varkw, defaults = inspect.getargspec(object) + argspec = inspect.formatargspec( + args, varargs, varkw, defaults, formatvalue=self.formatvalue) + if realname == '<lambda>': + title = self.bold(name) + ' lambda ' + argspec = argspec[1:-1] # remove parentheses + else: + argspec = '(...)' + decl = title + argspec + note + + if skipdocs: + return decl + '\n' + else: + doc = getdoc(object) or '' + return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\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 + +# --------------------------------------------------------- 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 type(sys.stdout) is not types.FileType: + return plainpager + if not sys.stdin.isatty() or not sys.stdout.isatty(): + return plainpager + if 'PAGER' in os.environ: + if sys.platform == 'win32': # pipes completely broken in Windows + return lambda text: tempfilepager(plain(text), os.environ['PAGER']) + elif os.environ.get('TERM') in ('dumb', 'emacs'): + return lambda text: pipepager(plain(text), os.environ['PAGER']) + else: + return lambda text: pipepager(text, os.environ['PAGER']) + if os.environ.get('TERM') in ('dumb', 'emacs'): + return plainpager + if sys.platform == 'win32' or sys.platform.startswith('os2'): + 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.""" + pipe = os.popen(cmd, 'w') + try: + pipe.write(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() + file = open(filename, 'w') + file.write(text) + file.close() + try: + os.system(cmd + ' "' + filename + '"') + finally: + os.unlink(filename) + +def ttypager(text): + """Page through text on a text terminal.""" + lines = split(plain(text), '\n') + try: + import tty + fd = sys.stdin.fileno() + old = tty.tcgetattr(fd) + tty.setcbreak(fd) + getchar = lambda: sys.stdin.read(1) + except (ImportError, AttributeError): + tty = None + getchar = lambda: sys.stdin.readline()[:-1][:1] + + try: + r = inc = os.environ.get('LINES', 25) - 1 + sys.stdout.write(join(lines[:inc], '\n') + '\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' + join(lines[r:r+inc], '\n') + '\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(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__ + if type(thing) is types.InstanceType: + return 'instance of ' + thing.__class__.__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 split(path, '.') 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 = __builtin__ + for part in parts[n:]: + try: + object = getattr(object, part) + except AttributeError: + return None + return object + +# --------------------------------------- interactive interpreter interface + +text = TextDoc() +html = HTMLDoc() + +class _OldStyleClass: pass +_OLD_INSTANCE_TYPE = type(_OldStyleClass()) + +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 not object: + raise ImportError, 'no Python documentation found for %r' % 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): + """Render text documentation, given an object or a path to an object.""" + 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 type(object) is _OLD_INSTANCE_TYPE: + # If the passed object is an instance of an old-style class, + # document its available methods instead of its value. + object = object.__class__ + elif 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' + text.document(object, name) + +def doc(thing, title='Python Library Documentation: %s', forceload=0): + """Display text documentation, given an object or a path to an object.""" + try: + pager(render_doc(thing, title, forceload)) + except (ImportError, ErrorDuringImport), 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)) + file = open(name + '.html', 'w') + file.write(page) + file.close() + print 'wrote', name + '.html' + except (ImportError, ErrorDuringImport), 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/sphinxext/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 = { + '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', + 'exec': ('exec', ''), + 'finally': 'try', + 'for': ('for', 'break continue while'), + 'from': 'import', + 'global': ('global', 'NAMESPACES'), + 'if': ('if', 'TRUTHVALUE'), + 'import': ('import', 'MODULES'), + 'in': ('in', 'SEQUENCEMETHODS2'), + 'is': 'COMPARISON', + 'lambda': ('lambda', 'FUNCTIONS'), + 'not': 'BOOLEAN', + 'or': 'BOOLEAN', + 'pass': ('pass', ''), + 'print': ('print', ''), + '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. + _symbols_inverse = { + 'STRINGS' : ("'", "'''", "r'", "u'", '"""', '"', 'r"', 'u"'), + '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.iteritems(): + 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 xrange 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'), + 'FILES': ('bltin-file-objects', ''), + '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 BACKQUOTES'), + 'OPERATORS': 'EXPRESSIONS', + 'PRECEDENCE': 'EXPRESSIONS', + 'OBJECTS': ('objects', 'TYPES'), + 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS ' + 'CALLABLEMETHODS SEQUENCEMETHODS1 MAPPINGMETHODS ' + 'SEQUENCEMETHODS2 NUMBERMETHODS CLASSES'), + 'BASICMETHODS': ('customization', 'cmp hash repr str SPECIALMETHODS'), + 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'), + 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'), + 'SEQUENCEMETHODS1': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS2 ' + 'SPECIALMETHODS'), + 'SEQUENCEMETHODS2': ('sequence-methods', 'SEQUENCES SEQUENCEMETHODS1 ' + 'SPECIALMETHODS'), + 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'), + 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT ' + 'SPECIALMETHODS'), + 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'), + 'NAMESPACES': ('naming', 'global ASSIGNMENT DELETION DYNAMICFEATURES'), + 'DYNAMICFEATURES': ('dynamic-features', ''), + 'SCOPING': 'NAMESPACES', + 'FRAMES': 'NAMESPACES', + 'EXCEPTIONS': ('exceptions', 'try except finally raise'), + 'COERCIONS': ('coercion-rules','CONVERSIONS'), + 'CONVERSIONS': ('conversions', 'COERCIONS'), + 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'), + 'SPECIALIDENTIFIERS': ('id-classes', ''), + 'PRIVATENAMES': ('atom-identifiers', ''), + 'LITERALS': ('atom-literals', 'STRINGS BACKQUOTES 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'), + 'BACKQUOTES': ('string-conversions', 'repr str STRINGS LITERALS'), + 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ' + 'ATTRIBUTEMETHODS'), + 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS1'), + 'SLICINGS': ('slicings', 'SEQUENCEMETHODS2'), + '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', + 'PRINTING': 'print', + '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 '<pydoc.Helper instance>' + + _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 = strip(replace(request, '"', '', "'", '')) + if lower(request) in ('q', 'quit'): break + self.help(request) + + def getline(self, prompt): + """Read one line, using raw_input when available.""" + if self.input is sys.stdin: + return raw_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 == 'help': self.intro() + elif 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(split(request)[1]) + elif request in self.symbols: self.showsymbol(request) + elif request in self.keywords: self.showtopic(request) + elif request in self.topics: self.showtopic(request) + elif request: doc(request, 'Help on %s:') + elif isinstance(request, Helper): self() + else: doc(request, 'Help on %s:') + self.output.write('\n') + + def intro(self): + self.output.write(''' +Welcome to Python %s! This is the online help utility. + +If this is your first time using Python, you should definitely check out +the tutorial on the Internet at http://docs.python.org/%s/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, or topics, type "modules", +"keywords", or "topics". Each module also comes with a one-line summary +of what it does; to list the modules whose summaries contain a given word +such as "spam", type "modules spam". +''' % tuple([sys.version[:3]]*2)) + + def list(self, items, columns=4, width=80): + items = items[:] + items.sort() + 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 + pager(strip(doc) + '\n') + if more_xrefs: + xrefs = (xrefs or '') + ' ' + more_xrefs + if xrefs: + import StringIO, formatter + buffer = StringIO.StringIO() + formatter.DumbWriter(buffer).send_flowing_data( + 'Related help topics: ' + join(split(xrefs), ', ') + '\n') + self.output.write('\n%s\n' % buffer.getvalue()) + + 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 matching modules. Enter any module name to get more help. + +''') + 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 find(modname, '.') < 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 descriptions contain the word "spam". +''') + +help = Helper() + +class Scanner: + """A generic tree iterator.""" + def __init__(self, roots, children, descendp): + self.roots = roots[:] + self.state = [] + self.children = children + self.descendp = descendp + + def next(self): + if not self.state: + if not self.roots: + return None + root = self.roots.pop(0) + self.state = [(root, self.children(root))] + node, children = self.state[-1] + if not children: + self.state.pop() + return self.next() + child = children.pop(0) + if self.descendp(child): + self.state.append((child, self.children(child))) + return child + + +class ModuleScanner: + """An interruptible scanner that searches module synopses.""" + + def run(self, callback, key=None, completer=None, onerror=None): + if key: key = lower(key) + 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: + desc = split(__import__(modname).__doc__ or '', '\n')[0] + if find(lower(modname + ' - ' + desc), 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: + loader = importer.find_module(modname) + if hasattr(loader,'get_source'): + import StringIO + desc = source_synopsis( + StringIO.StringIO(loader.get_source(modname)) + ) or '' + if hasattr(loader,'get_filename'): + path = loader.get_filename(modname) + else: + path = None + else: + module = loader.load_module(modname) + desc = (module.__doc__ or '').splitlines()[0] + path = getattr(module,'__file__',None) + if find(lower(modname + ' - ' + desc), 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) + +# --------------------------------------------------- web browser interface + +def serve(port, callback=None, completer=None): + import BaseHTTPServer, mimetools, select + + # Patch up mimetools.Message so it doesn't break if rfc822 is reloaded. + class Message(mimetools.Message): + def __init__(self, fp, seekable=1): + Message = self.__class__ + Message.__bases__[0].__bases__[0].__init__(self, fp, seekable) + self.encodingheader = self.getheader('content-transfer-encoding') + self.typeheader = self.getheader('content-type') + self.parsetype() + self.parseplist() + + class DocHandler(BaseHTTPServer.BaseHTTPRequestHandler): + def send_document(self, title, contents): + try: + self.send_response(200) + self.send_header('Content-Type', 'text/html') + self.end_headers() + self.wfile.write(html.page(title, contents)) + except IOError: pass + + def do_GET(self): + path = self.path + if path[-5:] == '.html': path = path[:-5] + if path[:1] == '/': path = path[1:] + if path and path != '.': + try: + obj = locate(path, forceload=1) + except ErrorDuringImport, value: + self.send_document(path, html.escape(str(value))) + return + if obj: + self.send_document(describe(obj), html.document(obj, path)) + else: + self.send_document(path, +'no Python documentation found for %s' % repr(path)) + else: + heading = html.heading( +'<big><big><strong>Python: Index of Modules</strong></big></big>', +'#ffffff', '#7799ee') + def bltinlink(name): + return '<a href="%s.html">%s</a>' % (name, name) + names = filter(lambda x: x != '__main__', + sys.builtin_module_names) + contents = html.multicolumn(names, bltinlink) + indices = ['<p>' + html.bigsection( + 'Built-in Modules', '#ffffff', '#ee77aa', contents)] + + seen = {} + for dir in sys.path: + indices.append(html.index(dir, seen)) + contents = heading + join(indices) + '''<p align=right> +<font color="#909090" face="helvetica, arial"><strong> +pydoc</strong> by Ka-Ping Yee <ping@lfw.org></font>''' + self.send_document('Index of Modules', contents) + + def log_message(self, *args): pass + + class DocServer(BaseHTTPServer.HTTPServer): + def __init__(self, port, callback): + host = 'localhost' + self.address = (host, port) + self.url = 'http://%s:%d/' % (host, port) + self.callback = callback + self.base.__init__(self, self.address, self.handler) + + def serve_until_quit(self): + import select + self.quit = False + while not self.quit: + rd, wr, ex = select.select([self.socket.fileno()], [], [], 1) + if rd: self.handle_request() + + def server_activate(self): + self.base.server_activate(self) + if self.callback: self.callback(self) + + DocServer.base = BaseHTTPServer.HTTPServer + DocServer.handler = DocHandler + DocHandler.MessageClass = Message + try: + try: + DocServer(port, callback).serve_until_quit() + except (KeyboardInterrupt, select.error): + pass + finally: + if completer: completer() + +# ----------------------------------------------------- graphical interface + +def gui(): + """Graphical interface (starts web server and pops up a control window).""" + class GUI: + def __init__(self, window, port=7464): + self.window = window + self.server = None + self.scanner = None + + import Tkinter + self.server_frm = Tkinter.Frame(window) + self.title_lbl = Tkinter.Label(self.server_frm, + text='Starting server...\n ') + self.open_btn = Tkinter.Button(self.server_frm, + text='open browser', command=self.open, state='disabled') + self.quit_btn = Tkinter.Button(self.server_frm, + text='quit serving', command=self.quit, state='disabled') + + self.search_frm = Tkinter.Frame(window) + self.search_lbl = Tkinter.Label(self.search_frm, text='Search for') + self.search_ent = Tkinter.Entry(self.search_frm) + self.search_ent.bind('<Return>', self.search) + self.stop_btn = Tkinter.Button(self.search_frm, + text='stop', pady=0, command=self.stop, state='disabled') + if sys.platform == 'win32': + # Trying to hide and show this button crashes under Windows. + self.stop_btn.pack(side='right') + + self.window.title('pydoc') + self.window.protocol('WM_DELETE_WINDOW', self.quit) + self.title_lbl.pack(side='top', fill='x') + self.open_btn.pack(side='left', fill='x', expand=1) + self.quit_btn.pack(side='right', fill='x', expand=1) + self.server_frm.pack(side='top', fill='x') + + self.search_lbl.pack(side='left') + self.search_ent.pack(side='right', fill='x', expand=1) + self.search_frm.pack(side='top', fill='x') + self.search_ent.focus_set() + + font = ('helvetica', sys.platform == 'win32' and 8 or 10) + self.result_lst = Tkinter.Listbox(window, font=font, height=6) + self.result_lst.bind('<Button-1>', self.select) + self.result_lst.bind('<Double-Button-1>', self.goto) + self.result_scr = Tkinter.Scrollbar(window, + orient='vertical', command=self.result_lst.yview) + self.result_lst.config(yscrollcommand=self.result_scr.set) + + self.result_frm = Tkinter.Frame(window) + self.goto_btn = Tkinter.Button(self.result_frm, + text='go to selected', command=self.goto) + self.hide_btn = Tkinter.Button(self.result_frm, + text='hide results', command=self.hide) + self.goto_btn.pack(side='left', fill='x', expand=1) + self.hide_btn.pack(side='right', fill='x', expand=1) + + self.window.update() + self.minwidth = self.window.winfo_width() + self.minheight = self.window.winfo_height() + self.bigminheight = (self.server_frm.winfo_reqheight() + + self.search_frm.winfo_reqheight() + + self.result_lst.winfo_reqheight() + + self.result_frm.winfo_reqheight()) + self.bigwidth, self.bigheight = self.minwidth, self.bigminheight + self.expanded = 0 + self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight)) + self.window.wm_minsize(self.minwidth, self.minheight) + self.window.tk.willdispatch() + + import threading + threading.Thread( + target=serve, args=(port, self.ready, self.quit)).start() + + def ready(self, server): + self.server = server + self.title_lbl.config( + text='Python documentation server at\n' + server.url) + self.open_btn.config(state='normal') + self.quit_btn.config(state='normal') + + def open(self, event=None, url=None): + url = url or self.server.url + try: + import webbrowser + webbrowser.open(url) + except ImportError: # pre-webbrowser.py compatibility + if sys.platform == 'win32': + os.system('start "%s"' % url) + else: + rc = os.system('netscape -remote "openURL(%s)" &' % url) + if rc: os.system('netscape "%s" &' % url) + + def quit(self, event=None): + if self.server: + self.server.quit = 1 + self.window.quit() + + def search(self, event=None): + key = self.search_ent.get() + self.stop_btn.pack(side='right') + self.stop_btn.config(state='normal') + self.search_lbl.config(text='Searching for "%s"...' % key) + self.search_ent.forget() + self.search_lbl.pack(side='left') + self.result_lst.delete(0, 'end') + self.goto_btn.config(state='disabled') + self.expand() + + import threading + if self.scanner: + self.scanner.quit = 1 + self.scanner = ModuleScanner() + threading.Thread(target=self.scanner.run, + args=(self.update, key, self.done)).start() + + def update(self, path, modname, desc): + if modname[-9:] == '.__init__': + modname = modname[:-9] + ' (package)' + self.result_lst.insert('end', + modname + ' - ' + (desc or '(no description)')) + + def stop(self, event=None): + if self.scanner: + self.scanner.quit = 1 + self.scanner = None + + def done(self): + self.scanner = None + self.search_lbl.config(text='Search for') + self.search_lbl.pack(side='left') + self.search_ent.pack(side='right', fill='x', expand=1) + if sys.platform != 'win32': self.stop_btn.forget() + self.stop_btn.config(state='disabled') + + def select(self, event=None): + self.goto_btn.config(state='normal') + + def goto(self, event=None): + selection = self.result_lst.curselection() + if selection: + modname = split(self.result_lst.get(selection[0]))[0] + self.open(url=self.server.url + modname + '.html') + + def collapse(self): + if not self.expanded: return + self.result_frm.forget() + self.result_scr.forget() + self.result_lst.forget() + self.bigwidth = self.window.winfo_width() + self.bigheight = self.window.winfo_height() + self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight)) + self.window.wm_minsize(self.minwidth, self.minheight) + self.expanded = 0 + + def expand(self): + if self.expanded: return + self.result_frm.pack(side='bottom', fill='x') + self.result_scr.pack(side='right', fill='y') + self.result_lst.pack(side='top', fill='both', expand=1) + self.window.wm_geometry('%dx%d' % (self.bigwidth, self.bigheight)) + self.window.wm_minsize(self.minwidth, self.bigminheight) + self.expanded = 1 + + def hide(self, event=None): + self.stop() + self.collapse() + + import Tkinter + try: + root = Tkinter.Tk() + # Tk will crash if pythonw.exe has an XP .manifest + # file and the root has is not destroyed explicitly. + # If the problem is ever fixed in Tk, the explicit + # destroy can go. + try: + gui = GUI(root) + root.mainloop() + finally: + root.destroy() + except KeyboardInterrupt: + pass + +# -------------------------------------------------- command-line interface + +def ispath(x): + return isinstance(x, str) and find(x, os.sep) >= 0 + +def cli(): + """Command-line interface (looks at sys.argv to decide what to do).""" + import getopt + class BadUsage: 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:], 'gk:p:w') + writing = 0 + + for opt, val in opts: + if opt == '-g': + gui() + return + if opt == '-k': + apropos(val) + return + if opt == '-p': + try: + port = int(val) + except ValueError: + raise BadUsage + def ready(server): + print 'pydoc server ready at %s' % server.url + def stopped(): + print 'pydoc server stopped' + serve(port, ready, stopped) + return + if opt == '-w': + writing = 1 + + 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, value: + print value + + except (getopt.error, BadUsage): + cmd = os.path.basename(sys.argv[0]) + print """pydoc - the Python documentation tool + +%s <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 '%s', 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. + +%s -k <keyword> + Search for a keyword in the synopsis lines of all available modules. + +%s -p <port> + Start an HTTP server on the given port on the local machine. + +%s -g + Pop up a graphical interface for finding and serving documentation. + +%s -w <name> ... + Write out the HTML documentation for a module to a file in the current + directory. If <name> contains a '%s', it is treated as a filename; if + it names a directory, documentation is written for all the contents. +""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep) + +if __name__ == '__main__': cli() diff --git a/src/main/resources/PythonLibs/pyexpat.py b/src/main/resources/PythonLibs/pyexpat.py new file mode 100644 index 0000000000000000000000000000000000000000..7d3b815c4b0c114fd6cc5a275a18915aef0080c4 --- /dev/null +++ b/src/main/resources/PythonLibs/pyexpat.py @@ -0,0 +1 @@ +from xml.parsers.expat import * diff --git a/src/main/resources/PythonLibs/quopri.py b/src/main/resources/PythonLibs/quopri.py new file mode 100644 index 0000000000000000000000000000000000000000..8788afc2f188faeb357442e130431dfa569ff571 --- /dev/null +++ b/src/main/resources/PythonLibs/quopri.py @@ -0,0 +1,237 @@ +#! /usr/bin/env python + +"""Conversions to/from quoted-printable transport encoding as per RFC 1521.""" + +# (Dec 1991 version). + +__all__ = ["encode", "decode", "encodestring", "decodestring"] + +ESCAPE = '=' +MAXLINESIZE = 76 +HEX = '0123456789ABCDEF' +EMPTYSTRING = '' + +try: + from binascii import a2b_qp, b2a_qp +except ImportError: + a2b_qp = None + b2a_qp = None + + +def needsquoting(c, quotetabs, header): + """Decide whether a particular character needs to be quoted. + + The 'quotetabs' flag indicates whether embedded tabs and spaces should be + quoted. Note that line-ending tabs and spaces are always encoded, as per + RFC 1521. + """ + if c in ' \t': + return quotetabs + # if header, we have to escape _ because _ is used to escape space + if c == '_': + return header + return c == ESCAPE or not (' ' <= c <= '~') + +def quote(c): + """Quote a single character.""" + i = ord(c) + return ESCAPE + HEX[i//16] + HEX[i%16] + + + +def encode(input, output, quotetabs, header = 0): + """Read 'input', apply quoted-printable encoding, and write to 'output'. + + 'input' and 'output' are files with readline() and write() methods. + The 'quotetabs' flag indicates whether embedded tabs and spaces should be + quoted. Note that line-ending tabs and spaces are always encoded, as per + RFC 1521. + The 'header' flag indicates whether we are encoding spaces as _ as per + RFC 1522. + """ + + if b2a_qp is not None: + data = input.read() + odata = b2a_qp(data, quotetabs = quotetabs, header = header) + output.write(odata) + return + + def write(s, output=output, lineEnd='\n'): + # RFC 1521 requires that the line ending in a space or tab must have + # that trailing character encoded. + if s and s[-1:] in ' \t': + output.write(s[:-1] + quote(s[-1]) + lineEnd) + elif s == '.': + output.write(quote(s) + lineEnd) + else: + output.write(s + lineEnd) + + prevline = None + while 1: + line = input.readline() + if not line: + break + outline = [] + # Strip off any readline induced trailing newline + stripped = '' + if line[-1:] == '\n': + line = line[:-1] + stripped = '\n' + # Calculate the un-length-limited encoded line + for c in line: + if needsquoting(c, quotetabs, header): + c = quote(c) + if header and c == ' ': + outline.append('_') + else: + outline.append(c) + # First, write out the previous line + if prevline is not None: + write(prevline) + # Now see if we need any soft line breaks because of RFC-imposed + # length limitations. Then do the thisline->prevline dance. + thisline = EMPTYSTRING.join(outline) + while len(thisline) > MAXLINESIZE: + # Don't forget to include the soft line break `=' sign in the + # length calculation! + write(thisline[:MAXLINESIZE-1], lineEnd='=\n') + thisline = thisline[MAXLINESIZE-1:] + # Write out the current line + prevline = thisline + # Write out the last line, without a trailing newline + if prevline is not None: + write(prevline, lineEnd=stripped) + +def encodestring(s, quotetabs = 0, header = 0): + if b2a_qp is not None: + return b2a_qp(s, quotetabs = quotetabs, header = header) + from cStringIO import StringIO + infp = StringIO(s) + outfp = StringIO() + encode(infp, outfp, quotetabs, header) + return outfp.getvalue() + + + +def decode(input, output, header = 0): + """Read 'input', apply quoted-printable decoding, and write to 'output'. + 'input' and 'output' are files with readline() and write() methods. + If 'header' is true, decode underscore as space (per RFC 1522).""" + + if a2b_qp is not None: + data = input.read() + odata = a2b_qp(data, header = header) + output.write(odata) + return + + new = '' + while 1: + line = input.readline() + if not line: break + i, n = 0, len(line) + if n > 0 and line[n-1] == '\n': + partial = 0; n = n-1 + # Strip trailing whitespace + while n > 0 and line[n-1] in " \t\r": + n = n-1 + else: + partial = 1 + while i < n: + c = line[i] + if c == '_' and header: + new = new + ' '; i = i+1 + elif c != ESCAPE: + new = new + c; i = i+1 + elif i+1 == n and not partial: + partial = 1; break + elif i+1 < n and line[i+1] == ESCAPE: + new = new + ESCAPE; i = i+2 + elif i+2 < n and ishex(line[i+1]) and ishex(line[i+2]): + new = new + chr(unhex(line[i+1:i+3])); i = i+3 + else: # Bad escape sequence -- leave it in + new = new + c; i = i+1 + if not partial: + output.write(new + '\n') + new = '' + if new: + output.write(new) + +def decodestring(s, header = 0): + if a2b_qp is not None: + return a2b_qp(s, header = header) + from cStringIO import StringIO + infp = StringIO(s) + outfp = StringIO() + decode(infp, outfp, header = header) + return outfp.getvalue() + + + +# Other helper functions +def ishex(c): + """Return true if the character 'c' is a hexadecimal digit.""" + return '0' <= c <= '9' or 'a' <= c <= 'f' or 'A' <= c <= 'F' + +def unhex(s): + """Get the integer value of a hexadecimal number.""" + bits = 0 + for c in s: + if '0' <= c <= '9': + i = ord('0') + elif 'a' <= c <= 'f': + i = ord('a')-10 + elif 'A' <= c <= 'F': + i = ord('A')-10 + else: + break + bits = bits*16 + (ord(c) - i) + return bits + + + +def main(): + import sys + import getopt + try: + opts, args = getopt.getopt(sys.argv[1:], 'td') + except getopt.error, msg: + sys.stdout = sys.stderr + print msg + print "usage: quopri [-t | -d] [file] ..." + print "-t: quote tabs" + print "-d: decode; default encode" + sys.exit(2) + deco = 0 + tabs = 0 + for o, a in opts: + if o == '-t': tabs = 1 + if o == '-d': deco = 1 + if tabs and deco: + sys.stdout = sys.stderr + print "-t and -d are mutually exclusive" + sys.exit(2) + if not args: args = ['-'] + sts = 0 + for file in args: + if file == '-': + fp = sys.stdin + else: + try: + fp = open(file) + except IOError, msg: + sys.stderr.write("%s: can't open (%s)\n" % (file, msg)) + sts = 1 + continue + if deco: + decode(fp, sys.stdout) + else: + encode(fp, sys.stdout, tabs) + if fp is not sys.stdin: + fp.close() + if sts: + sys.exit(sts) + + + +if __name__ == '__main__': + main() diff --git a/src/main/resources/PythonLibs/random.py b/src/main/resources/PythonLibs/random.py new file mode 100644 index 0000000000000000000000000000000000000000..af04ab207d37c098d274caf852d37bdbcfc28198 --- /dev/null +++ b/src/main/resources/PythonLibs/random.py @@ -0,0 +1,904 @@ +"""Random variable generators. + + integers + -------- + uniform within range + + sequences + --------- + pick random element + pick random sample + generate random permutation + + distributions on the real line: + ------------------------------ + uniform + triangular + normal (Gaussian) + lognormal + negative exponential + gamma + beta + pareto + Weibull + + distributions on the circle (angles 0 to 2pi) + --------------------------------------------- + circular uniform + von Mises + +General notes on the underlying Mersenne Twister core generator: + +* The period is 2**19937-1. +* It is one of the most extensively tested generators in existence. +* Without a direct way to compute N steps forward, the semantics of + jumpahead(n) are weakened to simply jump to another distant state and rely + on the large period to avoid overlapping sequences. +* The random() method is implemented in C, executes in a single Python step, + and is, therefore, threadsafe. + +""" + +from __future__ import division +from warnings import warn as _warn +from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType +from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil +from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin +from os import urandom as _urandom +from binascii import hexlify as _hexlify +import hashlib as _hashlib + +__all__ = ["Random","seed","random","uniform","randint","choice","sample", + "randrange","shuffle","normalvariate","lognormvariate", + "expovariate","vonmisesvariate","gammavariate","triangular", + "gauss","betavariate","paretovariate","weibullvariate", + "getstate","setstate","jumpahead", "WichmannHill", "getrandbits", + "SystemRandom"] + +NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0) +TWOPI = 2.0*_pi +LOG4 = _log(4.0) +SG_MAGICCONST = 1.0 + _log(4.5) +BPF = 53 # Number of bits in a float +RECIP_BPF = 2**-BPF + + +# Translated by Guido van Rossum from C source provided by +# Adrian Baddeley. Adapted by Raymond Hettinger for use with +# the Mersenne Twister and os.urandom() core generators. + +import _random + +class Random(_random.Random): + """Random number generator base class used by bound module functions. + + Used to instantiate instances of Random to get generators that don't + share state. Especially useful for multi-threaded programs, creating + a different instance of Random for each thread, and using the jumpahead() + method to ensure that the generated sequences seen by each thread don't + overlap. + + Class Random can also be subclassed if you want to use a different basic + generator of your own devising: in that case, override the following + methods: random(), seed(), getstate(), setstate() and jumpahead(). + Optionally, implement a getrandbits() method so that randrange() can cover + arbitrarily large ranges. + + """ + + VERSION = 3 # used by getstate/setstate + + def __init__(self, x=None): + """Initialize an instance. + + Optional argument x controls seeding, as for Random.seed(). + """ + + self.seed(x) + self.gauss_next = None + + def seed(self, a=None): + """Initialize internal state from hashable object. + + None or no argument seeds from current time or from an operating + system specific randomness source if available. + + If a is not None or an int or long, hash(a) is used instead. + """ + + if a is None: + try: + a = long(_hexlify(_urandom(16)), 16) + except NotImplementedError: + import time + a = long(time.time() * 256) # use fractional seconds + + super(Random, self).seed(a) + self.gauss_next = None + + def getstate(self): + """Return internal state; can be passed to setstate() later.""" + return self.VERSION, super(Random, self).getstate(), self.gauss_next + + def setstate(self, state): + """Restore internal state from object returned by getstate().""" + version = state[0] + if version == 3: + version, internalstate, self.gauss_next = state + super(Random, self).setstate(internalstate) + elif version == 2: + version, internalstate, self.gauss_next = state + # In version 2, the state was saved as signed ints, which causes + # inconsistencies between 32/64-bit systems. The state is + # really unsigned 32-bit ints, so we convert negative ints from + # version 2 to positive longs for version 3. + try: + internalstate = tuple( long(x) % (2**32) for x in internalstate ) + except ValueError, e: + raise TypeError, e + super(Random, self).setstate(internalstate) + else: + raise ValueError("state with version %s passed to " + "Random.setstate() of version %s" % + (version, self.VERSION)) + + def jumpahead(self, n): + """Change the internal state to one that is likely far away + from the current state. This method will not be in Py3.x, + so it is better to simply reseed. + """ + # The super.jumpahead() method uses shuffling to change state, + # so it needs a large and "interesting" n to work with. Here, + # we use hashing to create a large n for the shuffle. + s = repr(n) + repr(self.getstate()) + n = int(_hashlib.new('sha512', s).hexdigest(), 16) + super(Random, self).jumpahead(n) + +## ---- Methods below this point do not need to be overridden when +## ---- subclassing for the purpose of using a different core generator. + +## -------------------- pickle support ------------------- + + def __getstate__(self): # for pickle + return self.getstate() + + def __setstate__(self, state): # for pickle + self.setstate(state) + + def __reduce__(self): + return self.__class__, (), self.getstate() + +## -------------------- integer methods ------------------- + + def randrange(self, start, stop=None, step=1, int=int, default=None, + maxwidth=1L<<BPF): + """Choose a random item from range(start, stop[, step]). + + This fixes the problem with randint() which includes the + endpoint; in Python this is usually not what you want. + Do not supply the 'int', 'default', and 'maxwidth' arguments. + """ + + # This code is a bit messy to make it fast for the + # common case while still doing adequate error checking. + istart = int(start) + if istart != start: + raise ValueError, "non-integer arg 1 for randrange()" + if stop is default: + if istart > 0: + if istart >= maxwidth: + return self._randbelow(istart) + return int(self.random() * istart) + raise ValueError, "empty range for randrange()" + + # stop argument supplied. + istop = int(stop) + if istop != stop: + raise ValueError, "non-integer stop for randrange()" + width = istop - istart + if step == 1 and width > 0: + # Note that + # int(istart + self.random()*width) + # instead would be incorrect. For example, consider istart + # = -2 and istop = 0. Then the guts would be in + # -2.0 to 0.0 exclusive on both ends (ignoring that random() + # might return 0.0), and because int() truncates toward 0, the + # final result would be -1 or 0 (instead of -2 or -1). + # istart + int(self.random()*width) + # would also be incorrect, for a subtler reason: the RHS + # can return a long, and then randrange() would also return + # a long, but we're supposed to return an int (for backward + # compatibility). + + if width >= maxwidth: + return int(istart + self._randbelow(width)) + return int(istart + int(self.random()*width)) + if step == 1: + raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width) + + # Non-unit step argument supplied. + istep = int(step) + if istep != step: + raise ValueError, "non-integer step for randrange()" + if istep > 0: + n = (width + istep - 1) // istep + elif istep < 0: + n = (width + istep + 1) // istep + else: + raise ValueError, "zero step for randrange()" + + if n <= 0: + raise ValueError, "empty range for randrange()" + + if n >= maxwidth: + return istart + istep*self._randbelow(n) + return istart + istep*int(self.random() * n) + + def randint(self, a, b): + """Return random integer in range [a, b], including both end points. + """ + + return self.randrange(a, b+1) + + def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<<BPF, + _Method=_MethodType, _BuiltinMethod=_BuiltinMethodType): + """Return a random int in the range [0,n) + + Handles the case where n has more bits than returned + by a single call to the underlying generator. + """ + + try: + getrandbits = self.getrandbits + except AttributeError: + pass + else: + # Only call self.getrandbits if the original random() builtin method + # has not been overridden or if a new getrandbits() was supplied. + # This assures that the two methods correspond. + if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method: + k = int(1.00001 + _log(n-1, 2.0)) # 2**k > n-1 > 2**(k-2) + r = getrandbits(k) + while r >= n: + r = getrandbits(k) + return r + if n >= _maxwidth: + _warn("Underlying random() generator does not supply \n" + "enough bits to choose from a population range this large") + return int(self.random() * n) + +## -------------------- sequence methods ------------------- + + def choice(self, seq): + """Choose a random element from a non-empty sequence.""" + return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty + + def shuffle(self, x, random=None, int=int): + """x, random=random.random -> shuffle list x in place; return None. + + Optional arg random is a 0-argument function returning a random + float in [0.0, 1.0); by default, the standard random.random. + """ + + if random is None: + random = self.random + for i in reversed(xrange(1, len(x))): + # pick an element in x[:i+1] with which to exchange x[i] + j = int(random() * (i+1)) + x[i], x[j] = x[j], x[i] + + def sample(self, population, k): + """Chooses k unique random elements from a population sequence. + + Returns a new list containing elements from the population while + leaving the original population unchanged. The resulting list is + in selection order so that all sub-slices will also be valid random + samples. This allows raffle winners (the sample) to be partitioned + into grand prize and second place winners (the subslices). + + Members of the population need not be hashable or unique. If the + population contains repeats, then each occurrence is a possible + selection in the sample. + + To choose a sample in a range of integers, use xrange as an argument. + This is especially fast and space efficient for sampling from a + large population: sample(xrange(10000000), 60) + """ + + # Sampling without replacement entails tracking either potential + # selections (the pool) in a list or previous selections in a set. + + # When the number of selections is small compared to the + # population, then tracking selections is efficient, requiring + # only a small set and an occasional reselection. For + # a larger number of selections, the pool tracking method is + # preferred since the list takes less space than the + # set and it doesn't suffer from frequent reselections. + + n = len(population) + if not 0 <= k <= n: + raise ValueError("sample larger than population") + random = self.random + _int = int + result = [None] * k + setsize = 21 # size of a small set minus size of an empty list + if k > 5: + setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets + if n <= setsize or hasattr(population, "keys"): + # An n-length list is smaller than a k-length set, or this is a + # mapping type so the other algorithm wouldn't work. + pool = list(population) + for i in xrange(k): # invariant: non-selected at [0,n-i) + j = _int(random() * (n-i)) + result[i] = pool[j] + pool[j] = pool[n-i-1] # move non-selected item into vacancy + else: + try: + selected = set() + selected_add = selected.add + for i in xrange(k): + j = _int(random() * n) + while j in selected: + j = _int(random() * n) + selected_add(j) + result[i] = population[j] + except (TypeError, KeyError): # handle (at least) sets + if isinstance(population, list): + raise + return self.sample(tuple(population), k) + return result + +## -------------------- real-valued distributions ------------------- + +## -------------------- uniform distribution ------------------- + + def uniform(self, a, b): + "Get a random number in the range [a, b) or [a, b] depending on rounding." + return a + (b-a) * self.random() + +## -------------------- triangular -------------------- + + def triangular(self, low=0.0, high=1.0, mode=None): + """Triangular distribution. + + Continuous distribution bounded by given lower and upper limits, + and having a given mode value in-between. + + http://en.wikipedia.org/wiki/Triangular_distribution + + """ + u = self.random() + c = 0.5 if mode is None else (mode - low) / (high - low) + if u > c: + u = 1.0 - u + c = 1.0 - c + low, high = high, low + return low + (high - low) * (u * c) ** 0.5 + +## -------------------- normal distribution -------------------- + + def normalvariate(self, mu, sigma): + """Normal distribution. + + mu is the mean, and sigma is the standard deviation. + + """ + # mu = mean, sigma = standard deviation + + # Uses Kinderman and Monahan method. Reference: Kinderman, + # A.J. and Monahan, J.F., "Computer generation of random + # variables using the ratio of uniform deviates", ACM Trans + # Math Software, 3, (1977), pp257-260. + + random = self.random + while 1: + u1 = random() + u2 = 1.0 - random() + z = NV_MAGICCONST*(u1-0.5)/u2 + zz = z*z/4.0 + if zz <= -_log(u2): + break + return mu + z*sigma + +## -------------------- lognormal distribution -------------------- + + def lognormvariate(self, mu, sigma): + """Log normal distribution. + + If you take the natural logarithm of this distribution, you'll get a + normal distribution with mean mu and standard deviation sigma. + mu can have any value, and sigma must be greater than zero. + + """ + return _exp(self.normalvariate(mu, sigma)) + +## -------------------- exponential distribution -------------------- + + def expovariate(self, lambd): + """Exponential distribution. + + lambd is 1.0 divided by the desired mean. It should be + nonzero. (The parameter would be called "lambda", but that is + a reserved word in Python.) Returned values range from 0 to + positive infinity if lambd is positive, and from negative + infinity to 0 if lambd is negative. + + """ + # lambd: rate lambd = 1/mean + # ('lambda' is a Python reserved word) + + # we use 1-random() instead of random() to preclude the + # possibility of taking the log of zero. + return -_log(1.0 - self.random())/lambd + +## -------------------- von Mises distribution -------------------- + + def vonmisesvariate(self, mu, kappa): + """Circular data distribution. + + mu is the mean angle, expressed in radians between 0 and 2*pi, and + kappa is the concentration parameter, which must be greater than or + equal to zero. If kappa is equal to zero, this distribution reduces + to a uniform random angle over the range 0 to 2*pi. + + """ + # mu: mean angle (in radians between 0 and 2*pi) + # kappa: concentration parameter kappa (>= 0) + # if kappa = 0 generate uniform random angle + + # Based upon an algorithm published in: Fisher, N.I., + # "Statistical Analysis of Circular Data", Cambridge + # University Press, 1993. + + # Thanks to Magnus Kessler for a correction to the + # implementation of step 4. + + random = self.random + if kappa <= 1e-6: + return TWOPI * random() + + s = 0.5 / kappa + r = s + _sqrt(1.0 + s * s) + + while 1: + u1 = random() + z = _cos(_pi * u1) + + d = z / (r + z) + u2 = random() + if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d): + break + + q = 1.0 / r + f = (q + z) / (1.0 + q * z) + u3 = random() + if u3 > 0.5: + theta = (mu + _acos(f)) % TWOPI + else: + theta = (mu - _acos(f)) % TWOPI + + return theta + +## -------------------- gamma distribution -------------------- + + def gammavariate(self, alpha, beta): + """Gamma distribution. Not the gamma function! + + Conditions on the parameters are alpha > 0 and beta > 0. + + The probability distribution function is: + + x ** (alpha - 1) * math.exp(-x / beta) + pdf(x) = -------------------------------------- + math.gamma(alpha) * beta ** alpha + + """ + + # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 + + # Warning: a few older sources define the gamma distribution in terms + # of alpha > -1.0 + if alpha <= 0.0 or beta <= 0.0: + raise ValueError, 'gammavariate: alpha and beta must be > 0.0' + + random = self.random + if alpha > 1.0: + + # Uses R.C.H. Cheng, "The generation of Gamma + # variables with non-integral shape parameters", + # Applied Statistics, (1977), 26, No. 1, p71-74 + + ainv = _sqrt(2.0 * alpha - 1.0) + bbb = alpha - LOG4 + ccc = alpha + ainv + + while 1: + u1 = random() + if not 1e-7 < u1 < .9999999: + continue + u2 = 1.0 - random() + v = _log(u1/(1.0-u1))/ainv + x = alpha*_exp(v) + z = u1*u1*u2 + r = bbb+ccc*v-x + if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z): + return x * beta + + elif alpha == 1.0: + # expovariate(1) + u = random() + while u <= 1e-7: + u = random() + return -_log(u) * beta + + else: # alpha is between 0 and 1 (exclusive) + + # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle + + while 1: + u = random() + b = (_e + alpha)/_e + p = b*u + if p <= 1.0: + x = p ** (1.0/alpha) + else: + x = -_log((b-p)/alpha) + u1 = random() + if p > 1.0: + if u1 <= x ** (alpha - 1.0): + break + elif u1 <= _exp(-x): + break + return x * beta + +## -------------------- Gauss (faster alternative) -------------------- + + def gauss(self, mu, sigma): + """Gaussian distribution. + + mu is the mean, and sigma is the standard deviation. This is + slightly faster than the normalvariate() function. + + Not thread-safe without a lock around calls. + + """ + + # When x and y are two variables from [0, 1), uniformly + # distributed, then + # + # cos(2*pi*x)*sqrt(-2*log(1-y)) + # sin(2*pi*x)*sqrt(-2*log(1-y)) + # + # are two *independent* variables with normal distribution + # (mu = 0, sigma = 1). + # (Lambert Meertens) + # (corrected version; bug discovered by Mike Miller, fixed by LM) + + # Multithreading note: When two threads call this function + # simultaneously, it is possible that they will receive the + # same return value. The window is very small though. To + # avoid this, you have to use a lock around all calls. (I + # didn't want to slow this down in the serial case by using a + # lock here.) + + random = self.random + z = self.gauss_next + self.gauss_next = None + if z is None: + x2pi = random() * TWOPI + g2rad = _sqrt(-2.0 * _log(1.0 - random())) + z = _cos(x2pi) * g2rad + self.gauss_next = _sin(x2pi) * g2rad + + return mu + z*sigma + +## -------------------- beta -------------------- +## See +## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html +## for Ivan Frohne's insightful analysis of why the original implementation: +## +## def betavariate(self, alpha, beta): +## # Discrete Event Simulation in C, pp 87-88. +## +## y = self.expovariate(alpha) +## z = self.expovariate(1.0/beta) +## return z/(y+z) +## +## was dead wrong, and how it probably got that way. + + def betavariate(self, alpha, beta): + """Beta distribution. + + Conditions on the parameters are alpha > 0 and beta > 0. + Returned values range between 0 and 1. + + """ + + # This version due to Janne Sinkkonen, and matches all the std + # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution"). + y = self.gammavariate(alpha, 1.) + if y == 0: + return 0.0 + else: + return y / (y + self.gammavariate(beta, 1.)) + +## -------------------- Pareto -------------------- + + def paretovariate(self, alpha): + """Pareto distribution. alpha is the shape parameter.""" + # Jain, pg. 495 + + u = 1.0 - self.random() + return 1.0 / pow(u, 1.0/alpha) + +## -------------------- Weibull -------------------- + + def weibullvariate(self, alpha, beta): + """Weibull distribution. + + alpha is the scale parameter and beta is the shape parameter. + + """ + # Jain, pg. 499; bug fix courtesy Bill Arms + + u = 1.0 - self.random() + return alpha * pow(-_log(u), 1.0/beta) + +## -------------------- Wichmann-Hill ------------------- + +class WichmannHill(Random): + + VERSION = 1 # used by getstate/setstate + + def seed(self, a=None): + """Initialize internal state from hashable object. + + None or no argument seeds from current time or from an operating + system specific randomness source if available. + + If a is not None or an int or long, hash(a) is used instead. + + If a is an int or long, a is used directly. Distinct values between + 0 and 27814431486575L inclusive are guaranteed to yield distinct + internal states (this guarantee is specific to the default + Wichmann-Hill generator). + """ + + if a is None: + try: + a = long(_hexlify(_urandom(16)), 16) + except NotImplementedError: + import time + a = long(time.time() * 256) # use fractional seconds + + if not isinstance(a, (int, long)): + a = hash(a) + + a, x = divmod(a, 30268) + a, y = divmod(a, 30306) + a, z = divmod(a, 30322) + self._seed = int(x)+1, int(y)+1, int(z)+1 + + self.gauss_next = None + + def random(self): + """Get the next random number in the range [0.0, 1.0).""" + + # Wichman-Hill random number generator. + # + # Wichmann, B. A. & Hill, I. D. (1982) + # Algorithm AS 183: + # An efficient and portable pseudo-random number generator + # Applied Statistics 31 (1982) 188-190 + # + # see also: + # Correction to Algorithm AS 183 + # Applied Statistics 33 (1984) 123 + # + # McLeod, A. I. (1985) + # A remark on Algorithm AS 183 + # Applied Statistics 34 (1985),198-200 + + # This part is thread-unsafe: + # BEGIN CRITICAL SECTION + x, y, z = self._seed + x = (171 * x) % 30269 + y = (172 * y) % 30307 + z = (170 * z) % 30323 + self._seed = x, y, z + # END CRITICAL SECTION + + # Note: on a platform using IEEE-754 double arithmetic, this can + # never return 0.0 (asserted by Tim; proof too long for a comment). + return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0 + + def getstate(self): + """Return internal state; can be passed to setstate() later.""" + return self.VERSION, self._seed, self.gauss_next + + def setstate(self, state): + """Restore internal state from object returned by getstate().""" + version = state[0] + if version == 1: + version, self._seed, self.gauss_next = state + else: + raise ValueError("state with version %s passed to " + "Random.setstate() of version %s" % + (version, self.VERSION)) + + def jumpahead(self, n): + """Act as if n calls to random() were made, but quickly. + + n is an int, greater than or equal to 0. + + Example use: If you have 2 threads and know that each will + consume no more than a million random numbers, create two Random + objects r1 and r2, then do + r2.setstate(r1.getstate()) + r2.jumpahead(1000000) + Then r1 and r2 will use guaranteed-disjoint segments of the full + period. + """ + + if not n >= 0: + raise ValueError("n must be >= 0") + x, y, z = self._seed + x = int(x * pow(171, n, 30269)) % 30269 + y = int(y * pow(172, n, 30307)) % 30307 + z = int(z * pow(170, n, 30323)) % 30323 + self._seed = x, y, z + + def __whseed(self, x=0, y=0, z=0): + """Set the Wichmann-Hill seed from (x, y, z). + + These must be integers in the range [0, 256). + """ + + if not type(x) == type(y) == type(z) == int: + raise TypeError('seeds must be integers') + if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256): + raise ValueError('seeds must be in range(0, 256)') + if 0 == x == y == z: + # Initialize from current time + import time + t = long(time.time() * 256) + t = int((t&0xffffff) ^ (t>>24)) + t, x = divmod(t, 256) + t, y = divmod(t, 256) + t, z = divmod(t, 256) + # Zero is a poor seed, so substitute 1 + self._seed = (x or 1, y or 1, z or 1) + + self.gauss_next = None + + def whseed(self, a=None): + """Seed from hashable object's hash code. + + None or no argument seeds from current time. It is not guaranteed + that objects with distinct hash codes lead to distinct internal + states. + + This is obsolete, provided for compatibility with the seed routine + used prior to Python 2.1. Use the .seed() method instead. + """ + + if a is None: + self.__whseed() + return + a = hash(a) + a, x = divmod(a, 256) + a, y = divmod(a, 256) + a, z = divmod(a, 256) + x = (x + a) % 256 or 1 + y = (y + a) % 256 or 1 + z = (z + a) % 256 or 1 + self.__whseed(x, y, z) + +## --------------- Operating System Random Source ------------------ + +class SystemRandom(Random): + """Alternate random number generator using sources provided + by the operating system (such as /dev/urandom on Unix or + CryptGenRandom on Windows). + + Not available on all systems (see os.urandom() for details). + """ + + def random(self): + """Get the next random number in the range [0.0, 1.0).""" + return (long(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF + + def getrandbits(self, k): + """getrandbits(k) -> x. Generates a long int with k random bits.""" + if k <= 0: + raise ValueError('number of bits must be greater than zero') + if k != int(k): + raise TypeError('number of bits should be an integer') + bytes = (k + 7) // 8 # bits / 8 and rounded up + x = long(_hexlify(_urandom(bytes)), 16) + return x >> (bytes * 8 - k) # trim excess bits + + def _stub(self, *args, **kwds): + "Stub method. Not used for a system random number generator." + return None + seed = jumpahead = _stub + + def _notimplemented(self, *args, **kwds): + "Method should not be called for a system random number generator." + raise NotImplementedError('System entropy source does not have state.') + getstate = setstate = _notimplemented + +## -------------------- test program -------------------- + +def _test_generator(n, func, args): + import time + print n, 'times', func.__name__ + total = 0.0 + sqsum = 0.0 + smallest = 1e10 + largest = -1e10 + t0 = time.time() + for i in range(n): + x = func(*args) + total += x + sqsum = sqsum + x*x + smallest = min(x, smallest) + largest = max(x, largest) + t1 = time.time() + print round(t1-t0, 3), 'sec,', + avg = total/n + stddev = _sqrt(sqsum/n - avg*avg) + print 'avg %g, stddev %g, min %g, max %g' % \ + (avg, stddev, smallest, largest) + + +def _test(N=2000): + _test_generator(N, random, ()) + _test_generator(N, normalvariate, (0.0, 1.0)) + _test_generator(N, lognormvariate, (0.0, 1.0)) + _test_generator(N, vonmisesvariate, (0.0, 1.0)) + _test_generator(N, gammavariate, (0.01, 1.0)) + _test_generator(N, gammavariate, (0.1, 1.0)) + _test_generator(N, gammavariate, (0.1, 2.0)) + _test_generator(N, gammavariate, (0.5, 1.0)) + _test_generator(N, gammavariate, (0.9, 1.0)) + _test_generator(N, gammavariate, (1.0, 1.0)) + _test_generator(N, gammavariate, (2.0, 1.0)) + _test_generator(N, gammavariate, (20.0, 1.0)) + _test_generator(N, gammavariate, (200.0, 1.0)) + _test_generator(N, gauss, (0.0, 1.0)) + _test_generator(N, betavariate, (3.0, 3.0)) + _test_generator(N, triangular, (0.0, 1.0, 1.0/3.0)) + +# Create one instance, seeded from current time, and export its methods +# as module-level functions. The functions share state across all uses +#(both in the user's code and in the Python libraries), but that's fine +# for most programs and is easier for the casual user than making them +# instantiate their own Random() instance. + +_inst = Random() +seed = _inst.seed +random = _inst.random +uniform = _inst.uniform +triangular = _inst.triangular +randint = _inst.randint +choice = _inst.choice +randrange = _inst.randrange +sample = _inst.sample +shuffle = _inst.shuffle +normalvariate = _inst.normalvariate +lognormvariate = _inst.lognormvariate +expovariate = _inst.expovariate +vonmisesvariate = _inst.vonmisesvariate +gammavariate = _inst.gammavariate +gauss = _inst.gauss +betavariate = _inst.betavariate +paretovariate = _inst.paretovariate +weibullvariate = _inst.weibullvariate +getstate = _inst.getstate +setstate = _inst.setstate +jumpahead = _inst.jumpahead +getrandbits = _inst.getrandbits + +if __name__ == '__main__': + _test() diff --git a/src/main/resources/PythonLibs/re.py b/src/main/resources/PythonLibs/re.py new file mode 100644 index 0000000000000000000000000000000000000000..aab5d37e589252dfe9b06f0ed3e8aa13def49eed --- /dev/null +++ b/src/main/resources/PythonLibs/re.py @@ -0,0 +1,324 @@ +# +# Secret Labs' Regular Expression Engine +# +# re-compatible interface for the sre matching engine +# +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. +# +# This version of the SRE library can be redistributed under CNRI's +# Python 1.6 license. For any other use, please contact Secret Labs +# AB (info@pythonware.com). +# +# Portions of this engine have been developed in cooperation with +# CNRI. Hewlett-Packard provided funding for 1.6 integration and +# other compatibility work. +# + +r"""Support for regular expressions (RE). + +This module provides regular expression matching operations similar to +those found in Perl. It supports both 8-bit and Unicode strings; both +the pattern and the strings being processed can contain null bytes and +characters outside the US ASCII range. + +Regular expressions can contain both special and ordinary characters. +Most ordinary characters, like "A", "a", or "0", are the simplest +regular expressions; they simply match themselves. You can +concatenate ordinary characters, so last matches the string 'last'. + +The special characters are: + "." Matches any character except a newline. + "^" Matches the start of the string. + "$" Matches the end of the string or just before the newline at + the end of the string. + "*" Matches 0 or more (greedy) repetitions of the preceding RE. + Greedy means that it will match as many repetitions as possible. + "+" Matches 1 or more (greedy) repetitions of the preceding RE. + "?" Matches 0 or 1 (greedy) of the preceding RE. + *?,+?,?? Non-greedy versions of the previous three special characters. + {m,n} Matches from m to n repetitions of the preceding RE. + {m,n}? Non-greedy version of the above. + "\\" Either escapes special characters or signals a special sequence. + [] Indicates a set of characters. + A "^" as the first character indicates a complementing set. + "|" A|B, creates an RE that will match either A or B. + (...) Matches the RE inside the parentheses. + The contents can be retrieved or matched later in the string. + (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below). + (?:...) Non-grouping version of regular parentheses. + (?P<name>...) The substring matched by the group is accessible by name. + (?P=name) Matches the text matched earlier by the group named name. + (?#...) A comment; ignored. + (?=...) Matches if ... matches next, but doesn't consume the string. + (?!...) Matches if ... doesn't match next. + (?<=...) Matches if preceded by ... (must be fixed length). + (?<!...) Matches if not preceded by ... (must be fixed length). + (?(id/name)yes|no) Matches yes pattern if the group with id/name matched, + the (optional) no pattern otherwise. + +The special sequences consist of "\\" and a character from the list +below. If the ordinary character is not on the list, then the +resulting RE will match the second character. + \number Matches the contents of the group of the same number. + \A Matches only at the start of the string. + \Z Matches only at the end of the string. + \b Matches the empty string, but only at the start or end of a word. + \B Matches the empty string, but not at the start or end of a word. + \d Matches any decimal digit; equivalent to the set [0-9]. + \D Matches any non-digit character; equivalent to the set [^0-9]. + \s Matches any whitespace character; equivalent to [ \t\n\r\f\v]. + \S Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v]. + \w Matches any alphanumeric character; equivalent to [a-zA-Z0-9_]. + With LOCALE, it will match the set [0-9_] plus characters defined + as letters for the current locale. + \W Matches the complement of \w. + \\ Matches a literal backslash. + +This module exports the following functions: + match Match a regular expression pattern to the beginning of a string. + search Search a string for the presence of a pattern. + sub Substitute occurrences of a pattern found in a string. + subn Same as sub, but also return the number of substitutions made. + split Split a string by the occurrences of a pattern. + findall Find all occurrences of a pattern in a string. + finditer Return an iterator yielding a match object for each match. + compile Compile a pattern into a RegexObject. + purge Clear the regular expression cache. + escape Backslash all non-alphanumerics in a string. + +Some of the functions in this module takes flags as optional parameters: + I IGNORECASE Perform case-insensitive matching. + L LOCALE Make \w, \W, \b, \B, dependent on the current locale. + M MULTILINE "^" matches the beginning of lines (after a newline) + as well as the string. + "$" matches the end of lines (before a newline) as well + as the end of the string. + S DOTALL "." matches any character at all, including the newline. + X VERBOSE Ignore whitespace and comments for nicer looking RE's. + U UNICODE Make \w, \W, \b, \B, dependent on the Unicode locale. + +This module also defines an exception 'error'. + +""" + +import sys +import sre_compile +import sre_parse + +# public symbols +__all__ = [ "match", "search", "sub", "subn", "split", "findall", + "compile", "purge", "template", "escape", "I", "L", "M", "S", "X", + "U", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", + "UNICODE", "error" ] + +__version__ = "2.2.1" + +# flags +I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case +L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale +U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale +M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline +S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline +X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments + +# sre extensions (experimental, don't rely on these) +T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking +DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation + +# sre exception +error = sre_compile.error + +# -------------------------------------------------------------------- +# public interface + +def match(pattern, string, flags=0): + """Try to apply the pattern at the start of the string, returning + a match object, or None if no match was found.""" + return _compile(pattern, flags).match(string) + +def search(pattern, string, flags=0): + """Scan through string looking for a match to the pattern, returning + a match object, or None if no match was found.""" + return _compile(pattern, flags).search(string) + +def sub(pattern, repl, string, count=0, flags=0): + """Return the string obtained by replacing the leftmost + non-overlapping occurrences of the pattern in string by the + replacement repl. repl can be either a string or a callable; + if a string, backslash escapes in it are processed. If it is + a callable, it's passed the match object and must return + a replacement string to be used.""" + return _compile(pattern, flags).sub(repl, string, count) + +def subn(pattern, repl, string, count=0, flags=0): + """Return a 2-tuple containing (new_string, number). + new_string is the string obtained by replacing the leftmost + non-overlapping occurrences of the pattern in the source + string by the replacement repl. number is the number of + substitutions that were made. repl can be either a string or a + callable; if a string, backslash escapes in it are processed. + If it is a callable, it's passed the match object and must + return a replacement string to be used.""" + return _compile(pattern, flags).subn(repl, string, count) + +def split(pattern, string, maxsplit=0, flags=0): + """Split the source string by the occurrences of the pattern, + returning a list containing the resulting substrings.""" + return _compile(pattern, flags).split(string, maxsplit) + +def findall(pattern, string, flags=0): + """Return a list of all non-overlapping matches in the string. + + If one or more groups are present in the pattern, return a + list of groups; this will be a list of tuples if the pattern + has more than one group. + + Empty matches are included in the result.""" + return _compile(pattern, flags).findall(string) + +if sys.hexversion >= 0x02020000: + __all__.append("finditer") + def finditer(pattern, string, flags=0): + """Return an iterator over all non-overlapping matches in the + string. For each match, the iterator returns a match object. + + Empty matches are included in the result.""" + return _compile(pattern, flags).finditer(string) + +def compile(pattern, flags=0): + "Compile a regular expression pattern, returning a pattern object." + return _compile(pattern, flags) + +def purge(): + "Clear the regular expression cache" + _cache.clear() + _cache_repl.clear() + +def template(pattern, flags=0): + "Compile a template pattern, returning a pattern object" + return _compile(pattern, flags|T) + +_alphanum = frozenset( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + +def escape(pattern): + "Escape all non-alphanumeric characters in pattern." + s = list(pattern) + alphanum = _alphanum + for i, c in enumerate(pattern): + if c not in alphanum: + if c == "\000": + s[i] = "\\000" + else: + s[i] = "\\" + c + return pattern[:0].join(s) + +# -------------------------------------------------------------------- +# internals + +_cache = {} +_cache_repl = {} + +_pattern_type = type(sre_compile.compile("", 0)) + +_MAXCACHE = 100 + +def _compile(*key): + # internal: compile pattern + cachekey = (type(key[0]),) + key + p = _cache.get(cachekey) + if p is not None: + return p + pattern, flags = key + if isinstance(pattern, _pattern_type): + if flags: + raise ValueError('Cannot process flags argument with a compiled pattern') + return pattern + if not sre_compile.isstring(pattern): + raise TypeError, "first argument must be string or compiled pattern" + try: + p = sre_compile.compile(pattern, flags) + except error, v: + raise error, v # invalid expression + if len(_cache) >= _MAXCACHE: + _cache.clear() + _cache[cachekey] = p + return p + +def _compile_repl(*key): + # internal: compile replacement pattern + p = _cache_repl.get(key) + if p is not None: + return p + repl, pattern = key + try: + p = sre_parse.parse_template(repl, pattern) + except error, v: + raise error, v # invalid expression + if len(_cache_repl) >= _MAXCACHE: + _cache_repl.clear() + _cache_repl[key] = p + return p + +def _expand(pattern, match, template): + # internal: match.expand implementation hook + template = sre_parse.parse_template(template, pattern) + return sre_parse.expand_template(template, match) + +def _subx(pattern, template): + # internal: pattern.sub/subn implementation helper + template = _compile_repl(template, pattern) + if not template[0] and len(template[1]) == 1: + # literal replacement + return template[1][0] + def filter(match, template=template): + return sre_parse.expand_template(template, match) + return filter + +# register myself for pickling + +import copy_reg + +def _pickle(p): + return _compile, (p.pattern, p.flags) + +copy_reg.pickle(_pattern_type, _pickle, _compile) + +# -------------------------------------------------------------------- +# experimental stuff (see python-dev discussions for details) + +class Scanner: + def __init__(self, lexicon, flags=0): + from sre_constants import BRANCH, SUBPATTERN + self.lexicon = lexicon + # combine phrases into a compound pattern + p = [] + s = sre_parse.Pattern() + s.flags = flags + for phrase, action in lexicon: + p.append(sre_parse.SubPattern(s, [ + (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))), + ])) + s.groups = len(p)+1 + p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) + self.scanner = sre_compile.compile(p) + def scan(self, string): + result = [] + append = result.append + match = self.scanner.scanner(string).match + i = 0 + while 1: + m = match() + if not m: + break + j = m.end() + if i == j: + break + action = self.lexicon[m.lastindex-1][1] + if hasattr(action, '__call__'): + self.match = m + action = action(self, m.group()) + if action is not None: + append(action) + i = j + return result, string[i:] diff --git a/src/main/resources/PythonLibs/readline.py b/src/main/resources/PythonLibs/readline.py new file mode 100644 index 0000000000000000000000000000000000000000..2296a5404469beca080ba6b5d0b37cb7e085e9bc --- /dev/null +++ b/src/main/resources/PythonLibs/readline.py @@ -0,0 +1,192 @@ +from __future__ import with_statement +import os.path +import sys +from warnings import warn + +import java.lang.reflect.Array + +__all__ = ['add_history', 'clear_history', 'get_begidx', 'get_completer', + 'get_completer_delims', 'get_current_history_length', + 'get_endidx', 'get_history_item', 'get_history_length', + 'get_line_buffer', 'insert_text', 'parse_and_bind', + 'read_history_file', 'read_init_file', 'redisplay', + 'remove_history_item', 'set_completer', 'set_completer_delims', + 'set_history_length', 'set_pre_input_hook', 'set_startup_hook', + 'write_history_file'] + +try: + _console = sys._jy_console + _reader = _console.reader +except AttributeError: + raise ImportError("Cannot access JLineConsole reader") + +_history_list = None + +# The need for the following warnings should go away once we update +# JLine. Choosing ImportWarning as the closest warning to what is +# going on here, namely this is functionality not yet available on +# Jython. + +class NotImplementedWarning(ImportWarning): + """Not yet implemented by Jython""" + +class SecurityWarning(ImportWarning): + """Security manager prevents access to private field""" + + +def _setup_history(): + # This is obviously not desirable, but avoids O(n) workarounds to + # modify the history (ipython uses the function + # remove_history_item to mutate the history relatively frequently) + global _history_list + + history = _reader.history + try: + history_list_field = history.class.getDeclaredField("history") + history_list_field.setAccessible(True) + _history_list = history_list_field.get(history) + except: + pass + +_setup_history() + +def parse_and_bind(string): + if string == "tab: complete": + try: + keybindings_field = _reader.class.getDeclaredField("keybindings") + keybindings_field.setAccessible(True) + keybindings = keybindings_field.get(_reader) + COMPLETE = _reader.KEYMAP_NAMES.get('COMPLETE') + if java.lang.reflect.Array.getShort(keybindings, 9) != COMPLETE: + java.lang.reflect.Array.setShort(keybindings, 9, COMPLETE) + except: + warn("Cannot bind tab key to complete. You need to do this in a .jlinebindings.properties file instead", SecurityWarning, stacklevel=2) + else: + warn("Cannot bind key %s. You need to do this in a .jlinebindings.properties file instead" % (string,), NotImplementedWarning, stacklevel=2) + +def get_line_buffer(): + return str(_reader.cursorBuffer.buffer) + +def insert_text(string): + _reader.putString(string) + +def read_init_file(filename=None): + warn("read_init_file: %s" % (filename,), NotImplementedWarning, "module", 2) + +def read_history_file(filename="~/.history"): + print "Reading history:", filename + expanded = os.path.expanduser(filename) + new_history = _reader.getHistory().getClass()() + # new_history.clear() + with open(expanded) as f: + for line in f: + new_history.addToHistory(line.rstrip()) + _reader.history = new_history + _setup_history() + +def write_history_file(filename="~/.history"): + expanded = os.path.expanduser(filename) + with open(expanded, 'w') as f: + for line in _reader.history.historyList: + f.write(line) + f.write("\n") + +def clear_history(): + _reader.history.clear() + +def add_history(line): + _reader.history.addToHistory(line) + +def get_history_length(): + return _reader.history.maxSize + +def set_history_length(length): + _reader.history.maxSize = length + +def get_current_history_length(): + return len(_reader.history.historyList) + +def get_history_item(index): + # JLine indexes from 0 while readline indexes from 1 (at least in test_readline) + if index>0: + return _reader.history.historyList[index-1] + else: + return None + +def remove_history_item(pos): + if _history_list: + _history_list.remove(pos) + else: + warn("Cannot remove history item at position: %s" % (pos,), SecurityWarning, stacklevel=2) + +def replace_history_item(pos, line): + if _history_list: + _history_list.set(pos, line) + else: + warn("Cannot replace history item at position: %s" % (pos,), SecurityWarning, stacklevel=2) + +def redisplay(): + _reader.redrawLine() + +def set_startup_hook(function=None): + _console.startupHook = function + +def set_pre_input_hook(function=None): + warn("set_pre_input_hook %s" % (function,), NotImplementedWarning, stacklevel=2) + +_completer_function = None + +def set_completer(function=None): + """set_completer([function]) -> None + Set or remove the completer function. + The function is called as function(text, state), + for state in 0, 1, 2, ..., until it returns a non-string. + It should return the next possible completion starting with 'text'.""" + + global _completer_function + _completer_function = function + + def complete_handler(buffer, cursor, candidates): + start = _get_delimited(buffer, cursor)[0] + delimited = buffer[start:cursor] + for state in xrange(100): # TODO arbitrary, what's the number used by gnu readline? + completion = None + try: + completion = function(delimited, state) + except: + pass + if completion: + candidates.add(completion) + else: + break + return start + + _reader.addCompletor(complete_handler) + + +def get_completer(): + return _completer_function + +def _get_delimited(buffer, cursor): + start = cursor + for i in xrange(cursor-1, -1, -1): + if buffer[i] in _completer_delims: + break + start = i + return start, cursor + +def get_begidx(): + return _get_delimited(str(_reader.cursorBuffer.buffer), _reader.cursorBuffer.cursor)[0] + +def get_endidx(): + return _get_delimited(str(_reader.cursorBuffer.buffer), _reader.cursorBuffer.cursor)[1] + +def set_completer_delims(string): + global _completer_delims, _completer_delims_set + _completer_delims = string + _completer_delims_set = set(string) + +def get_completer_delims(): + return _completer_delims + +set_completer_delims(' \t\n`~!@#$%^&*()-=+[{]}\\|;:\'",<>/?') diff --git a/src/main/resources/PythonLibs/repr.py b/src/main/resources/PythonLibs/repr.py new file mode 100644 index 0000000000000000000000000000000000000000..3c26cc39a2190ccdeebd6fb6a93738b6f4a50fdd --- /dev/null +++ b/src/main/resources/PythonLibs/repr.py @@ -0,0 +1,132 @@ +"""Redo the builtin repr() (representation) but with limits on most sizes.""" + +__all__ = ["Repr","repr"] + +import __builtin__ +from itertools import islice + +class Repr: + + def __init__(self): + self.maxlevel = 6 + self.maxtuple = 6 + self.maxlist = 6 + self.maxarray = 5 + self.maxdict = 4 + self.maxset = 6 + self.maxfrozenset = 6 + self.maxdeque = 6 + self.maxstring = 30 + self.maxlong = 40 + self.maxother = 20 + + def repr(self, x): + return self.repr1(x, self.maxlevel) + + def repr1(self, x, level): + typename = type(x).__name__ + if ' ' in typename: + parts = typename.split() + typename = '_'.join(parts) + if hasattr(self, 'repr_' + typename): + return getattr(self, 'repr_' + typename)(x, level) + else: + s = __builtin__.repr(x) + if len(s) > self.maxother: + i = max(0, (self.maxother-3)//2) + j = max(0, self.maxother-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def _repr_iterable(self, x, level, left, right, maxiter, trail=''): + n = len(x) + if level <= 0 and n: + s = '...' + else: + newlevel = level - 1 + repr1 = self.repr1 + pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] + if n > maxiter: pieces.append('...') + s = ', '.join(pieces) + if n == 1 and trail: right = trail + right + return '%s%s%s' % (left, s, right) + + def repr_tuple(self, x, level): + return self._repr_iterable(x, level, '(', ')', self.maxtuple, ',') + + def repr_list(self, x, level): + return self._repr_iterable(x, level, '[', ']', self.maxlist) + + def repr_array(self, x, level): + header = "array('%s', [" % x.typecode + return self._repr_iterable(x, level, header, '])', self.maxarray) + + def repr_set(self, x, level): + x = _possibly_sorted(x) + return self._repr_iterable(x, level, 'set([', '])', self.maxset) + + def repr_frozenset(self, x, level): + x = _possibly_sorted(x) + return self._repr_iterable(x, level, 'frozenset([', '])', + self.maxfrozenset) + + def repr_deque(self, x, level): + return self._repr_iterable(x, level, 'deque([', '])', self.maxdeque) + + def repr_dict(self, x, level): + n = len(x) + if n == 0: return '{}' + if level <= 0: return '{...}' + newlevel = level - 1 + repr1 = self.repr1 + pieces = [] + for key in islice(_possibly_sorted(x), self.maxdict): + keyrepr = repr1(key, newlevel) + valrepr = repr1(x[key], newlevel) + pieces.append('%s: %s' % (keyrepr, valrepr)) + if n > self.maxdict: pieces.append('...') + s = ', '.join(pieces) + return '{%s}' % (s,) + + def repr_str(self, x, level): + s = __builtin__.repr(x[:self.maxstring]) + if len(s) > self.maxstring: + i = max(0, (self.maxstring-3)//2) + j = max(0, self.maxstring-3-i) + s = __builtin__.repr(x[:i] + x[len(x)-j:]) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def repr_long(self, x, level): + s = __builtin__.repr(x) # XXX Hope this isn't too slow... + if len(s) > self.maxlong: + i = max(0, (self.maxlong-3)//2) + j = max(0, self.maxlong-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + def repr_instance(self, x, level): + try: + s = __builtin__.repr(x) + # Bugs in x.__repr__() can cause arbitrary + # exceptions -- then make up something + except Exception: + return '<%s instance at %x>' % (x.__class__.__name__, id(x)) + if len(s) > self.maxstring: + i = max(0, (self.maxstring-3)//2) + j = max(0, self.maxstring-3-i) + s = s[:i] + '...' + s[len(s)-j:] + return s + + +def _possibly_sorted(x): + # Since not all sequences of items can be sorted and comparison + # functions may raise arbitrary exceptions, return an unsorted + # sequence in that case. + try: + return sorted(x) + except Exception: + return list(x) + +aRepr = Repr() +repr = aRepr.repr diff --git a/src/main/resources/PythonLibs/rfc822.py b/src/main/resources/PythonLibs/rfc822.py new file mode 100644 index 0000000000000000000000000000000000000000..b65d8da0d25babd71cd52720e1e422524e38d921 --- /dev/null +++ b/src/main/resources/PythonLibs/rfc822.py @@ -0,0 +1,1011 @@ +"""RFC 2822 message manipulation. + +Note: This is only a very rough sketch of a full RFC-822 parser; in particular +the tokenizing of addresses does not adhere to all the quoting rules. + +Note: RFC 2822 is a long awaited update to RFC 822. This module should +conform to RFC 2822, and is thus mis-named (it's not worth renaming it). Some +effort at RFC 2822 updates have been made, but a thorough audit has not been +performed. Consider any RFC 2822 non-conformance to be a bug. + + RFC 2822: http://www.faqs.org/rfcs/rfc2822.html + RFC 822 : http://www.faqs.org/rfcs/rfc822.html (obsolete) + +Directions for use: + +To create a Message object: first open a file, e.g.: + + fp = open(file, 'r') + +You can use any other legal way of getting an open file object, e.g. use +sys.stdin or call os.popen(). Then pass the open file object to the Message() +constructor: + + m = Message(fp) + +This class can work with any input object that supports a readline method. If +the input object has seek and tell capability, the rewindbody method will +work; also illegal lines will be pushed back onto the input stream. If the +input object lacks seek but has an `unread' method that can push back a line +of input, Message will use that to push back illegal lines. Thus this class +can be used to parse messages coming from a buffered stream. + +The optional `seekable' argument is provided as a workaround for certain stdio +libraries in which tell() discards buffered data before discovering that the +lseek() system call doesn't work. For maximum portability, you should set the +seekable argument to zero to prevent that initial \code{tell} when passing in +an unseekable object such as a file object created from a socket object. If +it is 1 on entry -- which it is by default -- the tell() method of the open +file object is called once; if this raises an exception, seekable is reset to +0. For other nonzero values of seekable, this test is not made. + +To get the text of a particular header there are several methods: + + str = m.getheader(name) + str = m.getrawheader(name) + +where name is the name of the header, e.g. 'Subject'. The difference is that +getheader() strips the leading and trailing whitespace, while getrawheader() +doesn't. Both functions retain embedded whitespace (including newlines) +exactly as they are specified in the header, and leave the case of the text +unchanged. + +For addresses and address lists there are functions + + realname, mailaddress = m.getaddr(name) + list = m.getaddrlist(name) + +where the latter returns a list of (realname, mailaddr) tuples. + +There is also a method + + time = m.getdate(name) + +which parses a Date-like field and returns a time-compatible tuple, +i.e. a tuple such as returned by time.localtime() or accepted by +time.mktime(). + +See the class definition for lower level access methods. + +There are also some utility functions here. +""" +# Cleanup and extensions by Eric S. Raymond <esr@thyrsus.com> + +import time + +from warnings import warnpy3k +warnpy3k("in 3.x, rfc822 has been removed in favor of the email package", + stacklevel=2) + +__all__ = ["Message","AddressList","parsedate","parsedate_tz","mktime_tz"] + +_blanklines = ('\r\n', '\n') # Optimization for islast() + + +class Message: + """Represents a single RFC 2822-compliant message.""" + + def __init__(self, fp, seekable = 1): + """Initialize the class instance and read the headers.""" + if seekable == 1: + # Exercise tell() to make sure it works + # (and then assume seek() works, too) + try: + fp.tell() + except (AttributeError, IOError): + seekable = 0 + self.fp = fp + self.seekable = seekable + self.startofheaders = None + self.startofbody = None + # + if self.seekable: + try: + self.startofheaders = self.fp.tell() + except IOError: + self.seekable = 0 + # + self.readheaders() + # + if self.seekable: + try: + self.startofbody = self.fp.tell() + except IOError: + self.seekable = 0 + + def rewindbody(self): + """Rewind the file to the start of the body (if seekable).""" + if not self.seekable: + raise IOError, "unseekable file" + self.fp.seek(self.startofbody) + + def readheaders(self): + """Read header lines. + + Read header lines up to the entirely blank line that terminates them. + The (normally blank) line that ends the headers is skipped, but not + included in the returned list. If a non-header line ends the headers, + (which is an error), an attempt is made to backspace over it; it is + never included in the returned list. + + The variable self.status is set to the empty string if all went well, + otherwise it is an error message. The variable self.headers is a + completely uninterpreted list of lines contained in the header (so + printing them will reproduce the header exactly as it appears in the + file). + """ + self.dict = {} + self.unixfrom = '' + self.headers = lst = [] + self.status = '' + headerseen = "" + firstline = 1 + startofline = unread = tell = None + if hasattr(self.fp, 'unread'): + unread = self.fp.unread + elif self.seekable: + tell = self.fp.tell + while 1: + if tell: + try: + startofline = tell() + except IOError: + startofline = tell = None + self.seekable = 0 + line = self.fp.readline() + if not line: + self.status = 'EOF in headers' + break + # Skip unix From name time lines + if firstline and line.startswith('From '): + self.unixfrom = self.unixfrom + line + continue + firstline = 0 + if headerseen and line[0] in ' \t': + # It's a continuation line. + lst.append(line) + x = (self.dict[headerseen] + "\n " + line.strip()) + self.dict[headerseen] = x.strip() + continue + elif self.iscomment(line): + # It's a comment. Ignore it. + continue + elif self.islast(line): + # Note! No pushback here! The delimiter line gets eaten. + break + headerseen = self.isheader(line) + if headerseen: + # It's a legal header line, save it. + lst.append(line) + self.dict[headerseen] = line[len(headerseen)+1:].strip() + continue + else: + # It's not a header line; throw it back and stop here. + if not self.dict: + self.status = 'No headers' + else: + self.status = 'Non-header line where header expected' + # Try to undo the read. + if unread: + unread(line) + elif tell: + self.fp.seek(startofline) + else: + self.status = self.status + '; bad seek' + break + + def isheader(self, line): + """Determine whether a given line is a legal header. + + This method should return the header name, suitably canonicalized. + You may override this method in order to use Message parsing on tagged + data in RFC 2822-like formats with special header formats. + """ + i = line.find(':') + if i > 0: + return line[:i].lower() + return None + + def islast(self, line): + """Determine whether a line is a legal end of RFC 2822 headers. + + You may override this method if your application wants to bend the + rules, e.g. to strip trailing whitespace, or to recognize MH template + separators ('--------'). For convenience (e.g. for code reading from + sockets) a line consisting of \\r\\n also matches. + """ + return line in _blanklines + + def iscomment(self, line): + """Determine whether a line should be skipped entirely. + + You may override this method in order to use Message parsing on tagged + data in RFC 2822-like formats that support embedded comments or + free-text data. + """ + return False + + 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.headers: + if line[:n].lower() == name: + hit = 1 + elif not line[:1].isspace(): + hit = 0 + if hit: + lst.append(line) + return lst + + def getfirstmatchingheader(self, name): + """Get the first header line matching name. + + This is similar to getallmatchingheaders, but it returns only the + first matching header (and its continuation lines). + """ + name = name.lower() + ':' + n = len(name) + lst = [] + hit = 0 + for line in self.headers: + if hit: + if not line[:1].isspace(): + break + elif line[:n].lower() == name: + hit = 1 + if hit: + lst.append(line) + return lst + + def getrawheader(self, name): + """A higher-level interface to getfirstmatchingheader(). + + Return a string containing the literal text of the header but with the + keyword stripped. All leading, trailing and embedded whitespace is + kept in the string, however. Return None if the header does not + occur. + """ + + lst = self.getfirstmatchingheader(name) + if not lst: + return None + lst[0] = lst[0][len(name) + 1:] + return ''.join(lst) + + def getheader(self, name, default=None): + """Get the header value for a name. + + This is the normal interface: it returns a stripped version of the + header value for a given header name, or None if it doesn't exist. + This uses the dictionary version which finds the *last* such header. + """ + return self.dict.get(name.lower(), default) + get = getheader + + def getheaders(self, name): + """Get all values for a header. + + This returns a list of values for headers given more than once; each + value in the result list is stripped in the same way as the result of + getheader(). If the header is not given, return an empty list. + """ + result = [] + current = '' + have_header = 0 + for s in self.getallmatchingheaders(name): + if s[0].isspace(): + if current: + current = "%s\n %s" % (current, s.strip()) + else: + current = s.strip() + else: + if have_header: + result.append(current) + current = s[s.find(":") + 1:].strip() + have_header = 1 + if have_header: + result.append(current) + return result + + def getaddr(self, name): + """Get a single address from a header, as a tuple. + + An example return value: + ('Guido van Rossum', 'guido@cwi.nl') + """ + # New, by Ben Escoto + alist = self.getaddrlist(name) + if alist: + return alist[0] + else: + return (None, None) + + def getaddrlist(self, name): + """Get a list of addresses from a header. + + Retrieves a list of addresses from a header, where each address is a + tuple as returned by getaddr(). Scans all named headers, so it works + properly with multiple To: or Cc: headers for example. + """ + raw = [] + for h in self.getallmatchingheaders(name): + if h[0] in ' \t': + raw.append(h) + else: + if raw: + raw.append(', ') + i = h.find(':') + if i > 0: + addr = h[i+1:] + raw.append(addr) + alladdrs = ''.join(raw) + a = AddressList(alladdrs) + return a.addresslist + + def getdate(self, name): + """Retrieve a date field from a header. + + Retrieves a date field from the named header, returning a tuple + compatible with time.mktime(). + """ + try: + data = self[name] + except KeyError: + return None + return parsedate(data) + + def getdate_tz(self, name): + """Retrieve a date field from a header as a 10-tuple. + + The first 9 elements make up a tuple compatible with time.mktime(), + and the 10th is the offset of the poster's time zone from GMT/UTC. + """ + try: + data = self[name] + except KeyError: + return None + return parsedate_tz(data) + + + # Access as a dictionary (only finds *last* header of each type): + + def __len__(self): + """Get the number of headers in a message.""" + return len(self.dict) + + def __getitem__(self, name): + """Get a specific header, as from a dictionary.""" + return self.dict[name.lower()] + + def __setitem__(self, name, value): + """Set the value of a header. + + Note: This is not a perfect inversion of __getitem__, because any + changed headers get stuck at the end of the raw-headers list rather + than where the altered header was. + """ + del self[name] # Won't fail if it doesn't exist + self.dict[name.lower()] = value + text = name + ": " + value + for line in text.split("\n"): + self.headers.append(line + "\n") + + def __delitem__(self, name): + """Delete all occurrences of a specific header, if it is present.""" + name = name.lower() + if not name in self.dict: + return + del self.dict[name] + name = name + ':' + n = len(name) + lst = [] + hit = 0 + for i in range(len(self.headers)): + line = self.headers[i] + if line[:n].lower() == name: + hit = 1 + elif not line[:1].isspace(): + hit = 0 + if hit: + lst.append(i) + for i in reversed(lst): + del self.headers[i] + + def setdefault(self, name, default=""): + lowername = name.lower() + if lowername in self.dict: + return self.dict[lowername] + else: + text = name + ": " + default + for line in text.split("\n"): + self.headers.append(line + "\n") + self.dict[lowername] = default + return default + + def has_key(self, name): + """Determine whether a message contains the named header.""" + return name.lower() in self.dict + + def __contains__(self, name): + """Determine whether a message contains the named header.""" + return name.lower() in self.dict + + def __iter__(self): + return iter(self.dict) + + def keys(self): + """Get all of a message's header field names.""" + return self.dict.keys() + + def values(self): + """Get all of a message's header field values.""" + return self.dict.values() + + def items(self): + """Get all of a message's headers. + + Returns a list of name, value tuples. + """ + return self.dict.items() + + def __str__(self): + return ''.join(self.headers) + + +# Utility functions +# ----------------- + +# XXX Should fix unquote() and quote() to be really conformant. +# XXX The inverses of the parse functions may also be useful. + + +def unquote(s): + """Remove quotes from a string.""" + if len(s) > 1: + if s.startswith('"') and s.endswith('"'): + return s[1:-1].replace('\\\\', '\\').replace('\\"', '"') + if s.startswith('<') and s.endswith('>'): + return s[1:-1] + return s + + +def quote(s): + """Add quotes around a string.""" + return s.replace('\\', '\\\\').replace('"', '\\"') + + +def parseaddr(address): + """Parse an address into a (realname, mailaddr) tuple.""" + a = AddressList(address) + lst = a.addresslist + if not lst: + return (None, None) + return lst[0] + + +class AddrlistClass: + """Address parser class by Ben Escoto. + + To understand what this class does, it helps to have a copy of + RFC 2822 in front of you. + + http://www.faqs.org/rfcs/rfc2822.html + + Note: this class interface is deprecated and may be removed in the future. + Use rfc822.AddressList instead. + """ + + def __init__(self, field): + """Initialize a new instance. + + `field' is an unparsed address header field, containing one or more + addresses. + """ + self.specials = '()<>@,:;.\"[]' + self.pos = 0 + self.LWS = ' \t' + self.CR = '\r\n' + self.atomends = self.specials + self.LWS + self.CR + # Note that RFC 2822 now specifies `.' as obs-phrase, meaning that it + # is obsolete syntax. RFC 2822 requires that we recognize obsolete + # syntax, so allow dots in phrases. + self.phraseends = self.atomends.replace('.', '') + self.field = field + self.commentlist = [] + + def gotonext(self): + """Parse up to the start of the next address.""" + while self.pos < len(self.field): + if self.field[self.pos] in self.LWS + '\n\r': + self.pos = self.pos + 1 + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + else: break + + def getaddrlist(self): + """Parse all addresses. + + Returns a list containing all of the addresses. + """ + result = [] + ad = self.getaddress() + while ad: + result += ad + ad = self.getaddress() + return result + + def getaddress(self): + """Parse the next address.""" + self.commentlist = [] + self.gotonext() + + oldpos = self.pos + oldcl = self.commentlist + plist = self.getphraselist() + + self.gotonext() + returnlist = [] + + if self.pos >= len(self.field): + # Bad email address technically, no domain. + if plist: + returnlist = [(' '.join(self.commentlist), plist[0])] + + elif self.field[self.pos] in '.@': + # email address is just an addrspec + # this isn't very efficient since we start over + self.pos = oldpos + self.commentlist = oldcl + addrspec = self.getaddrspec() + returnlist = [(' '.join(self.commentlist), addrspec)] + + elif self.field[self.pos] == ':': + # address is a group + returnlist = [] + + fieldlen = len(self.field) + self.pos += 1 + while self.pos < len(self.field): + self.gotonext() + if self.pos < fieldlen and self.field[self.pos] == ';': + self.pos += 1 + break + returnlist = returnlist + self.getaddress() + + elif self.field[self.pos] == '<': + # Address is a phrase then a route addr + routeaddr = self.getrouteaddr() + + if self.commentlist: + returnlist = [(' '.join(plist) + ' (' + \ + ' '.join(self.commentlist) + ')', routeaddr)] + else: returnlist = [(' '.join(plist), routeaddr)] + + else: + if plist: + returnlist = [(' '.join(self.commentlist), plist[0])] + elif self.field[self.pos] in self.specials: + self.pos += 1 + + self.gotonext() + if self.pos < len(self.field) and self.field[self.pos] == ',': + self.pos += 1 + return returnlist + + def getrouteaddr(self): + """Parse a route address (Return-path value). + + This method just skips all the route stuff and returns the addrspec. + """ + if self.field[self.pos] != '<': + return + + expectroute = 0 + self.pos += 1 + self.gotonext() + adlist = "" + while self.pos < len(self.field): + if expectroute: + self.getdomain() + expectroute = 0 + elif self.field[self.pos] == '>': + self.pos += 1 + break + elif self.field[self.pos] == '@': + self.pos += 1 + expectroute = 1 + elif self.field[self.pos] == ':': + self.pos += 1 + else: + adlist = self.getaddrspec() + self.pos += 1 + break + self.gotonext() + + return adlist + + def getaddrspec(self): + """Parse an RFC 2822 addr-spec.""" + aslist = [] + + self.gotonext() + while self.pos < len(self.field): + if self.field[self.pos] == '.': + aslist.append('.') + self.pos += 1 + elif self.field[self.pos] == '"': + aslist.append('"%s"' % self.getquote()) + elif self.field[self.pos] in self.atomends: + break + else: aslist.append(self.getatom()) + self.gotonext() + + if self.pos >= len(self.field) or self.field[self.pos] != '@': + return ''.join(aslist) + + aslist.append('@') + self.pos += 1 + self.gotonext() + return ''.join(aslist) + self.getdomain() + + def getdomain(self): + """Get the complete domain name from an address.""" + sdlist = [] + while self.pos < len(self.field): + if self.field[self.pos] in self.LWS: + self.pos += 1 + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + elif self.field[self.pos] == '[': + sdlist.append(self.getdomainliteral()) + elif self.field[self.pos] == '.': + self.pos += 1 + sdlist.append('.') + elif self.field[self.pos] in self.atomends: + break + else: sdlist.append(self.getatom()) + return ''.join(sdlist) + + def getdelimited(self, beginchar, endchars, allowcomments = 1): + """Parse a header fragment delimited by special characters. + + `beginchar' is the start character for the fragment. If self is not + looking at an instance of `beginchar' then getdelimited returns the + empty string. + + `endchars' is a sequence of allowable end-delimiting characters. + Parsing stops when one of these is encountered. + + If `allowcomments' is non-zero, embedded RFC 2822 comments are allowed + within the parsed fragment. + """ + if self.field[self.pos] != beginchar: + return '' + + slist = [''] + quote = 0 + self.pos += 1 + while self.pos < len(self.field): + if quote == 1: + slist.append(self.field[self.pos]) + quote = 0 + elif self.field[self.pos] in endchars: + self.pos += 1 + break + elif allowcomments and self.field[self.pos] == '(': + slist.append(self.getcomment()) + continue # have already advanced pos from getcomment + elif self.field[self.pos] == '\\': + quote = 1 + else: + slist.append(self.field[self.pos]) + self.pos += 1 + + return ''.join(slist) + + def getquote(self): + """Get a quote-delimited fragment from self's field.""" + return self.getdelimited('"', '"\r', 0) + + def getcomment(self): + """Get a parenthesis-delimited fragment from self's field.""" + return self.getdelimited('(', ')\r', 1) + + def getdomainliteral(self): + """Parse an RFC 2822 domain-literal.""" + return '[%s]' % self.getdelimited('[', ']\r', 0) + + def getatom(self, atomends=None): + """Parse an RFC 2822 atom. + + Optional atomends specifies a different set of end token delimiters + (the default is to use self.atomends). This is used e.g. in + getphraselist() since phrase endings must not include the `.' (which + is legal in phrases).""" + atomlist = [''] + if atomends is None: + atomends = self.atomends + + while self.pos < len(self.field): + if self.field[self.pos] in atomends: + break + else: atomlist.append(self.field[self.pos]) + self.pos += 1 + + return ''.join(atomlist) + + def getphraselist(self): + """Parse a sequence of RFC 2822 phrases. + + A phrase is a sequence of words, which are in turn either RFC 2822 + atoms or quoted-strings. Phrases are canonicalized by squeezing all + runs of continuous whitespace into one space. + """ + plist = [] + + while self.pos < len(self.field): + if self.field[self.pos] in self.LWS: + self.pos += 1 + elif self.field[self.pos] == '"': + plist.append(self.getquote()) + elif self.field[self.pos] == '(': + self.commentlist.append(self.getcomment()) + elif self.field[self.pos] in self.phraseends: + break + else: + plist.append(self.getatom(self.phraseends)) + + return plist + +class AddressList(AddrlistClass): + """An AddressList encapsulates a list of parsed RFC 2822 addresses.""" + def __init__(self, field): + AddrlistClass.__init__(self, field) + if field: + self.addresslist = self.getaddrlist() + else: + self.addresslist = [] + + def __len__(self): + return len(self.addresslist) + + def __str__(self): + return ", ".join(map(dump_address_pair, self.addresslist)) + + def __add__(self, other): + # Set union + newaddr = AddressList(None) + newaddr.addresslist = self.addresslist[:] + for x in other.addresslist: + if not x in self.addresslist: + newaddr.addresslist.append(x) + return newaddr + + def __iadd__(self, other): + # Set union, in-place + for x in other.addresslist: + if not x in self.addresslist: + self.addresslist.append(x) + return self + + def __sub__(self, other): + # Set difference + newaddr = AddressList(None) + for x in self.addresslist: + if not x in other.addresslist: + newaddr.addresslist.append(x) + return newaddr + + def __isub__(self, other): + # Set difference, in-place + for x in other.addresslist: + if x in self.addresslist: + self.addresslist.remove(x) + return self + + def __getitem__(self, index): + # Make indexing, slices, and 'in' work + return self.addresslist[index] + +def dump_address_pair(pair): + """Dump a (name, address) pair in a canonicalized form.""" + if pair[0]: + return '"' + pair[0] + '" <' + pair[1] + '>' + else: + return pair[1] + +# Parse a date field + +_monthnames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', + 'aug', 'sep', 'oct', 'nov', 'dec', + 'january', 'february', 'march', 'april', 'may', 'june', 'july', + 'august', 'september', 'october', 'november', 'december'] +_daynames = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] + +# The timezone table does not include the military time zones defined +# in RFC822, other than Z. According to RFC1123, the description in +# RFC822 gets the signs wrong, so we can't rely on any such time +# zones. RFC1123 recommends that numeric timezone indicators be used +# instead of timezone names. + +_timezones = {'UT':0, 'UTC':0, 'GMT':0, 'Z':0, + 'AST': -400, 'ADT': -300, # Atlantic (used in Canada) + 'EST': -500, 'EDT': -400, # Eastern + 'CST': -600, 'CDT': -500, # Central + 'MST': -700, 'MDT': -600, # Mountain + 'PST': -800, 'PDT': -700 # Pacific + } + + +def parsedate_tz(data): + """Convert a date string to a time tuple. + + Accounts for military timezones. + """ + if not data: + return None + data = data.split() + if data[0][-1] in (',', '.') or data[0].lower() in _daynames: + # There's a dayname here. Skip it + del data[0] + else: + # no space after the "weekday,"? + i = data[0].rfind(',') + if i >= 0: + data[0] = data[0][i+1:] + if len(data) == 3: # RFC 850 date, deprecated + stuff = data[0].split('-') + if len(stuff) == 3: + data = stuff + data[1:] + if len(data) == 4: + s = data[3] + i = s.find('+') + if i > 0: + data[3:] = [s[:i], s[i+1:]] + else: + data.append('') # Dummy tz + if len(data) < 5: + return None + data = data[:5] + [dd, mm, yy, tm, tz] = data + mm = mm.lower() + if not mm in _monthnames: + dd, mm = mm, dd.lower() + if not mm in _monthnames: + return None + mm = _monthnames.index(mm)+1 + if mm > 12: mm = mm - 12 + if dd[-1] == ',': + dd = dd[:-1] + i = yy.find(':') + if i > 0: + yy, tm = tm, yy + if yy[-1] == ',': + yy = yy[:-1] + if not yy[0].isdigit(): + yy, tz = tz, yy + if tm[-1] == ',': + tm = tm[:-1] + tm = tm.split(':') + if len(tm) == 2: + [thh, tmm] = tm + tss = '0' + elif len(tm) == 3: + [thh, tmm, tss] = tm + else: + return None + try: + yy = int(yy) + dd = int(dd) + thh = int(thh) + tmm = int(tmm) + tss = int(tss) + except ValueError: + return None + tzoffset = None + tz = tz.upper() + if tz in _timezones: + tzoffset = _timezones[tz] + else: + try: + tzoffset = int(tz) + except ValueError: + pass + # Convert a timezone offset into seconds ; -0500 -> -18000 + if tzoffset: + if tzoffset < 0: + tzsign = -1 + tzoffset = -tzoffset + else: + tzsign = 1 + tzoffset = tzsign * ( (tzoffset//100)*3600 + (tzoffset % 100)*60) + return (yy, mm, dd, thh, tmm, tss, 0, 1, 0, tzoffset) + + +def parsedate(data): + """Convert a time string to a time tuple.""" + t = parsedate_tz(data) + if t is None: + return t + return t[:9] + + +def mktime_tz(data): + """Turn a 10-tuple as returned by parsedate_tz() into a UTC timestamp.""" + if data[9] is None: + # No zone info, so localtime is better assumption than GMT + return time.mktime(data[:8] + (-1,)) + else: + t = time.mktime(data[:8] + (0,)) + return t - data[9] - time.timezone + +def formatdate(timeval=None): + """Returns time format preferred for Internet standards. + + Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 + + According to RFC 1123, day and month names must always be in + English. If not for that, this code could use strftime(). It + can't because strftime() honors the locale and could generated + non-English names. + """ + if timeval is None: + timeval = time.time() + timeval = time.gmtime(timeval) + return "%s, %02d %s %04d %02d:%02d:%02d GMT" % ( + ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")[timeval[6]], + timeval[2], + ("Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[timeval[1]-1], + timeval[0], timeval[3], timeval[4], timeval[5]) + + +# When used as script, run a small test program. +# The first command line argument must be a filename containing one +# message in RFC-822 format. + +if __name__ == '__main__': + import sys, os + file = os.path.join(os.environ['HOME'], 'Mail/inbox/1') + if sys.argv[1:]: file = sys.argv[1] + f = open(file, 'r') + m = Message(f) + print 'From:', m.getaddr('from') + print 'To:', m.getaddrlist('to') + print 'Subject:', m.getheader('subject') + print 'Date:', m.getheader('date') + date = m.getdate_tz('date') + tz = date[-1] + date = time.localtime(mktime_tz(date)) + if date: + print 'ParsedDate:', time.asctime(date), + hhmmss = tz + hhmm, ss = divmod(hhmmss, 60) + hh, mm = divmod(hhmm, 60) + print "%+03d%02d" % (hh, mm), + if ss: print ".%02d" % ss, + print + else: + print 'ParsedDate:', None + m.rewindbody() + n = 0 + while f.readline(): + n += 1 + print 'Lines:', n + print '-'*70 + print 'len =', len(m) + if 'Date' in m: print 'Date =', m['Date'] + if 'X-Nonsense' in m: pass + print 'keys =', m.keys() + print 'values =', m.values() + print 'items =', m.items() diff --git a/src/main/resources/PythonLibs/rlcompleter.py b/src/main/resources/PythonLibs/rlcompleter.py new file mode 100644 index 0000000000000000000000000000000000000000..366c59c0cdf04ab9989a43d784341d905cdf11b6 --- /dev/null +++ b/src/main/resources/PythonLibs/rlcompleter.py @@ -0,0 +1,166 @@ +"""Word completion for GNU readline. + +The completer completes keywords, built-ins and globals in a selectable +namespace (which defaults to __main__); when completing NAME.NAME..., it +evaluates (!) the expression up to the last dot and completes its attributes. + +It's very cool to do "import sys" type "sys.", hit the completion key (twice), +and see the list of names defined by the sys module! + +Tip: to use the tab key as the completion key, call + + readline.parse_and_bind("tab: complete") + +Notes: + +- Exceptions raised by the completer function are *ignored* (and generally cause + the completion to fail). This is a feature -- since readline sets the tty + device in raw (or cbreak) mode, printing a traceback wouldn't work well + without some complicated hoopla to save, reset and restore the tty state. + +- The evaluation of the NAME.NAME... form may cause arbitrary application + defined code to be executed if an object with a __getattr__ hook is found. + Since it is the responsibility of the application (or the user) to enable this + feature, I consider this an acceptable risk. More complicated expressions + (e.g. function calls or indexing operations) are *not* evaluated. + +- GNU readline is also used by the built-in functions input() and +raw_input(), and thus these also benefit/suffer from the completer +features. Clearly an interactive application can benefit by +specifying its own completer function and using raw_input() for all +its input. + +- When the original stdin is not a tty device, GNU readline is never + used, and this module (and the readline module) are silently inactive. + +""" + +import __builtin__ +import __main__ + +__all__ = ["Completer"] + +class Completer: + def __init__(self, namespace = None): + """Create a new completer for the command line. + + Completer([namespace]) -> completer instance. + + If unspecified, the default namespace where completions are performed + is __main__ (technically, __main__.__dict__). Namespaces should be + given as dictionaries. + + Completer instances should be used as the completion mechanism of + readline via the set_completer() call: + + readline.set_completer(Completer(my_namespace).complete) + """ + + if namespace and not isinstance(namespace, dict): + raise TypeError,'namespace must be a dictionary' + + # Don't bind to namespace quite yet, but flag whether the user wants a + # specific namespace or to use __main__.__dict__. This will allow us + # to bind to __main__.__dict__ at completion time, not now. + if namespace is None: + self.use_main_ns = 1 + else: + self.use_main_ns = 0 + self.namespace = namespace + + def complete(self, text, state): + """Return the next possible completion for 'text'. + + This is called successively with state == 0, 1, 2, ... until it + returns None. The completion should begin with 'text'. + + """ + if self.use_main_ns: + self.namespace = __main__.__dict__ + + if state == 0: + if "." in text: + self.matches = self.attr_matches(text) + else: + self.matches = self.global_matches(text) + try: + return self.matches[state] + except IndexError: + return None + + def _callable_postfix(self, val, word): + if hasattr(val, '__call__'): + word = word + "(" + return word + + def global_matches(self, text): + """Compute matches when text is a simple name. + + Return a list of all keywords, built-in functions and names currently + defined in self.namespace that match. + + """ + import keyword + matches = [] + n = len(text) + for word in keyword.kwlist: + if word[:n] == text: + matches.append(word) + for nspace in [__builtin__.__dict__, self.namespace]: + for word, val in nspace.items(): + if word[:n] == text and word != "__builtins__": + matches.append(self._callable_postfix(val, word)) + return matches + + def attr_matches(self, text): + """Compute matches when text contains a dot. + + Assuming the text is of the form NAME.NAME....[NAME], and is + evaluatable in self.namespace, it will be evaluated and its attributes + (as revealed by dir()) are used as possible completions. (For class + instances, class members are also considered.) + + WARNING: this can still invoke arbitrary C code, if an object + with a __getattr__ hook is evaluated. + + """ + import re + m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text) + if not m: + return [] + expr, attr = m.group(1, 3) + try: + thisobject = eval(expr, self.namespace) + except Exception: + return [] + + # get the content of the object, except __builtins__ + words = dir(thisobject) + if "__builtins__" in words: + words.remove("__builtins__") + + if hasattr(thisobject, '__class__'): + words.append('__class__') + words.extend(get_class_members(thisobject.__class__)) + matches = [] + n = len(attr) + for word in words: + if word[:n] == attr and hasattr(thisobject, word): + val = getattr(thisobject, word) + word = self._callable_postfix(val, "%s.%s" % (expr, word)) + matches.append(word) + return matches + +def get_class_members(klass): + ret = dir(klass) + if hasattr(klass,'__bases__'): + for base in klass.__bases__: + ret = ret + get_class_members(base) + return ret + +try: + import readline +except ImportError: + pass +else: + readline.set_completer(Completer().complete) diff --git a/src/main/resources/PythonLibs/robotparser.py b/src/main/resources/PythonLibs/robotparser.py new file mode 100644 index 0000000000000000000000000000000000000000..1722863d144db7fc1956292892ebf49dc3f0cd3a --- /dev/null +++ b/src/main/resources/PythonLibs/robotparser.py @@ -0,0 +1,222 @@ +""" robotparser.py + + Copyright (C) 2000 Bastian Kleineidam + + You can choose between two licenses when using this package: + 1) GNU GPLv2 + 2) PSF license for Python 2.2 + + The robots.txt Exclusion Protocol is implemented as specified in + http://info.webcrawler.com/mak/projects/robots/norobots-rfc.html +""" +import urlparse +import urllib + +__all__ = ["RobotFileParser"] + + +class RobotFileParser: + """ This class provides a set of methods to read, parse and answer + questions about a single robots.txt file. + + """ + + def __init__(self, url=''): + self.entries = [] + self.default_entry = None + self.disallow_all = False + self.allow_all = False + self.set_url(url) + self.last_checked = 0 + + def mtime(self): + """Returns the time the robots.txt file was last fetched. + + This is useful for long-running web spiders that need to + check for new robots.txt files periodically. + + """ + return self.last_checked + + def modified(self): + """Sets the time the robots.txt file was last fetched to the + current time. + + """ + import time + self.last_checked = time.time() + + def set_url(self, url): + """Sets the URL referring to a robots.txt file.""" + self.url = url + self.host, self.path = urlparse.urlparse(url)[1:3] + + def read(self): + """Reads the robots.txt URL and feeds it to the parser.""" + opener = URLopener() + f = opener.open(self.url) + lines = [line.strip() for line in f] + f.close() + self.errcode = opener.errcode + if self.errcode in (401, 403): + self.disallow_all = True + elif self.errcode >= 400: + self.allow_all = True + elif self.errcode == 200 and lines: + self.parse(lines) + + def _add_entry(self, entry): + if "*" in entry.useragents: + # the default entry is considered last + if self.default_entry is None: + # the first default entry wins + self.default_entry = entry + else: + self.entries.append(entry) + + def parse(self, lines): + """parse the input lines from a robots.txt file. + We allow that a user-agent: line is not preceded by + one or more blank lines.""" + # states: + # 0: start state + # 1: saw user-agent line + # 2: saw an allow or disallow line + state = 0 + linenumber = 0 + entry = Entry() + + for line in lines: + linenumber += 1 + if not line: + if state == 1: + entry = Entry() + state = 0 + elif state == 2: + self._add_entry(entry) + entry = Entry() + state = 0 + # remove optional comment and strip line + i = line.find('#') + if i >= 0: + line = line[:i] + line = line.strip() + if not line: + continue + line = line.split(':', 1) + if len(line) == 2: + line[0] = line[0].strip().lower() + line[1] = urllib.unquote(line[1].strip()) + if line[0] == "user-agent": + if state == 2: + self._add_entry(entry) + entry = Entry() + entry.useragents.append(line[1]) + state = 1 + elif line[0] == "disallow": + if state != 0: + entry.rulelines.append(RuleLine(line[1], False)) + state = 2 + elif line[0] == "allow": + if state != 0: + entry.rulelines.append(RuleLine(line[1], True)) + state = 2 + if state == 2: + self._add_entry(entry) + + + def can_fetch(self, useragent, url): + """using the parsed robots.txt decide if useragent can fetch url""" + if self.disallow_all: + return False + if self.allow_all: + return True + # search for given user agent matches + # the first match counts + parsed_url = urlparse.urlparse(urllib.unquote(url)) + url = urlparse.urlunparse(('', '', parsed_url.path, + parsed_url.params, parsed_url.query, parsed_url.fragment)) + url = urllib.quote(url) + if not url: + url = "/" + for entry in self.entries: + if entry.applies_to(useragent): + return entry.allowance(url) + # try the default entry last + if self.default_entry: + return self.default_entry.allowance(url) + # agent not found ==> access granted + return True + + + def __str__(self): + return ''.join([str(entry) + "\n" for entry in self.entries]) + + +class RuleLine: + """A rule line is a single "Allow:" (allowance==True) or "Disallow:" + (allowance==False) followed by a path.""" + def __init__(self, path, allowance): + if path == '' and not allowance: + # an empty value means allow all + allowance = True + self.path = urllib.quote(path) + self.allowance = allowance + + def applies_to(self, filename): + return self.path == "*" or filename.startswith(self.path) + + def __str__(self): + return (self.allowance and "Allow" or "Disallow") + ": " + self.path + + +class Entry: + """An entry has one or more user-agents and zero or more rulelines""" + def __init__(self): + self.useragents = [] + self.rulelines = [] + + def __str__(self): + ret = [] + for agent in self.useragents: + ret.extend(["User-agent: ", agent, "\n"]) + for line in self.rulelines: + ret.extend([str(line), "\n"]) + return ''.join(ret) + + def applies_to(self, useragent): + """check if this entry applies to the specified agent""" + # split the name token and make it lower case + useragent = useragent.split("/")[0].lower() + for agent in self.useragents: + if agent == '*': + # we have the catch-all agent + return True + agent = agent.lower() + if agent in useragent: + return True + return False + + def allowance(self, filename): + """Preconditions: + - our agent applies to this entry + - filename is URL decoded""" + for line in self.rulelines: + if line.applies_to(filename): + return line.allowance + return True + +class URLopener(urllib.FancyURLopener): + def __init__(self, *args): + urllib.FancyURLopener.__init__(self, *args) + self.errcode = 200 + + def prompt_user_passwd(self, host, realm): + ## If robots.txt file is accessible only with a password, + ## we act as if the file wasn't there. + return None, None + + def http_error_default(self, url, fp, errcode, errmsg, headers): + self.errcode = errcode + return urllib.FancyURLopener.http_error_default(self, url, fp, errcode, + errmsg, headers) diff --git a/src/main/resources/PythonLibs/runpy.py b/src/main/resources/PythonLibs/runpy.py new file mode 100644 index 0000000000000000000000000000000000000000..c4d7cc26a259bb0cc457a79af415435de1f4129f --- /dev/null +++ b/src/main/resources/PythonLibs/runpy.py @@ -0,0 +1,278 @@ +"""runpy.py - locating and running Python code using the module namespace + +Provides support for locating and running Python scripts using the Python +module namespace instead of the native filesystem. + +This allows Python code to play nicely with non-filesystem based PEP 302 +importers when locating support scripts as well as when importing modules. +""" +# Written by Nick Coghlan <ncoghlan at gmail.com> +# to implement PEP 338 (Executing Modules as Scripts) + +import sys +import imp +from pkgutil import read_code +try: + from imp import get_loader +except ImportError: + from pkgutil import get_loader + +__all__ = [ + "run_module", "run_path", +] + +class _TempModule(object): + """Temporarily replace a module in sys.modules with an empty namespace""" + def __init__(self, mod_name): + self.mod_name = mod_name + self.module = imp.new_module(mod_name) + self._saved_module = [] + + def __enter__(self): + mod_name = self.mod_name + try: + self._saved_module.append(sys.modules[mod_name]) + except KeyError: + pass + sys.modules[mod_name] = self.module + return self + + def __exit__(self, *args): + if self._saved_module: + sys.modules[self.mod_name] = self._saved_module[0] + else: + del sys.modules[self.mod_name] + self._saved_module = [] + +class _ModifiedArgv0(object): + def __init__(self, value): + self.value = value + self._saved_value = self._sentinel = object() + + def __enter__(self): + if self._saved_value is not self._sentinel: + raise RuntimeError("Already preserving saved value") + self._saved_value = sys.argv[0] + sys.argv[0] = self.value + + def __exit__(self, *args): + self.value = self._sentinel + sys.argv[0] = self._saved_value + +def _run_code(code, run_globals, init_globals=None, + mod_name=None, mod_fname=None, + mod_loader=None, pkg_name=None): + """Helper to run code in nominated namespace""" + if init_globals is not None: + run_globals.update(init_globals) + run_globals.update(__name__ = mod_name, + __file__ = mod_fname, + __loader__ = mod_loader, + __package__ = pkg_name) + exec code in run_globals + return run_globals + +def _run_module_code(code, init_globals=None, + mod_name=None, mod_fname=None, + mod_loader=None, pkg_name=None): + """Helper to run code in new namespace with sys modified""" + with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname): + mod_globals = temp_module.module.__dict__ + _run_code(code, mod_globals, init_globals, + mod_name, mod_fname, mod_loader, pkg_name) + # Copy the globals of the temporary module, as they + # may be cleared when the temporary module goes away + return mod_globals.copy() + + +# This helper is needed due to a missing component in the PEP 302 +# loader protocol (specifically, "get_filename" is non-standard) +# Since we can't introduce new features in maintenance releases, +# support was added to zipimporter under the name '_get_filename' +def _get_filename(loader, mod_name): + for attr in ("get_filename", "_get_filename"): + meth = getattr(loader, attr, None) + if meth is not None: + return meth(mod_name) + return None + +# Helper to get the loader, code and filename for a module +def _get_module_details(mod_name): + loader = get_loader(mod_name) + if loader is None: + raise ImportError("No module named %s" % mod_name) + if loader.is_package(mod_name): + if mod_name == "__main__" or mod_name.endswith(".__main__"): + raise ImportError("Cannot use package as __main__ module") + try: + pkg_main_name = mod_name + ".__main__" + return _get_module_details(pkg_main_name) + except ImportError, e: + raise ImportError(("%s; %r is a package and cannot " + + "be directly executed") %(e, mod_name)) + code = loader.get_code(mod_name) + if code is None: + raise ImportError("No code object available for %s" % mod_name) + filename = _get_filename(loader, mod_name) + return mod_name, loader, code, filename + + +def _get_main_module_details(): + # Helper that gives a nicer error message when attempting to + # execute a zipfile or directory by invoking __main__.py + main_name = "__main__" + try: + return _get_module_details(main_name) + except ImportError as exc: + if main_name in str(exc): + raise ImportError("can't find %r module in %r" % + (main_name, sys.path[0])) + raise + +# This function is the actual implementation of the -m switch and direct +# execution of zipfiles and directories and is deliberately kept private. +# This avoids a repeat of the situation where run_module() no longer met the +# needs of mainmodule.c, but couldn't be changed because it was public +def _run_module_as_main(mod_name, alter_argv=True): + """Runs the designated module in the __main__ namespace + + Note that the executed module will have full access to the + __main__ namespace. If this is not desirable, the run_module() + function should be used to run the module code in a fresh namespace. + + At the very least, these variables in __main__ will be overwritten: + __name__ + __file__ + __loader__ + __package__ + """ + try: + if alter_argv or mod_name != "__main__": # i.e. -m switch + mod_name, loader, code, fname = _get_module_details(mod_name) + else: # i.e. directory or zipfile execution + mod_name, loader, code, fname = _get_main_module_details() + except ImportError as exc: + msg = "%s: %s" % (sys.executable, str(exc)) + sys.exit(msg) + pkg_name = mod_name.rpartition('.')[0] + main_globals = sys.modules["__main__"].__dict__ + if alter_argv: + sys.argv[0] = fname + return _run_code(code, main_globals, None, + "__main__", fname, loader, pkg_name) + +def run_module(mod_name, init_globals=None, + run_name=None, alter_sys=False): + """Execute a module's code without importing it + + Returns the resulting top level namespace dictionary + """ + mod_name, loader, code, fname = _get_module_details(mod_name) + if run_name is None: + run_name = mod_name + pkg_name = mod_name.rpartition('.')[0] + if alter_sys: + return _run_module_code(code, init_globals, run_name, + fname, loader, pkg_name) + else: + # Leave the sys module alone + return _run_code(code, {}, init_globals, run_name, + fname, loader, pkg_name) + + +# XXX (ncoghlan): Perhaps expose the C API function +# as imp.get_importer instead of reimplementing it in Python? +def _get_importer(path_name): + """Python version of PyImport_GetImporter C API function""" + cache = sys.path_importer_cache + try: + importer = cache[path_name] + except KeyError: + # Not yet cached. Flag as using the + # standard machinery until we finish + # checking the hooks + cache[path_name] = None + for hook in sys.path_hooks: + try: + importer = hook(path_name) + break + except ImportError: + pass + else: + # The following check looks a bit odd. The trick is that + # NullImporter raises ImportError if the supplied path is a + # *valid* directory entry (and hence able to be handled + # by the standard import machinery) + try: + importer = imp.NullImporter(path_name) + except ImportError: + return None + cache[path_name] = importer + return importer + +def _get_code_from_file(fname): + # Check for a compiled file first + with open(fname, "rb") as f: + code = read_code(f) + if code is None: + # That didn't work, so try it as normal source code + with open(fname, "rU") as f: + code = compile(f.read(), fname, 'exec') + return code + +def run_path(path_name, init_globals=None, run_name=None): + """Execute code located at the specified filesystem location + + Returns the resulting top level namespace dictionary + + The file path may refer directly to a Python script (i.e. + one that could be directly executed with execfile) or else + it may refer to a zipfile or directory containing a top + level __main__.py script. + """ + if run_name is None: + run_name = "<run_path>" + importer = _get_importer(path_name) + if isinstance(importer, imp.NullImporter): + # Not a valid sys.path entry, so run the code directly + # execfile() doesn't help as we want to allow compiled files + code = _get_code_from_file(path_name) + return _run_module_code(code, init_globals, run_name, path_name) + else: + # Importer is defined for path, so add it to + # the start of sys.path + sys.path.insert(0, path_name) + try: + # Here's where things are a little different from the run_module + # case. There, we only had to replace the module in sys while the + # code was running and doing so was somewhat optional. Here, we + # have no choice and we have to remove it even while we read the + # code. If we don't do this, a __loader__ attribute in the + # existing __main__ module may prevent location of the new module. + main_name = "__main__" + saved_main = sys.modules[main_name] + del sys.modules[main_name] + try: + mod_name, loader, code, fname = _get_main_module_details() + finally: + sys.modules[main_name] = saved_main + pkg_name = "" + with _TempModule(run_name) as temp_module, \ + _ModifiedArgv0(path_name): + mod_globals = temp_module.module.__dict__ + return _run_code(code, mod_globals, init_globals, + run_name, fname, loader, pkg_name).copy() + finally: + try: + sys.path.remove(path_name) + except ValueError: + pass + + +if __name__ == "__main__": + # Run the module specified as the next command line argument + if len(sys.argv) < 2: + print >> sys.stderr, "No module specified for execution" + else: + del sys.argv[0] # Make the requested module sys.argv[0] + _run_module_as_main(sys.argv[0]) diff --git a/src/main/resources/PythonLibs/sched.py b/src/main/resources/PythonLibs/sched.py new file mode 100644 index 0000000000000000000000000000000000000000..47646a10081143103f6a4070321207d7848d5435 --- /dev/null +++ b/src/main/resources/PythonLibs/sched.py @@ -0,0 +1,134 @@ +"""A generally useful event scheduler class. + +Each instance of this class manages its own queue. +No multi-threading is implied; you are supposed to hack that +yourself, or use a single instance per application. + +Each instance is parametrized with two functions, one that is +supposed to return the current time, one that is supposed to +implement a delay. You can implement real-time scheduling by +substituting time and sleep from built-in module time, or you can +implement simulated time by writing your own functions. This can +also be used to integrate scheduling with STDWIN events; the delay +function is allowed to modify the queue. Time can be expressed as +integers or floating point numbers, as long as it is consistent. + +Events are specified by tuples (time, priority, action, argument). +As in UNIX, lower priority numbers mean higher priority; in this +way the queue can be maintained as a priority queue. Execution of the +event means calling the action function, passing it the argument +sequence in "argument" (remember that in Python, multiple function +arguments are be packed in a sequence). +The action function may be an instance method so it +has another way to reference private data (besides global variables). +""" + +# XXX The timefunc and delayfunc should have been defined as methods +# XXX so you can define new kinds of schedulers using subclassing +# XXX instead of having to define a module or class just to hold +# XXX the global state of your particular time and delay functions. + +import heapq +from collections import namedtuple + +__all__ = ["scheduler"] + +Event = namedtuple('Event', 'time, priority, action, argument') + +class scheduler: + def __init__(self, timefunc, delayfunc): + """Initialize a new instance, passing the time and delay + functions""" + self._queue = [] + self.timefunc = timefunc + self.delayfunc = delayfunc + + def enterabs(self, time, priority, action, argument): + """Enter a new event in the queue at an absolute time. + + Returns an ID for the event which can be used to remove it, + if necessary. + + """ + event = Event(time, priority, action, argument) + heapq.heappush(self._queue, event) + return event # The ID + + def enter(self, delay, priority, action, argument): + """A variant that specifies the time as a relative time. + + This is actually the more commonly used interface. + + """ + time = self.timefunc() + delay + return self.enterabs(time, priority, action, argument) + + def cancel(self, event): + """Remove an event from the queue. + + This must be presented the ID as returned by enter(). + If the event is not in the queue, this raises ValueError. + + """ + self._queue.remove(event) + heapq.heapify(self._queue) + + def empty(self): + """Check whether the queue is empty.""" + return not self._queue + + def run(self): + """Execute events until the queue is empty. + + When there is a positive delay until the first event, the + delay function is called and the event is left in the queue; + otherwise, the event is removed from the queue and executed + (its action function is called, passing it the argument). If + the delay function returns prematurely, it is simply + restarted. + + It is legal for both the delay function and the action + function to modify the queue or to raise an exception; + exceptions are not caught but the scheduler's state remains + well-defined so run() may be called again. + + A questionable hack is added to allow other threads to run: + just after an event is executed, a delay of 0 is executed, to + avoid monopolizing the CPU when other threads are also + runnable. + + """ + # localize variable access to minimize overhead + # and to improve thread safety + q = self._queue + delayfunc = self.delayfunc + timefunc = self.timefunc + pop = heapq.heappop + while q: + time, priority, action, argument = checked_event = q[0] + now = timefunc() + if now < time: + delayfunc(time - now) + else: + event = pop(q) + # Verify that the event was not removed or altered + # by another thread after we last looked at q[0]. + if event is checked_event: + action(*argument) + delayfunc(0) # Let other threads run + else: + heapq.heappush(q, event) + + @property + def queue(self): + """An ordered list of upcoming events. + + Events are named tuples with fields for: + time, priority, action, arguments + + """ + # Use heapq to sort the queue rather than using 'sorted(self._queue)'. + # With heapq, two events scheduled at the same time will show in + # the actual order they would be retrieved. + events = self._queue[:] + return map(heapq.heappop, [events]*len(events)) diff --git a/src/main/resources/PythonLibs/select.py b/src/main/resources/PythonLibs/select.py new file mode 100644 index 0000000000000000000000000000000000000000..846b86c23173cc9df3922f397449233fceb25019 --- /dev/null +++ b/src/main/resources/PythonLibs/select.py @@ -0,0 +1,264 @@ +""" +This is an select module for use on JVMs >= 1.5. +It is documented, along with known issues and workarounds, on the jython wiki. +http://wiki.python.org/jython/SelectModule +""" + +import java.nio.channels.SelectableChannel +import java.nio.channels.SelectionKey +import java.nio.channels.Selector +from java.nio.channels.SelectionKey import OP_ACCEPT, OP_CONNECT, OP_WRITE, OP_READ + +import errno +import os +import Queue +import socket + +class error(Exception): pass + +ALL = None + +_exception_map = { + +# (<javaexception>, <circumstance>) : lambda: <code that raises the python equivalent> + +(java.nio.channels.ClosedChannelException, ALL) : error(errno.ENOTCONN, 'Socket is not connected'), +(java.nio.channels.CancelledKeyException, ALL) : error(errno.ENOTCONN, 'Socket is not connected'), +(java.nio.channels.IllegalBlockingModeException, ALL) : error(errno.ESOCKISBLOCKING, 'socket must be in non-blocking mode'), +} + +def _map_exception(exc, circumstance=ALL): + try: + mapped_exception = _exception_map[(exc.__class__, circumstance)] + mapped_exception.java_exception = exc + return mapped_exception + except KeyError: + return error(-1, 'Unmapped java exception: <%s:%s>' % (exc.toString(), circumstance)) + +POLLIN = 1 +POLLOUT = 2 + +# The following event types are completely ignored on jython +# Java does not support them, AFAICT +# They are declared only to support code compatibility with cpython + +POLLPRI = 4 +POLLERR = 8 +POLLHUP = 16 +POLLNVAL = 32 + +def _getselectable(selectable_object): + try: + channel = selectable_object.getchannel() + except: + try: + channel = selectable_object.fileno().getChannel() + except: + raise TypeError("Object '%s' is not watchable" % selectable_object, + errno.ENOTSOCK) + + if channel and not isinstance(channel, java.nio.channels.SelectableChannel): + raise TypeError("Object '%s' is not watchable" % selectable_object, + errno.ENOTSOCK) + return channel + +class poll: + + def __init__(self): + self.selector = java.nio.channels.Selector.open() + self.chanmap = {} + self.unconnected_sockets = [] + + def _register_channel(self, socket_object, channel, mask): + jmask = 0 + if mask & POLLIN: + # Note that OP_READ is NOT a valid event on server socket channels. + if channel.validOps() & OP_ACCEPT: + jmask = OP_ACCEPT + else: + jmask = OP_READ + if mask & POLLOUT: + if channel.validOps() & OP_WRITE: + jmask |= OP_WRITE + if channel.validOps() & OP_CONNECT: + jmask |= OP_CONNECT + selectionkey = channel.register(self.selector, jmask) + self.chanmap[channel] = (socket_object, selectionkey) + + def _check_unconnected_sockets(self): + temp_list = [] + for socket_object, mask in self.unconnected_sockets: + channel = _getselectable(socket_object) + if channel is not None: + self._register_channel(socket_object, channel, mask) + else: + temp_list.append( (socket_object, mask) ) + self.unconnected_sockets = temp_list + + def register(self, socket_object, mask = POLLIN|POLLOUT|POLLPRI): + try: + channel = _getselectable(socket_object) + if channel is None: + # The socket is not yet connected, and thus has no channel + # Add it to a pending list, and return + self.unconnected_sockets.append( (socket_object, mask) ) + return + self._register_channel(socket_object, channel, mask) + except java.lang.Exception, jlx: + raise _map_exception(jlx) + + def unregister(self, socket_object): + try: + channel = _getselectable(socket_object) + self.chanmap[channel][1].cancel() + del self.chanmap[channel] + except java.lang.Exception, jlx: + raise _map_exception(jlx) + + def _dopoll(self, timeout): + if timeout is None or timeout < 0: + self.selector.select() + else: + try: + timeout = int(timeout) + if not timeout: + self.selector.selectNow() + else: + # No multiplication required: both cpython and java use millisecond timeouts + self.selector.select(timeout) + except ValueError, vx: + raise error("poll timeout must be a number of milliseconds or None", errno.EINVAL) + # The returned selectedKeys cannot be used from multiple threads! + return self.selector.selectedKeys() + + def poll(self, timeout=None): + try: + self._check_unconnected_sockets() + selectedkeys = self._dopoll(timeout) + results = [] + for k in selectedkeys.iterator(): + jmask = k.readyOps() + pymask = 0 + if jmask & OP_READ: pymask |= POLLIN + if jmask & OP_WRITE: pymask |= POLLOUT + if jmask & OP_ACCEPT: pymask |= POLLIN + if jmask & OP_CONNECT: pymask |= POLLOUT + # Now return the original userobject, and the return event mask + results.append( (self.chanmap[k.channel()][0], pymask) ) + return results + except java.lang.Exception, jlx: + raise _map_exception(jlx) + + def _deregister_all(self): + try: + for k in self.selector.keys(): + k.cancel() + # Keys are not actually removed from the selector until the next select operation. + self.selector.selectNow() + except java.lang.Exception, jlx: + raise _map_exception(jlx) + + def close(self): + try: + self._deregister_all() + self.selector.close() + except java.lang.Exception, jlx: + raise _map_exception(jlx) + +def _calcselecttimeoutvalue(value): + if value is None: + return None + try: + floatvalue = float(value) + except Exception, x: + raise TypeError("Select timeout value must be a number or None") + if value < 0: + raise error("Select timeout value cannot be negative", errno.EINVAL) + if floatvalue < 0.000001: + return 0 + return int(floatvalue * 1000) # Convert to milliseconds + +# This cache for poll objects is required because of a bug in java on MS Windows +# http://bugs.jython.org/issue1291 + +class poll_object_cache: + + def __init__(self): + self.is_windows = os._name == 'nt' + if self.is_windows: + self.poll_object_queue = Queue.Queue() + import atexit + atexit.register(self.finalize) + + def get_poll_object(self): + if not self.is_windows: + return poll() + try: + return self.poll_object_queue.get(False) + except Queue.Empty: + return poll() + + def release_poll_object(self, pobj): + if self.is_windows: + pobj._deregister_all() + self.poll_object_queue.put(pobj) + else: + pobj.close() + + def finalize(self): + if self.is_windows: + while True: + try: + p = self.poll_object_queue.get(False) + p.close() + except Queue.Empty: + return + +_poll_object_cache = poll_object_cache() + +def native_select(read_fd_list, write_fd_list, outofband_fd_list, timeout=None): + timeout = _calcselecttimeoutvalue(timeout) + # First create a poll object to do the actual watching. + pobj = _poll_object_cache.get_poll_object() + try: + registered_for_read = {} + # Check the read list + for fd in read_fd_list: + pobj.register(fd, POLLIN) + registered_for_read[fd] = 1 + # And now the write list + for fd in write_fd_list: + if fd in registered_for_read: + # registering a second time overwrites the first + pobj.register(fd, POLLIN|POLLOUT) + else: + pobj.register(fd, POLLOUT) + results = pobj.poll(timeout) + # Now start preparing the results + read_ready_list, write_ready_list, oob_ready_list = [], [], [] + for fd, mask in results: + if mask & POLLIN: + read_ready_list.append(fd) + if mask & POLLOUT: + write_ready_list.append(fd) + return read_ready_list, write_ready_list, oob_ready_list + finally: + _poll_object_cache.release_poll_object(pobj) + +select = native_select + +def cpython_compatible_select(read_fd_list, write_fd_list, outofband_fd_list, timeout=None): + # First turn all sockets to non-blocking + # keeping track of which ones have changed + modified_channels = [] + try: + for socket_list in [read_fd_list, write_fd_list, outofband_fd_list]: + for s in socket_list: + channel = _getselectable(s) + if channel.isBlocking(): + modified_channels.append(channel) + channel.configureBlocking(0) + return native_select(read_fd_list, write_fd_list, outofband_fd_list, timeout) + finally: + for channel in modified_channels: + channel.configureBlocking(1) diff --git a/src/main/resources/PythonLibs/sets.py b/src/main/resources/PythonLibs/sets.py new file mode 100644 index 0000000000000000000000000000000000000000..fe31a0b7e979ca8aa67a4ca7c41b04318b5e69df --- /dev/null +++ b/src/main/resources/PythonLibs/sets.py @@ -0,0 +1,557 @@ +"""Classes to represent arbitrary sets (including sets of sets). + +This module implements sets using dictionaries whose values are +ignored. The usual operations (union, intersection, deletion, etc.) +are provided as both methods and operators. + +Important: sets are not sequences! While they support 'x in s', +'len(s)', and 'for x in s', none of those operations are unique for +sequences; for example, mappings support all three as well. The +characteristic operation for sequences is subscripting with small +integers: s[i], for i in range(len(s)). Sets don't support +subscripting at all. Also, sequences allow multiple occurrences and +their elements have a definite order; sets on the other hand don't +record multiple occurrences and don't remember the order of element +insertion (which is why they don't support s[i]). + +The following classes are provided: + +BaseSet -- All the operations common to both mutable and immutable + sets. This is an abstract class, not meant to be directly + instantiated. + +Set -- Mutable sets, subclass of BaseSet; not hashable. + +ImmutableSet -- Immutable sets, subclass of BaseSet; hashable. + An iterable argument is mandatory to create an ImmutableSet. + +_TemporarilyImmutableSet -- A wrapper around a Set, hashable, + giving the same hash value as the immutable set equivalent + would have. Do not use this class directly. + +Only hashable objects can be added to a Set. In particular, you cannot +really add a Set as an element to another Set; if you try, what is +actually added is an ImmutableSet built from it (it compares equal to +the one you tried adding). + +When you ask if `x in y' where x is a Set and y is a Set or +ImmutableSet, x is wrapped into a _TemporarilyImmutableSet z, and +what's tested is actually `z in y'. + +""" + +# Code history: +# +# - Greg V. Wilson wrote the first version, using a different approach +# to the mutable/immutable problem, and inheriting from dict. +# +# - Alex Martelli modified Greg's version to implement the current +# Set/ImmutableSet approach, and make the data an attribute. +# +# - Guido van Rossum rewrote much of the code, made some API changes, +# and cleaned up the docstrings. +# +# - Raymond Hettinger added a number of speedups and other +# improvements. + +from itertools import ifilter, ifilterfalse + +__all__ = ['BaseSet', 'Set', 'ImmutableSet'] + +import warnings +warnings.warn("the sets module is deprecated", DeprecationWarning, + stacklevel=2) + +class BaseSet(object): + """Common base class for mutable and immutable sets.""" + + __slots__ = ['_data'] + + # Constructor + + def __init__(self): + """This is an abstract class.""" + # Don't call this from a concrete subclass! + if self.__class__ is BaseSet: + raise TypeError, ("BaseSet is an abstract class. " + "Use Set or ImmutableSet.") + + # Standard protocols: __len__, __repr__, __str__, __iter__ + + def __len__(self): + """Return the number of elements of a set.""" + return len(self._data) + + def __repr__(self): + """Return string representation of a set. + + This looks like 'Set([<list of elements>])'. + """ + return self._repr() + + # __str__ is the same as __repr__ + __str__ = __repr__ + + def _repr(self, sorted=False): + elements = self._data.keys() + if sorted: + elements.sort() + return '%s(%r)' % (self.__class__.__name__, elements) + + def __iter__(self): + """Return an iterator over the elements or a set. + + This is the keys iterator for the underlying dict. + """ + return self._data.iterkeys() + + # Three-way comparison is not supported. However, because __eq__ is + # tried before __cmp__, if Set x == Set y, x.__eq__(y) returns True and + # then cmp(x, y) returns 0 (Python doesn't actually call __cmp__ in this + # case). + + def __cmp__(self, other): + raise TypeError, "can't compare sets using cmp()" + + # Equality comparisons using the underlying dicts. Mixed-type comparisons + # are allowed here, where Set == z for non-Set z always returns False, + # and Set != z always True. This allows expressions like "x in y" to + # give the expected result when y is a sequence of mixed types, not + # raising a pointless TypeError just because y contains a Set, or x is + # a Set and y contain's a non-set ("in" invokes only __eq__). + # Subtle: it would be nicer if __eq__ and __ne__ could return + # NotImplemented instead of True or False. Then the other comparand + # would get a chance to determine the result, and if the other comparand + # also returned NotImplemented then it would fall back to object address + # comparison (which would always return False for __eq__ and always + # True for __ne__). However, that doesn't work, because this type + # *also* implements __cmp__: if, e.g., __eq__ returns NotImplemented, + # Python tries __cmp__ next, and the __cmp__ here then raises TypeError. + + def __eq__(self, other): + if isinstance(other, BaseSet): + return self._data == other._data + else: + return False + + def __ne__(self, other): + if isinstance(other, BaseSet): + return self._data != other._data + else: + return True + + # Copying operations + + def copy(self): + """Return a shallow copy of a set.""" + result = self.__class__() + result._data.update(self._data) + return result + + __copy__ = copy # For the copy module + + def __deepcopy__(self, memo): + """Return a deep copy of a set; used by copy module.""" + # This pre-creates the result and inserts it in the memo + # early, in case the deep copy recurses into another reference + # to this same set. A set can't be an element of itself, but + # it can certainly contain an object that has a reference to + # itself. + from copy import deepcopy + result = self.__class__() + memo[id(self)] = result + data = result._data + value = True + for elt in self: + data[deepcopy(elt, memo)] = value + return result + + # Standard set operations: union, intersection, both differences. + # Each has an operator version (e.g. __or__, invoked with |) and a + # method version (e.g. union). + # Subtle: Each pair requires distinct code so that the outcome is + # correct when the type of other isn't suitable. For example, if + # we did "union = __or__" instead, then Set().union(3) would return + # NotImplemented instead of raising TypeError (albeit that *why* it + # raises TypeError as-is is also a bit subtle). + + def __or__(self, other): + """Return the union of two sets as a new set. + + (I.e. all elements that are in either set.) + """ + if not isinstance(other, BaseSet): + return NotImplemented + return self.union(other) + + def union(self, other): + """Return the union of two sets as a new set. + + (I.e. all elements that are in either set.) + """ + result = self.__class__(self) + result._update(other) + return result + + def __and__(self, other): + """Return the intersection of two sets as a new set. + + (I.e. all elements that are in both sets.) + """ + if not isinstance(other, BaseSet): + return NotImplemented + return self.intersection(other) + + def intersection(self, other): + """Return the intersection of two sets as a new set. + + (I.e. all elements that are in both sets.) + """ + if not isinstance(other, BaseSet): + other = Set(other) + if len(self) <= len(other): + little, big = self, other + else: + little, big = other, self + common = ifilter(big._data.__contains__, little) + return self.__class__(common) + + def __xor__(self, other): + """Return the symmetric difference of two sets as a new set. + + (I.e. all elements that are in exactly one of the sets.) + """ + if not isinstance(other, BaseSet): + return NotImplemented + return self.symmetric_difference(other) + + def symmetric_difference(self, other): + """Return the symmetric difference of two sets as a new set. + + (I.e. all elements that are in exactly one of the sets.) + """ + result = self.__class__() + data = result._data + value = True + selfdata = self._data + try: + otherdata = other._data + except AttributeError: + otherdata = Set(other)._data + for elt in ifilterfalse(otherdata.__contains__, selfdata): + data[elt] = value + for elt in ifilterfalse(selfdata.__contains__, otherdata): + data[elt] = value + return result + + def __sub__(self, other): + """Return the difference of two sets as a new Set. + + (I.e. all elements that are in this set and not in the other.) + """ + if not isinstance(other, BaseSet): + return NotImplemented + return self.difference(other) + + def difference(self, other): + """Return the difference of two sets as a new Set. + + (I.e. all elements that are in this set and not in the other.) + """ + result = self.__class__() + data = result._data + try: + otherdata = other._data + except AttributeError: + otherdata = Set(other)._data + value = True + for elt in ifilterfalse(otherdata.__contains__, self): + data[elt] = value + return result + + # Membership test + + def __contains__(self, element): + """Report whether an element is a member of a set. + + (Called in response to the expression `element in self'.) + """ + try: + return element in self._data + except TypeError: + transform = getattr(element, "__as_temporarily_immutable__", None) + if transform is None: + raise # re-raise the TypeError exception we caught + return transform() in self._data + + # Subset and superset test + + def issubset(self, other): + """Report whether another set contains this set.""" + self._binary_sanity_check(other) + if len(self) > len(other): # Fast check for obvious cases + return False + for elt in ifilterfalse(other._data.__contains__, self): + return False + return True + + def issuperset(self, other): + """Report whether this set contains another set.""" + self._binary_sanity_check(other) + if len(self) < len(other): # Fast check for obvious cases + return False + for elt in ifilterfalse(self._data.__contains__, other): + return False + return True + + # Inequality comparisons using the is-subset relation. + __le__ = issubset + __ge__ = issuperset + + def __lt__(self, other): + self._binary_sanity_check(other) + return len(self) < len(other) and self.issubset(other) + + def __gt__(self, other): + self._binary_sanity_check(other) + return len(self) > len(other) and self.issuperset(other) + + # We inherit object.__hash__, so we must deny this explicitly + __hash__ = None + + # Assorted helpers + + def _binary_sanity_check(self, other): + # Check that the other argument to a binary operation is also + # a set, raising a TypeError otherwise. + if not isinstance(other, BaseSet): + raise TypeError, "Binary operation only permitted between sets" + + def _compute_hash(self): + # Calculate hash code for a set by xor'ing the hash codes of + # the elements. This ensures that the hash code does not depend + # on the order in which elements are added to the set. This is + # not called __hash__ because a BaseSet should not be hashable; + # only an ImmutableSet is hashable. + result = 0 + for elt in self: + result ^= hash(elt) + return result + + def _update(self, iterable): + # The main loop for update() and the subclass __init__() methods. + data = self._data + + # Use the fast update() method when a dictionary is available. + if isinstance(iterable, BaseSet): + data.update(iterable._data) + return + + value = True + + if type(iterable) in (list, tuple, xrange): + # Optimized: we know that __iter__() and next() can't + # raise TypeError, so we can move 'try:' out of the loop. + it = iter(iterable) + while True: + try: + for element in it: + data[element] = value + return + except TypeError: + transform = getattr(element, "__as_immutable__", None) + if transform is None: + raise # re-raise the TypeError exception we caught + data[transform()] = value + else: + # Safe: only catch TypeError where intended + for element in iterable: + try: + data[element] = value + except TypeError: + transform = getattr(element, "__as_immutable__", None) + if transform is None: + raise # re-raise the TypeError exception we caught + data[transform()] = value + + +class ImmutableSet(BaseSet): + """Immutable set class.""" + + __slots__ = ['_hashcode'] + + # BaseSet + hashing + + def __init__(self, iterable=None): + """Construct an immutable set from an optional iterable.""" + self._hashcode = None + self._data = {} + if iterable is not None: + self._update(iterable) + + def __hash__(self): + if self._hashcode is None: + self._hashcode = self._compute_hash() + return self._hashcode + + def __getstate__(self): + return self._data, self._hashcode + + def __setstate__(self, state): + self._data, self._hashcode = state + +class Set(BaseSet): + """ Mutable set class.""" + + __slots__ = [] + + # BaseSet + operations requiring mutability; no hashing + + def __init__(self, iterable=None): + """Construct a set from an optional iterable.""" + self._data = {} + if iterable is not None: + self._update(iterable) + + def __getstate__(self): + # getstate's results are ignored if it is not + return self._data, + + def __setstate__(self, data): + self._data, = data + + # In-place union, intersection, differences. + # Subtle: The xyz_update() functions deliberately return None, + # as do all mutating operations on built-in container types. + # The __xyz__ spellings have to return self, though. + + def __ior__(self, other): + """Update a set with the union of itself and another.""" + self._binary_sanity_check(other) + self._data.update(other._data) + return self + + def union_update(self, other): + """Update a set with the union of itself and another.""" + self._update(other) + + def __iand__(self, other): + """Update a set with the intersection of itself and another.""" + self._binary_sanity_check(other) + self._data = (self & other)._data + return self + + def intersection_update(self, other): + """Update a set with the intersection of itself and another.""" + if isinstance(other, BaseSet): + self &= other + else: + self._data = (self.intersection(other))._data + + def __ixor__(self, other): + """Update a set with the symmetric difference of itself and another.""" + self._binary_sanity_check(other) + self.symmetric_difference_update(other) + return self + + def symmetric_difference_update(self, other): + """Update a set with the symmetric difference of itself and another.""" + data = self._data + value = True + if not isinstance(other, BaseSet): + other = Set(other) + if self is other: + self.clear() + for elt in other: + if elt in data: + del data[elt] + else: + data[elt] = value + + def __isub__(self, other): + """Remove all elements of another set from this set.""" + self._binary_sanity_check(other) + self.difference_update(other) + return self + + def difference_update(self, other): + """Remove all elements of another set from this set.""" + data = self._data + if not isinstance(other, BaseSet): + other = Set(other) + if self is other: + self.clear() + for elt in ifilter(data.__contains__, other): + del data[elt] + + # Python dict-like mass mutations: update, clear + + def update(self, iterable): + """Add all values from an iterable (such as a list or file).""" + self._update(iterable) + + def clear(self): + """Remove all elements from this set.""" + self._data.clear() + + # Single-element mutations: add, remove, discard + + def add(self, element): + """Add an element to a set. + + This has no effect if the element is already present. + """ + try: + self._data[element] = True + except TypeError: + transform = getattr(element, "__as_immutable__", None) + if transform is None: + raise # re-raise the TypeError exception we caught + self._data[transform()] = True + + def remove(self, element): + """Remove an element from a set; it must be a member. + + If the element is not a member, raise a KeyError. + """ + try: + del self._data[element] + except TypeError: + transform = getattr(element, "__as_temporarily_immutable__", None) + if transform is None: + raise # re-raise the TypeError exception we caught + del self._data[transform()] + + def discard(self, element): + """Remove an element from a set if it is a member. + + If the element is not a member, do nothing. + """ + try: + self.remove(element) + except KeyError: + pass + + def pop(self): + """Remove and return an arbitrary set element.""" + return self._data.popitem()[0] + + def __as_immutable__(self): + # Return a copy of self as an immutable set + return ImmutableSet(self) + + def __as_temporarily_immutable__(self): + # Return self wrapped in a temporarily immutable set + return _TemporarilyImmutableSet(self) + + +class _TemporarilyImmutableSet(BaseSet): + # Wrap a mutable set as if it was temporarily immutable. + # This only supplies hashing and equality comparisons. + + def __init__(self, set): + self._set = set + self._data = set._data # Needed by ImmutableSet.__eq__() + + def __hash__(self): + return self._set._compute_hash() diff --git a/src/main/resources/PythonLibs/sgmllib.py b/src/main/resources/PythonLibs/sgmllib.py new file mode 100644 index 0000000000000000000000000000000000000000..104b25f2a07b0e716c40328d1878f56e774d8169 --- /dev/null +++ b/src/main/resources/PythonLibs/sgmllib.py @@ -0,0 +1,553 @@ +"""A parser for SGML, using the derived class as a static DTD.""" + +# XXX This only supports those SGML features used by HTML. + +# XXX There should be a way to distinguish between PCDATA (parsed +# character data -- the normal case), RCDATA (replaceable character +# data -- only char and entity references and end tags are special) +# and CDATA (character data -- only end tags are special). RCDATA is +# not supported at all. + + +from warnings import warnpy3k +warnpy3k("the sgmllib module has been removed in Python 3.0", + stacklevel=2) +del warnpy3k + +import markupbase +import re + +__all__ = ["SGMLParser", "SGMLParseError"] + +# Regular expressions used for parsing + +interesting = re.compile('[&<]') +incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|' + '<([a-zA-Z][^<>]*|' + '/([a-zA-Z][^<>]*)?|' + '![^<>]*)?') + +entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') +charref = re.compile('&#([0-9]+)[^0-9]') + +starttagopen = re.compile('<[>a-zA-Z]') +shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/') +shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/') +piclose = re.compile('>') +endbracket = re.compile('[<>]') +tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*') +attrfind = re.compile( + r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*' + r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?') + + +class SGMLParseError(RuntimeError): + """Exception raised for all parse errors.""" + pass + + +# SGML parser base class -- find tags and call handler functions. +# Usage: p = SGMLParser(); p.feed(data); ...; p.close(). +# The dtd is defined by deriving a class which defines methods +# with special names to handle tags: start_foo and end_foo to handle +# <foo> and </foo>, respectively, or do_foo to handle <foo> by itself. +# (Tags are converted to lower case for this purpose.) The data +# between tags is passed to the parser by calling self.handle_data() +# with some data as argument (the data may be split up in arbitrary +# chunks). Entity references are passed by calling +# self.handle_entityref() with the entity reference as argument. + +class SGMLParser(markupbase.ParserBase): + # Definition of entities -- derived classes may override + entity_or_charref = re.compile('&(?:' + '([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)' + ')(;?)') + + def __init__(self, verbose=0): + """Initialize and reset this instance.""" + self.verbose = verbose + self.reset() + + def reset(self): + """Reset this instance. Loses all unprocessed data.""" + self.__starttag_text = None + self.rawdata = '' + self.stack = [] + self.lasttag = '???' + self.nomoretags = 0 + self.literal = 0 + markupbase.ParserBase.reset(self) + + def setnomoretags(self): + """Enter literal mode (CDATA) till EOF. + + Intended for derived classes only. + """ + self.nomoretags = self.literal = 1 + + def setliteral(self, *args): + """Enter literal mode (CDATA). + + Intended for derived classes only. + """ + self.literal = 1 + + def feed(self, data): + """Feed some data to the parser. + + Call this as often as you want, with as little or as much text + as you want (may include '\n'). (This just saves the text, + all the processing is done by goahead().) + """ + + self.rawdata = self.rawdata + data + self.goahead(0) + + def close(self): + """Handle the remaining data.""" + self.goahead(1) + + def error(self, message): + raise SGMLParseError(message) + + # Internal -- handle data as far as reasonable. May leave state + # and data to be processed by a subsequent call. If 'end' is + # true, force handling all data as if followed by EOF marker. + def goahead(self, end): + rawdata = self.rawdata + i = 0 + n = len(rawdata) + while i < n: + if self.nomoretags: + self.handle_data(rawdata[i:n]) + i = n + break + match = interesting.search(rawdata, i) + if match: j = match.start() + else: j = n + if i < j: + self.handle_data(rawdata[i:j]) + i = j + if i == n: break + if rawdata[i] == '<': + if starttagopen.match(rawdata, i): + if self.literal: + self.handle_data(rawdata[i]) + i = i+1 + continue + k = self.parse_starttag(i) + if k < 0: break + i = k + continue + if rawdata.startswith("</", i): + k = self.parse_endtag(i) + if k < 0: break + i = k + self.literal = 0 + continue + if self.literal: + if n > (i + 1): + self.handle_data("<") + i = i+1 + else: + # incomplete + break + continue + if rawdata.startswith("<!--", i): + # Strictly speaking, a comment is --.*-- + # within a declaration tag <!...>. + # This should be removed, + # and comments handled only in parse_declaration. + k = self.parse_comment(i) + if k < 0: break + i = k + continue + if rawdata.startswith("<?", i): + k = self.parse_pi(i) + if k < 0: break + i = i+k + continue + if rawdata.startswith("<!", i): + # This is some sort of declaration; in "HTML as + # deployed," this should only be the document type + # declaration ("<!DOCTYPE html...>"). + k = self.parse_declaration(i) + if k < 0: break + i = k + continue + elif rawdata[i] == '&': + if self.literal: + self.handle_data(rawdata[i]) + i = i+1 + continue + match = charref.match(rawdata, i) + if match: + name = match.group(1) + self.handle_charref(name) + i = match.end(0) + if rawdata[i-1] != ';': i = i-1 + continue + match = entityref.match(rawdata, i) + if match: + name = match.group(1) + self.handle_entityref(name) + i = match.end(0) + if rawdata[i-1] != ';': i = i-1 + continue + else: + self.error('neither < nor & ??') + # We get here only if incomplete matches but + # nothing else + match = incomplete.match(rawdata, i) + if not match: + self.handle_data(rawdata[i]) + i = i+1 + continue + j = match.end(0) + if j == n: + break # Really incomplete + self.handle_data(rawdata[i:j]) + i = j + # end while + if end and i < n: + self.handle_data(rawdata[i:n]) + i = n + self.rawdata = rawdata[i:] + # XXX if end: check for empty stack + + # Extensions for the DOCTYPE scanner: + _decl_otherchars = '=' + + # Internal -- parse processing instr, return length or -1 if not terminated + def parse_pi(self, i): + rawdata = self.rawdata + if rawdata[i:i+2] != '<?': + self.error('unexpected call to parse_pi()') + match = piclose.search(rawdata, i+2) + if not match: + return -1 + j = match.start(0) + self.handle_pi(rawdata[i+2: j]) + j = match.end(0) + return j-i + + def get_starttag_text(self): + return self.__starttag_text + + # Internal -- handle starttag, return length or -1 if not terminated + def parse_starttag(self, i): + self.__starttag_text = None + start_pos = i + rawdata = self.rawdata + if shorttagopen.match(rawdata, i): + # SGML shorthand: <tag/data/ == <tag>data</tag> + # XXX Can data contain &... (entity or char refs)? + # XXX Can data contain < or > (tag characters)? + # XXX Can there be whitespace before the first /? + match = shorttag.match(rawdata, i) + if not match: + return -1 + tag, data = match.group(1, 2) + self.__starttag_text = '<%s/' % tag + tag = tag.lower() + k = match.end(0) + self.finish_shorttag(tag, data) + self.__starttag_text = rawdata[start_pos:match.end(1) + 1] + return k + # XXX The following should skip matching quotes (' or ") + # As a shortcut way to exit, this isn't so bad, but shouldn't + # be used to locate the actual end of the start tag since the + # < or > characters may be embedded in an attribute value. + match = endbracket.search(rawdata, i+1) + if not match: + return -1 + j = match.start(0) + # Now parse the data between i+1 and j into a tag and attrs + attrs = [] + if rawdata[i:i+2] == '<>': + # SGML shorthand: <> == <last open tag seen> + k = j + tag = self.lasttag + else: + match = tagfind.match(rawdata, i+1) + if not match: + self.error('unexpected call to parse_starttag') + k = match.end(0) + tag = rawdata[i+1:k].lower() + self.lasttag = tag + while k < j: + match = attrfind.match(rawdata, k) + if not match: break + attrname, rest, attrvalue = match.group(1, 2, 3) + if not rest: + attrvalue = attrname + else: + if (attrvalue[:1] == "'" == attrvalue[-1:] or + attrvalue[:1] == '"' == attrvalue[-1:]): + # strip quotes + attrvalue = attrvalue[1:-1] + attrvalue = self.entity_or_charref.sub( + self._convert_ref, attrvalue) + attrs.append((attrname.lower(), attrvalue)) + k = match.end(0) + if rawdata[j] == '>': + j = j+1 + self.__starttag_text = rawdata[start_pos:j] + self.finish_starttag(tag, attrs) + return j + + # Internal -- convert entity or character reference + def _convert_ref(self, match): + if match.group(2): + return self.convert_charref(match.group(2)) or \ + '&#%s%s' % match.groups()[1:] + elif match.group(3): + return self.convert_entityref(match.group(1)) or \ + '&%s;' % match.group(1) + else: + return '&%s' % match.group(1) + + # Internal -- parse endtag + def parse_endtag(self, i): + rawdata = self.rawdata + match = endbracket.search(rawdata, i+1) + if not match: + return -1 + j = match.start(0) + tag = rawdata[i+2:j].strip().lower() + if rawdata[j] == '>': + j = j+1 + self.finish_endtag(tag) + return j + + # Internal -- finish parsing of <tag/data/ (same as <tag>data</tag>) + def finish_shorttag(self, tag, data): + self.finish_starttag(tag, []) + self.handle_data(data) + self.finish_endtag(tag) + + # Internal -- finish processing of start tag + # Return -1 for unknown tag, 0 for open-only tag, 1 for balanced tag + def finish_starttag(self, tag, attrs): + try: + method = getattr(self, 'start_' + tag) + except AttributeError: + try: + method = getattr(self, 'do_' + tag) + except AttributeError: + self.unknown_starttag(tag, attrs) + return -1 + else: + self.handle_starttag(tag, method, attrs) + return 0 + else: + self.stack.append(tag) + self.handle_starttag(tag, method, attrs) + return 1 + + # Internal -- finish processing of end tag + def finish_endtag(self, tag): + if not tag: + found = len(self.stack) - 1 + if found < 0: + self.unknown_endtag(tag) + return + else: + if tag not in self.stack: + try: + method = getattr(self, 'end_' + tag) + except AttributeError: + self.unknown_endtag(tag) + else: + self.report_unbalanced(tag) + return + found = len(self.stack) + for i in range(found): + if self.stack[i] == tag: found = i + while len(self.stack) > found: + tag = self.stack[-1] + try: + method = getattr(self, 'end_' + tag) + except AttributeError: + method = None + if method: + self.handle_endtag(tag, method) + else: + self.unknown_endtag(tag) + del self.stack[-1] + + # Overridable -- handle start tag + def handle_starttag(self, tag, method, attrs): + method(attrs) + + # Overridable -- handle end tag + def handle_endtag(self, tag, method): + method() + + # Example -- report an unbalanced </...> tag. + def report_unbalanced(self, tag): + if self.verbose: + print '*** Unbalanced </' + tag + '>' + print '*** Stack:', self.stack + + def convert_charref(self, name): + """Convert character reference, may be overridden.""" + try: + n = int(name) + except ValueError: + return + if not 0 <= n <= 127: + return + return self.convert_codepoint(n) + + def convert_codepoint(self, codepoint): + return chr(codepoint) + + def handle_charref(self, name): + """Handle character reference, no need to override.""" + replacement = self.convert_charref(name) + if replacement is None: + self.unknown_charref(name) + else: + self.handle_data(replacement) + + # Definition of entities -- derived classes may override + entitydefs = \ + {'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''} + + def convert_entityref(self, name): + """Convert entity references. + + As an alternative to overriding this method; one can tailor the + results by setting up the self.entitydefs mapping appropriately. + """ + table = self.entitydefs + if name in table: + return table[name] + else: + return + + def handle_entityref(self, name): + """Handle entity references, no need to override.""" + replacement = self.convert_entityref(name) + if replacement is None: + self.unknown_entityref(name) + else: + self.handle_data(replacement) + + # Example -- handle data, should be overridden + def handle_data(self, data): + pass + + # Example -- handle comment, could be overridden + def handle_comment(self, data): + pass + + # Example -- handle declaration, could be overridden + def handle_decl(self, decl): + pass + + # Example -- handle processing instruction, could be overridden + def handle_pi(self, data): + pass + + # To be overridden -- handlers for unknown objects + def unknown_starttag(self, tag, attrs): pass + def unknown_endtag(self, tag): pass + def unknown_charref(self, ref): pass + def unknown_entityref(self, ref): pass + + +class TestSGMLParser(SGMLParser): + + def __init__(self, verbose=0): + self.testdata = "" + SGMLParser.__init__(self, verbose) + + def handle_data(self, data): + self.testdata = self.testdata + data + if len(repr(self.testdata)) >= 70: + self.flush() + + def flush(self): + data = self.testdata + if data: + self.testdata = "" + print 'data:', repr(data) + + def handle_comment(self, data): + self.flush() + r = repr(data) + if len(r) > 68: + r = r[:32] + '...' + r[-32:] + print 'comment:', r + + def unknown_starttag(self, tag, attrs): + self.flush() + if not attrs: + print 'start tag: <' + tag + '>' + else: + print 'start tag: <' + tag, + for name, value in attrs: + print name + '=' + '"' + value + '"', + print '>' + + def unknown_endtag(self, tag): + self.flush() + print 'end tag: </' + tag + '>' + + def unknown_entityref(self, ref): + self.flush() + print '*** unknown entity ref: &' + ref + ';' + + def unknown_charref(self, ref): + self.flush() + print '*** unknown char ref: &#' + ref + ';' + + def unknown_decl(self, data): + self.flush() + print '*** unknown decl: [' + data + ']' + + def close(self): + SGMLParser.close(self) + self.flush() + + +def test(args = None): + import sys + + if args is None: + args = sys.argv[1:] + + if args and args[0] == '-s': + args = args[1:] + klass = SGMLParser + else: + klass = TestSGMLParser + + if args: + file = args[0] + else: + file = 'test.html' + + if file == '-': + f = sys.stdin + else: + try: + f = open(file, 'r') + except IOError, msg: + print file, ":", msg + sys.exit(1) + + data = f.read() + if f is not sys.stdin: + f.close() + + x = klass() + for c in data: + x.feed(c) + x.close() + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/sha.py b/src/main/resources/PythonLibs/sha.py new file mode 100644 index 0000000000000000000000000000000000000000..41dde8dde27b57c8d1fe9a3b06ee13b8aa9af5d7 --- /dev/null +++ b/src/main/resources/PythonLibs/sha.py @@ -0,0 +1,15 @@ +# $Id$ +# +# Copyright (C) 2005 Gregory P. Smith (greg@krypto.org) +# Licensed to PSF under a Contributor Agreement. + +import warnings +warnings.warn("the sha module is deprecated; use the hashlib module instead", + DeprecationWarning, 2) + +from hashlib import sha1 as sha +new = sha + +blocksize = 1 # legacy value (wrong in any useful sense) +digest_size = 20 +digestsize = 20 diff --git a/src/main/resources/PythonLibs/shelve.py b/src/main/resources/PythonLibs/shelve.py new file mode 100644 index 0000000000000000000000000000000000000000..c8cba8582d6ff1ed7a4c7af6e42492fdfca3d13d --- /dev/null +++ b/src/main/resources/PythonLibs/shelve.py @@ -0,0 +1,239 @@ +"""Manage shelves of pickled objects. + +A "shelf" is a persistent, dictionary-like object. The difference +with dbm databases is that the values (not the keys!) in a shelf can +be essentially arbitrary Python objects -- anything that the "pickle" +module can handle. This includes most class instances, recursive data +types, and objects containing lots of shared sub-objects. The keys +are ordinary strings. + +To summarize the interface (key is a string, data is an arbitrary +object): + + import shelve + d = shelve.open(filename) # open, with (g)dbm filename -- no suffix + + d[key] = data # store data at key (overwrites old data if + # using an existing key) + data = d[key] # retrieve a COPY of the data at key (raise + # KeyError if no such key) -- NOTE that this + # access returns a *copy* of the entry! + del d[key] # delete data stored at key (raises KeyError + # if no such key) + flag = d.has_key(key) # true if the key exists; same as "key in d" + list = d.keys() # a list of all existing keys (slow!) + + d.close() # close it + +Dependent on the implementation, closing a persistent dictionary may +or may not be necessary to flush changes to disk. + +Normally, d[key] returns a COPY of the entry. This needs care when +mutable entries are mutated: for example, if d[key] is a list, + d[key].append(anitem) +does NOT modify the entry d[key] itself, as stored in the persistent +mapping -- it only modifies the copy, which is then immediately +discarded, so that the append has NO effect whatsoever. To append an +item to d[key] in a way that will affect the persistent mapping, use: + data = d[key] + data.append(anitem) + d[key] = data + +To avoid the problem with mutable entries, you may pass the keyword +argument writeback=True in the call to shelve.open. When you use: + d = shelve.open(filename, writeback=True) +then d keeps a cache of all entries you access, and writes them all back +to the persistent mapping when you call d.close(). This ensures that +such usage as d[key].append(anitem) works as intended. + +However, using keyword argument writeback=True may consume vast amount +of memory for the cache, and it may make d.close() very slow, if you +access many of d's entries after opening it in this way: d has no way to +check which of the entries you access are mutable and/or which ones you +actually mutate, so it must cache, and write back at close, all of the +entries that you access. You can call d.sync() to write back all the +entries in the cache, and empty the cache (d.sync() also synchronizes +the persistent dictionary on disk, if feasible). +""" + +# Try using cPickle and cStringIO if available. + +try: + from cPickle import Pickler, Unpickler +except ImportError: + from pickle import Pickler, Unpickler + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +import UserDict + +__all__ = ["Shelf","BsdDbShelf","DbfilenameShelf","open"] + +class _ClosedDict(UserDict.DictMixin): + 'Marker for a closed dict. Access attempts raise a ValueError.' + + def closed(self, *args): + raise ValueError('invalid operation on closed shelf') + __getitem__ = __setitem__ = __delitem__ = keys = closed + + def __repr__(self): + return '<Closed Dictionary>' + +class Shelf(UserDict.DictMixin): + """Base class for shelf implementations. + + This is initialized with a dictionary-like object. + See the module's __doc__ string for an overview of the interface. + """ + + def __init__(self, dict, protocol=None, writeback=False): + self.dict = dict + if protocol is None: + protocol = 0 + self._protocol = protocol + self.writeback = writeback + self.cache = {} + + def keys(self): + return self.dict.keys() + + def __len__(self): + return len(self.dict) + + def has_key(self, key): + return key in self.dict + + def __contains__(self, key): + return key in self.dict + + def get(self, key, default=None): + if key in self.dict: + return self[key] + return default + + def __getitem__(self, key): + try: + value = self.cache[key] + except KeyError: + f = StringIO(self.dict[key]) + value = Unpickler(f).load() + if self.writeback: + self.cache[key] = value + return value + + def __setitem__(self, key, value): + if self.writeback: + self.cache[key] = value + f = StringIO() + p = Pickler(f, self._protocol) + p.dump(value) + self.dict[key] = f.getvalue() + + def __delitem__(self, key): + del self.dict[key] + try: + del self.cache[key] + except KeyError: + pass + + def close(self): + self.sync() + try: + self.dict.close() + except AttributeError: + pass + # Catch errors that may happen when close is called from __del__ + # because CPython is in interpreter shutdown. + try: + self.dict = _ClosedDict() + except (NameError, TypeError): + self.dict = None + + def __del__(self): + if not hasattr(self, 'writeback'): + # __init__ didn't succeed, so don't bother closing + return + self.close() + + def sync(self): + if self.writeback and self.cache: + self.writeback = False + for key, entry in self.cache.iteritems(): + self[key] = entry + self.writeback = True + self.cache = {} + if hasattr(self.dict, 'sync'): + self.dict.sync() + + +class BsdDbShelf(Shelf): + """Shelf implementation using the "BSD" db interface. + + This adds methods first(), next(), previous(), last() and + set_location() that have no counterpart in [g]dbm databases. + + The actual database must be opened using one of the "bsddb" + modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or + bsddb.rnopen) and passed to the constructor. + + See the module's __doc__ string for an overview of the interface. + """ + + def __init__(self, dict, protocol=None, writeback=False): + Shelf.__init__(self, dict, protocol, writeback) + + def set_location(self, key): + (key, value) = self.dict.set_location(key) + f = StringIO(value) + return (key, Unpickler(f).load()) + + def next(self): + (key, value) = self.dict.next() + f = StringIO(value) + return (key, Unpickler(f).load()) + + def previous(self): + (key, value) = self.dict.previous() + f = StringIO(value) + return (key, Unpickler(f).load()) + + def first(self): + (key, value) = self.dict.first() + f = StringIO(value) + return (key, Unpickler(f).load()) + + def last(self): + (key, value) = self.dict.last() + f = StringIO(value) + return (key, Unpickler(f).load()) + + +class DbfilenameShelf(Shelf): + """Shelf implementation using the "anydbm" generic dbm interface. + + This is initialized with the filename for the dbm database. + See the module's __doc__ string for an overview of the interface. + """ + + def __init__(self, filename, flag='c', protocol=None, writeback=False): + import anydbm + Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) + + +def open(filename, flag='c', protocol=None, writeback=False): + """Open a persistent dictionary for reading and writing. + + The filename parameter is the base filename for the underlying + database. As a side-effect, an extension may be added to the + filename and more than one file may be created. The optional flag + parameter has the same interpretation as the flag parameter of + anydbm.open(). The optional protocol parameter specifies the + version of the pickle protocol (0, 1, or 2). + + See the module's __doc__ string for an overview of the interface. + """ + + return DbfilenameShelf(filename, flag, protocol, writeback) diff --git a/src/main/resources/PythonLibs/shlex.py b/src/main/resources/PythonLibs/shlex.py new file mode 100644 index 0000000000000000000000000000000000000000..e7c8accd427590b035bdf47f82d005daec879c63 --- /dev/null +++ b/src/main/resources/PythonLibs/shlex.py @@ -0,0 +1,292 @@ +# -*- coding: iso-8859-1 -*- +"""A lexical analyzer class for simple shell-like syntaxes.""" + +# Module and documentation by Eric S. Raymond, 21 Dec 1998 +# Input stacking and error message cleanup added by ESR, March 2000 +# push_source() and pop_source() made explicit by ESR, January 2001. +# Posix compliance, split(), string arguments, and +# iterator interface by Gustavo Niemeyer, April 2003. + +import os.path +import sys +from collections import deque + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +__all__ = ["shlex", "split"] + +class shlex: + "A lexical analyzer class for simple shell-like syntaxes." + def __init__(self, instream=None, infile=None, posix=False): + if isinstance(instream, basestring): + instream = StringIO(instream) + if instream is not None: + self.instream = instream + self.infile = infile + else: + self.instream = sys.stdin + self.infile = None + self.posix = posix + if posix: + self.eof = None + else: + self.eof = '' + self.commenters = '#' + self.wordchars = ('abcdfeghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_') + if self.posix: + self.wordchars += ('ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ' + 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ') + self.whitespace = ' \t\r\n' + self.whitespace_split = False + self.quotes = '\'"' + self.escape = '\\' + self.escapedquotes = '"' + self.state = ' ' + self.pushback = deque() + self.lineno = 1 + self.debug = 0 + self.token = '' + self.filestack = deque() + self.source = None + if self.debug: + print 'shlex: reading from %s, line %d' \ + % (self.instream, self.lineno) + + def push_token(self, tok): + "Push a token onto the stack popped by the get_token method" + if self.debug >= 1: + print "shlex: pushing token " + repr(tok) + self.pushback.appendleft(tok) + + def push_source(self, newstream, newfile=None): + "Push an input source onto the lexer's input source stack." + if isinstance(newstream, basestring): + newstream = StringIO(newstream) + self.filestack.appendleft((self.infile, self.instream, self.lineno)) + self.infile = newfile + self.instream = newstream + self.lineno = 1 + if self.debug: + if newfile is not None: + print 'shlex: pushing to file %s' % (self.infile,) + else: + print 'shlex: pushing to stream %s' % (self.instream,) + + def pop_source(self): + "Pop the input source stack." + self.instream.close() + (self.infile, self.instream, self.lineno) = self.filestack.popleft() + if self.debug: + print 'shlex: popping to %s, line %d' \ + % (self.instream, self.lineno) + self.state = ' ' + + def get_token(self): + "Get a token from the input stream (or from stack if it's nonempty)" + if self.pushback: + tok = self.pushback.popleft() + if self.debug >= 1: + print "shlex: popping token " + repr(tok) + return tok + # No pushback. Get a token. + raw = self.read_token() + # Handle inclusions + if self.source is not None: + while raw == self.source: + spec = self.sourcehook(self.read_token()) + if spec: + (newfile, newstream) = spec + self.push_source(newstream, newfile) + raw = self.get_token() + # Maybe we got EOF instead? + while raw == self.eof: + if not self.filestack: + return self.eof + else: + self.pop_source() + raw = self.get_token() + # Neither inclusion nor EOF + if self.debug >= 1: + if raw != self.eof: + print "shlex: token=" + repr(raw) + else: + print "shlex: token=EOF" + return raw + + def read_token(self): + quoted = False + escapedstate = ' ' + while True: + nextchar = self.instream.read(1) + if nextchar == '\n': + self.lineno = self.lineno + 1 + if self.debug >= 3: + print "shlex: in state", repr(self.state), \ + "I see character:", repr(nextchar) + if self.state is None: + self.token = '' # past end of file + break + elif self.state == ' ': + if not nextchar: + self.state = None # end of file + break + elif nextchar in self.whitespace: + if self.debug >= 2: + print "shlex: I see whitespace in whitespace state" + if self.token or (self.posix and quoted): + break # emit current token + else: + continue + elif nextchar in self.commenters: + self.instream.readline() + self.lineno = self.lineno + 1 + elif self.posix and nextchar in self.escape: + escapedstate = 'a' + self.state = nextchar + elif nextchar in self.wordchars: + self.token = nextchar + self.state = 'a' + elif nextchar in self.quotes: + if not self.posix: + self.token = nextchar + self.state = nextchar + elif self.whitespace_split: + self.token = nextchar + self.state = 'a' + else: + self.token = nextchar + if self.token or (self.posix and quoted): + break # emit current token + else: + continue + elif self.state in self.quotes: + quoted = True + if not nextchar: # end of file + if self.debug >= 2: + print "shlex: I see EOF in quotes state" + # XXX what error should be raised here? + raise ValueError, "No closing quotation" + if nextchar == self.state: + if not self.posix: + self.token = self.token + nextchar + self.state = ' ' + break + else: + self.state = 'a' + elif self.posix and nextchar in self.escape and \ + self.state in self.escapedquotes: + escapedstate = self.state + self.state = nextchar + else: + self.token = self.token + nextchar + elif self.state in self.escape: + if not nextchar: # end of file + if self.debug >= 2: + print "shlex: I see EOF in escape state" + # XXX what error should be raised here? + raise ValueError, "No escaped character" + # In posix shells, only the quote itself or the escape + # character may be escaped within quotes. + if escapedstate in self.quotes and \ + nextchar != self.state and nextchar != escapedstate: + self.token = self.token + self.state + self.token = self.token + nextchar + self.state = escapedstate + elif self.state == 'a': + if not nextchar: + self.state = None # end of file + break + elif nextchar in self.whitespace: + if self.debug >= 2: + print "shlex: I see whitespace in word state" + self.state = ' ' + if self.token or (self.posix and quoted): + break # emit current token + else: + continue + elif nextchar in self.commenters: + self.instream.readline() + self.lineno = self.lineno + 1 + if self.posix: + self.state = ' ' + if self.token or (self.posix and quoted): + break # emit current token + else: + continue + elif self.posix and nextchar in self.quotes: + self.state = nextchar + elif self.posix and nextchar in self.escape: + escapedstate = 'a' + self.state = nextchar + elif nextchar in self.wordchars or nextchar in self.quotes \ + or self.whitespace_split: + self.token = self.token + nextchar + else: + self.pushback.appendleft(nextchar) + if self.debug >= 2: + print "shlex: I see punctuation in word state" + self.state = ' ' + if self.token: + break # emit current token + else: + continue + result = self.token + self.token = '' + if self.posix and not quoted and result == '': + result = None + if self.debug > 1: + if result: + print "shlex: raw token=" + repr(result) + else: + print "shlex: raw token=EOF" + return result + + def sourcehook(self, newfile): + "Hook called on a filename to be sourced." + if newfile[0] == '"': + newfile = newfile[1:-1] + # This implements cpp-like semantics for relative-path inclusion. + if isinstance(self.infile, basestring) and not os.path.isabs(newfile): + newfile = os.path.join(os.path.dirname(self.infile), newfile) + return (newfile, open(newfile, "r")) + + def error_leader(self, infile=None, lineno=None): + "Emit a C-compiler-like, Emacs-friendly error-message leader." + if infile is None: + infile = self.infile + if lineno is None: + lineno = self.lineno + return "\"%s\", line %d: " % (infile, lineno) + + def __iter__(self): + return self + + def next(self): + token = self.get_token() + if token == self.eof: + raise StopIteration + return token + +def split(s, comments=False, posix=True): + lex = shlex(s, posix=posix) + lex.whitespace_split = True + if not comments: + lex.commenters = '' + return list(lex) + +if __name__ == '__main__': + if len(sys.argv) == 1: + lexer = shlex() + else: + file = sys.argv[1] + lexer = shlex(open(file), file) + while 1: + tt = lexer.get_token() + if tt: + print "Token: " + repr(tt) + else: + break diff --git a/src/main/resources/PythonLibs/shutil.py b/src/main/resources/PythonLibs/shutil.py new file mode 100644 index 0000000000000000000000000000000000000000..420802fafdff81fcd78b886b7474dd5322b444ae --- /dev/null +++ b/src/main/resources/PythonLibs/shutil.py @@ -0,0 +1,556 @@ +"""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 +from os.path import abspath +import fnmatch +import collections +import errno + +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", + "ignore_patterns"] + +class Error(EnvironmentError): + pass + +class SpecialFileError(EnvironmentError): + """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(EnvironmentError): + """Raised when a command could not be executed""" + +try: + WindowsError +except NameError: + WindowsError = None + +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): + """Copy data from src to dst""" + if _samefile(src, dst): + raise Error("`%s` and `%s` are the same file" % (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) + + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + +def copymode(src, dst): + """Copy mode bits from src to dst""" + if hasattr(os, 'chmod'): + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + os.chmod(dst, mode) + +def copystat(src, dst): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + if hasattr(os, 'utime'): + os.utime(dst, (st.st_atime, st.st_mtime)) + if hasattr(os, 'chmod'): + os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + try: + os.chflags(dst, st.st_flags) + except OSError, why: + for err in 'EOPNOTSUPP', 'ENOTSUP': + if hasattr(errno, err) and why.errno == getattr(errno, err): + break + else: + raise + +def copy(src, dst): + """Copy data and mode bits ("cp src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copymode(src, dst) + +def copy2(src, dst): + """Copy data and all stat info ("cp -p src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copystat(src, 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): + """Recursively copy a directory tree using copy2(). + + 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. + + 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. + + XXX Consider this example code rather than the ultimate tool. + + """ + 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 symlinks and os.path.islink(srcname): + linkto = os.readlink(srcname) + os.symlink(linkto, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore) + else: + # Will raise a SpecialFileError for unsupported file types + copy2(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error, err: + errors.extend(err.args[0]) + except EnvironmentError, why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError, why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.append((src, dst, str(why))) + if errors: + raise Error, errors + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is os.listdir, os.remove, or os.rmdir; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + 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 os.error, err: + 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 os.error: + mode = 0 + if stat.S_ISDIR(mode): + rmtree(fullname, ignore_errors, onerror) + else: + try: + os.remove(fullname) + except os.error, err: + onerror(os.remove, fullname, sys.exc_info()) + try: + os.rmdir(path) + except os.error: + onerror(os.rmdir, path, sys.exc_info()) + + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + return os.path.basename(path.rstrip(os.path.sep)) + +def move(src, dst): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error, "Destination path '%s' already exists" % real_dst + try: + os.rename(src, real_dst) + except OSError: + if os.path.isdir(src): + if _destinsrc(src, dst): + raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst) + copytree(src, real_dst, symlinks=True) + rmtree(src) + else: + copy2(src, real_dst) + os.unlink(src) + +def _destinsrc(src, dst): + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", or ".bz2"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: ''} + compress_ext = {'gzip': '.gz', 'bzip2': '.bz2'} + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext.keys(): + raise ValueError, \ + ("bad value for 'compress': must be None, 'gzip' or 'bzip2'") + + archive_name = base_name + '.tar' + compress_ext.get(compress, '') + archive_dir = os.path.dirname(archive_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + + # creating the tarball + import tarfile # late import so Python build itself doesn't break + + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): + # XXX see if we want to keep an external call here + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + from distutils.errors import DistutilsExecError + from distutils.spawn import spawn + try: + spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise ExecError, \ + ("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises ExecError. Returns the name of the output zip + file. + """ + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # If zipfile module is not available, try spawning an external 'zip' + # command. + try: + import zipfile + except ImportError: + zipfile = None + + if zipfile is None: + _call_external_zip(base_dir, zip_filename, verbose, dry_run) + else: + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + zip.close() + + return zip_filename + +_ARCHIVE_FORMATS = { + 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (_make_zipfile, [],"ZIP file") + } + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not isinstance(function, collections.Callable): + raise TypeError('The %s object is not callable' % function) + if not isinstance(extra_args, (tuple, list)): + raise TypeError('extra_args needs to be a sequence') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2 : + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "bztar" + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError, "unknown archive format '%s'" % format + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename diff --git a/src/main/resources/PythonLibs/signal.py b/src/main/resources/PythonLibs/signal.py new file mode 100644 index 0000000000000000000000000000000000000000..f7a8cc00bdc08653ccfaa86f9ec9871b246e9a8f --- /dev/null +++ b/src/main/resources/PythonLibs/signal.py @@ -0,0 +1,239 @@ +""" + This module provides mechanisms to use signal handlers in Python. + + Functions: + + signal(sig,action) -- set the action for a given signal (done) + pause(sig) -- wait until a signal arrives [Unix only] + alarm(seconds) -- cause SIGALRM after a specified time [Unix only] + getsignal(sig) -- get the signal action for a given signal + default_int_handler(action) -- default SIGINT handler (done, but acts string) + + Constants: + + SIG_DFL -- used to refer to the system default handler + SIG_IGN -- used to ignore the signal + NSIG -- number of defined signals + + SIGINT, SIGTERM, etc. -- signal numbers + + *** IMPORTANT NOTICES *** + A signal handler function is called with two arguments: + the first is the signal number, the second is the interrupted stack frame. + + According to http://java.sun.com/products/jdk/faq/faq-sun-packages.html + 'writing java programs that rely on sun.* is risky: they are not portable, and are not supported.' + + However, in Jython, like Python, we let you decide what makes + sense for your application. If sun.misc.Signal is not available, + an ImportError is raised. +""" + + +try: + import sun.misc.Signal +except ImportError: + raise ImportError("signal module requires sun.misc.Signal, which is not available on this platform") + +import os +import sun.misc.SignalHandler +import sys +import threading +import time +from java.lang import IllegalArgumentException +from java.util.concurrent.atomic import AtomicReference + +debug = 0 + +def _init_signals(): + # install signals by checking for standard names + # using IllegalArgumentException to diagnose + + possible_signals = """ + SIGABRT + SIGALRM + SIGBUS + SIGCHLD + SIGCONT + SIGFPE + SIGHUP + SIGILL + SIGINFO + SIGINT + SIGIOT + SIGKILL + SIGPIPE + SIGPOLL + SIGPROF + SIGQUIT + SIGSEGV + SIGSTOP + SIGSYS + SIGTERM + SIGTRAP + SIGTSTP + SIGTTIN + SIGTTOU + SIGURG + SIGUSR1 + SIGUSR2 + SIGVTALRM + SIGWINCH + SIGXCPU + SIGXFSZ + """.split() + + _module = __import__(__name__) + signals = {} + signals_by_name = {} + for signal_name in possible_signals: + try: + java_signal = sun.misc.Signal(signal_name[3:]) + except IllegalArgumentException: + continue + + signal_number = java_signal.getNumber() + signals[signal_number] = java_signal + signals_by_name[signal_name] = java_signal + setattr(_module, signal_name, signal_number) # install as a module constant + return signals + +_signals = _init_signals() +NSIG = max(_signals.iterkeys()) + 1 +SIG_DFL = sun.misc.SignalHandler.SIG_DFL # default system handler +SIG_IGN = sun.misc.SignalHandler.SIG_IGN # handler to ignore a signal + +class JythonSignalHandler(sun.misc.SignalHandler): + def __init__(self, action): + self.action = action + + def handle(self, signal): + # passing a frame here probably don't make sense in a threaded system, + # but perhaps revisit + self.action(signal.getNumber(), None) + +def signal(sig, action): + """ + signal(sig, action) -> action + + Set the action for the given signal. The action can be SIG_DFL, + SIG_IGN, or a callable Python object. The previous action is + returned. See getsignal() for possible return values. + + *** IMPORTANT NOTICE *** + A signal handler function is called with two arguments: + the first is the signal number, the second is the interrupted stack frame. + """ + # maybe keep a weak ref map of handlers we have returned? + + try: + signal = _signals[sig] + except KeyError: + raise ValueError("signal number out of range") + + if callable(action): + prev = sun.misc.Signal.handle(signal, JythonSignalHandler(action)) + elif action in (SIG_IGN, SIG_DFL) or isinstance(action, sun.misc.SignalHandler): + prev = sun.misc.Signal.handle(signal, action) + else: + raise TypeError("signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object") + + if isinstance(prev, JythonSignalHandler): + return prev.action + else: + return prev + + +# dangerous! don't use! +def getsignal(sig): + """getsignal(sig) -> action + + Return the current action for the given signal. The return value can be: + SIG_IGN -- if the signal is being ignored + SIG_DFL -- if the default action for the signal is in effect + None -- if an unknown handler is in effect + anything else -- the callable Python object used as a handler + + Note for Jython: this function is NOT threadsafe. The underlying + Java support only enables getting the current signal handler by + setting a new one. So this is completely prone to race conditions. + """ + try: + signal = _signals[sig] + except KeyError: + raise ValueError("signal number out of range") + current = sun.misc.Signal.handle(signal, SIG_DFL) + sun.misc.Signal.handle(signal, current) # and reinstall + + if isinstance(current, JythonSignalHandler): + return current.action + else: + return current + +def default_int_handler(sig, frame): + """ + default_int_handler(...) + + The default handler for SIGINT installed by Python. + It raises KeyboardInterrupt. + """ + raise KeyboardInterrupt + +def pause(): + raise NotImplementedError + +_alarm_timer_holder = AtomicReference() + +def _alarm_handler(sig, frame): + print "Alarm clock" + os._exit(0) + +# install a default alarm handler, the one we get by default doesn't +# work terribly well since it throws a bus error (at least on OS X)! +try: + SIGALRM + signal(SIGALRM, _alarm_handler) +except NameError: + pass + +class _Alarm(object): + def __init__(self, interval, task): + self.interval = interval + self.task = task + self.scheduled = None + self.timer = threading.Timer(self.interval, self.task) + + def start(self): + self.timer.start() + self.scheduled = time.time() + self.interval + + def cancel(self): + self.timer.cancel() + now = time.time() + if self.scheduled and self.scheduled > now: + return self.scheduled - now + else: + return 0 + +def alarm(time): + try: + SIGALRM + except NameError: + raise NotImplementedError("alarm not implemented on this platform") + + def raise_alarm(): + sun.misc.Signal.raise(_signals[SIGALRM]) + + if time > 0: + new_alarm_timer = _Alarm(time, raise_alarm) + else: + new_alarm_timer = None + old_alarm_timer = _alarm_timer_holder.getAndSet(new_alarm_timer) + if old_alarm_timer: + scheduled = int(old_alarm_timer.cancel()) + else: + scheduled = 0 + + if new_alarm_timer: + new_alarm_timer.start() + return scheduled diff --git a/src/main/resources/PythonLibs/site-packages/README b/src/main/resources/PythonLibs/site-packages/README new file mode 100644 index 0000000000000000000000000000000000000000..273f6251a7f9d9c4142522e9ab1d699a8ab1bad6 --- /dev/null +++ b/src/main/resources/PythonLibs/site-packages/README @@ -0,0 +1,2 @@ +This directory exists so that 3rd party packages can be installed +here. Read the source for site.py for more details. diff --git a/src/main/resources/PythonLibs/site.py b/src/main/resources/PythonLibs/site.py new file mode 100644 index 0000000000000000000000000000000000000000..2c4f52076c8ac7c5d98d62fb1ed4b7b28db25f7e --- /dev/null +++ b/src/main/resources/PythonLibs/site.py @@ -0,0 +1,623 @@ +"""Append module search paths for third-party packages to sys.path. + +**************************************************************** +* This module is automatically imported during initialization. * +**************************************************************** + +In earlier versions of Python (up to 1.5a3), scripts or modules that +needed to use site-specific modules would place ``import site'' +somewhere near the top of their code. Because of the automatic +import, this is no longer necessary (but code that does it still +works). + +This will append site-specific paths to the module search path. On +Unix (including Mac OSX), it starts with sys.prefix and +sys.exec_prefix (if different) and appends +lib/python<version>/site-packages as well as lib/site-python. +On other platforms (such as Windows), it tries each of the +prefixes directly, as well as with lib/site-packages appended. The +resulting directories, if they exist, are appended to sys.path, and +also inspected for path configuration files. + +A path configuration file is a file whose name has the form +<package>.pth; its contents are additional directories (one per line) +to be added to sys.path. Non-existing directories (or +non-directories) are never added to sys.path; no directory is added to +sys.path more than once. Blank lines and lines beginning with +'#' are skipped. Lines starting with 'import' are executed. + +For example, suppose sys.prefix and sys.exec_prefix are set to +/usr/local and there is a directory /usr/local/lib/python2.5/site-packages +with three subdirectories, foo, bar and spam, and two path +configuration files, foo.pth and bar.pth. Assume foo.pth contains the +following: + + # foo package configuration + foo + bar + bletch + +and bar.pth contains: + + # bar package configuration + bar + +Then the following directories are added to sys.path, in this order: + + /usr/local/lib/python2.5/site-packages/bar + /usr/local/lib/python2.5/site-packages/foo + +Note that bletch is omitted because it doesn't exist; bar precedes foo +because bar.pth comes alphabetically before foo.pth; and spam is +omitted because it is not mentioned in either path configuration file. + +After these path manipulations, an attempt is made to import a module +named sitecustomize, which can perform arbitrary additional +site-specific customizations. If this import fails with an +ImportError exception, it is silently ignored. + +""" + +import sys +import os +import __builtin__ +import traceback + +_is_jython = sys.platform.startswith("java") +if _is_jython: + _ModuleType = type(os) + +# Prefixes for site-packages; add additional prefixes like /usr/local here +PREFIXES = [sys.prefix, sys.exec_prefix] +# Enable per user site-packages directory +# set it to False to disable the feature or True to force the feature +ENABLE_USER_SITE = None + +# for distutils.commands.install +# These values are initialized by the getuserbase() and getusersitepackages() +# functions, through the main() function when Python starts. +USER_SITE = None +USER_BASE = None + + +def makepath(*paths): + dir = os.path.join(*paths) + if _is_jython and (dir == '__classpath__' or + dir.startswith('__pyclasspath__')): + return dir, dir + try: + dir = os.path.abspath(dir) + except OSError: + pass + return dir, os.path.normcase(dir) + + +def abs__file__(): + """Set all module' __file__ attribute to an absolute path""" + for m in sys.modules.values(): + if hasattr(m, '__loader__') or ( + _is_jython and not isinstance(m, _ModuleType)): + continue # don't mess with a PEP 302-supplied __file__ + f = getattr(m, '__file__', None) + if f is None: + continue + m.__file__ = os.path.abspath(f) + + +def removeduppaths(): + """ Remove duplicate entries from sys.path along with making them + absolute""" + # This ensures that the initial path provided by the interpreter contains + # only absolute pathnames, even if we're running from the build directory. + L = [] + known_paths = set() + for dir in sys.path: + # Filter out duplicate paths (on case-insensitive file systems also + # if they only differ in case); turn relative paths into absolute + # paths. + dir, dircase = makepath(dir) + if not dircase in known_paths: + L.append(dir) + known_paths.add(dircase) + sys.path[:] = L + return known_paths + +# XXX This should not be part of site.py, since it is needed even when +# using the -S option for Python. See http://www.python.org/sf/586680 +def addbuilddir(): + """Append ./build/lib.<platform> in case we're running in the build dir + (especially for Guido :-)""" + from sysconfig import get_platform + s = "build/lib.%s-%.3s" % (get_platform(), sys.version) + if hasattr(sys, 'gettotalrefcount'): + s += '-pydebug' + s = os.path.join(os.path.dirname(sys.path.pop()), s) + sys.path.append(s) + + +def _init_pathinfo(): + """Return a set containing all existing directory entries from sys.path""" + d = set() + for dir in sys.path: + try: + if os.path.isdir(dir): + dir, dircase = makepath(dir) + d.add(dircase) + except TypeError: + continue + return d + + +def addpackage(sitedir, name, known_paths): + """Process a .pth file within the site-packages directory: + For each line in the file, either combine it with sitedir to a path + and add that to known_paths, or execute it if it starts with 'import '. + """ + if known_paths is None: + _init_pathinfo() + reset = 1 + else: + reset = 0 + fullname = os.path.join(sitedir, name) + try: + f = open(fullname, "rU") + except IOError: + return + with f: + for n, line in enumerate(f): + if line.startswith("#"): + continue + try: + if line.startswith(("import ", "import\t")): + exec line + continue + line = line.rstrip() + dir, dircase = makepath(sitedir, line) + if not dircase in known_paths and os.path.exists(dir): + sys.path.append(dir) + known_paths.add(dircase) + except Exception as err: + print >>sys.stderr, "Error processing line {:d} of {}:\n".format( + n+1, fullname) + for record in traceback.format_exception(*sys.exc_info()): + for line in record.splitlines(): + print >>sys.stderr, ' '+line + print >>sys.stderr, "\nRemainder of file ignored" + break + if reset: + known_paths = None + return known_paths + + +def addsitedir(sitedir, known_paths=None): + """Add 'sitedir' argument to sys.path if missing and handle .pth files in + 'sitedir'""" + if known_paths is None: + known_paths = _init_pathinfo() + reset = 1 + else: + reset = 0 + sitedir, sitedircase = makepath(sitedir) + if not sitedircase in known_paths: + sys.path.append(sitedir) # Add path component + try: + names = os.listdir(sitedir) + except os.error: + return + dotpth = os.extsep + "pth" + names = [name for name in names if name.endswith(dotpth)] + for name in sorted(names): + addpackage(sitedir, name, known_paths) + if reset: + known_paths = None + return known_paths + + +def check_enableusersite(): + """Check if user site directory is safe for inclusion + + The function tests for the command line flag (including environment var), + process uid/gid equal to effective uid/gid. + + None: Disabled for security reasons + False: Disabled by user (command line option) + True: Safe and enabled + """ + if sys.flags.no_user_site: + return False + + if hasattr(os, "getuid") and hasattr(os, "geteuid"): + # check process uid == effective uid + if os.geteuid() != os.getuid(): + return None + if hasattr(os, "getgid") and hasattr(os, "getegid"): + # check process gid == effective gid + if os.getegid() != os.getgid(): + return None + + return True + +def getuserbase(): + """Returns the `user base` directory path. + + The `user base` directory can be used to store data. If the global + variable ``USER_BASE`` is not initialized yet, this function will also set + it. + """ + global USER_BASE + if USER_BASE is not None: + return USER_BASE + from sysconfig import get_config_var + USER_BASE = get_config_var('userbase') + return USER_BASE + +def getusersitepackages(): + """Returns the user-specific site-packages directory path. + + If the global variable ``USER_SITE`` is not initialized yet, this + function will also set it. + """ + global USER_SITE + user_base = getuserbase() # this will also set USER_BASE + + if USER_SITE is not None: + return USER_SITE + + from sysconfig import get_path + import os + + if sys.platform == 'darwin': + from sysconfig import get_config_var + if get_config_var('PYTHONFRAMEWORK'): + USER_SITE = get_path('purelib', 'osx_framework_user') + return USER_SITE + + USER_SITE = get_path('purelib', '%s_user' % os.name) + return USER_SITE + +def addusersitepackages(known_paths): + """Add a per user site-package to sys.path + + Each user has its own python directory with site-packages in the + home directory. + """ + # get the per user site-package path + # this call will also make sure USER_BASE and USER_SITE are set + user_site = getusersitepackages() + + if ENABLE_USER_SITE and os.path.isdir(user_site): + addsitedir(user_site, known_paths) + return known_paths + +def getsitepackages(): + """Returns a list containing all global site-packages directories + (and possibly site-python). + + For each directory present in the global ``PREFIXES``, this function + will find its `site-packages` subdirectory depending on the system + environment, and will return a list of full paths. + """ + sitepackages = [] + seen = set() + + for prefix in PREFIXES: + if not prefix or prefix in seen: + continue + seen.add(prefix) + + if sys.platform in ('os2emx', 'riscos') or _is_jython: + sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) + elif os.sep == '/': + sitepackages.append(os.path.join(prefix, "lib", + "python" + sys.version[:3], + "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-python")) + else: + sitepackages.append(prefix) + sitepackages.append(os.path.join(prefix, "lib", "site-packages")) + if sys.platform == "darwin": + # for framework builds *only* we add the standard Apple + # locations. + from sysconfig import get_config_var + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + sitepackages.append( + os.path.join("/Library", framework, + sys.version[:3], "site-packages")) + return sitepackages + +def addsitepackages(known_paths): + """Add site-packages (and possibly site-python) to sys.path""" + for sitedir in getsitepackages(): + if os.path.isdir(sitedir): + addsitedir(sitedir, known_paths) + + return known_paths + +def setBEGINLIBPATH(): + """The OS/2 EMX port has optional extension modules that do double duty + as DLLs (and must use the .DLL file extension) for other extensions. + The library search path needs to be amended so these will be found + during module import. Use BEGINLIBPATH so that these are at the start + of the library search path. + + """ + dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload") + libpath = os.environ['BEGINLIBPATH'].split(';') + if libpath[-1]: + libpath.append(dllpath) + else: + libpath[-1] = dllpath + os.environ['BEGINLIBPATH'] = ';'.join(libpath) + + +def setquit(): + """Define new builtins 'quit' and 'exit'. + + These are objects which make the interpreter exit when called. + The repr of each object contains a hint at how it works. + + """ + if os.sep == ':': + eof = 'Cmd-Q' + elif os.sep == '\\': + eof = 'Ctrl-Z plus Return' + else: + eof = 'Ctrl-D (i.e. EOF)' + + class Quitter(object): + def __init__(self, name): + self.name = name + def __repr__(self): + return 'Use %s() or %s to exit' % (self.name, eof) + def __call__(self, code=None): + # Shells like IDLE catch the SystemExit, but listen when their + # stdin wrapper is closed. + try: + sys.stdin.close() + except: + pass + raise SystemExit(code) + __builtin__.quit = Quitter('quit') + __builtin__.exit = Quitter('exit') + + +class _Printer(object): + """interactive prompt objects for printing the license text, a list of + contributors and the copyright notice.""" + + MAXLINES = 23 + + def __init__(self, name, data, files=(), dirs=()): + self.__name = name + self.__data = data + self.__files = files + self.__dirs = dirs + self.__lines = None + + def __setup(self): + if self.__lines: + return + data = None + for dir in self.__dirs: + for filename in self.__files: + filename = os.path.join(dir, filename) + try: + fp = file(filename, "rU") + data = fp.read() + fp.close() + break + except IOError: + pass + if data: + break + if not data: + data = self.__data + self.__lines = data.split('\n') + self.__linecnt = len(self.__lines) + + def __repr__(self): + self.__setup() + if len(self.__lines) <= self.MAXLINES: + return "\n".join(self.__lines) + else: + return "Type %s() to see the full %s text" % ((self.__name,)*2) + + def __call__(self): + self.__setup() + prompt = 'Hit Return for more, or q (and Return) to quit: ' + lineno = 0 + while 1: + try: + for i in range(lineno, lineno + self.MAXLINES): + print self.__lines[i] + except IndexError: + break + else: + lineno += self.MAXLINES + key = None + while key is None: + key = raw_input(prompt) + if key not in ('', 'q'): + key = None + if key == 'q': + break + +def setcopyright(): + """Set 'copyright' and 'credits' in __builtin__""" + __builtin__.copyright = _Printer("copyright", sys.copyright) + if sys.platform[:4] == 'java': + __builtin__.credits = _Printer( + "credits", + "Jython is maintained by the Jython developers (www.jython.org).") + else: + __builtin__.credits = _Printer("credits", """\ + Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information.""") + here = os.path.dirname(os.__file__) + __builtin__.license = _Printer( + "license", "See http://www.python.org/%.3s/license.html" % sys.version, + ["LICENSE.txt", "LICENSE"], + [os.path.join(here, os.pardir), here, os.curdir]) + + +class _Helper(object): + """Define the builtin 'help'. + This is a wrapper around pydoc.help (with a twist). + + """ + + def __repr__(self): + return "Type help() for interactive help, " \ + "or help(object) for help about object." + def __call__(self, *args, **kwds): + import pydoc + return pydoc.help(*args, **kwds) + +def sethelper(): + __builtin__.help = _Helper() + +def aliasmbcs(): + """On Windows, some default encodings are not provided by Python, + while they are always available as "mbcs" in each locale. Make + them usable by aliasing to "mbcs" in such a case.""" + if sys.platform == 'win32': + import locale, codecs + enc = locale.getdefaultlocale()[1] + if enc.startswith('cp'): # "cp***" ? + try: + codecs.lookup(enc) + except LookupError: + import encodings + encodings._cache[enc] = encodings._unknown + encodings.aliases.aliases[enc] = 'mbcs' + +def setencoding(): + """Set the string encoding used by the Unicode implementation. The + default is 'ascii', but if you're willing to experiment, you can + change this.""" + encoding = "ascii" # Default value set by _PyUnicode_Init() + if 0: + # Enable to support locale aware default string encodings. + import locale + loc = locale.getdefaultlocale() + if loc[1]: + encoding = loc[1] + if 0: + # Enable to switch off string to Unicode coercion and implicit + # Unicode to string conversion. + encoding = "undefined" + if encoding != "ascii": + # On Non-Unicode builds this will raise an AttributeError... + sys.setdefaultencoding(encoding) # Needs Python Unicode build ! + + +def execsitecustomize(): + """Run custom site specific code, if available.""" + try: + import sitecustomize + except ImportError: + pass + except Exception: + if sys.flags.verbose: + sys.excepthook(*sys.exc_info()) + else: + print >>sys.stderr, \ + "'import sitecustomize' failed; use -v for traceback" + + +def execusercustomize(): + """Run custom user specific code, if available.""" + try: + import usercustomize + except ImportError: + pass + except Exception: + if sys.flags.verbose: + sys.excepthook(*sys.exc_info()) + else: + print>>sys.stderr, \ + "'import usercustomize' failed; use -v for traceback" + + +def main(): + global ENABLE_USER_SITE + + abs__file__() + known_paths = removeduppaths() + if (os.name == "posix" and sys.path and + os.path.basename(sys.path[-1]) == "Modules"): + addbuilddir() + if ENABLE_USER_SITE is None: + ENABLE_USER_SITE = check_enableusersite() + known_paths = addusersitepackages(known_paths) + known_paths = addsitepackages(known_paths) + if sys.platform == 'os2emx': + setBEGINLIBPATH() + setquit() + setcopyright() + sethelper() + aliasmbcs() + setencoding() + execsitecustomize() + if ENABLE_USER_SITE: + execusercustomize() + # Remove sys.setdefaultencoding() so that users cannot change the + # encoding after initialization. The test for presence is needed when + # this module is run as a script, because this code is executed twice. + if hasattr(sys, "setdefaultencoding"): + del sys.setdefaultencoding + +main() + +def _script(): + help = """\ + %s [--user-base] [--user-site] + + Without arguments print some useful information + With arguments print the value of USER_BASE and/or USER_SITE separated + by '%s'. + + Exit codes with --user-base or --user-site: + 0 - user site directory is enabled + 1 - user site directory is disabled by user + 2 - uses site directory is disabled by super user + or for security reasons + >2 - unknown error + """ + args = sys.argv[1:] + if not args: + print "sys.path = [" + for dir in sys.path: + print " %r," % (dir,) + print "]" + print "USER_BASE: %r (%s)" % (USER_BASE, + "exists" if os.path.isdir(USER_BASE) else "doesn't exist") + print "USER_SITE: %r (%s)" % (USER_SITE, + "exists" if os.path.isdir(USER_SITE) else "doesn't exist") + print "ENABLE_USER_SITE: %r" % ENABLE_USER_SITE + sys.exit(0) + + buffer = [] + if '--user-base' in args: + buffer.append(USER_BASE) + if '--user-site' in args: + buffer.append(USER_SITE) + + if buffer: + print os.pathsep.join(buffer) + if ENABLE_USER_SITE: + sys.exit(0) + elif ENABLE_USER_SITE is False: + sys.exit(1) + elif ENABLE_USER_SITE is None: + sys.exit(2) + else: + sys.exit(3) + else: + import textwrap + print textwrap.dedent(help % (sys.argv[0], os.pathsep)) + sys.exit(10) + +if __name__ == '__main__': + _script() diff --git a/src/main/resources/PythonLibs/smtpd.py b/src/main/resources/PythonLibs/smtpd.py new file mode 100644 index 0000000000000000000000000000000000000000..b4d208b2eeb9857e89fcc9df8ffdb6a0233e429f --- /dev/null +++ b/src/main/resources/PythonLibs/smtpd.py @@ -0,0 +1,555 @@ +#! /usr/bin/env python +"""An RFC 2821 smtp proxy. + +Usage: %(program)s [options] [localhost:localport [remotehost:remoteport]] + +Options: + + --nosetuid + -n + This program generally tries to setuid `nobody', unless this flag is + set. The setuid call will fail if this program is not run as root (in + which case, use this flag). + + --version + -V + Print the version number and exit. + + --class classname + -c classname + Use `classname' as the concrete SMTP proxy class. Uses `PureProxy' by + default. + + --debug + -d + Turn on debugging prints. + + --help + -h + Print this message and exit. + +Version: %(__version__)s + +If localhost is not given then `localhost' is used, and if localport is not +given then 8025 is used. If remotehost is not given then `localhost' is used, +and if remoteport is not given, then 25 is used. +""" + +# Overview: +# +# This file implements the minimal SMTP protocol as defined in RFC 821. It +# has a hierarchy of classes which implement the backend functionality for the +# smtpd. A number of classes are provided: +# +# SMTPServer - the base class for the backend. Raises NotImplementedError +# if you try to use it. +# +# DebuggingServer - simply prints each message it receives on stdout. +# +# PureProxy - Proxies all messages to a real smtpd which does final +# delivery. One known problem with this class is that it doesn't handle +# SMTP errors from the backend server at all. This should be fixed +# (contributions are welcome!). +# +# MailmanProxy - An experimental hack to work with GNU Mailman +# <www.list.org>. Using this server as your real incoming smtpd, your +# mailhost will automatically recognize and accept mail destined to Mailman +# lists when those lists are created. Every message not destined for a list +# gets forwarded to a real backend smtpd, as with PureProxy. Again, errors +# are not handled correctly yet. +# +# Please note that this script requires Python 2.0 +# +# Author: Barry Warsaw <barry@python.org> +# +# TODO: +# +# - support mailbox delivery +# - alias files +# - ESMTP +# - handle error codes from the backend smtpd + +import sys +import os +import errno +import getopt +import time +import socket +import asyncore +import asynchat + +__all__ = ["SMTPServer","DebuggingServer","PureProxy","MailmanProxy"] + +program = sys.argv[0] +__version__ = 'Python SMTP proxy version 0.2' + + +class Devnull: + def write(self, msg): pass + def flush(self): pass + + +DEBUGSTREAM = Devnull() +NEWLINE = '\n' +EMPTYSTRING = '' +COMMASPACE = ', ' + + +def usage(code, msg=''): + print >> sys.stderr, __doc__ % globals() + if msg: + print >> sys.stderr, msg + sys.exit(code) + + +class SMTPChannel(asynchat.async_chat): + COMMAND = 0 + DATA = 1 + + def __init__(self, server, conn, addr): + asynchat.async_chat.__init__(self, conn) + self.__server = server + self.__conn = conn + self.__addr = addr + self.__line = [] + self.__state = self.COMMAND + self.__greeting = 0 + self.__mailfrom = None + self.__rcpttos = [] + self.__data = '' + self.__fqdn = socket.getfqdn() + try: + self.__peer = conn.getpeername() + except socket.error, err: + # a race condition may occur if the other end is closing + # before we can get the peername + self.close() + if err[0] != errno.ENOTCONN: + raise + return + print >> DEBUGSTREAM, 'Peer:', repr(self.__peer) + self.push('220 %s %s' % (self.__fqdn, __version__)) + self.set_terminator('\r\n') + + # Overrides base class for convenience + def push(self, msg): + asynchat.async_chat.push(self, msg + '\r\n') + + # Implementation of base class abstract method + def collect_incoming_data(self, data): + self.__line.append(data) + + # Implementation of base class abstract method + def found_terminator(self): + line = EMPTYSTRING.join(self.__line) + print >> DEBUGSTREAM, 'Data:', repr(line) + self.__line = [] + if self.__state == self.COMMAND: + if not line: + self.push('500 Error: bad syntax') + return + method = None + i = line.find(' ') + if i < 0: + command = line.upper() + arg = None + else: + command = line[:i].upper() + arg = line[i+1:].strip() + method = getattr(self, 'smtp_' + command, None) + if not method: + self.push('502 Error: command "%s" not implemented' % command) + return + method(arg) + return + else: + if self.__state != self.DATA: + self.push('451 Internal confusion') + return + # Remove extraneous carriage returns and de-transparency according + # to RFC 821, Section 4.5.2. + data = [] + for text in line.split('\r\n'): + if text and text[0] == '.': + data.append(text[1:]) + else: + data.append(text) + self.__data = NEWLINE.join(data) + status = self.__server.process_message(self.__peer, + self.__mailfrom, + self.__rcpttos, + self.__data) + self.__rcpttos = [] + self.__mailfrom = None + self.__state = self.COMMAND + self.set_terminator('\r\n') + if not status: + self.push('250 Ok') + else: + self.push(status) + + # SMTP and ESMTP commands + def smtp_HELO(self, arg): + if not arg: + self.push('501 Syntax: HELO hostname') + return + if self.__greeting: + self.push('503 Duplicate HELO/EHLO') + else: + self.__greeting = arg + self.push('250 %s' % self.__fqdn) + + def smtp_NOOP(self, arg): + if arg: + self.push('501 Syntax: NOOP') + else: + self.push('250 Ok') + + def smtp_QUIT(self, arg): + # args is ignored + self.push('221 Bye') + self.close_when_done() + + # factored + def __getaddr(self, keyword, arg): + address = None + keylen = len(keyword) + if arg[:keylen].upper() == keyword: + address = arg[keylen:].strip() + if not address: + pass + elif address[0] == '<' and address[-1] == '>' and address != '<>': + # Addresses can be in the form <person@dom.com> but watch out + # for null address, e.g. <> + address = address[1:-1] + return address + + def smtp_MAIL(self, arg): + print >> DEBUGSTREAM, '===> MAIL', arg + address = self.__getaddr('FROM:', arg) if arg else None + if not address: + self.push('501 Syntax: MAIL FROM:<address>') + return + if self.__mailfrom: + self.push('503 Error: nested MAIL command') + return + self.__mailfrom = address + print >> DEBUGSTREAM, 'sender:', self.__mailfrom + self.push('250 Ok') + + def smtp_RCPT(self, arg): + print >> DEBUGSTREAM, '===> RCPT', arg + if not self.__mailfrom: + self.push('503 Error: need MAIL command') + return + address = self.__getaddr('TO:', arg) if arg else None + if not address: + self.push('501 Syntax: RCPT TO: <address>') + return + self.__rcpttos.append(address) + print >> DEBUGSTREAM, 'recips:', self.__rcpttos + self.push('250 Ok') + + def smtp_RSET(self, arg): + if arg: + self.push('501 Syntax: RSET') + return + # Resets the sender, recipients, and data, but not the greeting + self.__mailfrom = None + self.__rcpttos = [] + self.__data = '' + self.__state = self.COMMAND + self.push('250 Ok') + + def smtp_DATA(self, arg): + if not self.__rcpttos: + self.push('503 Error: need RCPT command') + return + if arg: + self.push('501 Syntax: DATA') + return + self.__state = self.DATA + self.set_terminator('\r\n.\r\n') + self.push('354 End data with <CR><LF>.<CR><LF>') + + +class SMTPServer(asyncore.dispatcher): + def __init__(self, localaddr, remoteaddr): + self._localaddr = localaddr + self._remoteaddr = remoteaddr + asyncore.dispatcher.__init__(self) + try: + self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + # try to re-use a server port if possible + self.set_reuse_addr() + self.bind(localaddr) + self.listen(5) + except: + # cleanup asyncore.socket_map before raising + self.close() + raise + else: + print >> DEBUGSTREAM, \ + '%s started at %s\n\tLocal addr: %s\n\tRemote addr:%s' % ( + self.__class__.__name__, time.ctime(time.time()), + localaddr, remoteaddr) + + def handle_accept(self): + pair = self.accept() + if pair is not None: + conn, addr = pair + print >> DEBUGSTREAM, 'Incoming connection from %s' % repr(addr) + channel = SMTPChannel(self, conn, addr) + + # API for "doing something useful with the message" + def process_message(self, peer, mailfrom, rcpttos, data): + """Override this abstract method to handle messages from the client. + + peer is a tuple containing (ipaddr, port) of the client that made the + socket connection to our smtp port. + + mailfrom is the raw address the client claims the message is coming + from. + + rcpttos is a list of raw addresses the client wishes to deliver the + message to. + + data is a string containing the entire full text of the message, + headers (if supplied) and all. It has been `de-transparencied' + according to RFC 821, Section 4.5.2. In other words, a line + containing a `.' followed by other text has had the leading dot + removed. + + This function should return None, for a normal `250 Ok' response; + otherwise it returns the desired response string in RFC 821 format. + + """ + raise NotImplementedError + + +class DebuggingServer(SMTPServer): + # Do something with the gathered message + def process_message(self, peer, mailfrom, rcpttos, data): + inheaders = 1 + lines = data.split('\n') + print '---------- MESSAGE FOLLOWS ----------' + for line in lines: + # headers first + if inheaders and not line: + print 'X-Peer:', peer[0] + inheaders = 0 + print line + print '------------ END MESSAGE ------------' + + +class PureProxy(SMTPServer): + def process_message(self, peer, mailfrom, rcpttos, data): + lines = data.split('\n') + # Look for the last header + i = 0 + for line in lines: + if not line: + break + i += 1 + lines.insert(i, 'X-Peer: %s' % peer[0]) + data = NEWLINE.join(lines) + refused = self._deliver(mailfrom, rcpttos, data) + # TBD: what to do with refused addresses? + print >> DEBUGSTREAM, 'we got some refusals:', refused + + def _deliver(self, mailfrom, rcpttos, data): + import smtplib + refused = {} + try: + s = smtplib.SMTP() + s.connect(self._remoteaddr[0], self._remoteaddr[1]) + try: + refused = s.sendmail(mailfrom, rcpttos, data) + finally: + s.quit() + except smtplib.SMTPRecipientsRefused, e: + print >> DEBUGSTREAM, 'got SMTPRecipientsRefused' + refused = e.recipients + except (socket.error, smtplib.SMTPException), e: + print >> DEBUGSTREAM, 'got', e.__class__ + # All recipients were refused. If the exception had an associated + # error code, use it. Otherwise,fake it with a non-triggering + # exception code. + errcode = getattr(e, 'smtp_code', -1) + errmsg = getattr(e, 'smtp_error', 'ignore') + for r in rcpttos: + refused[r] = (errcode, errmsg) + return refused + + +class MailmanProxy(PureProxy): + def process_message(self, peer, mailfrom, rcpttos, data): + from cStringIO import StringIO + from Mailman import Utils + from Mailman import Message + from Mailman import MailList + # If the message is to a Mailman mailing list, then we'll invoke the + # Mailman script directly, without going through the real smtpd. + # Otherwise we'll forward it to the local proxy for disposition. + listnames = [] + for rcpt in rcpttos: + local = rcpt.lower().split('@')[0] + # We allow the following variations on the theme + # listname + # listname-admin + # listname-owner + # listname-request + # listname-join + # listname-leave + parts = local.split('-') + if len(parts) > 2: + continue + listname = parts[0] + if len(parts) == 2: + command = parts[1] + else: + command = '' + if not Utils.list_exists(listname) or command not in ( + '', 'admin', 'owner', 'request', 'join', 'leave'): + continue + listnames.append((rcpt, listname, command)) + # Remove all list recipients from rcpttos and forward what we're not + # going to take care of ourselves. Linear removal should be fine + # since we don't expect a large number of recipients. + for rcpt, listname, command in listnames: + rcpttos.remove(rcpt) + # If there's any non-list destined recipients left, + print >> DEBUGSTREAM, 'forwarding recips:', ' '.join(rcpttos) + if rcpttos: + refused = self._deliver(mailfrom, rcpttos, data) + # TBD: what to do with refused addresses? + print >> DEBUGSTREAM, 'we got refusals:', refused + # Now deliver directly to the list commands + mlists = {} + s = StringIO(data) + msg = Message.Message(s) + # These headers are required for the proper execution of Mailman. All + # MTAs in existence seem to add these if the original message doesn't + # have them. + if not msg.getheader('from'): + msg['From'] = mailfrom + if not msg.getheader('date'): + msg['Date'] = time.ctime(time.time()) + for rcpt, listname, command in listnames: + print >> DEBUGSTREAM, 'sending message to', rcpt + mlist = mlists.get(listname) + if not mlist: + mlist = MailList.MailList(listname, lock=0) + mlists[listname] = mlist + # dispatch on the type of command + if command == '': + # post + msg.Enqueue(mlist, tolist=1) + elif command == 'admin': + msg.Enqueue(mlist, toadmin=1) + elif command == 'owner': + msg.Enqueue(mlist, toowner=1) + elif command == 'request': + msg.Enqueue(mlist, torequest=1) + elif command in ('join', 'leave'): + # TBD: this is a hack! + if command == 'join': + msg['Subject'] = 'subscribe' + else: + msg['Subject'] = 'unsubscribe' + msg.Enqueue(mlist, torequest=1) + + +class Options: + setuid = 1 + classname = 'PureProxy' + + +def parseargs(): + global DEBUGSTREAM + try: + opts, args = getopt.getopt( + sys.argv[1:], 'nVhc:d', + ['class=', 'nosetuid', 'version', 'help', 'debug']) + except getopt.error, e: + usage(1, e) + + options = Options() + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-V', '--version'): + print >> sys.stderr, __version__ + sys.exit(0) + elif opt in ('-n', '--nosetuid'): + options.setuid = 0 + elif opt in ('-c', '--class'): + options.classname = arg + elif opt in ('-d', '--debug'): + DEBUGSTREAM = sys.stderr + + # parse the rest of the arguments + if len(args) < 1: + localspec = 'localhost:8025' + remotespec = 'localhost:25' + elif len(args) < 2: + localspec = args[0] + remotespec = 'localhost:25' + elif len(args) < 3: + localspec = args[0] + remotespec = args[1] + else: + usage(1, 'Invalid arguments: %s' % COMMASPACE.join(args)) + + # split into host/port pairs + i = localspec.find(':') + if i < 0: + usage(1, 'Bad local spec: %s' % localspec) + options.localhost = localspec[:i] + try: + options.localport = int(localspec[i+1:]) + except ValueError: + usage(1, 'Bad local port: %s' % localspec) + i = remotespec.find(':') + if i < 0: + usage(1, 'Bad remote spec: %s' % remotespec) + options.remotehost = remotespec[:i] + try: + options.remoteport = int(remotespec[i+1:]) + except ValueError: + usage(1, 'Bad remote port: %s' % remotespec) + return options + + +if __name__ == '__main__': + options = parseargs() + # Become nobody + classname = options.classname + if "." in classname: + lastdot = classname.rfind(".") + mod = __import__(classname[:lastdot], globals(), locals(), [""]) + classname = classname[lastdot+1:] + else: + import __main__ as mod + class_ = getattr(mod, classname) + proxy = class_((options.localhost, options.localport), + (options.remotehost, options.remoteport)) + if options.setuid: + try: + import pwd + except ImportError: + print >> sys.stderr, \ + 'Cannot import module "pwd"; try running with -n option.' + sys.exit(1) + nobody = pwd.getpwnam('nobody')[2] + try: + os.setuid(nobody) + except OSError, e: + if e.errno != errno.EPERM: raise + print >> sys.stderr, \ + 'Cannot setuid "nobody"; try running with -n option.' + sys.exit(1) + try: + asyncore.loop() + except KeyboardInterrupt: + pass diff --git a/src/main/resources/PythonLibs/smtplib.py b/src/main/resources/PythonLibs/smtplib.py new file mode 100644 index 0000000000000000000000000000000000000000..099e54a4fa1e3ccbd43a235a502e4fef7f5b2683 --- /dev/null +++ b/src/main/resources/PythonLibs/smtplib.py @@ -0,0 +1,857 @@ +#! /usr/bin/env python + +'''SMTP/ESMTP client class. + +This should follow RFC 821 (SMTP), RFC 1869 (ESMTP), RFC 2554 (SMTP +Authentication) and RFC 2487 (Secure SMTP over TLS). + +Notes: + +Please remember, when doing ESMTP, that the names of the SMTP service +extensions are NOT the same thing as the option keywords for the RCPT +and MAIL commands! + +Example: + + >>> import smtplib + >>> s=smtplib.SMTP("localhost") + >>> print s.help() + This is Sendmail version 8.8.4 + Topics: + HELO EHLO MAIL RCPT DATA + RSET NOOP QUIT HELP VRFY + EXPN VERB ETRN DSN + For more info use "HELP <topic>". + To report bugs in the implementation send email to + sendmail-bugs@sendmail.org. + For local information send email to Postmaster at your site. + End of HELP info + >>> s.putcmd("vrfy","someone@here") + >>> s.getreply() + (250, "Somebody OverHere <somebody@here.my.org>") + >>> s.quit() +''' + +# Author: The Dragon De Monsyne <dragondm@integral.org> +# ESMTP support, test code and doc fixes added by +# Eric S. Raymond <esr@thyrsus.com> +# Better RFC 821 compliance (MAIL and RCPT, and CRLF in data) +# by Carey Evans <c.evans@clear.net.nz>, for picky mail servers. +# RFC 2554 (authentication) support by Gerhard Haering <gerhard@bigfoot.de>. +# +# This was modified from the Python 1.5 library HTTP lib. + +import socket +import re +import email.utils +import base64 +import hmac +from email.base64mime import encode as encode_base64 +from sys import stderr + +__all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException", + "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError", + "SMTPConnectError", "SMTPHeloError", "SMTPAuthenticationError", + "quoteaddr", "quotedata", "SMTP"] + +SMTP_PORT = 25 +SMTP_SSL_PORT = 465 +CRLF = "\r\n" + +OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I) + + +# Exception classes used by this module. +class SMTPException(Exception): + """Base class for all exceptions raised by this module.""" + +class SMTPServerDisconnected(SMTPException): + """Not connected to any SMTP server. + + This exception is raised when the server unexpectedly disconnects, + or when an attempt is made to use the SMTP instance before + connecting it to a server. + """ + +class SMTPResponseException(SMTPException): + """Base class for all exceptions that include an SMTP error code. + + These exceptions are generated in some instances when the SMTP + server returns an error code. The error code is stored in the + `smtp_code' attribute of the error, and the `smtp_error' attribute + is set to the error message. + """ + + def __init__(self, code, msg): + self.smtp_code = code + self.smtp_error = msg + self.args = (code, msg) + +class SMTPSenderRefused(SMTPResponseException): + """Sender address refused. + + In addition to the attributes set by on all SMTPResponseException + exceptions, this sets `sender' to the string that the SMTP refused. + """ + + def __init__(self, code, msg, sender): + self.smtp_code = code + self.smtp_error = msg + self.sender = sender + self.args = (code, msg, sender) + +class SMTPRecipientsRefused(SMTPException): + """All recipient addresses refused. + + The errors for each recipient are accessible through the attribute + 'recipients', which is a dictionary of exactly the same sort as + SMTP.sendmail() returns. + """ + + def __init__(self, recipients): + self.recipients = recipients + self.args = (recipients,) + + +class SMTPDataError(SMTPResponseException): + """The SMTP server didn't accept the data.""" + +class SMTPConnectError(SMTPResponseException): + """Error during connection establishment.""" + +class SMTPHeloError(SMTPResponseException): + """The server refused our HELO reply.""" + +class SMTPAuthenticationError(SMTPResponseException): + """Authentication error. + + Most probably the server didn't accept the username/password + combination provided. + """ + + +def quoteaddr(addr): + """Quote a subset of the email addresses defined by RFC 821. + + Should be able to handle anything rfc822.parseaddr can handle. + """ + m = (None, None) + try: + m = email.utils.parseaddr(addr)[1] + except AttributeError: + pass + if m == (None, None): # Indicates parse failure or AttributeError + # something weird here.. punt -ddm + return "<%s>" % addr + elif m is None: + # the sender wants an empty return address + return "<>" + else: + return "<%s>" % m + +def _addr_only(addrstring): + displayname, addr = email.utils.parseaddr(addrstring) + if (displayname, addr) == ('', ''): + # parseaddr couldn't parse it, so use it as is. + return addrstring + return addr + +def quotedata(data): + """Quote data for email. + + Double leading '.', and change Unix newline '\\n', or Mac '\\r' into + Internet CRLF end-of-line. + """ + return re.sub(r'(?m)^\.', '..', + re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)) + + +try: + import ssl +except ImportError: + _have_ssl = False +else: + class SSLFakeFile: + """A fake file like object that really wraps a SSLObject. + + It only supports what is needed in smtplib. + """ + def __init__(self, sslobj): + self.sslobj = sslobj + + def readline(self): + str = "" + chr = None + while chr != "\n": + chr = self.sslobj.read(1) + if not chr: + break + str += chr + return str + + def close(self): + pass + + _have_ssl = True + +class SMTP: + """This class manages a connection to an SMTP or ESMTP server. + SMTP Objects: + SMTP objects have the following attributes: + helo_resp + This is the message given by the server in response to the + most recent HELO command. + + ehlo_resp + This is the message given by the server in response to the + most recent EHLO command. This is usually multiline. + + does_esmtp + This is a True value _after you do an EHLO command_, if the + server supports ESMTP. + + esmtp_features + This is a dictionary, which, if the server supports ESMTP, + will _after you do an EHLO command_, contain the names of the + SMTP service extensions this server supports, and their + parameters (if any). + + Note, all extension names are mapped to lower case in the + dictionary. + + See each method's docstrings for details. In general, there is a + method of the same name to perform each SMTP command. There is also a + method called 'sendmail' that will do an entire mail transaction. + """ + debuglevel = 0 + file = None + helo_resp = None + ehlo_msg = "ehlo" + ehlo_resp = None + does_esmtp = 0 + default_port = SMTP_PORT + + def __init__(self, host='', port=0, local_hostname=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + """Initialize a new instance. + + If specified, `host' is the name of the remote host to which to + connect. If specified, `port' specifies the port to which to connect. + By default, smtplib.SMTP_PORT is used. An SMTPConnectError is raised + if the specified `host' doesn't respond correctly. If specified, + `local_hostname` is used as the FQDN of the local host. By default, + the local hostname is found using socket.getfqdn(). + + """ + self.timeout = timeout + self.esmtp_features = {} + if host: + (code, msg) = self.connect(host, port) + if code != 220: + raise SMTPConnectError(code, msg) + if local_hostname is not None: + self.local_hostname = local_hostname + else: + # RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and + # if that can't be calculated, that we should use a domain literal + # instead (essentially an encoded IP address like [A.B.C.D]). + fqdn = socket.getfqdn() + if '.' in fqdn: + self.local_hostname = fqdn + else: + # We can't find an fqdn hostname, so use a domain literal + addr = '127.0.0.1' + try: + addr = socket.gethostbyname(socket.gethostname()) + except socket.gaierror: + pass + self.local_hostname = '[%s]' % addr + + def set_debuglevel(self, debuglevel): + """Set the debug output level. + + A non-false value results in debug messages for connection and for all + messages sent to and received from the server. + + """ + self.debuglevel = debuglevel + + def _get_socket(self, port, host, timeout): + # This makes it simpler for SMTP_SSL to use the SMTP connect code + # and just alter the socket connection bit. + if self.debuglevel > 0: + print>>stderr, 'connect:', (host, port) + return socket.create_connection((port, host), timeout) + + def connect(self, host='localhost', port=0): + """Connect to a host on a given port. + + If the hostname ends with a colon (`:') followed by a number, and + there is no port specified, that suffix will be stripped off and the + number interpreted as the port number to use. + + Note: This method is automatically invoked by __init__, if a host is + specified during instantiation. + + """ + if not port and (host.find(':') == host.rfind(':')): + i = host.rfind(':') + if i >= 0: + host, port = host[:i], host[i + 1:] + try: + port = int(port) + except ValueError: + raise socket.error, "nonnumeric port" + if not port: + port = self.default_port + if self.debuglevel > 0: + print>>stderr, 'connect:', (host, port) + self.sock = self._get_socket(host, port, self.timeout) + (code, msg) = self.getreply() + if self.debuglevel > 0: + print>>stderr, "connect:", msg + return (code, msg) + + def send(self, str): + """Send `str' to the server.""" + if self.debuglevel > 0: + print>>stderr, 'send:', repr(str) + if hasattr(self, 'sock') and self.sock: + try: + self.sock.sendall(str) + except socket.error: + self.close() + raise SMTPServerDisconnected('Server not connected') + else: + raise SMTPServerDisconnected('please run connect() first') + + def putcmd(self, cmd, args=""): + """Send a command to the server.""" + if args == "": + str = '%s%s' % (cmd, CRLF) + else: + str = '%s %s%s' % (cmd, args, CRLF) + self.send(str) + + def getreply(self): + """Get a reply from the server. + + Returns a tuple consisting of: + + - server response code (e.g. '250', or such, if all goes well) + Note: returns -1 if it can't read response code. + + - server response string corresponding to response code (multiline + responses are converted to a single, multiline string). + + Raises SMTPServerDisconnected if end-of-file is reached. + """ + resp = [] + if self.file is None: + self.file = self.sock.makefile('rb') + while 1: + try: + line = self.file.readline() + except socket.error as e: + self.close() + raise SMTPServerDisconnected("Connection unexpectedly closed: " + + str(e)) + if line == '': + self.close() + raise SMTPServerDisconnected("Connection unexpectedly closed") + if self.debuglevel > 0: + print>>stderr, 'reply:', repr(line) + resp.append(line[4:].strip()) + code = line[:3] + # Check that the error code is syntactically correct. + # Don't attempt to read a continuation line if it is broken. + try: + errcode = int(code) + except ValueError: + errcode = -1 + break + # Check if multiline response. + if line[3:4] != "-": + break + + errmsg = "\n".join(resp) + if self.debuglevel > 0: + print>>stderr, 'reply: retcode (%s); Msg: %s' % (errcode, errmsg) + return errcode, errmsg + + def docmd(self, cmd, args=""): + """Send a command, and return its response code.""" + self.putcmd(cmd, args) + return self.getreply() + + # std smtp commands + def helo(self, name=''): + """SMTP 'helo' command. + Hostname to send for this command defaults to the FQDN of the local + host. + """ + self.putcmd("helo", name or self.local_hostname) + (code, msg) = self.getreply() + self.helo_resp = msg + return (code, msg) + + def ehlo(self, name=''): + """ SMTP 'ehlo' command. + Hostname to send for this command defaults to the FQDN of the local + host. + """ + self.esmtp_features = {} + self.putcmd(self.ehlo_msg, name or self.local_hostname) + (code, msg) = self.getreply() + # According to RFC1869 some (badly written) + # MTA's will disconnect on an ehlo. Toss an exception if + # that happens -ddm + if code == -1 and len(msg) == 0: + self.close() + raise SMTPServerDisconnected("Server not connected") + self.ehlo_resp = msg + if code != 250: + return (code, msg) + self.does_esmtp = 1 + #parse the ehlo response -ddm + resp = self.ehlo_resp.split('\n') + del resp[0] + for each in resp: + # To be able to communicate with as many SMTP servers as possible, + # we have to take the old-style auth advertisement into account, + # because: + # 1) Else our SMTP feature parser gets confused. + # 2) There are some servers that only advertise the auth methods we + # support using the old style. + auth_match = OLDSTYLE_AUTH.match(each) + if auth_match: + # This doesn't remove duplicates, but that's no problem + self.esmtp_features["auth"] = self.esmtp_features.get("auth", "") \ + + " " + auth_match.groups(0)[0] + continue + + # RFC 1869 requires a space between ehlo keyword and parameters. + # It's actually stricter, in that only spaces are allowed between + # parameters, but were not going to check for that here. Note + # that the space isn't present if there are no parameters. + m = re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*) ?', each) + if m: + feature = m.group("feature").lower() + params = m.string[m.end("feature"):].strip() + if feature == "auth": + self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \ + + " " + params + else: + self.esmtp_features[feature] = params + return (code, msg) + + def has_extn(self, opt): + """Does the server support a given SMTP service extension?""" + return opt.lower() in self.esmtp_features + + def help(self, args=''): + """SMTP 'help' command. + Returns help text from server.""" + self.putcmd("help", args) + return self.getreply()[1] + + def rset(self): + """SMTP 'rset' command -- resets session.""" + return self.docmd("rset") + + def noop(self): + """SMTP 'noop' command -- doesn't do anything :>""" + return self.docmd("noop") + + def mail(self, sender, options=[]): + """SMTP 'mail' command -- begins mail xfer session.""" + optionlist = '' + if options and self.does_esmtp: + optionlist = ' ' + ' '.join(options) + self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist)) + return self.getreply() + + def rcpt(self, recip, options=[]): + """SMTP 'rcpt' command -- indicates 1 recipient for this mail.""" + optionlist = '' + if options and self.does_esmtp: + optionlist = ' ' + ' '.join(options) + self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist)) + return self.getreply() + + def data(self, msg): + """SMTP 'DATA' command -- sends message data to server. + + Automatically quotes lines beginning with a period per rfc821. + Raises SMTPDataError if there is an unexpected reply to the + DATA command; the return value from this method is the final + response code received when the all data is sent. + """ + self.putcmd("data") + (code, repl) = self.getreply() + if self.debuglevel > 0: + print>>stderr, "data:", (code, repl) + if code != 354: + raise SMTPDataError(code, repl) + else: + q = quotedata(msg) + if q[-2:] != CRLF: + q = q + CRLF + q = q + "." + CRLF + self.send(q) + (code, msg) = self.getreply() + if self.debuglevel > 0: + print>>stderr, "data:", (code, msg) + return (code, msg) + + def verify(self, address): + """SMTP 'verify' command -- checks for address validity.""" + self.putcmd("vrfy", _addr_only(address)) + return self.getreply() + # a.k.a. + vrfy = verify + + def expn(self, address): + """SMTP 'expn' command -- expands a mailing list.""" + self.putcmd("expn", _addr_only(address)) + return self.getreply() + + # some useful methods + + def ehlo_or_helo_if_needed(self): + """Call self.ehlo() and/or self.helo() if needed. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + """ + if self.helo_resp is None and self.ehlo_resp is None: + if not (200 <= self.ehlo()[0] <= 299): + (code, resp) = self.helo() + if not (200 <= code <= 299): + raise SMTPHeloError(code, resp) + + def login(self, user, password): + """Log in on an SMTP server that requires authentication. + + The arguments are: + - user: The user name to authenticate with. + - password: The password for the authentication. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + + This method will return normally if the authentication was successful. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + SMTPAuthenticationError The server didn't accept the username/ + password combination. + SMTPException No suitable authentication method was + found. + """ + + def encode_cram_md5(challenge, user, password): + challenge = base64.decodestring(challenge) + response = user + " " + hmac.HMAC(password, challenge).hexdigest() + return encode_base64(response, eol="") + + def encode_plain(user, password): + return encode_base64("\0%s\0%s" % (user, password), eol="") + + + AUTH_PLAIN = "PLAIN" + AUTH_CRAM_MD5 = "CRAM-MD5" + AUTH_LOGIN = "LOGIN" + + self.ehlo_or_helo_if_needed() + + if not self.has_extn("auth"): + raise SMTPException("SMTP AUTH extension not supported by server.") + + # Authentication methods the server supports: + authlist = self.esmtp_features["auth"].split() + + # List of authentication methods we support: from preferred to + # less preferred methods. Except for the purpose of testing the weaker + # ones, we prefer stronger methods like CRAM-MD5: + preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN] + + # Determine the authentication method we'll use + authmethod = None + for method in preferred_auths: + if method in authlist: + authmethod = method + break + + if authmethod == AUTH_CRAM_MD5: + (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5) + if code == 503: + # 503 == 'Error: already authenticated' + return (code, resp) + (code, resp) = self.docmd(encode_cram_md5(resp, user, password)) + elif authmethod == AUTH_PLAIN: + (code, resp) = self.docmd("AUTH", + AUTH_PLAIN + " " + encode_plain(user, password)) + elif authmethod == AUTH_LOGIN: + (code, resp) = self.docmd("AUTH", + "%s %s" % (AUTH_LOGIN, encode_base64(user, eol=""))) + if code != 334: + raise SMTPAuthenticationError(code, resp) + (code, resp) = self.docmd(encode_base64(password, eol="")) + elif authmethod is None: + raise SMTPException("No suitable authentication method found.") + if code not in (235, 503): + # 235 == 'Authentication successful' + # 503 == 'Error: already authenticated' + raise SMTPAuthenticationError(code, resp) + return (code, resp) + + def starttls(self, keyfile=None, certfile=None): + """Puts the connection to the SMTP server into TLS mode. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. + + If the server supports TLS, this will encrypt the rest of the SMTP + session. If you provide the keyfile and certfile parameters, + the identity of the SMTP server and client can be checked. This, + however, depends on whether the socket module really checks the + certificates. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + """ + self.ehlo_or_helo_if_needed() + if not self.has_extn("starttls"): + raise SMTPException("STARTTLS extension not supported by server.") + (resp, reply) = self.docmd("STARTTLS") + if resp == 220: + if not _have_ssl: + raise RuntimeError("No SSL support included in this Python") + self.sock = ssl.wrap_socket(self.sock, keyfile, certfile) + self.file = SSLFakeFile(self.sock) + # RFC 3207: + # The client MUST discard any knowledge obtained from + # the server, such as the list of SMTP service extensions, + # which was not obtained from the TLS negotiation itself. + self.helo_resp = None + self.ehlo_resp = None + self.esmtp_features = {} + self.does_esmtp = 0 + return (resp, reply) + + def sendmail(self, from_addr, to_addrs, msg, mail_options=[], + rcpt_options=[]): + """This command performs an entire mail transaction. + + The arguments are: + - from_addr : The address sending this mail. + - to_addrs : A list of addresses to send this mail to. A bare + string will be treated as a list with 1 address. + - msg : The message to send. + - mail_options : List of ESMTP options (such as 8bitmime) for the + mail command. + - rcpt_options : List of ESMTP options (such as DSN commands) for + all the rcpt commands. + + If there has been no previous EHLO or HELO command this session, this + method tries ESMTP EHLO first. If the server does ESMTP, message size + and each of the specified options will be passed to it. If EHLO + fails, HELO will be tried and ESMTP options suppressed. + + This method will return normally if the mail is accepted for at least + one recipient. It returns a dictionary, with one entry for each + recipient that was refused. Each entry contains a tuple of the SMTP + error code and the accompanying error message sent by the server. + + This method may raise the following exceptions: + + SMTPHeloError The server didn't reply properly to + the helo greeting. + SMTPRecipientsRefused The server rejected ALL recipients + (no mail was sent). + SMTPSenderRefused The server didn't accept the from_addr. + SMTPDataError The server replied with an unexpected + error code (other than a refusal of + a recipient). + + Note: the connection will be open even after an exception is raised. + + Example: + + >>> import smtplib + >>> s=smtplib.SMTP("localhost") + >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"] + >>> msg = '''\\ + ... From: Me@my.org + ... Subject: testin'... + ... + ... This is a test ''' + >>> s.sendmail("me@my.org",tolist,msg) + { "three@three.org" : ( 550 ,"User unknown" ) } + >>> s.quit() + + In the above example, the message was accepted for delivery to three + of the four addresses, and one was rejected, with the error code + 550. If all addresses are accepted, then the method will return an + empty dictionary. + + """ + self.ehlo_or_helo_if_needed() + esmtp_opts = [] + if self.does_esmtp: + # Hmmm? what's this? -ddm + # self.esmtp_features['7bit']="" + if self.has_extn('size'): + esmtp_opts.append("size=%d" % len(msg)) + for option in mail_options: + esmtp_opts.append(option) + + (code, resp) = self.mail(from_addr, esmtp_opts) + if code != 250: + self.rset() + raise SMTPSenderRefused(code, resp, from_addr) + senderrs = {} + if isinstance(to_addrs, basestring): + to_addrs = [to_addrs] + for each in to_addrs: + (code, resp) = self.rcpt(each, rcpt_options) + if (code != 250) and (code != 251): + senderrs[each] = (code, resp) + if len(senderrs) == len(to_addrs): + # the server refused all our recipients + self.rset() + raise SMTPRecipientsRefused(senderrs) + (code, resp) = self.data(msg) + if code != 250: + self.rset() + raise SMTPDataError(code, resp) + #if we got here then somebody got our mail + return senderrs + + + def close(self): + """Close the connection to the SMTP server.""" + if self.file: + self.file.close() + self.file = None + if self.sock: + self.sock.close() + self.sock = None + + + def quit(self): + """Terminate the SMTP session.""" + res = self.docmd("quit") + self.close() + return res + +if _have_ssl: + + class SMTP_SSL(SMTP): + """ This is a subclass derived from SMTP that connects over an SSL encrypted + socket (to use this class you need a socket module that was compiled with SSL + support). If host is not specified, '' (the local host) is used. If port is + omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile + are also optional - they can contain a PEM formatted private key and + certificate chain file for the SSL connection. + """ + + default_port = SMTP_SSL_PORT + + def __init__(self, host='', port=0, local_hostname=None, + keyfile=None, certfile=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + self.keyfile = keyfile + self.certfile = certfile + SMTP.__init__(self, host, port, local_hostname, timeout) + + def _get_socket(self, host, port, timeout): + if self.debuglevel > 0: + print>>stderr, 'connect:', (host, port) + new_socket = socket.create_connection((host, port), timeout) + new_socket = ssl.wrap_socket(new_socket, self.keyfile, self.certfile) + self.file = SSLFakeFile(new_socket) + return new_socket + + __all__.append("SMTP_SSL") + +# +# LMTP extension +# +LMTP_PORT = 2003 + +class LMTP(SMTP): + """LMTP - Local Mail Transfer Protocol + + The LMTP protocol, which is very similar to ESMTP, is heavily based + on the standard SMTP client. It's common to use Unix sockets for LMTP, + so our connect() method must support that as well as a regular + host:port server. To specify a Unix socket, you must use an absolute + path as the host, starting with a '/'. + + Authentication is supported, using the regular SMTP mechanism. When + using a Unix socket, LMTP generally don't support or require any + authentication, but your mileage might vary.""" + + ehlo_msg = "lhlo" + + def __init__(self, host='', port=LMTP_PORT, local_hostname=None): + """Initialize a new instance.""" + SMTP.__init__(self, host, port, local_hostname) + + def connect(self, host='localhost', port=0): + """Connect to the LMTP daemon, on either a Unix or a TCP socket.""" + if host[0] != '/': + return SMTP.connect(self, host, port) + + # Handle Unix-domain sockets. + try: + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.sock.connect(host) + except socket.error: + if self.debuglevel > 0: + print>>stderr, 'connect fail:', host + if self.sock: + self.sock.close() + self.sock = None + raise + (code, msg) = self.getreply() + if self.debuglevel > 0: + print>>stderr, "connect:", msg + return (code, msg) + + +# Test the sendmail method, which tests most of the others. +# Note: This always sends to localhost. +if __name__ == '__main__': + import sys + + def prompt(prompt): + sys.stdout.write(prompt + ": ") + return sys.stdin.readline().strip() + + fromaddr = prompt("From") + toaddrs = prompt("To").split(',') + print "Enter message, end with ^D:" + msg = '' + while 1: + line = sys.stdin.readline() + if not line: + break + msg = msg + line + print "Message length is %d" % len(msg) + + server = SMTP('localhost') + server.set_debuglevel(1) + server.sendmail(fromaddr, toaddrs, msg) + server.quit() diff --git a/src/main/resources/PythonLibs/sndhdr.py b/src/main/resources/PythonLibs/sndhdr.py new file mode 100644 index 0000000000000000000000000000000000000000..cc2d6b8b197b704782be0c35abecb262ae5c69ae --- /dev/null +++ b/src/main/resources/PythonLibs/sndhdr.py @@ -0,0 +1,228 @@ +"""Routines to help recognizing sound files. + +Function whathdr() recognizes various types of sound file headers. +It understands almost all headers that SOX can decode. + +The return tuple contains the following items, in this order: +- file type (as SOX understands it) +- sampling rate (0 if unknown or hard to decode) +- number of channels (0 if unknown or hard to decode) +- number of frames in the file (-1 if unknown or hard to decode) +- number of bits/sample, or 'U' for U-LAW, or 'A' for A-LAW + +If the file doesn't have a recognizable type, it returns None. +If the file can't be opened, IOError is raised. + +To compute the total time, divide the number of frames by the +sampling rate (a frame contains a sample for each channel). + +Function what() calls whathdr(). (It used to also use some +heuristics for raw data, but this doesn't work very well.) + +Finally, the function test() is a simple main program that calls +what() for all files mentioned on the argument list. For directory +arguments it calls what() for all files in that directory. Default +argument is "." (testing all files in the current directory). The +option -r tells it to recurse down directories found inside +explicitly given directories. +""" + +# The file structure is top-down except that the test program and its +# subroutine come last. + +__all__ = ["what","whathdr"] + +def what(filename): + """Guess the type of a sound file""" + res = whathdr(filename) + return res + + +def whathdr(filename): + """Recognize sound headers""" + f = open(filename, 'rb') + h = f.read(512) + for tf in tests: + res = tf(h, f) + if res: + return res + return None + + +#-----------------------------------# +# Subroutines per sound header type # +#-----------------------------------# + +tests = [] + +def test_aifc(h, f): + import aifc + if h[:4] != 'FORM': + return None + if h[8:12] == 'AIFC': + fmt = 'aifc' + elif h[8:12] == 'AIFF': + fmt = 'aiff' + else: + return None + f.seek(0) + try: + a = aifc.openfp(f, 'r') + except (EOFError, aifc.Error): + return None + return (fmt, a.getframerate(), a.getnchannels(), \ + a.getnframes(), 8*a.getsampwidth()) + +tests.append(test_aifc) + + +def test_au(h, f): + if h[:4] == '.snd': + f = get_long_be + elif h[:4] in ('\0ds.', 'dns.'): + f = get_long_le + else: + return None + type = 'au' + hdr_size = f(h[4:8]) + data_size = f(h[8:12]) + encoding = f(h[12:16]) + rate = f(h[16:20]) + nchannels = f(h[20:24]) + sample_size = 1 # default + if encoding == 1: + sample_bits = 'U' + elif encoding == 2: + sample_bits = 8 + elif encoding == 3: + sample_bits = 16 + sample_size = 2 + else: + sample_bits = '?' + frame_size = sample_size * nchannels + return type, rate, nchannels, data_size//frame_size, sample_bits + +tests.append(test_au) + + +def test_hcom(h, f): + if h[65:69] != 'FSSD' or h[128:132] != 'HCOM': + return None + divisor = get_long_be(h[128+16:128+20]) + return 'hcom', 22050//divisor, 1, -1, 8 + +tests.append(test_hcom) + + +def test_voc(h, f): + if h[:20] != 'Creative Voice File\032': + return None + sbseek = get_short_le(h[20:22]) + rate = 0 + if 0 <= sbseek < 500 and h[sbseek] == '\1': + ratecode = ord(h[sbseek+4]) + rate = int(1000000.0 / (256 - ratecode)) + return 'voc', rate, 1, -1, 8 + +tests.append(test_voc) + + +def test_wav(h, f): + # 'RIFF' <len> 'WAVE' 'fmt ' <len> + if h[:4] != 'RIFF' or h[8:12] != 'WAVE' or h[12:16] != 'fmt ': + return None + style = get_short_le(h[20:22]) + nchannels = get_short_le(h[22:24]) + rate = get_long_le(h[24:28]) + sample_bits = get_short_le(h[34:36]) + return 'wav', rate, nchannels, -1, sample_bits + +tests.append(test_wav) + + +def test_8svx(h, f): + if h[:4] != 'FORM' or h[8:12] != '8SVX': + return None + # Should decode it to get #channels -- assume always 1 + return '8svx', 0, 1, 0, 8 + +tests.append(test_8svx) + + +def test_sndt(h, f): + if h[:5] == 'SOUND': + nsamples = get_long_le(h[8:12]) + rate = get_short_le(h[20:22]) + return 'sndt', rate, 1, nsamples, 8 + +tests.append(test_sndt) + + +def test_sndr(h, f): + if h[:2] == '\0\0': + rate = get_short_le(h[2:4]) + if 4000 <= rate <= 25000: + return 'sndr', rate, 1, -1, 8 + +tests.append(test_sndr) + + +#---------------------------------------------# +# Subroutines to extract numbers from strings # +#---------------------------------------------# + +def get_long_be(s): + return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) + +def get_long_le(s): + return (ord(s[3])<<24) | (ord(s[2])<<16) | (ord(s[1])<<8) | ord(s[0]) + +def get_short_be(s): + return (ord(s[0])<<8) | ord(s[1]) + +def get_short_le(s): + return (ord(s[1])<<8) | ord(s[0]) + + +#--------------------# +# Small test program # +#--------------------# + +def test(): + import sys + recursive = 0 + if sys.argv[1:] and sys.argv[1] == '-r': + del sys.argv[1:2] + recursive = 1 + try: + if sys.argv[1:]: + testall(sys.argv[1:], recursive, 1) + else: + testall(['.'], recursive, 1) + except KeyboardInterrupt: + sys.stderr.write('\n[Interrupted]\n') + sys.exit(1) + +def testall(list, recursive, toplevel): + import sys + import os + for filename in list: + if os.path.isdir(filename): + print filename + '/:', + if recursive or toplevel: + print 'recursing down:' + import glob + names = glob.glob(os.path.join(filename, '*')) + testall(names, recursive, 0) + else: + print '*** directory (use -r) ***' + else: + print filename + ':', + sys.stdout.flush() + try: + print what(filename) + except IOError: + print '*** not found ***' + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/socket.py b/src/main/resources/PythonLibs/socket.py new file mode 100644 index 0000000000000000000000000000000000000000..25c779a3555f61a15b6f92fdcbde7d019315e96a --- /dev/null +++ b/src/main/resources/PythonLibs/socket.py @@ -0,0 +1,1889 @@ +""" +This is an updated socket module for use on JVMs >= 1.5; it is derived from the old jython socket module. +It is documented, along with known issues and workarounds, on the jython wiki. +http://wiki.python.org/jython/NewSocketModule +""" + +_defaulttimeout = None + +import errno +import jarray +import string +import struct +import sys +import threading +import time +import types + +# Java.io classes +import java.io.BufferedInputStream +import java.io.BufferedOutputStream +# Java.io exceptions +import java.io.InterruptedIOException +import java.io.IOException + +# Java.lang classes +import java.lang.String +# Java.lang exceptions +import java.lang.Exception + +# Java.net classes +import java.net.DatagramPacket +import java.net.InetAddress +import java.net.InetSocketAddress +import java.net.Socket +# Java.net exceptions +import java.net.BindException +import java.net.ConnectException +import java.net.NoRouteToHostException +import java.net.PortUnreachableException +import java.net.ProtocolException +import java.net.SocketException +import java.net.SocketTimeoutException +import java.net.UnknownHostException + +# Java.nio classes +import java.nio.ByteBuffer +import java.nio.channels.DatagramChannel +import java.nio.channels.ServerSocketChannel +import java.nio.channels.SocketChannel +# Java.nio exceptions +import java.nio.channels.AlreadyConnectedException +import java.nio.channels.AsynchronousCloseException +import java.nio.channels.CancelledKeyException +import java.nio.channels.ClosedByInterruptException +import java.nio.channels.ClosedChannelException +import java.nio.channels.ClosedSelectorException +import java.nio.channels.ConnectionPendingException +import java.nio.channels.IllegalBlockingModeException +import java.nio.channels.IllegalSelectorException +import java.nio.channels.NoConnectionPendingException +import java.nio.channels.NonReadableChannelException +import java.nio.channels.NonWritableChannelException +import java.nio.channels.NotYetBoundException +import java.nio.channels.NotYetConnectedException +import java.nio.channels.UnresolvedAddressException +import java.nio.channels.UnsupportedAddressTypeException + +# Javax.net.ssl classes +import javax.net.ssl.SSLSocketFactory +# Javax.net.ssl exceptions +javax.net.ssl.SSLException +javax.net.ssl.SSLHandshakeException +javax.net.ssl.SSLKeyException +javax.net.ssl.SSLPeerUnverifiedException +javax.net.ssl.SSLProtocolException + +import org.python.core.io.DatagramSocketIO +import org.python.core.io.ServerSocketIO +import org.python.core.io.SocketIO +from org.python.core.Py import newString as asPyString + +class error(IOError): pass +class herror(error): pass +class gaierror(error): pass +class timeout(error): pass +class sslerror(error): pass + +def _add_exception_attrs(exc): + setattr(exc, 'errno', exc[0]) + setattr(exc, 'strerror', exc[1]) + return exc + +def _unmapped_exception(exc): + return _add_exception_attrs(error(-1, 'Unmapped exception: %s' % exc)) + +def java_net_socketexception_handler(exc): + if exc.message.startswith("Address family not supported by protocol family"): + return _add_exception_attrs(error(errno.EAFNOSUPPORT, + 'Address family not supported by protocol family: See http://wiki.python.org/jython/NewSocketModule#IPV6_address_support')) + return _unmapped_exception(exc) + +def would_block_error(exc=None): + return _add_exception_attrs(error(errno.EWOULDBLOCK, 'The socket operation could not complete without blocking')) + +ALL = None + +_ssl_message = ": Differences between the SSL socket behaviour of cpython vs. jython are explained on the wiki: http://wiki.python.org/jython/NewSocketModule#SSL_Support" + +_exception_map = { + +# (<javaexception>, <circumstance>) : callable that raises the python equivalent exception, or None to stub out as unmapped + +(java.io.IOException, ALL) : lambda x: error(errno.ECONNRESET, 'Software caused connection abort'), +(java.io.InterruptedIOException, ALL) : lambda x: timeout(None, 'timed out'), + +(java.net.BindException, ALL) : lambda x: error(errno.EADDRINUSE, 'Address already in use'), +(java.net.ConnectException, ALL) : lambda x: error(errno.ECONNREFUSED, 'Connection refused'), +(java.net.NoRouteToHostException, ALL) : lambda x: error(errno.EHOSTUNREACH, 'No route to host'), +(java.net.PortUnreachableException, ALL) : None, +(java.net.ProtocolException, ALL) : None, +(java.net.SocketException, ALL) : java_net_socketexception_handler, +(java.net.SocketTimeoutException, ALL) : lambda x: timeout(None, 'timed out'), +(java.net.UnknownHostException, ALL) : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'), + +(java.nio.channels.AlreadyConnectedException, ALL) : lambda x: error(errno.EISCONN, 'Socket is already connected'), +(java.nio.channels.AsynchronousCloseException, ALL) : None, +(java.nio.channels.CancelledKeyException, ALL) : None, +(java.nio.channels.ClosedByInterruptException, ALL) : None, +(java.nio.channels.ClosedChannelException, ALL) : lambda x: error(errno.EPIPE, 'Socket closed'), +(java.nio.channels.ClosedSelectorException, ALL) : None, +(java.nio.channels.ConnectionPendingException, ALL) : None, +(java.nio.channels.IllegalBlockingModeException, ALL) : None, +(java.nio.channels.IllegalSelectorException, ALL) : None, +(java.nio.channels.NoConnectionPendingException, ALL) : None, +(java.nio.channels.NonReadableChannelException, ALL) : None, +(java.nio.channels.NonWritableChannelException, ALL) : None, +(java.nio.channels.NotYetBoundException, ALL) : None, +(java.nio.channels.NotYetConnectedException, ALL) : None, +(java.nio.channels.UnresolvedAddressException, ALL) : lambda x: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'), +(java.nio.channels.UnsupportedAddressTypeException, ALL) : None, + +# These error codes are currently wrong: getting them correct is going to require +# some investigation. Cpython 2.6 introduced extensive SSL support. + +(javax.net.ssl.SSLException, ALL) : lambda x: sslerror(-1, 'SSL exception'+_ssl_message), +(javax.net.ssl.SSLHandshakeException, ALL) : lambda x: sslerror(-1, 'SSL handshake exception'+_ssl_message), +(javax.net.ssl.SSLKeyException, ALL) : lambda x: sslerror(-1, 'SSL key exception'+_ssl_message), +(javax.net.ssl.SSLPeerUnverifiedException, ALL) : lambda x: sslerror(-1, 'SSL peer unverified exception'+_ssl_message), +(javax.net.ssl.SSLProtocolException, ALL) : lambda x: sslerror(-1, 'SSL protocol exception'+_ssl_message), + +} + +def _map_exception(java_exception, circumstance=ALL): + mapped_exception = _exception_map.get((java_exception.__class__, circumstance)) + if mapped_exception: + py_exception = mapped_exception(java_exception) + else: + py_exception = error(-1, 'Unmapped exception: %s' % java_exception) + setattr(py_exception, 'java_exception', java_exception) + return _add_exception_attrs(py_exception) + +from functools import wraps + +# Used to map java exceptions to the equivalent python exception +# And to set the _last_error attribute on socket objects, to support SO_ERROR +def raises_java_exception(method_or_function): + @wraps(method_or_function) + def handle_exception(*args, **kwargs): + is_socket = (len(args) > 0 and isinstance(args[0], _nonblocking_api_mixin)) + try: + try: + return method_or_function(*args, **kwargs) + except java.lang.Exception, jlx: + raise _map_exception(jlx) + except error, e: + if is_socket: + setattr(args[0], '_last_error', e[0]) + raise + else: + if is_socket: + setattr(args[0], '_last_error', 0) + return handle_exception + +_feature_support_map = { + 'ipv6': True, + 'idna': False, + 'tipc': False, +} + +def supports(feature, *args): + if len(args) == 1: + _feature_support_map[feature] = args[0] + return _feature_support_map.get(feature, False) + +MODE_BLOCKING = 'block' +MODE_NONBLOCKING = 'nonblock' +MODE_TIMEOUT = 'timeout' + +_permitted_modes = (MODE_BLOCKING, MODE_NONBLOCKING, MODE_TIMEOUT) + +SHUT_RD = 0 +SHUT_WR = 1 +SHUT_RDWR = 2 + +AF_UNSPEC = 0 +AF_INET = 2 +AF_INET6 = 23 + +AI_PASSIVE = 1 +AI_CANONNAME = 2 +AI_NUMERICHOST = 4 +AI_V4MAPPED = 8 +AI_ALL = 16 +AI_ADDRCONFIG = 32 +AI_NUMERICSERV = 1024 + +EAI_NONAME = -2 +EAI_SERVICE = -8 +EAI_ADDRFAMILY = -9 + +NI_NUMERICHOST = 1 +NI_NUMERICSERV = 2 +NI_NOFQDN = 4 +NI_NAMEREQD = 8 +NI_DGRAM = 16 +NI_MAXSERV = 32 +NI_IDN = 64 +NI_IDN_ALLOW_UNASSIGNED = 128 +NI_IDN_USE_STD3_ASCII_RULES = 256 +NI_MAXHOST = 1025 + +# For some reason, probably historical, SOCK_DGRAM and SOCK_STREAM are opposite values of what they are on cpython. +# I.E. The following is the way they are on cpython +# SOCK_STREAM = 1 +# SOCK_DGRAM = 2 +# At some point, we should probably switch them around, which *should* not affect anybody + +SOCK_DGRAM = 1 +SOCK_STREAM = 2 +SOCK_RAW = 3 # not supported +SOCK_RDM = 4 # not supported +SOCK_SEQPACKET = 5 # not supported + +SOL_SOCKET = 0xFFFF + +IPPROTO_AH = 51 # not supported +IPPROTO_DSTOPTS = 60 # not supported +IPPROTO_ESP = 50 # not supported +IPPROTO_FRAGMENT = 44 # not supported +IPPROTO_GGP = 3 # not supported +IPPROTO_HOPOPTS = 0 # not supported +IPPROTO_ICMP = 1 # not supported +IPPROTO_ICMPV6 = 58 # not supported +IPPROTO_IDP = 22 # not supported +IPPROTO_IGMP = 2 # not supported +IPPROTO_IP = 0 +IPPROTO_IPV4 = 4 # not supported +IPPROTO_IPV6 = 41 # not supported +IPPROTO_MAX = 256 # not supported +IPPROTO_ND = 77 # not supported +IPPROTO_NONE = 59 # not supported +IPPROTO_PUP = 12 # not supported +IPPROTO_RAW = 255 # not supported +IPPROTO_ROUTING = 43 # not supported +IPPROTO_TCP = 6 +IPPROTO_UDP = 17 + +SO_ACCEPTCONN = 1 +SO_BROADCAST = 2 +SO_ERROR = 4 +SO_KEEPALIVE = 8 +SO_LINGER = 16 +SO_OOBINLINE = 32 +SO_RCVBUF = 64 +SO_REUSEADDR = 128 +SO_SNDBUF = 256 +SO_TIMEOUT = 512 +SO_TYPE = 1024 + +TCP_NODELAY = 2048 + +INADDR_ANY = "0.0.0.0" +INADDR_BROADCAST = "255.255.255.255" + +IN6ADDR_ANY_INIT = "::" + +# Options with negative constants are not supported +# They are being added here so that code that refers to them +# will not break with an AttributeError + +SO_DEBUG = -1 +SO_DONTROUTE = -1 +SO_EXCLUSIVEADDRUSE = -8 +SO_RCVLOWAT = -16 +SO_RCVTIMEO = -32 +SO_REUSEPORT = -64 +SO_SNDLOWAT = -128 +SO_SNDTIMEO = -256 +SO_USELOOPBACK = -512 + +__all__ = [ + # Families + 'AF_UNSPEC', 'AF_INET', 'AF_INET6', + # getaddrinfo and getnameinfo flags + 'AI_PASSIVE', 'AI_CANONNAME', 'AI_NUMERICHOST', 'AI_V4MAPPED', + 'AI_ALL', 'AI_ADDRCONFIG', 'AI_NUMERICSERV', 'EAI_NONAME', + 'EAI_SERVICE', 'EAI_ADDRFAMILY', + 'NI_NUMERICHOST', 'NI_NUMERICSERV', 'NI_NOFQDN', 'NI_NAMEREQD', + 'NI_DGRAM', 'NI_MAXSERV', 'NI_IDN', 'NI_IDN_ALLOW_UNASSIGNED', + 'NI_IDN_USE_STD3_ASCII_RULES', 'NI_MAXHOST', + # socket types + 'SOCK_DGRAM', 'SOCK_STREAM', 'SOCK_RAW', 'SOCK_RDM', 'SOCK_SEQPACKET', + # levels + 'SOL_SOCKET', + # protocols + 'IPPROTO_AH', 'IPPROTO_DSTOPTS', 'IPPROTO_ESP', 'IPPROTO_FRAGMENT', + 'IPPROTO_GGP', 'IPPROTO_HOPOPTS', 'IPPROTO_ICMP', 'IPPROTO_ICMPV6', + 'IPPROTO_IDP', 'IPPROTO_IGMP', 'IPPROTO_IP', 'IPPROTO_IPV4', + 'IPPROTO_IPV6', 'IPPROTO_MAX', 'IPPROTO_ND', 'IPPROTO_NONE', + 'IPPROTO_PUP', 'IPPROTO_RAW', 'IPPROTO_ROUTING', 'IPPROTO_TCP', + 'IPPROTO_UDP', + # Special hostnames + 'INADDR_ANY', 'INADDR_BROADCAST', 'IN6ADDR_ANY_INIT', + # support socket options + 'SO_BROADCAST', 'SO_KEEPALIVE', 'SO_LINGER', 'SO_OOBINLINE', + 'SO_RCVBUF', 'SO_REUSEADDR', 'SO_SNDBUF', 'SO_TIMEOUT', 'TCP_NODELAY', + # unsupported socket options + 'SO_ACCEPTCONN', 'SO_DEBUG', 'SO_DONTROUTE', 'SO_ERROR', + 'SO_EXCLUSIVEADDRUSE', 'SO_RCVLOWAT', 'SO_RCVTIMEO', 'SO_REUSEPORT', + 'SO_SNDLOWAT', 'SO_SNDTIMEO', 'SO_TYPE', 'SO_USELOOPBACK', + # functions + 'getfqdn', 'gethostname', 'gethostbyname', 'gethostbyaddr', + 'getservbyname', 'getservbyport', 'getprotobyname', 'getaddrinfo', + 'getnameinfo', 'getdefaulttimeout', 'setdefaulttimeout', 'htons', + 'htonl', 'ntohs', 'ntohl', 'inet_pton', 'inet_ntop', 'inet_aton', + 'inet_ntoa', 'create_connection', 'socket', 'ssl', + # exceptions + 'error', 'herror', 'gaierror', 'timeout', 'sslerror', + # classes + 'SocketType', + # Misc flags + 'has_ipv6', 'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR', +] + +def _constant_to_name(const_value, expected_name_starts): + sock_module = sys.modules['socket'] + try: + for name in dir(sock_module): + if getattr(sock_module, name) is const_value: + for name_start in expected_name_starts: + if name.startswith(name_start): + return name + return "Unknown" + finally: + sock_module = None + +import _google_ipaddr_r234 + +def _is_ip_address(addr, version=None): + try: + _google_ipaddr_r234.IPAddress(addr, version) + return True + except ValueError: + return False + +def is_ipv4_address(addr): + return _is_ip_address(addr, 4) + +def is_ipv6_address(addr): + return _is_ip_address(addr, 6) + +def is_ip_address(addr): + return _is_ip_address(addr) + +class _nio_impl: + + timeout = None + mode = MODE_BLOCKING + + def config(self, mode, timeout): + self.mode = mode + if self.mode == MODE_BLOCKING: + self.jchannel.configureBlocking(1) + if self.mode == MODE_NONBLOCKING: + self.jchannel.configureBlocking(0) + if self.mode == MODE_TIMEOUT: + self.jchannel.configureBlocking(1) + self._timeout_millis = int(timeout*1000) + self.jsocket.setSoTimeout(self._timeout_millis) + + def getsockopt(self, level, option): + if (level, option) in self.options: + result = getattr(self.jsocket, "get%s" % self.options[ (level, option) ])() + if option == SO_LINGER: + if result == -1: + enabled, linger_time = 0, 0 + else: + enabled, linger_time = 1, result + return struct.pack('ii', enabled, linger_time) + return result + else: + raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \ + (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket))) + + def setsockopt(self, level, option, value): + if (level, option) in self.options: + if option == SO_LINGER: + values = struct.unpack('ii', value) + self.jsocket.setSoLinger(*values) + else: + getattr(self.jsocket, "set%s" % self.options[ (level, option) ])(value) + else: + raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \ + (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket))) + + def close(self): + self.jsocket.close() + + def getchannel(self): + return self.jchannel + + def fileno(self): + return self.socketio + +class _client_socket_impl(_nio_impl): + + options = { + (SOL_SOCKET, SO_KEEPALIVE): 'KeepAlive', + (SOL_SOCKET, SO_LINGER): 'SoLinger', + (SOL_SOCKET, SO_OOBINLINE): 'OOBInline', + (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize', + (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress', + (SOL_SOCKET, SO_SNDBUF): 'SendBufferSize', + (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout', + (IPPROTO_TCP, TCP_NODELAY): 'TcpNoDelay', + } + + def __init__(self, socket=None, pending_options=None): + if socket: + self.jchannel = socket.getChannel() + else: + self.jchannel = java.nio.channels.SocketChannel.open() + self.jsocket = self.jchannel.socket() + self.socketio = org.python.core.io.SocketIO(self.jchannel, 'rw') + if pending_options: + for level, optname in pending_options.keys(): + self.setsockopt(level, optname, pending_options[ (level, optname) ]) + + def bind(self, jsockaddr, reuse_addr): + self.jsocket.setReuseAddress(reuse_addr) + self.jsocket.bind(jsockaddr) + + def connect(self, jsockaddr): + if self.mode == MODE_TIMEOUT: + self.jsocket.connect (jsockaddr, self._timeout_millis) + else: + self.jchannel.connect(jsockaddr) + + def finish_connect(self): + return self.jchannel.finishConnect() + + def _do_read_net(self, buf): + # Need two separate implementations because the java.nio APIs do not support timeouts + return self.jsocket.getInputStream().read(buf) + + def _do_read_nio(self, buf): + bytebuf = java.nio.ByteBuffer.wrap(buf) + count = self.jchannel.read(bytebuf) + return count + + def _do_write_net(self, buf): + self.jsocket.getOutputStream().write(buf) + return len(buf) + + def _do_write_nio(self, buf): + bytebuf = java.nio.ByteBuffer.wrap(buf) + count = self.jchannel.write(bytebuf) + return count + + def read(self, buf): + if self.mode == MODE_TIMEOUT: + return self._do_read_net(buf) + else: + return self._do_read_nio(buf) + + def write(self, buf): + if self.mode == MODE_TIMEOUT: + return self._do_write_net(buf) + else: + return self._do_write_nio(buf) + + def shutdown(self, how): + if how in (SHUT_RD, SHUT_RDWR): + self.jsocket.shutdownInput() + if how in (SHUT_WR, SHUT_RDWR): + self.jsocket.shutdownOutput() + + def getsockname(self): + return (self.jsocket.getLocalAddress().getHostAddress(), self.jsocket.getLocalPort()) + + def getpeername(self): + return (self.jsocket.getInetAddress().getHostAddress(), self.jsocket.getPort() ) + +class _server_socket_impl(_nio_impl): + + options = { + (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize', + (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress', + (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout', + } + + def __init__(self, jsockaddr, backlog, reuse_addr): + self.pending_client_options = {} + self.jchannel = java.nio.channels.ServerSocketChannel.open() + self.jsocket = self.jchannel.socket() + self.jsocket.setReuseAddress(reuse_addr) + self.jsocket.bind(jsockaddr, backlog) + self.socketio = org.python.core.io.ServerSocketIO(self.jchannel, 'rw') + + def accept(self): + if self.mode in (MODE_BLOCKING, MODE_NONBLOCKING): + new_cli_chan = self.jchannel.accept() + if new_cli_chan is not None: + return _client_socket_impl(new_cli_chan.socket(), self.pending_client_options) + else: + return None + else: + # In timeout mode now + new_cli_sock = self.jsocket.accept() + return _client_socket_impl(new_cli_sock, self.pending_client_options) + + def shutdown(self, how): + # This is no-op on java, for server sockets. + # What the user wants to achieve is achieved by calling close() on + # java/jython. But we can't call that here because that would then + # later cause the user explicit close() call to fail + pass + + def getsockopt(self, level, option): + if self.options.has_key( (level, option) ): + return _nio_impl.getsockopt(self, level, option) + elif _client_socket_impl.options.has_key( (level, option) ): + return self.pending_client_options.get( (level, option), None) + else: + raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \ + (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket))) + + def setsockopt(self, level, option, value): + if self.options.has_key( (level, option) ): + _nio_impl.setsockopt(self, level, option, value) + elif _client_socket_impl.options.has_key( (level, option) ): + self.pending_client_options[ (level, option) ] = value + else: + raise error(errno.ENOPROTOOPT, "Socket option '%s' (level '%s') not supported on socket(%s)" % \ + (_constant_to_name(option, ['SO_', 'TCP_']), _constant_to_name(level, ['SOL_', 'IPPROTO_']), str(self.jsocket))) + + def getsockname(self): + return (self.jsocket.getInetAddress().getHostAddress(), self.jsocket.getLocalPort()) + + def getpeername(self): + # Not a meaningful operation for server sockets. + raise error(errno.ENOTCONN, "Socket is not connected") + +class _datagram_socket_impl(_nio_impl): + + options = { + (SOL_SOCKET, SO_BROADCAST): 'Broadcast', + (SOL_SOCKET, SO_RCVBUF): 'ReceiveBufferSize', + (SOL_SOCKET, SO_REUSEADDR): 'ReuseAddress', + (SOL_SOCKET, SO_SNDBUF): 'SendBufferSize', + (SOL_SOCKET, SO_TIMEOUT): 'SoTimeout', + } + + def __init__(self, jsockaddr=None, reuse_addr=0): + self.jchannel = java.nio.channels.DatagramChannel.open() + self.jsocket = self.jchannel.socket() + if jsockaddr is not None: + self.jsocket.setReuseAddress(reuse_addr) + self.jsocket.bind(jsockaddr) + self.socketio = org.python.core.io.DatagramSocketIO(self.jchannel, 'rw') + + def connect(self, jsockaddr): + self.jchannel.connect(jsockaddr) + + def disconnect(self): + """ + Disconnect the datagram socket. + cpython appears not to have this operation + """ + self.jchannel.disconnect() + + def shutdown(self, how): + # This is no-op on java, for datagram sockets. + # What the user wants to achieve is achieved by calling close() on + # java/jython. But we can't call that here because that would then + # later cause the user explicit close() call to fail + pass + + def _do_send_net(self, byte_array, socket_address, flags): + # Need two separate implementations because the java.nio APIs do not support timeouts + num_bytes = len(byte_array) + if self.jsocket.isConnected() and socket_address is None: + packet = java.net.DatagramPacket(byte_array, num_bytes) + else: + packet = java.net.DatagramPacket(byte_array, num_bytes, socket_address) + self.jsocket.send(packet) + return num_bytes + + def _do_send_nio(self, byte_array, socket_address, flags): + byte_buf = java.nio.ByteBuffer.wrap(byte_array) + if self.jchannel.isConnected() and socket_address is None: + bytes_sent = self.jchannel.write(byte_buf) + else: + bytes_sent = self.jchannel.send(byte_buf, socket_address) + return bytes_sent + + def sendto(self, byte_array, jsockaddr, flags): + if self.mode == MODE_TIMEOUT: + return self._do_send_net(byte_array, jsockaddr, flags) + else: + return self._do_send_nio(byte_array, jsockaddr, flags) + + def send(self, byte_array, flags): + if self.mode == MODE_TIMEOUT: + return self._do_send_net(byte_array, None, flags) + else: + return self._do_send_nio(byte_array, None, flags) + + def _do_receive_net(self, return_source_address, num_bytes, flags): + byte_array = jarray.zeros(num_bytes, 'b') + packet = java.net.DatagramPacket(byte_array, num_bytes) + self.jsocket.receive(packet) + bytes_rcvd = packet.getLength() + if bytes_rcvd < num_bytes: + byte_array = byte_array[:bytes_rcvd] + return_data = byte_array.tostring() + if return_source_address: + host = None + if packet.getAddress(): + host = packet.getAddress().getHostAddress() + port = packet.getPort() + return return_data, (host, port) + else: + return return_data + + def _do_receive_nio(self, return_source_address, num_bytes, flags): + byte_array = jarray.zeros(num_bytes, 'b') + byte_buf = java.nio.ByteBuffer.wrap(byte_array) + source_address = self.jchannel.receive(byte_buf) + if source_address is None and not self.jchannel.isBlocking(): + raise would_block_error() + byte_buf.flip() ; bytes_read = byte_buf.remaining() + if bytes_read < num_bytes: + byte_array = byte_array[:bytes_read] + return_data = byte_array.tostring() + if return_source_address: + return return_data, (source_address.getAddress().getHostAddress(), source_address.getPort()) + else: + return return_data + + def recvfrom(self, num_bytes, flags): + if self.mode == MODE_TIMEOUT: + return self._do_receive_net(1, num_bytes, flags) + else: + return self._do_receive_nio(1, num_bytes, flags) + + def recv(self, num_bytes, flags): + if self.mode == MODE_TIMEOUT: + return self._do_receive_net(0, num_bytes, flags) + else: + return self._do_receive_nio(0, num_bytes, flags) + + def getsockname(self): + return (self.jsocket.getLocalAddress().getHostAddress(), self.jsocket.getLocalPort()) + + def getpeername(self): + peer_address = self.jsocket.getInetAddress() + if peer_address is None: + raise error(errno.ENOTCONN, "Socket is not connected") + return (peer_address.getHostAddress(), self.jsocket.getPort() ) + +has_ipv6 = True # IPV6 FTW! + +# Name and address functions + +def _gethostbyaddr(name): + # This is as close as I can get; at least the types are correct... + addresses = java.net.InetAddress.getAllByName(gethostbyname(name)) + names = [] + addrs = [] + for addr in addresses: + names.append(asPyString(addr.getHostName())) + addrs.append(asPyString(addr.getHostAddress())) + return (names, addrs) + +@raises_java_exception +def getfqdn(name=None): + """ + Return a fully qualified domain name for name. If name is omitted or empty + it is interpreted as the local host. To find the fully qualified name, + the hostname returned by gethostbyaddr() is checked, then aliases for the + host, if available. The first name which includes a period is selected. + In case no fully qualified domain name is available, the hostname is retur + New in version 2.0. + """ + if not name: + name = gethostname() + names, addrs = _gethostbyaddr(name) + for a in names: + if a.find(".") >= 0: + return a + return name + +@raises_java_exception +def gethostname(): + return asPyString(java.net.InetAddress.getLocalHost().getHostName()) + +@raises_java_exception +def gethostbyname(name): + return asPyString(java.net.InetAddress.getByName(name).getHostAddress()) + +# +# Skeleton implementation of gethostbyname_ex +# Needed because urllib2 refers to it +# + +@raises_java_exception +def gethostbyname_ex(name): + return (name, [], gethostbyname(name)) + +@raises_java_exception +def gethostbyaddr(name): + names, addrs = _gethostbyaddr(name) + return (names[0], names, addrs) + +def getservbyname(service_name, protocol_name=None): + try: + from jnr.netdb import Service + except ImportError: + return None + service = Service.getServiceByName(service_name, protocol_name) + if service is None: + raise error('service/proto not found') + return service.getPort() + +def getservbyport(port, protocol_name=None): + try: + from jnr.netdb import Service + except ImportError: + return None + service = Service.getServiceByPort(port, protocol_name) + if service is None: + raise error('port/proto not found') + return service.getName() + +def getprotobyname(protocol_name=None): + try: + from jnr.netdb import Protocol + except ImportError: + return None + proto = Protocol.getProtocolByName(protocol_name) + if proto is None: + raise error('protocol not found') + return proto.getProto() + +def _realsocket(family = AF_INET, sock_type = SOCK_STREAM, protocol=0): + assert family in (AF_INET, AF_INET6), "Only AF_INET and AF_INET6 sockets are currently supported on jython" + assert sock_type in (SOCK_DGRAM, SOCK_STREAM), "Only SOCK_STREAM and SOCK_DGRAM sockets are currently supported on jython" + if sock_type == SOCK_STREAM: + if protocol != 0: + assert protocol == IPPROTO_TCP, "Only IPPROTO_TCP supported on SOCK_STREAM sockets" + else: + protocol = IPPROTO_TCP + result = _tcpsocket() + else: + if protocol != 0: + assert protocol == IPPROTO_UDP, "Only IPPROTO_UDP supported on SOCK_DGRAM sockets" + else: + protocol = IPPROTO_UDP + result = _udpsocket() + setattr(result, "family", family) + setattr(result, "type", sock_type) + setattr(result, "proto", protocol) + return result + +# +# Attempt to provide IDNA (RFC 3490) support. +# +# Try java.net.IDN, built into java 6 +# + +idna_libraries = [ + ('java.net.IDN', 'toASCII', 'toUnicode', + 'ALLOW_UNASSIGNED', 'USE_STD3_ASCII_RULES', + java.lang.IllegalArgumentException) +] + +for idna_lib, efn, dfn, au, usar, exc in idna_libraries: + try: + m = __import__(idna_lib, globals(), locals(), [efn, dfn, au, usar]) + encode_fn = getattr(m, efn) + def _encode_idna(name): + try: + return encode_fn(name) + except exc: + raise UnicodeEncodeError(name) + decode_fn = getattr(m, dfn) + def _decode_idna(name, flags=0): + try: + jflags = 0 + if flags & NI_IDN_ALLOW_UNASSIGNED: + jflags |= au + if flags & NI_IDN_USE_STD3_ASCII_RULES: + jflags |= usar + return decode_fn(name, jflags) + except Exception, x: + raise UnicodeDecodeError(name) + supports('idna', True) + break + except (AttributeError, ImportError), e: + pass +else: + _encode_idna = lambda x: x.encode("ascii") + _decode_idna = lambda x, y=0: x.decode("ascii") + +# +# Define data structures to support IPV4 and IPV6. +# + +class _ip_address_t: pass + +class _ipv4_address_t(_ip_address_t): + + def __init__(self, sockaddr, port, jaddress): + self.sockaddr = sockaddr + self.port = port + self.jaddress = jaddress + + def __getitem__(self, index): + if 0 == index: + return self.sockaddr + elif 1 == index: + return self.port + else: + raise IndexError() + + def __len__(self): + return 2 + + def __str__(self): + return "('%s', %d)" % (self.sockaddr, self.port) + + __repr__ = __str__ + +class _ipv6_address_t(_ip_address_t): + + def __init__(self, sockaddr, port, jaddress): + self.sockaddr = sockaddr + self.port = port + self.jaddress = jaddress + + def __getitem__(self, index): + if 0 == index: + return self.sockaddr + elif 1 == index: + return self.port + elif 2 == index: + return 0 + elif 3 == index: + return self.jaddress.scopeId + else: + raise IndexError() + + def __len__(self): + return 4 + + def __str__(self): + return "('%s', %d, 0, %d)" % (self.sockaddr, self.port, self.jaddress.scopeId) + + __repr__ = __str__ + +def _get_jsockaddr(address_object, family, sock_type, proto, flags): + # Is this an object that was returned from getaddrinfo? If so, it already contains an InetAddress + if isinstance(address_object, _ip_address_t): + return java.net.InetSocketAddress(address_object.jaddress, address_object[1]) + # The user passed an address tuple, not an object returned from getaddrinfo + # So we must call getaddrinfo, after some translations and checking + if address_object is None: + address_object = ("", 0) + error_message = "Address must be a 2-tuple (ipv4: (host, port)) or a 4-tuple (ipv6: (host, port, flow, scope))" + if not isinstance(address_object, tuple) or \ + ((family == AF_INET and len(address_object) != 2) or (family == AF_INET6 and len(address_object) not in [2,4] )) or \ + not isinstance(address_object[0], (basestring, types.NoneType)) or \ + not isinstance(address_object[1], (int, long)): + raise TypeError(error_message) + if len(address_object) == 4 and not isinstance(address_object[3], (int, long)): + raise TypeError(error_message) + hostname = address_object[0] + if hostname is not None: + hostname = hostname.strip() + port = address_object[1] + if family == AF_INET and sock_type == SOCK_DGRAM and hostname == "<broadcast>": + hostname = INADDR_BROADCAST + if hostname in ["", None]: + if flags & AI_PASSIVE: + hostname = {AF_INET: INADDR_ANY, AF_INET6: IN6ADDR_ANY_INIT}[family] + else: + hostname = "localhost" + if isinstance(hostname, unicode): + hostname = _encode_idna(hostname) + addresses = getaddrinfo(hostname, port, family, sock_type, proto, flags) + if len(addresses) == 0: + raise gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed') + return java.net.InetSocketAddress(addresses[0][4].jaddress, port) + +# Workaround for this (predominantly windows) issue +# http://wiki.python.org/jython/NewSocketModule#IPV6_address_support + +_ipv4_addresses_only = False + +def _use_ipv4_addresses_only(value): + global _ipv4_addresses_only + _ipv4_addresses_only = value + +def _getaddrinfo_get_host(host, family, flags): + if not isinstance(host, basestring) and host is not None: + raise TypeError("getaddrinfo() argument 1 must be string or None") + if flags & AI_NUMERICHOST: + if not is_ip_address(host): + raise gaierror(EAI_NONAME, "Name or service not known") + if family == AF_INET and not is_ipv4_address(host): + raise gaierror(EAI_ADDRFAMILY, "Address family for hostname not supported") + if family == AF_INET6 and not is_ipv6_address(host): + raise gaierror(EAI_ADDRFAMILY, "Address family for hostname not supported") + if isinstance(host, unicode): + host = _encode_idna(host) + return host + +def _getaddrinfo_get_port(port, flags): + if isinstance(port, basestring): + try: + int_port = int(port) + except ValueError: + if flags & AI_NUMERICSERV: + raise gaierror(EAI_NONAME, "Name or service not known") + # Lookup the service by name + try: + int_port = getservbyname(port) + except error: + raise gaierror(EAI_SERVICE, "Servname not supported for ai_socktype") + elif port is None: + int_port = 0 + elif not isinstance(port, (int, long)): + raise error("Int or String expected") + else: + int_port = int(port) + return int_port % 65536 + +@raises_java_exception +def getaddrinfo(host, port, family=AF_UNSPEC, socktype=0, proto=0, flags=0): + if _ipv4_addresses_only: + family = AF_INET + if not family in [AF_INET, AF_INET6, AF_UNSPEC]: + raise gaierror(errno.EIO, 'ai_family not supported') + host = _getaddrinfo_get_host(host, family, flags) + port = _getaddrinfo_get_port(port, flags) + if socktype not in [0, SOCK_DGRAM, SOCK_STREAM]: + raise error(errno.ESOCKTNOSUPPORT, "Socket type %s is not supported" % _constant_to_name(socktype, ['SOCK_'])) + filter_fns = [] + filter_fns.append({ + AF_INET: lambda x: isinstance(x, java.net.Inet4Address), + AF_INET6: lambda x: isinstance(x, java.net.Inet6Address), + AF_UNSPEC: lambda x: isinstance(x, java.net.InetAddress), + }[family]) + if host in [None, ""]: + if flags & AI_PASSIVE: + hosts = {AF_INET: [INADDR_ANY], AF_INET6: [IN6ADDR_ANY_INIT], AF_UNSPEC: [INADDR_ANY, IN6ADDR_ANY_INIT]}[family] + else: + hosts = ["localhost"] + else: + hosts = [host] + results = [] + for h in hosts: + for a in java.net.InetAddress.getAllByName(h): + if len([f for f in filter_fns if f(a)]): + family = {java.net.Inet4Address: AF_INET, java.net.Inet6Address: AF_INET6}[a.getClass()] + if flags & AI_CANONNAME: + canonname = asPyString(a.getCanonicalHostName()) + else: + canonname = "" + sockaddr = asPyString(a.getHostAddress()) + # TODO: Include flowinfo and scopeid in a 4-tuple for IPv6 addresses + sock_tuple = {AF_INET : _ipv4_address_t, AF_INET6 : _ipv6_address_t}[family](sockaddr, port, a) + if socktype == 0: + socktypes = [SOCK_DGRAM, SOCK_STREAM] + else: + socktypes = [socktype] + for result_socktype in socktypes: + result_proto = {SOCK_DGRAM: IPPROTO_UDP, SOCK_STREAM: IPPROTO_TCP}[result_socktype] + if proto in [0, result_proto]: + # The returned socket will only support the result_proto + # If this does not match the requested proto, don't return it + results.append((family, result_socktype, result_proto, canonname, sock_tuple)) + return results + +def _getnameinfo_get_host(address, flags): + if not isinstance(address, basestring): + raise TypeError("getnameinfo() address 1 must be string, not None") + if isinstance(address, unicode): + address = _encode_idna(address) + jia = java.net.InetAddress.getByName(address) + result = jia.getCanonicalHostName() + if flags & NI_NAMEREQD: + if is_ip_address(result): + raise gaierror(EAI_NONAME, "Name or service not known") + elif flags & NI_NUMERICHOST: + result = jia.getHostAddress() + # Ignoring NI_NOFQDN for now + if flags & NI_IDN: + result = _decode_idna(result, flags) + return result + +def _getnameinfo_get_port(port, flags): + if not isinstance(port, (int, long)): + raise TypeError("getnameinfo() port number must be an integer") + if flags & NI_NUMERICSERV: + return port + proto = None + if flags & NI_DGRAM: + proto = "udp" + return getservbyport(port, proto) + +@raises_java_exception +def getnameinfo(sock_addr, flags): + if not isinstance(sock_addr, tuple) or len(sock_addr) < 2: + raise TypeError("getnameinfo() argument 1 must be a tuple") + host = _getnameinfo_get_host(sock_addr[0], flags) + port = _getnameinfo_get_port(sock_addr[1], flags) + return (host, port) + +def getdefaulttimeout(): + return _defaulttimeout + +def _calctimeoutvalue(value): + if value is None: + return None + try: + floatvalue = float(value) + except: + raise TypeError('Socket timeout value must be a number or None') + if floatvalue < 0.0: + raise ValueError("Socket timeout value cannot be negative") + if floatvalue < 0.000001: + return 0.0 + return floatvalue + +def setdefaulttimeout(timeout): + global _defaulttimeout + try: + _defaulttimeout = _calctimeoutvalue(timeout) + finally: + _nonblocking_api_mixin.timeout = _defaulttimeout + +def htons(x): return x +def htonl(x): return x +def ntohs(x): return x +def ntohl(x): return x + +@raises_java_exception +def inet_pton(family, ip_string): + if family == AF_INET: + if not is_ipv4_address(ip_string): + raise error("illegal IP address string passed to inet_pton") + elif family == AF_INET6: + if not is_ipv6_address(ip_string): + raise error("illegal IP address string passed to inet_pton") + else: + raise error(errno.EAFNOSUPPORT, "Address family not supported by protocol") + ia = java.net.InetAddress.getByName(ip_string) + bytes = [] + for byte in ia.getAddress(): + if byte < 0: + bytes.append(byte+256) + else: + bytes.append(byte) + return "".join([chr(byte) for byte in bytes]) + +@raises_java_exception +def inet_ntop(family, packed_ip): + jByteArray = jarray.array(packed_ip, 'b') + if family == AF_INET: + if len(jByteArray) != 4: + raise ValueError("invalid length of packed IP address string") + elif family == AF_INET6: + if len(jByteArray) != 16: + raise ValueError("invalid length of packed IP address string") + else: + raise ValueError("unknown address family %s" % family) + ia = java.net.InetAddress.getByAddress(jByteArray) + return ia.getHostAddress() + +def inet_aton(ip_string): + return inet_pton(AF_INET, ip_string) + +def inet_ntoa(packed_ip): + return inet_ntop(AF_INET, packed_ip) + +class _nonblocking_api_mixin: + + mode = MODE_BLOCKING + reference_count = 0 + close_lock = threading.Lock() + + def __init__(self): + self.timeout = _defaulttimeout + if self.timeout is not None: + self.mode = MODE_TIMEOUT + self.pending_options = { + (SOL_SOCKET, SO_REUSEADDR): 0, + } + + def gettimeout(self): + return self.timeout + + def settimeout(self, timeout): + self.timeout = _calctimeoutvalue(timeout) + if self.timeout is None: + self.mode = MODE_BLOCKING + elif self.timeout < 0.000001: + self.mode = MODE_NONBLOCKING + else: + self.mode = MODE_TIMEOUT + self._config() + + def setblocking(self, flag): + if flag: + self.mode = MODE_BLOCKING + self.timeout = None + else: + self.mode = MODE_NONBLOCKING + self.timeout = 0.0 + self._config() + + def getblocking(self): + return self.mode == MODE_BLOCKING + + @raises_java_exception + def setsockopt(self, level, optname, value): + if self.sock_impl: + self.sock_impl.setsockopt(level, optname, value) + else: + self.pending_options[ (level, optname) ] = value + + @raises_java_exception + def getsockopt(self, level, optname): + # Handle "pseudo" options first + if level == SOL_SOCKET and optname == SO_TYPE: + return getattr(self, "type") + if level == SOL_SOCKET and optname == SO_ERROR: + return_value = self._last_error + self._last_error = 0 + return return_value + # Now handle "real" options + if self.sock_impl: + return self.sock_impl.getsockopt(level, optname) + else: + return self.pending_options.get( (level, optname), None) + + @raises_java_exception + def shutdown(self, how): + assert how in (SHUT_RD, SHUT_WR, SHUT_RDWR) + if not self.sock_impl: + raise error(errno.ENOTCONN, "Transport endpoint is not connected") + self.sock_impl.shutdown(how) + + @raises_java_exception + def close(self): + if self.sock_impl: + self.sock_impl.close() + + @raises_java_exception + def getsockname(self): + if self.sock_impl is None: + # If the user has already bound an address, return that + if self.local_addr: + return self.local_addr + # The user has not bound, connected or listened + # This is what cpython raises in this scenario + raise error(errno.EINVAL, "Invalid argument") + return self.sock_impl.getsockname() + + @raises_java_exception + def getpeername(self): + if self.sock_impl is None: + raise error(errno.ENOTCONN, "Socket is not connected") + return self.sock_impl.getpeername() + + def _config(self): + assert self.mode in _permitted_modes + if self.sock_impl: + self.sock_impl.config(self.mode, self.timeout) + for level, optname in self.pending_options.keys(): + if optname != SO_REUSEADDR: + self.sock_impl.setsockopt(level, optname, self.pending_options[ (level, optname) ]) + + def getchannel(self): + if not self.sock_impl: + return None + return self.sock_impl.getchannel() + + def fileno(self): + if not self.sock_impl: + return None + return self.sock_impl.fileno() + + def _get_jsocket(self): + return self.sock_impl.jsocket + +class _tcpsocket(_nonblocking_api_mixin): + + sock_impl = None + istream = None + ostream = None + local_addr = None + server = 0 + _last_error = 0 + + def __init__(self): + _nonblocking_api_mixin.__init__(self) + + def getsockopt(self, level, optname): + if level == SOL_SOCKET and optname == SO_ACCEPTCONN: + return self.server + return _nonblocking_api_mixin.getsockopt(self, level, optname) + + @raises_java_exception + def bind(self, addr): + assert not self.sock_impl + assert not self.local_addr + # Do the address format check + _get_jsockaddr(addr, self.family, self.type, self.proto, AI_PASSIVE) + self.local_addr = addr + + @raises_java_exception + def listen(self, backlog): + "This signifies a server socket" + assert not self.sock_impl + self.server = 1 + self.sock_impl = _server_socket_impl(_get_jsockaddr(self.local_addr, self.family, self.type, self.proto, AI_PASSIVE), + backlog, self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ]) + self._config() + + @raises_java_exception + def accept(self): + "This signifies a server socket" + if not self.sock_impl: + self.listen() + assert self.server + new_sock = self.sock_impl.accept() + if not new_sock: + raise would_block_error() + cliconn = _tcpsocket() + cliconn.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ] = new_sock.jsocket.getReuseAddress() + cliconn.sock_impl = new_sock + cliconn._setup() + return cliconn, new_sock.getpeername() + + def _do_connect(self, addr): + assert not self.sock_impl + self.sock_impl = _client_socket_impl() + if self.local_addr: # Has the socket been bound to a local address? + self.sock_impl.bind(_get_jsockaddr(self.local_addr, self.family, self.type, self.proto, 0), + self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ]) + self._config() # Configure timeouts, etc, now that the socket exists + self.sock_impl.connect(_get_jsockaddr(addr, self.family, self.type, self.proto, 0)) + + @raises_java_exception + def connect(self, addr): + "This signifies a client socket" + self._do_connect(addr) + self._setup() + + @raises_java_exception + def connect_ex(self, addr): + "This signifies a client socket" + if not self.sock_impl: + self._do_connect(addr) + if self.sock_impl.finish_connect(): + self._setup() + if self.mode == MODE_NONBLOCKING: + return errno.EISCONN + return 0 + return errno.EINPROGRESS + + def _setup(self): + if self.mode != MODE_NONBLOCKING: + self.istream = self.sock_impl.jsocket.getInputStream() + self.ostream = self.sock_impl.jsocket.getOutputStream() + + @raises_java_exception + def recv(self, n): + if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected') + if self.sock_impl.jchannel.isConnectionPending(): + self.sock_impl.jchannel.finishConnect() + data = jarray.zeros(n, 'b') + m = self.sock_impl.read(data) + if m == -1:#indicates EOF has been reached, so we just return the empty string + return "" + elif m <= 0: + if self.mode == MODE_NONBLOCKING: + raise would_block_error() + return "" + if m < n: + data = data[:m] + return data.tostring() + + @raises_java_exception + def recvfrom(self, n): + return self.recv(n), self.getpeername() + + @raises_java_exception + def send(self, s): + if not self.sock_impl: raise error(errno.ENOTCONN, 'Socket is not connected') + if self.sock_impl.jchannel.isConnectionPending(): + self.sock_impl.jchannel.finishConnect() + numwritten = self.sock_impl.write(s) + if numwritten == 0 and self.mode == MODE_NONBLOCKING: + raise would_block_error() + return numwritten + + sendall = send + + @raises_java_exception + def close(self): + if self.istream: + self.istream.close() + if self.ostream: + self.ostream.close() + if self.sock_impl: + self.sock_impl.close() + + +class _udpsocket(_nonblocking_api_mixin): + + sock_impl = None + connected = False + local_addr = None + _last_error = 0 + + def __init__(self): + _nonblocking_api_mixin.__init__(self) + + @raises_java_exception + def bind(self, addr): + assert not self.sock_impl + assert not self.local_addr + # Do the address format check + _get_jsockaddr(addr, self.family, self.type, self.proto, AI_PASSIVE) + self.local_addr = addr + self.sock_impl = _datagram_socket_impl(_get_jsockaddr(self.local_addr, self.family, self.type, self.proto, AI_PASSIVE), + self.pending_options[ (SOL_SOCKET, SO_REUSEADDR) ]) + self._config() + + def _do_connect(self, addr): + assert not self.connected, "Datagram Socket is already connected" + if not self.sock_impl: + self.sock_impl = _datagram_socket_impl() + self._config() + self.sock_impl.connect(_get_jsockaddr(addr, self.family, self.type, self.proto, 0)) + self.connected = True + + @raises_java_exception + def connect(self, addr): + self._do_connect(addr) + + @raises_java_exception + def connect_ex(self, addr): + if not self.sock_impl: + self._do_connect(addr) + return 0 + + @raises_java_exception + def sendto(self, data, p1, p2=None): + if not p2: + flags, addr = 0, p1 + else: + flags, addr = 0, p2 + if not self.sock_impl: + self.sock_impl = _datagram_socket_impl() + self._config() + byte_array = java.lang.String(data).getBytes('iso-8859-1') + result = self.sock_impl.sendto(byte_array, _get_jsockaddr(addr, self.family, self.type, self.proto, 0), flags) + return result + + @raises_java_exception + def send(self, data, flags=None): + if not self.connected: raise error(errno.ENOTCONN, "Socket is not connected") + byte_array = java.lang.String(data).getBytes('iso-8859-1') + return self.sock_impl.send(byte_array, flags) + + @raises_java_exception + def recvfrom(self, num_bytes, flags=None): + """ + There is some disagreement as to what the behaviour should be if + a recvfrom operation is requested on an unbound socket. + See the following links for more information + http://bugs.jython.org/issue1005 + http://bugs.sun.com/view_bug.do?bug_id=6621689 + """ + # This is the old 2.1 behaviour + #assert self.sock_impl + # This is amak's preferred interpretation + #raise error(errno.ENOTCONN, "Recvfrom on unbound udp socket meaningless operation") + # And this is the option for cpython compatibility + if not self.sock_impl: + self.sock_impl = _datagram_socket_impl() + self._config() + return self.sock_impl.recvfrom(num_bytes, flags) + + @raises_java_exception + def recv(self, num_bytes, flags=None): + if not self.sock_impl: + raise error(errno.ENOTCONN, "Socket is not connected") + return self.sock_impl.recv(num_bytes, flags) + + def __del__(self): + self.close() + +_socketmethods = ( + 'bind', 'connect', 'connect_ex', 'fileno', 'listen', + 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', + 'sendall', 'setblocking', + 'settimeout', 'gettimeout', 'shutdown', 'getchannel') + +# All the method names that must be delegated to either the real socket +# object or the _closedsocket object. +_delegate_methods = ("recv", "recvfrom", "recv_into", "recvfrom_into", + "send", "sendto") + +class _closedsocket(object): + __slots__ = [] + def _dummy(*args): + raise error(errno.EBADF, 'Bad file descriptor') + # All _delegate_methods must also be initialized here. + send = recv = recv_into = sendto = recvfrom = recvfrom_into = _dummy + __getattr__ = _dummy + +_active_sockets = set() + +def _closeActiveSockets(): + for socket in _active_sockets.copy(): + try: + socket.close() + except error: + msg = 'Problem closing socket: %s: %r' % (socket, sys.exc_info()) + print >> sys.stderr, msg + +class _socketobject(object): + + __doc__ = _realsocket.__doc__ + + __slots__ = ["_sock", "__weakref__"] + list(_delegate_methods) + + def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, _sock=None): + if _sock is None: + _sock = _realsocket(family, type, proto) + _sock.reference_count += 1 + elif isinstance(_sock, _nonblocking_api_mixin): + _sock.reference_count += 1 + self._sock = _sock + for method in _delegate_methods: + meth = getattr(_sock, method, None) + if meth: + setattr(self, method, meth) + _active_sockets.add(self) + + def close(self): + try: + _active_sockets.remove(self) + except KeyError: + pass + _sock = self._sock + if isinstance(_sock, _nonblocking_api_mixin): + _sock.close_lock.acquire() + try: + _sock.reference_count -=1 + if not _sock.reference_count: + _sock.close() + self._sock = _closedsocket() + dummy = self._sock._dummy + for method in _delegate_methods: + setattr(self, method, dummy) + self.send = self.recv = self.sendto = self.recvfrom = \ + self._sock._dummy + finally: + _sock.close_lock.release() + #close.__doc__ = _realsocket.close.__doc__ + + def accept(self): + sock, addr = self._sock.accept() + return _socketobject(_sock=sock), addr + #accept.__doc__ = _realsocket.accept.__doc__ + + def dup(self): + """dup() -> socket object + + Return a new socket object connected to the same system resource.""" + _sock = self._sock + if not isinstance(_sock, _nonblocking_api_mixin): + return _socketobject(_sock=_sock) + + _sock.close_lock.acquire() + try: + duped = _socketobject(_sock=_sock) + finally: + _sock.close_lock.release() + return duped + + def makefile(self, mode='r', bufsize=-1): + """makefile([mode[, bufsize]]) -> file object + + Return a regular file object corresponding to the socket. The mode + and bufsize arguments are as for the built-in open() function.""" + _sock = self._sock + if not isinstance(_sock, _nonblocking_api_mixin): + return _fileobject(_sock, mode, bufsize) + + _sock.close_lock.acquire() + try: + fileobject = _fileobject(_sock, mode, bufsize) + finally: + _sock.close_lock.release() + return fileobject + + family = property(lambda self: self._sock.family, doc="the socket family") + type = property(lambda self: self._sock.type, doc="the socket type") + proto = property(lambda self: self._sock.proto, doc="the socket protocol") + + _s = ("def %s(self, *args): return self._sock.%s(*args)\n\n" + #"%s.__doc__ = _realsocket.%s.__doc__\n") + ) + for _m in _socketmethods: + #exec _s % (_m, _m, _m, _m) + exec _s % (_m, _m) + del _m, _s + +socket = SocketType = _socketobject + +class _fileobject(object): + """Faux file object attached to a socket object.""" + + default_bufsize = 8192 + name = "<socket>" + + __slots__ = ["mode", "bufsize", "softspace", + # "closed" is a property, see below + "_sock", "_rbufsize", "_wbufsize", "_rbuf", "_wbuf", + "_close"] + + def __init__(self, sock, mode='rb', bufsize=-1, close=False): + self._sock = sock + if isinstance(sock, _nonblocking_api_mixin): + sock.reference_count += 1 + self.mode = mode # Not actually used in this version + if bufsize < 0: + bufsize = self.default_bufsize + self.bufsize = bufsize + self.softspace = False + if bufsize == 0: + self._rbufsize = 1 + elif bufsize == 1: + self._rbufsize = self.default_bufsize + else: + self._rbufsize = bufsize + self._wbufsize = bufsize + self._rbuf = "" # A string + self._wbuf = [] # A list of strings + self._close = close + + def _getclosed(self): + return self._sock is None + closed = property(_getclosed, doc="True if the file is closed") + + def close(self): + try: + if self._sock: + self.flush() + finally: + if self._sock: + if isinstance(self._sock, _nonblocking_api_mixin): + self._sock.reference_count -= 1 + if not self._sock.reference_count or self._close: + self._sock.close() + elif self._close: + self._sock.close() + self._sock = None + + def __del__(self): + try: + self.close() + except: + # close() may fail if __init__ didn't complete + pass + + def flush(self): + if self._wbuf: + buffer = "".join(self._wbuf) + self._wbuf = [] + self._sock.sendall(buffer) + + def fileno(self): + return self._sock.fileno() + + def write(self, data): + data = str(data) # XXX Should really reject non-string non-buffers + if not data: + return + self._wbuf.append(data) + if (self._wbufsize == 0 or + self._wbufsize == 1 and '\n' in data or + self._get_wbuf_len() >= self._wbufsize): + self.flush() + + def writelines(self, list): + # XXX We could do better here for very long lists + # XXX Should really reject non-string non-buffers + self._wbuf.extend(filter(None, map(str, list))) + if (self._wbufsize <= 1 or + self._get_wbuf_len() >= self._wbufsize): + self.flush() + + def _get_wbuf_len(self): + buf_len = 0 + for x in self._wbuf: + buf_len += len(x) + return buf_len + + def read(self, size=-1): + data = self._rbuf + if size < 0: + # Read until EOF + buffers = [] + if data: + buffers.append(data) + self._rbuf = "" + if self._rbufsize <= 1: + recv_size = self.default_bufsize + else: + recv_size = self._rbufsize + while True: + data = self._sock.recv(recv_size) + if not data: + break + buffers.append(data) + return "".join(buffers) + else: + # Read until size bytes or EOF seen, whichever comes first + buf_len = len(data) + if buf_len >= size: + self._rbuf = data[size:] + return data[:size] + buffers = [] + if data: + buffers.append(data) + self._rbuf = "" + while True: + left = size - buf_len + recv_size = max(self._rbufsize, left) + data = self._sock.recv(recv_size) + if not data: + break + buffers.append(data) + n = len(data) + if n >= left: + self._rbuf = data[left:] + buffers[-1] = data[:left] + break + buf_len += n + return "".join(buffers) + + def readline(self, size=-1): + data = self._rbuf + if size < 0: + # Read until \n or EOF, whichever comes first + if self._rbufsize <= 1: + # Speed up unbuffered case + assert data == "" + buffers = [] + recv = self._sock.recv + while data != "\n": + data = recv(1) + if not data: + break + buffers.append(data) + return "".join(buffers) + nl = data.find('\n') + if nl >= 0: + nl += 1 + self._rbuf = data[nl:] + return data[:nl] + buffers = [] + if data: + buffers.append(data) + self._rbuf = "" + while True: + data = self._sock.recv(self._rbufsize) + if not data: + break + buffers.append(data) + nl = data.find('\n') + if nl >= 0: + nl += 1 + self._rbuf = data[nl:] + buffers[-1] = data[:nl] + break + return "".join(buffers) + else: + # Read until size bytes or \n or EOF seen, whichever comes first + nl = data.find('\n', 0, size) + if nl >= 0: + nl += 1 + self._rbuf = data[nl:] + return data[:nl] + buf_len = len(data) + if buf_len >= size: + self._rbuf = data[size:] + return data[:size] + buffers = [] + if data: + buffers.append(data) + self._rbuf = "" + while True: + data = self._sock.recv(self._rbufsize) + if not data: + break + buffers.append(data) + left = size - buf_len + nl = data.find('\n', 0, left) + if nl >= 0: + nl += 1 + self._rbuf = data[nl:] + buffers[-1] = data[:nl] + break + n = len(data) + if n >= left: + self._rbuf = data[left:] + buffers[-1] = data[:left] + break + buf_len += n + return "".join(buffers) + + def readlines(self, sizehint=0): + total = 0 + list = [] + while True: + line = self.readline() + if not line: + break + list.append(line) + total += len(line) + if sizehint and total >= sizehint: + break + return list + + # Iterator protocols + + def __iter__(self): + return self + + def next(self): + line = self.readline() + if not line: + raise StopIteration + return line + +_GLOBAL_DEFAULT_TIMEOUT = object() + +def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT, + source_address=None): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + err = None + for res in getaddrinfo(host, port, 0, SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket(af, socktype, proto) + if timeout is not _GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except error as _: + err = _ + if sock is not None: + sock.close() + + if err is not None: + raise err + else: + raise error("getaddrinfo returns an empty list") + +# Define the SSL support + +class ssl: + + @raises_java_exception + def __init__(self, jython_socket_wrapper, keyfile=None, certfile=None): + self.jython_socket_wrapper = jython_socket_wrapper + jython_socket = self.jython_socket_wrapper._sock + self.java_ssl_socket = self._make_ssl_socket(jython_socket) + self._in_buf = java.io.BufferedInputStream(self.java_ssl_socket.getInputStream()) + self._out_buf = java.io.BufferedOutputStream(self.java_ssl_socket.getOutputStream()) + + def _make_ssl_socket(self, jython_socket, auto_close=0): + java_net_socket = jython_socket._get_jsocket() + assert isinstance(java_net_socket, java.net.Socket) + host = java_net_socket.getInetAddress().getHostAddress() + port = java_net_socket.getPort() + factory = javax.net.ssl.SSLSocketFactory.getDefault(); + java_ssl_socket = factory.createSocket(java_net_socket, host, port, auto_close) + java_ssl_socket.setEnabledCipherSuites(java_ssl_socket.getSupportedCipherSuites()) + java_ssl_socket.startHandshake() + return java_ssl_socket + + @raises_java_exception + def read(self, n=4096): + data = jarray.zeros(n, 'b') + m = self._in_buf.read(data, 0, n) + if m <= 0: + return "" + if m < n: + data = data[:m] + return data.tostring() + + recv = read + + @raises_java_exception + def write(self, s): + self._out_buf.write(s) + self._out_buf.flush() + return len(s) + + send = sendall = write + + def makefile(self, mode='r', bufsize=-1): + return _fileobject(self, mode, bufsize) + + def _get_server_cert(self): + return self.java_ssl_socket.getSession().getPeerCertificates()[0] + + @raises_java_exception + def server(self): + cert = self._get_server_cert() + return cert.getSubjectDN().toString() + + @raises_java_exception + def issuer(self): + cert = self._get_server_cert() + return cert.getIssuerDN().toString() + + def close(self): + self.jython_socket_wrapper.close() + +def test(): + s = socket(AF_INET, SOCK_STREAM) + s.connect(("", 80)) + s.send("GET / HTTP/1.0\r\n\r\n") + while 1: + data = s.recv(2000) + print data + if not data: + break + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/sre.py b/src/main/resources/PythonLibs/sre.py new file mode 100644 index 0000000000000000000000000000000000000000..c04576bafa58871e84333c0da2a074614c01e97b --- /dev/null +++ b/src/main/resources/PythonLibs/sre.py @@ -0,0 +1,13 @@ +"""This file is only retained for backwards compatibility. +It will be removed in the future. sre was moved to re in version 2.5. +""" + +import warnings +warnings.warn("The sre module is deprecated, please import re.", + DeprecationWarning, 2) + +from re import * +from re import __all__ + +# old pickles expect the _compile() reconstructor in this module +from re import _compile diff --git a/src/main/resources/PythonLibs/sre_compile.py b/src/main/resources/PythonLibs/sre_compile.py new file mode 100644 index 0000000000000000000000000000000000000000..a2279de8190c79fd9c74c38b58f0f37033ff3ed4 --- /dev/null +++ b/src/main/resources/PythonLibs/sre_compile.py @@ -0,0 +1,536 @@ +# +# Secret Labs' Regular Expression Engine +# +# convert template to internal format +# +# Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. +# +# See the sre.py file for information on usage and redistribution. +# + +"""Internal support module for sre""" + +import _sre, sys + +from sre_constants import * + +assert _sre.MAGIC == MAGIC, "SRE module mismatch" + +if _sre.CODESIZE == 2: + MAXCODE = 65535 +else: + MAXCODE = 0xFFFFFFFFL + +def _identityfunction(x): + return x + +def set(seq): + s = {} + for elem in seq: + s[elem] = 1 + return s + +_LITERAL_CODES = set([LITERAL, NOT_LITERAL]) +_REPEATING_CODES = set([REPEAT, MIN_REPEAT, MAX_REPEAT]) +_SUCCESS_CODES = set([SUCCESS, FAILURE]) +_ASSERT_CODES = set([ASSERT, ASSERT_NOT]) + +def _compile(code, pattern, flags): + # internal: compile a (sub)pattern + emit = code.append + _len = len + LITERAL_CODES = _LITERAL_CODES + REPEATING_CODES = _REPEATING_CODES + SUCCESS_CODES = _SUCCESS_CODES + ASSERT_CODES = _ASSERT_CODES + for op, av in pattern: + if op in LITERAL_CODES: + if flags & SRE_FLAG_IGNORECASE: + emit(OPCODES[OP_IGNORE[op]]) + emit(_sre.getlower(av, flags)) + else: + emit(OPCODES[op]) + emit(av) + elif op is IN: + if flags & SRE_FLAG_IGNORECASE: + emit(OPCODES[OP_IGNORE[op]]) + def fixup(literal, flags=flags): + return _sre.getlower(literal, flags) + else: + emit(OPCODES[op]) + fixup = _identityfunction + skip = _len(code); emit(0) + _compile_charset(av, flags, code, fixup) + code[skip] = _len(code) - skip + elif op is ANY: + if flags & SRE_FLAG_DOTALL: + emit(OPCODES[ANY_ALL]) + else: + emit(OPCODES[ANY]) + elif op in REPEATING_CODES: + if flags & SRE_FLAG_TEMPLATE: + raise error, "internal: unsupported template operator" + emit(OPCODES[REPEAT]) + skip = _len(code); emit(0) + emit(av[0]) + emit(av[1]) + _compile(code, av[2], flags) + emit(OPCODES[SUCCESS]) + code[skip] = _len(code) - skip + elif _simple(av) and op is not REPEAT: + if op is MAX_REPEAT: + emit(OPCODES[REPEAT_ONE]) + else: + emit(OPCODES[MIN_REPEAT_ONE]) + skip = _len(code); emit(0) + emit(av[0]) + emit(av[1]) + _compile(code, av[2], flags) + emit(OPCODES[SUCCESS]) + code[skip] = _len(code) - skip + else: + emit(OPCODES[REPEAT]) + skip = _len(code); emit(0) + emit(av[0]) + emit(av[1]) + _compile(code, av[2], flags) + code[skip] = _len(code) - skip + if op is MAX_REPEAT: + emit(OPCODES[MAX_UNTIL]) + else: + emit(OPCODES[MIN_UNTIL]) + elif op is SUBPATTERN: + if av[0]: + emit(OPCODES[MARK]) + emit((av[0]-1)*2) + # _compile_info(code, av[1], flags) + _compile(code, av[1], flags) + if av[0]: + emit(OPCODES[MARK]) + emit((av[0]-1)*2+1) + elif op in SUCCESS_CODES: + emit(OPCODES[op]) + elif op in ASSERT_CODES: + emit(OPCODES[op]) + skip = _len(code); emit(0) + if av[0] >= 0: + emit(0) # look ahead + else: + lo, hi = av[1].getwidth() + if lo != hi: + raise error, "look-behind requires fixed-width pattern" + emit(lo) # look behind + _compile(code, av[1], flags) + emit(OPCODES[SUCCESS]) + code[skip] = _len(code) - skip + elif op is CALL: + emit(OPCODES[op]) + skip = _len(code); emit(0) + _compile(code, av, flags) + emit(OPCODES[SUCCESS]) + code[skip] = _len(code) - skip + elif op is AT: + emit(OPCODES[op]) + if flags & SRE_FLAG_MULTILINE: + av = AT_MULTILINE.get(av, av) + if flags & SRE_FLAG_LOCALE: + av = AT_LOCALE.get(av, av) + elif flags & SRE_FLAG_UNICODE: + av = AT_UNICODE.get(av, av) + emit(ATCODES[av]) + elif op is BRANCH: + emit(OPCODES[op]) + tail = [] + tailappend = tail.append + for av in av[1]: + skip = _len(code); emit(0) + # _compile_info(code, av, flags) + _compile(code, av, flags) + emit(OPCODES[JUMP]) + tailappend(_len(code)); emit(0) + code[skip] = _len(code) - skip + emit(0) # end of branch + for tail in tail: + code[tail] = _len(code) - tail + elif op is CATEGORY: + emit(OPCODES[op]) + if flags & SRE_FLAG_LOCALE: + av = CH_LOCALE[av] + elif flags & SRE_FLAG_UNICODE: + av = CH_UNICODE[av] + emit(CHCODES[av]) + elif op is GROUPREF: + if flags & SRE_FLAG_IGNORECASE: + emit(OPCODES[OP_IGNORE[op]]) + else: + emit(OPCODES[op]) + emit(av-1) + elif op is GROUPREF_EXISTS: + emit(OPCODES[op]) + emit(av[0]-1) + skipyes = _len(code); emit(0) + _compile(code, av[1], flags) + if av[2]: + emit(OPCODES[JUMP]) + skipno = _len(code); emit(0) + code[skipyes] = _len(code) - skipyes + 1 + _compile(code, av[2], flags) + code[skipno] = _len(code) - skipno + else: + code[skipyes] = _len(code) - skipyes + 1 + else: + raise ValueError, ("unsupported operand type", op) + +def _compile_charset(charset, flags, code, fixup=None): + # compile charset subprogram + emit = code.append + if fixup is None: + fixup = _identityfunction + for op, av in _optimize_charset(charset, fixup): + emit(OPCODES[op]) + if op is NEGATE: + pass + elif op is LITERAL: + emit(fixup(av)) + elif op is RANGE: + emit(fixup(av[0])) + emit(fixup(av[1])) + elif op is CHARSET: + code.extend(av) + elif op is BIGCHARSET: + code.extend(av) + elif op is CATEGORY: + if flags & SRE_FLAG_LOCALE: + emit(CHCODES[CH_LOCALE[av]]) + elif flags & SRE_FLAG_UNICODE: + emit(CHCODES[CH_UNICODE[av]]) + else: + emit(CHCODES[av]) + else: + raise error, "internal: unsupported set operator" + emit(OPCODES[FAILURE]) + +def _optimize_charset(charset, fixup): + # internal: optimize character set + out = [] + outappend = out.append + charmap = [0]*256 + try: + for op, av in charset: + if op is NEGATE: + outappend((op, av)) + elif op is LITERAL: + charmap[fixup(av)] = 1 + elif op is RANGE: + for i in range(fixup(av[0]), fixup(av[1])+1): + charmap[i] = 1 + elif op is CATEGORY: + # XXX: could append to charmap tail + return charset # cannot compress + except IndexError: + # character set contains unicode characters + return _optimize_unicode(charset, fixup) + # compress character map + i = p = n = 0 + runs = [] + runsappend = runs.append + for c in charmap: + if c: + if n == 0: + p = i + n = n + 1 + elif n: + runsappend((p, n)) + n = 0 + i = i + 1 + if n: + runsappend((p, n)) + if len(runs) <= 2: + # use literal/range + for p, n in runs: + if n == 1: + outappend((LITERAL, p)) + else: + outappend((RANGE, (p, p+n-1))) + if len(out) < len(charset): + return out + else: + # use bitmap + data = _mk_bitmap(charmap) + outappend((CHARSET, data)) + return out + return charset + +def _mk_bitmap(bits): + data = [] + dataappend = data.append + if _sre.CODESIZE == 2: + start = (1, 0) + else: + start = (1L, 0L) + m, v = start + for c in bits: + if c: + v = v + m + m = m + m + if m > MAXCODE: + dataappend(v) + m, v = start + return data + +# To represent a big charset, first a bitmap of all characters in the +# set is constructed. Then, this bitmap is sliced into chunks of 256 +# characters, duplicate chunks are eliminated, and each chunk is +# given a number. In the compiled expression, the charset is +# represented by a 16-bit word sequence, consisting of one word for +# the number of different chunks, a sequence of 256 bytes (128 words) +# of chunk numbers indexed by their original chunk position, and a +# sequence of chunks (16 words each). + +# Compression is normally good: in a typical charset, large ranges of +# Unicode will be either completely excluded (e.g. if only cyrillic +# letters are to be matched), or completely included (e.g. if large +# subranges of Kanji match). These ranges will be represented by +# chunks of all one-bits or all zero-bits. + +# Matching can be also done efficiently: the more significant byte of +# the Unicode character is an index into the chunk number, and the +# less significant byte is a bit index in the chunk (just like the +# CHARSET matching). + +# In UCS-4 mode, the BIGCHARSET opcode still supports only subsets +# of the basic multilingual plane; an efficient representation +# for all of UTF-16 has not yet been developed. This means, +# in particular, that negated charsets cannot be represented as +# bigcharsets. + +def _optimize_unicode(charset, fixup): + # problems with optimization in Jython, forget about it for now + return charset + + try: + import array + except ImportError: + return charset + charmap = [0]*65536 + negate = 0 + try: + for op, av in charset: + if op is NEGATE: + negate = 1 + elif op is LITERAL: + charmap[fixup(av)] = 1 + elif op is RANGE: + for i in xrange(fixup(av[0]), fixup(av[1])+1): + charmap[i] = 1 + elif op is CATEGORY: + # XXX: could expand category + return charset # cannot compress + except IndexError: + # non-BMP characters + return charset + if negate: + if sys.maxunicode != 65535: + # XXX: negation does not work with big charsets + return charset + for i in xrange(65536): + charmap[i] = not charmap[i] + comps = {} + mapping = [0]*256 + block = 0 + data = [] + for i in xrange(256): + chunk = tuple(charmap[i*256:(i+1)*256]) + new = comps.setdefault(chunk, block) + mapping[i] = new + if new == block: + block = block + 1 + data = data + _mk_bitmap(chunk) + header = [block] + if _sre.CODESIZE == 2: + code = 'H' + else: + # change this for Jython from 'I', since that will expand to + # long, and cause needless complexity (or so it seems) + code = 'i' + # Convert block indices to byte array of 256 bytes + mapping = array.array('b', mapping).tostring() + # Convert byte array to word array + mapping = array.array(code, mapping) + assert mapping.itemsize == _sre.CODESIZE + header = header + mapping.tolist() + data[0:0] = header + return [(BIGCHARSET, data)] + +def _simple(av): + # check if av is a "simple" operator + lo, hi = av[2].getwidth() + if lo == 0 and hi == MAXREPEAT: + raise error, "nothing to repeat" + return lo == hi == 1 and av[2][0][0] != SUBPATTERN + +def _compile_info(code, pattern, flags): + # internal: compile an info block. in the current version, + # this contains min/max pattern width, and an optional literal + # prefix or a character map + lo, hi = pattern.getwidth() + if lo == 0: + return # not worth it + # look for a literal prefix + prefix = [] + prefixappend = prefix.append + prefix_skip = 0 + charset = [] # not used + charsetappend = charset.append + if not (flags & SRE_FLAG_IGNORECASE): + # look for literal prefix + for op, av in pattern.data: + if op is LITERAL: + if len(prefix) == prefix_skip: + prefix_skip = prefix_skip + 1 + prefixappend(av) + elif op is SUBPATTERN and len(av[1]) == 1: + op, av = av[1][0] + if op is LITERAL: + prefixappend(av) + else: + break + else: + break + # if no prefix, look for charset prefix + if not prefix and pattern.data: + op, av = pattern.data[0] + if op is SUBPATTERN and av[1]: + op, av = av[1][0] + if op is LITERAL: + charsetappend((op, av)) + elif op is BRANCH: + c = [] + cappend = c.append + for p in av[1]: + if not p: + break + op, av = p[0] + if op is LITERAL: + cappend((op, av)) + else: + break + else: + charset = c + elif op is BRANCH: + c = [] + cappend = c.append + for p in av[1]: + if not p: + break + op, av = p[0] + if op is LITERAL: + cappend((op, av)) + else: + break + else: + charset = c + elif op is IN: + charset = av +## if prefix: +## print "*** PREFIX", prefix, prefix_skip +## if charset: +## print "*** CHARSET", charset + # add an info block + emit = code.append + emit(OPCODES[INFO]) + skip = len(code); emit(0) + # literal flag + mask = 0 + if prefix: + mask = SRE_INFO_PREFIX + if len(prefix) == prefix_skip == len(pattern.data): + mask = mask + SRE_INFO_LITERAL + elif charset: + mask = mask + SRE_INFO_CHARSET + emit(mask) + # pattern length + if lo < MAXCODE: + emit(lo) + else: + emit(MAXCODE) + prefix = prefix[:MAXCODE] + if hi < MAXCODE: + emit(hi) + else: + emit(0) + # add literal prefix + if prefix: + emit(len(prefix)) # length + emit(prefix_skip) # skip + code.extend(prefix) + # generate overlap table + table = [-1] + ([0]*len(prefix)) + for i in xrange(len(prefix)): + table[i+1] = table[i]+1 + while table[i+1] > 0 and prefix[i] != prefix[table[i+1]-1]: + table[i+1] = table[table[i+1]-1]+1 + code.extend(table[1:]) # don't store first entry + elif charset: + _compile_charset(charset, flags, code) + code[skip] = len(code) - skip + +try: + unicode +except NameError: + STRING_TYPES = (type(""),) +else: + STRING_TYPES = (type(""), type(unicode(""))) + +def isstring(obj): + for tp in STRING_TYPES: + if isinstance(obj, tp): + return 1 + return 0 + +def _code(p, flags): + + flags = p.pattern.flags | flags + code = [] + + # compile info block + _compile_info(code, p, flags) + + # compile the pattern + _compile(code, p.data, flags) + + code.append(OPCODES[SUCCESS]) + + return code + +def compile(p, flags=0): + # internal: convert pattern list to internal format + + if isstring(p): + import sre_parse + pattern = p + p = sre_parse.parse(p, flags) + else: + pattern = None + + code = _code(p, flags) + + # print code + + # XXX: <fl> get rid of this limitation! + if p.pattern.groups > 100: + raise AssertionError( + "sorry, but this version only supports 100 named groups" + ) + + # map in either direction + groupindex = p.pattern.groupdict + indexgroup = [None] * p.pattern.groups + for k, i in groupindex.items(): + indexgroup[i] = k + + return _sre.compile( + pattern, flags | p.pattern.flags, code, + p.pattern.groups-1, + groupindex, indexgroup + ) diff --git a/src/main/resources/PythonLibs/sre_constants.py b/src/main/resources/PythonLibs/sre_constants.py new file mode 100644 index 0000000000000000000000000000000000000000..b0175e71be6597717244555654e3a9268bb6b439 --- /dev/null +++ b/src/main/resources/PythonLibs/sre_constants.py @@ -0,0 +1,259 @@ +# +# Secret Labs' Regular Expression Engine +# +# various symbols used by the regular expression engine. +# run this script to update the _sre include files! +# +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. +# +# See the sre.py file for information on usage and redistribution. +# + +"""Internal support module for sre""" + +# update when constants are added or removed + +MAGIC = 20031017 + +from _sre import MAXREPEAT + +# SRE standard exception (access as sre.error) +# should this really be here? + +class error(Exception): + pass + +# operators + +FAILURE = "failure" +SUCCESS = "success" + +ANY = "any" +ANY_ALL = "any_all" +ASSERT = "assert" +ASSERT_NOT = "assert_not" +AT = "at" +BIGCHARSET = "bigcharset" +BRANCH = "branch" +CALL = "call" +CATEGORY = "category" +CHARSET = "charset" +GROUPREF = "groupref" +GROUPREF_IGNORE = "groupref_ignore" +GROUPREF_EXISTS = "groupref_exists" +IN = "in" +IN_IGNORE = "in_ignore" +INFO = "info" +JUMP = "jump" +LITERAL = "literal" +LITERAL_IGNORE = "literal_ignore" +MARK = "mark" +MAX_REPEAT = "max_repeat" +MAX_UNTIL = "max_until" +MIN_REPEAT = "min_repeat" +MIN_UNTIL = "min_until" +NEGATE = "negate" +NOT_LITERAL = "not_literal" +NOT_LITERAL_IGNORE = "not_literal_ignore" +RANGE = "range" +REPEAT = "repeat" +REPEAT_ONE = "repeat_one" +SUBPATTERN = "subpattern" +MIN_REPEAT_ONE = "min_repeat_one" + +# positions +AT_BEGINNING = "at_beginning" +AT_BEGINNING_LINE = "at_beginning_line" +AT_BEGINNING_STRING = "at_beginning_string" +AT_BOUNDARY = "at_boundary" +AT_NON_BOUNDARY = "at_non_boundary" +AT_END = "at_end" +AT_END_LINE = "at_end_line" +AT_END_STRING = "at_end_string" +AT_LOC_BOUNDARY = "at_loc_boundary" +AT_LOC_NON_BOUNDARY = "at_loc_non_boundary" +AT_UNI_BOUNDARY = "at_uni_boundary" +AT_UNI_NON_BOUNDARY = "at_uni_non_boundary" + +# categories +CATEGORY_DIGIT = "category_digit" +CATEGORY_NOT_DIGIT = "category_not_digit" +CATEGORY_SPACE = "category_space" +CATEGORY_NOT_SPACE = "category_not_space" +CATEGORY_WORD = "category_word" +CATEGORY_NOT_WORD = "category_not_word" +CATEGORY_LINEBREAK = "category_linebreak" +CATEGORY_NOT_LINEBREAK = "category_not_linebreak" +CATEGORY_LOC_WORD = "category_loc_word" +CATEGORY_LOC_NOT_WORD = "category_loc_not_word" +CATEGORY_UNI_DIGIT = "category_uni_digit" +CATEGORY_UNI_NOT_DIGIT = "category_uni_not_digit" +CATEGORY_UNI_SPACE = "category_uni_space" +CATEGORY_UNI_NOT_SPACE = "category_uni_not_space" +CATEGORY_UNI_WORD = "category_uni_word" +CATEGORY_UNI_NOT_WORD = "category_uni_not_word" +CATEGORY_UNI_LINEBREAK = "category_uni_linebreak" +CATEGORY_UNI_NOT_LINEBREAK = "category_uni_not_linebreak" + +OPCODES = [ + + # failure=0 success=1 (just because it looks better that way :-) + FAILURE, SUCCESS, + + ANY, ANY_ALL, + ASSERT, ASSERT_NOT, + AT, + BRANCH, + CALL, + CATEGORY, + CHARSET, BIGCHARSET, + GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE, + IN, IN_IGNORE, + INFO, + JUMP, + LITERAL, LITERAL_IGNORE, + MARK, + MAX_UNTIL, + MIN_UNTIL, + NOT_LITERAL, NOT_LITERAL_IGNORE, + NEGATE, + RANGE, + REPEAT, + REPEAT_ONE, + SUBPATTERN, + MIN_REPEAT_ONE + +] + +ATCODES = [ + AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY, + AT_NON_BOUNDARY, AT_END, AT_END_LINE, AT_END_STRING, + AT_LOC_BOUNDARY, AT_LOC_NON_BOUNDARY, AT_UNI_BOUNDARY, + AT_UNI_NON_BOUNDARY +] + +CHCODES = [ + CATEGORY_DIGIT, CATEGORY_NOT_DIGIT, CATEGORY_SPACE, + CATEGORY_NOT_SPACE, CATEGORY_WORD, CATEGORY_NOT_WORD, + CATEGORY_LINEBREAK, CATEGORY_NOT_LINEBREAK, CATEGORY_LOC_WORD, + CATEGORY_LOC_NOT_WORD, CATEGORY_UNI_DIGIT, CATEGORY_UNI_NOT_DIGIT, + CATEGORY_UNI_SPACE, CATEGORY_UNI_NOT_SPACE, CATEGORY_UNI_WORD, + CATEGORY_UNI_NOT_WORD, CATEGORY_UNI_LINEBREAK, + CATEGORY_UNI_NOT_LINEBREAK +] + +def makedict(list): + d = {} + i = 0 + for item in list: + d[item] = i + i = i + 1 + return d + +OPCODES = makedict(OPCODES) +ATCODES = makedict(ATCODES) +CHCODES = makedict(CHCODES) + +# replacement operations for "ignore case" mode +OP_IGNORE = { + GROUPREF: GROUPREF_IGNORE, + IN: IN_IGNORE, + LITERAL: LITERAL_IGNORE, + NOT_LITERAL: NOT_LITERAL_IGNORE +} + +AT_MULTILINE = { + AT_BEGINNING: AT_BEGINNING_LINE, + AT_END: AT_END_LINE +} + +AT_LOCALE = { + AT_BOUNDARY: AT_LOC_BOUNDARY, + AT_NON_BOUNDARY: AT_LOC_NON_BOUNDARY +} + +AT_UNICODE = { + AT_BOUNDARY: AT_UNI_BOUNDARY, + AT_NON_BOUNDARY: AT_UNI_NON_BOUNDARY +} + +CH_LOCALE = { + CATEGORY_DIGIT: CATEGORY_DIGIT, + CATEGORY_NOT_DIGIT: CATEGORY_NOT_DIGIT, + CATEGORY_SPACE: CATEGORY_SPACE, + CATEGORY_NOT_SPACE: CATEGORY_NOT_SPACE, + CATEGORY_WORD: CATEGORY_LOC_WORD, + CATEGORY_NOT_WORD: CATEGORY_LOC_NOT_WORD, + CATEGORY_LINEBREAK: CATEGORY_LINEBREAK, + CATEGORY_NOT_LINEBREAK: CATEGORY_NOT_LINEBREAK +} + +CH_UNICODE = { + CATEGORY_DIGIT: CATEGORY_UNI_DIGIT, + CATEGORY_NOT_DIGIT: CATEGORY_UNI_NOT_DIGIT, + CATEGORY_SPACE: CATEGORY_UNI_SPACE, + CATEGORY_NOT_SPACE: CATEGORY_UNI_NOT_SPACE, + CATEGORY_WORD: CATEGORY_UNI_WORD, + CATEGORY_NOT_WORD: CATEGORY_UNI_NOT_WORD, + CATEGORY_LINEBREAK: CATEGORY_UNI_LINEBREAK, + CATEGORY_NOT_LINEBREAK: CATEGORY_UNI_NOT_LINEBREAK +} + +# flags +SRE_FLAG_TEMPLATE = 1 # template mode (disable backtracking) +SRE_FLAG_IGNORECASE = 2 # case insensitive +SRE_FLAG_LOCALE = 4 # honour system locale +SRE_FLAG_MULTILINE = 8 # treat target as multiline string +SRE_FLAG_DOTALL = 16 # treat target as a single string +SRE_FLAG_UNICODE = 32 # use unicode locale +SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments +SRE_FLAG_DEBUG = 128 # debugging + +# flags for INFO primitive +SRE_INFO_PREFIX = 1 # has prefix +SRE_INFO_LITERAL = 2 # entire pattern is literal (given by prefix) +SRE_INFO_CHARSET = 4 # pattern starts with character from given set + +if __name__ == "__main__": + def dump(f, d, prefix): + items = d.items() + items.sort(key=lambda a: a[1]) + for k, v in items: + f.write("#define %s_%s %s\n" % (prefix, k.upper(), v)) + f = open("sre_constants.h", "w") + f.write("""\ +/* + * Secret Labs' Regular Expression Engine + * + * regular expression matching engine + * + * NOTE: This file is generated by sre_constants.py. If you need + * to change anything in here, edit sre_constants.py and run it. + * + * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. + * + * See the _sre.c file for information on usage and redistribution. + */ + +""") + + f.write("#define SRE_MAGIC %d\n" % MAGIC) + + dump(f, OPCODES, "SRE_OP") + dump(f, ATCODES, "SRE") + dump(f, CHCODES, "SRE") + + f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE) + f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE) + f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE) + f.write("#define SRE_FLAG_MULTILINE %d\n" % SRE_FLAG_MULTILINE) + f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL) + f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE) + f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE) + + f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX) + f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL) + f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET) + + f.close() + print "done" diff --git a/src/main/resources/PythonLibs/sre_parse.py b/src/main/resources/PythonLibs/sre_parse.py new file mode 100644 index 0000000000000000000000000000000000000000..a0cf34414b6335d2747bcc319a410bce1d18a702 --- /dev/null +++ b/src/main/resources/PythonLibs/sre_parse.py @@ -0,0 +1,801 @@ +# +# Secret Labs' Regular Expression Engine +# +# convert re-style regular expression to sre pattern +# +# Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. +# +# See the sre.py file for information on usage and redistribution. +# + +"""Internal support module for sre""" + +# XXX: show string offset and offending character for all errors + +import sys + +from sre_constants import * +from _sre import MAXREPEAT + +SPECIAL_CHARS = ".\\[{()*+?^$|" +REPEAT_CHARS = "*+?{" + +DIGITS = set("0123456789") + +OCTDIGITS = set("01234567") +HEXDIGITS = set("0123456789abcdefABCDEF") + +WHITESPACE = set(" \t\n\r\v\f") + +ESCAPES = { + r"\a": (LITERAL, ord("\a")), + r"\b": (LITERAL, ord("\b")), + r"\f": (LITERAL, ord("\f")), + r"\n": (LITERAL, ord("\n")), + r"\r": (LITERAL, ord("\r")), + r"\t": (LITERAL, ord("\t")), + r"\v": (LITERAL, ord("\v")), + r"\\": (LITERAL, ord("\\")) +} + +CATEGORIES = { + r"\A": (AT, AT_BEGINNING_STRING), # start of string + r"\b": (AT, AT_BOUNDARY), + r"\B": (AT, AT_NON_BOUNDARY), + r"\d": (IN, [(CATEGORY, CATEGORY_DIGIT)]), + r"\D": (IN, [(CATEGORY, CATEGORY_NOT_DIGIT)]), + r"\s": (IN, [(CATEGORY, CATEGORY_SPACE)]), + r"\S": (IN, [(CATEGORY, CATEGORY_NOT_SPACE)]), + r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), + r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), + r"\Z": (AT, AT_END_STRING), # end of string +} + +FLAGS = { + # standard flags + "i": SRE_FLAG_IGNORECASE, + "L": SRE_FLAG_LOCALE, + "m": SRE_FLAG_MULTILINE, + "s": SRE_FLAG_DOTALL, + "x": SRE_FLAG_VERBOSE, + # extensions + "t": SRE_FLAG_TEMPLATE, + "u": SRE_FLAG_UNICODE, +} + +class Pattern: + # master pattern object. keeps track of global attributes + def __init__(self): + self.flags = 0 + self.open = [] + self.groups = 1 + self.groupdict = {} + def opengroup(self, name=None): + gid = self.groups + self.groups = gid + 1 + if name is not None: + ogid = self.groupdict.get(name, None) + if ogid is not None: + raise error, ("redefinition of group name %s as group %d; " + "was group %d" % (repr(name), gid, ogid)) + self.groupdict[name] = gid + self.open.append(gid) + return gid + def closegroup(self, gid): + self.open.remove(gid) + def checkgroup(self, gid): + return gid < self.groups and gid not in self.open + +class SubPattern: + # a subpattern, in intermediate form + def __init__(self, pattern, data=None): + self.pattern = pattern + if data is None: + data = [] + self.data = data + self.width = None + def dump(self, level=0): + nl = 1 + seqtypes = type(()), type([]) + for op, av in self.data: + print level*" " + op,; nl = 0 + if op == "in": + # member sublanguage + print; nl = 1 + for op, a in av: + print (level+1)*" " + op, a + elif op == "branch": + print; nl = 1 + i = 0 + for a in av[1]: + if i > 0: + print level*" " + "or" + a.dump(level+1); nl = 1 + i = i + 1 + elif type(av) in seqtypes: + for a in av: + if isinstance(a, SubPattern): + if not nl: print + a.dump(level+1); nl = 1 + else: + print a, ; nl = 0 + else: + print av, ; nl = 0 + if not nl: print + def __repr__(self): + return repr(self.data) + def __len__(self): + return len(self.data) + def __delitem__(self, index): + del self.data[index] + def __getitem__(self, index): + if isinstance(index, slice): + return SubPattern(self.pattern, self.data[index]) + return self.data[index] + def __setitem__(self, index, code): + self.data[index] = code + def insert(self, index, code): + self.data.insert(index, code) + def append(self, code): + self.data.append(code) + def getwidth(self): + # determine the width (min, max) for this subpattern + if self.width: + return self.width + lo = hi = 0L + UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY) + REPEATCODES = (MIN_REPEAT, MAX_REPEAT) + for op, av in self.data: + if op is BRANCH: + i = sys.maxint + j = 0 + for av in av[1]: + l, h = av.getwidth() + i = min(i, l) + j = max(j, h) + lo = lo + i + hi = hi + j + elif op is CALL: + i, j = av.getwidth() + lo = lo + i + hi = hi + j + elif op is SUBPATTERN: + i, j = av[1].getwidth() + lo = lo + i + hi = hi + j + elif op in REPEATCODES: + i, j = av[2].getwidth() + lo = lo + long(i) * av[0] + hi = hi + long(j) * av[1] + elif op in UNITCODES: + lo = lo + 1 + hi = hi + 1 + elif op == SUCCESS: + break + self.width = int(min(lo, sys.maxint)), int(min(hi, sys.maxint)) + return self.width + +class Tokenizer: + def __init__(self, string): + self.string = string + self.index = 0 + self.__next() + def __next(self): + if self.index >= len(self.string): + self.next = None + return + char = self.string[self.index] + if char[0] == "\\": + try: + c = self.string[self.index + 1] + except IndexError: + raise error, "bogus escape (end of line)" + char = char + c + self.index = self.index + len(char) + self.next = char + def match(self, char, skip=1): + if char == self.next: + if skip: + self.__next() + return 1 + return 0 + def get(self): + this = self.next + self.__next() + return this + def tell(self): + return self.index, self.next + def seek(self, index): + self.index, self.next = index + +def isident(char): + return "a" <= char <= "z" or "A" <= char <= "Z" or char == "_" + +def isdigit(char): + return "0" <= char <= "9" + +def isname(name): + # check that group name is a valid string + if not isident(name[0]): + return False + for char in name[1:]: + if not isident(char) and not isdigit(char): + return False + return True + +def _class_escape(source, escape): + # handle escape code inside character class + code = ESCAPES.get(escape) + if code: + return code + code = CATEGORIES.get(escape) + if code and code[0] == IN: + return code + try: + c = escape[1:2] + if c == "x": + # hexadecimal escape (exactly two digits) + while source.next in HEXDIGITS and len(escape) < 4: + escape = escape + source.get() + escape = escape[2:] + if len(escape) != 2: + raise error, "bogus escape: %s" % repr("\\" + escape) + return LITERAL, int(escape, 16) & 0xff + elif c in OCTDIGITS: + # octal escape (up to three digits) + while source.next in OCTDIGITS and len(escape) < 4: + escape = escape + source.get() + escape = escape[1:] + return LITERAL, int(escape, 8) & 0xff + elif c in DIGITS: + raise error, "bogus escape: %s" % repr(escape) + if len(escape) == 2: + return LITERAL, ord(escape[1]) + except ValueError: + pass + raise error, "bogus escape: %s" % repr(escape) + +def _escape(source, escape, state): + # handle escape code in expression + code = CATEGORIES.get(escape) + if code: + return code + code = ESCAPES.get(escape) + if code: + return code + try: + c = escape[1:2] + if c == "x": + # hexadecimal escape + while source.next in HEXDIGITS and len(escape) < 4: + escape = escape + source.get() + if len(escape) != 4: + raise ValueError + return LITERAL, int(escape[2:], 16) & 0xff + elif c == "0": + # octal escape + while source.next in OCTDIGITS and len(escape) < 4: + escape = escape + source.get() + return LITERAL, int(escape[1:], 8) & 0xff + elif c in DIGITS: + # octal escape *or* decimal group reference (sigh) + if source.next in DIGITS: + escape = escape + source.get() + if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and + source.next in OCTDIGITS): + # got three octal digits; this is an octal escape + escape = escape + source.get() + return LITERAL, int(escape[1:], 8) & 0xff + # not an octal escape, so this is a group reference + group = int(escape[1:]) + if group < state.groups: + if not state.checkgroup(group): + raise error, "cannot refer to open group" + return GROUPREF, group + raise ValueError + if len(escape) == 2: + return LITERAL, ord(escape[1]) + except ValueError: + pass + raise error, "bogus escape: %s" % repr(escape) + +def _parse_sub(source, state, nested=1): + # parse an alternation: a|b|c + + items = [] + itemsappend = items.append + sourcematch = source.match + while 1: + itemsappend(_parse(source, state)) + if sourcematch("|"): + continue + if not nested: + break + if not source.next or sourcematch(")", 0): + break + else: + raise error, "pattern not properly closed" + + if len(items) == 1: + return items[0] + + subpattern = SubPattern(state) + subpatternappend = subpattern.append + + # check if all items share a common prefix + while 1: + prefix = None + for item in items: + if not item: + break + if prefix is None: + prefix = item[0] + elif item[0] != prefix: + break + else: + # all subitems start with a common "prefix". + # move it out of the branch + for item in items: + del item[0] + subpatternappend(prefix) + continue # check next one + break + + # check if the branch can be replaced by a character set + for item in items: + if len(item) != 1 or item[0][0] != LITERAL: + break + else: + # we can store this as a character set instead of a + # branch (the compiler may optimize this even more) + set = [] + setappend = set.append + for item in items: + setappend(item[0]) + subpatternappend((IN, set)) + return subpattern + + subpattern.append((BRANCH, (None, items))) + return subpattern + +def _parse_sub_cond(source, state, condgroup): + item_yes = _parse(source, state) + if source.match("|"): + item_no = _parse(source, state) + if source.match("|"): + raise error, "conditional backref with more than two branches" + else: + item_no = None + if source.next and not source.match(")", 0): + raise error, "pattern not properly closed" + subpattern = SubPattern(state) + subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) + return subpattern + +_PATTERNENDERS = set("|)") +_ASSERTCHARS = set("=!<") +_LOOKBEHINDASSERTCHARS = set("=!") +_REPEATCODES = set([MIN_REPEAT, MAX_REPEAT]) + +def _parse(source, state): + # parse a simple pattern + subpattern = SubPattern(state) + + # precompute constants into local variables + subpatternappend = subpattern.append + sourceget = source.get + sourcematch = source.match + _len = len + PATTERNENDERS = _PATTERNENDERS + ASSERTCHARS = _ASSERTCHARS + LOOKBEHINDASSERTCHARS = _LOOKBEHINDASSERTCHARS + REPEATCODES = _REPEATCODES + + while 1: + + if source.next in PATTERNENDERS: + break # end of subpattern + this = sourceget() + if this is None: + break # end of pattern + + if state.flags & SRE_FLAG_VERBOSE: + # skip whitespace and comments + if this in WHITESPACE: + continue + if this == "#": + while 1: + this = sourceget() + if this in (None, "\n"): + break + continue + + if this and this[0] not in SPECIAL_CHARS: + subpatternappend((LITERAL, ord(this))) + + elif this == "[": + # character set + set = [] + setappend = set.append +## if sourcematch(":"): +## pass # handle character classes + if sourcematch("^"): + setappend((NEGATE, None)) + # check remaining characters + start = set[:] + while 1: + this = sourceget() + if this == "]" and set != start: + break + elif this and this[0] == "\\": + code1 = _class_escape(source, this) + elif this: + code1 = LITERAL, ord(this) + else: + raise error, "unexpected end of regular expression" + if sourcematch("-"): + # potential range + this = sourceget() + if this == "]": + if code1[0] is IN: + code1 = code1[1][0] + setappend(code1) + setappend((LITERAL, ord("-"))) + break + elif this: + if this[0] == "\\": + code2 = _class_escape(source, this) + else: + code2 = LITERAL, ord(this) + if code1[0] != LITERAL or code2[0] != LITERAL: + raise error, "bad character range" + lo = code1[1] + hi = code2[1] + if hi < lo: + raise error, "bad character range" + setappend((RANGE, (lo, hi))) + else: + raise error, "unexpected end of regular expression" + else: + if code1[0] is IN: + code1 = code1[1][0] + setappend(code1) + + # XXX: <fl> should move set optimization to compiler! + if _len(set)==1 and set[0][0] is LITERAL: + subpatternappend(set[0]) # optimization + elif _len(set)==2 and set[0][0] is NEGATE and set[1][0] is LITERAL: + subpatternappend((NOT_LITERAL, set[1][1])) # optimization + else: + # XXX: <fl> should add charmap optimization here + subpatternappend((IN, set)) + + elif this and this[0] in REPEAT_CHARS: + # repeat previous item + if this == "?": + min, max = 0, 1 + elif this == "*": + min, max = 0, MAXREPEAT + + elif this == "+": + min, max = 1, MAXREPEAT + elif this == "{": + if source.next == "}": + subpatternappend((LITERAL, ord(this))) + continue + here = source.tell() + min, max = 0, MAXREPEAT + lo = hi = "" + while source.next in DIGITS: + lo = lo + source.get() + if sourcematch(","): + while source.next in DIGITS: + hi = hi + sourceget() + else: + hi = lo + if not sourcematch("}"): + subpatternappend((LITERAL, ord(this))) + source.seek(here) + continue + if lo: + min = int(lo) + if min >= MAXREPEAT: + raise OverflowError("the repetition number is too large") + if hi: + max = int(hi) + if max >= MAXREPEAT: + raise OverflowError("the repetition number is too large") + if max < min: + raise error("bad repeat interval") + else: + raise error, "not supported" + # figure out which item to repeat + if subpattern: + item = subpattern[-1:] + else: + item = None + if not item or (_len(item) == 1 and item[0][0] == AT): + raise error, "nothing to repeat" + if item[0][0] in REPEATCODES: + raise error, "multiple repeat" + if sourcematch("?"): + subpattern[-1] = (MIN_REPEAT, (min, max, item)) + else: + subpattern[-1] = (MAX_REPEAT, (min, max, item)) + + elif this == ".": + subpatternappend((ANY, None)) + + elif this == "(": + group = 1 + name = None + condgroup = None + if sourcematch("?"): + group = 0 + # options + if sourcematch("P"): + # python extensions + if sourcematch("<"): + # named group: skip forward to end of name + name = "" + while 1: + char = sourceget() + if char is None: + raise error, "unterminated name" + if char == ">": + break + name = name + char + group = 1 + if not name: + raise error("missing group name") + if not isname(name): + raise error, "bad character in group name" + elif sourcematch("="): + # named backreference + name = "" + while 1: + char = sourceget() + if char is None: + raise error, "unterminated name" + if char == ")": + break + name = name + char + if not name: + raise error("missing group name") + if not isname(name): + raise error, "bad character in group name" + gid = state.groupdict.get(name) + if gid is None: + raise error, "unknown group name" + subpatternappend((GROUPREF, gid)) + continue + else: + char = sourceget() + if char is None: + raise error, "unexpected end of pattern" + raise error, "unknown specifier: ?P%s" % char + elif sourcematch(":"): + # non-capturing group + group = 2 + elif sourcematch("#"): + # comment + while 1: + if source.next is None or source.next == ")": + break + sourceget() + if not sourcematch(")"): + raise error, "unbalanced parenthesis" + continue + elif source.next in ASSERTCHARS: + # lookahead assertions + char = sourceget() + dir = 1 + if char == "<": + if source.next not in LOOKBEHINDASSERTCHARS: + raise error, "syntax error" + dir = -1 # lookbehind + char = sourceget() + p = _parse_sub(source, state) + if not sourcematch(")"): + raise error, "unbalanced parenthesis" + if char == "=": + subpatternappend((ASSERT, (dir, p))) + else: + subpatternappend((ASSERT_NOT, (dir, p))) + continue + elif sourcematch("("): + # conditional backreference group + condname = "" + while 1: + char = sourceget() + if char is None: + raise error, "unterminated name" + if char == ")": + break + condname = condname + char + group = 2 + if not condname: + raise error("missing group name") + if isname(condname): + condgroup = state.groupdict.get(condname) + if condgroup is None: + raise error, "unknown group name" + else: + try: + condgroup = int(condname) + except ValueError: + raise error, "bad character in group name" + else: + # flags + if not source.next in FLAGS: + raise error, "unexpected end of pattern" + while source.next in FLAGS: + state.flags = state.flags | FLAGS[sourceget()] + if group: + # parse group contents + if group == 2: + # anonymous group + group = None + else: + group = state.opengroup(name) + if condgroup: + p = _parse_sub_cond(source, state, condgroup) + else: + p = _parse_sub(source, state) + if not sourcematch(")"): + raise error, "unbalanced parenthesis" + if group is not None: + state.closegroup(group) + subpatternappend((SUBPATTERN, (group, p))) + else: + while 1: + char = sourceget() + if char is None: + raise error, "unexpected end of pattern" + if char == ")": + break + raise error, "unknown extension" + + elif this == "^": + subpatternappend((AT, AT_BEGINNING)) + + elif this == "$": + subpattern.append((AT, AT_END)) + + elif this and this[0] == "\\": + code = _escape(source, this, state) + subpatternappend(code) + + else: + raise error, "parser error" + + return subpattern + +def parse(str, flags=0, pattern=None): + # parse 're' pattern into list of (opcode, argument) tuples + + source = Tokenizer(str) + + if pattern is None: + pattern = Pattern() + pattern.flags = flags + pattern.str = str + + p = _parse_sub(source, pattern, 0) + + tail = source.get() + if tail == ")": + raise error, "unbalanced parenthesis" + elif tail: + raise error, "bogus characters at end of regular expression" + + if flags & SRE_FLAG_DEBUG: + p.dump() + + if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE: + # the VERBOSE flag was switched on inside the pattern. to be + # on the safe side, we'll parse the whole thing again... + return parse(str, p.pattern.flags) + + return p + +def parse_template(source, pattern): + # parse 're' replacement string into list of literals and + # group references + s = Tokenizer(source) + sget = s.get + p = [] + a = p.append + def literal(literal, p=p, pappend=a): + if p and p[-1][0] is LITERAL: + p[-1] = LITERAL, p[-1][1] + literal + else: + pappend((LITERAL, literal)) + sep = source[:0] + if type(sep) is type(""): + makechar = chr + else: + makechar = unichr + while 1: + this = sget() + if this is None: + break # end of replacement string + if this and this[0] == "\\": + # group + c = this[1:2] + if c == "g": + name = "" + if s.match("<"): + while 1: + char = sget() + if char is None: + raise error, "unterminated group name" + if char == ">": + break + name = name + char + if not name: + raise error, "missing group name" + try: + index = int(name) + if index < 0: + raise error, "negative group number" + except ValueError: + if not isname(name): + raise error, "bad character in group name" + try: + index = pattern.groupindex[name] + except KeyError: + raise IndexError, "unknown group name" + a((MARK, index)) + elif c == "0": + if s.next in OCTDIGITS: + this = this + sget() + if s.next in OCTDIGITS: + this = this + sget() + literal(makechar(int(this[1:], 8) & 0xff)) + elif c in DIGITS: + isoctal = False + if s.next in DIGITS: + this = this + sget() + if (c in OCTDIGITS and this[2] in OCTDIGITS and + s.next in OCTDIGITS): + this = this + sget() + isoctal = True + literal(makechar(int(this[1:], 8) & 0xff)) + if not isoctal: + a((MARK, int(this[1:]))) + else: + try: + this = makechar(ESCAPES[this][1]) + except KeyError: + pass + literal(this) + else: + literal(this) + # convert template to groups and literals lists + i = 0 + groups = [] + groupsappend = groups.append + literals = [None] * len(p) + for c, s in p: + if c is MARK: + groupsappend((i, s)) + # literal[i] is already None + else: + literals[i] = s + i = i + 1 + return groups, literals + +def expand_template(template, match): + g = match.group + sep = match.string[:0] + groups, literals = template + literals = literals[:] + try: + for index, group in groups: + literals[index] = s = g(group) + if s is None: + raise error, "unmatched group" + except IndexError: + raise error, "invalid group reference" + return sep.join(literals) diff --git a/src/main/resources/PythonLibs/ssl.py b/src/main/resources/PythonLibs/ssl.py new file mode 100644 index 0000000000000000000000000000000000000000..f4dce4dfe289ef136a16a4984872c034cc359d6c --- /dev/null +++ b/src/main/resources/PythonLibs/ssl.py @@ -0,0 +1,10 @@ +""" +This module provides very limited support for the SSL module on jython. + +See the jython wiki for more information. +http://wiki.python.org/jython/SSLModule +""" + +import socket + +wrap_socket = socket.ssl diff --git a/src/main/resources/PythonLibs/stat.py b/src/main/resources/PythonLibs/stat.py new file mode 100644 index 0000000000000000000000000000000000000000..abed5c9e0f57a118ee58aef158cf3c455d9821ec --- /dev/null +++ b/src/main/resources/PythonLibs/stat.py @@ -0,0 +1,96 @@ +"""Constants/functions for interpreting results of os.stat() and os.lstat(). + +Suggested usage: from stat import * +""" + +# Indices for stat struct members in the tuple returned by os.stat() + +ST_MODE = 0 +ST_INO = 1 +ST_DEV = 2 +ST_NLINK = 3 +ST_UID = 4 +ST_GID = 5 +ST_SIZE = 6 +ST_ATIME = 7 +ST_MTIME = 8 +ST_CTIME = 9 + +# Extract bits from the mode + +def S_IMODE(mode): + return mode & 07777 + +def S_IFMT(mode): + return mode & 0170000 + +# Constants used as S_IFMT() for various file types +# (not all are implemented on all systems) + +S_IFDIR = 0040000 +S_IFCHR = 0020000 +S_IFBLK = 0060000 +S_IFREG = 0100000 +S_IFIFO = 0010000 +S_IFLNK = 0120000 +S_IFSOCK = 0140000 + +# Functions to test for each file type + +def S_ISDIR(mode): + return S_IFMT(mode) == S_IFDIR + +def S_ISCHR(mode): + return S_IFMT(mode) == S_IFCHR + +def S_ISBLK(mode): + return S_IFMT(mode) == S_IFBLK + +def S_ISREG(mode): + return S_IFMT(mode) == S_IFREG + +def S_ISFIFO(mode): + return S_IFMT(mode) == S_IFIFO + +def S_ISLNK(mode): + return S_IFMT(mode) == S_IFLNK + +def S_ISSOCK(mode): + return S_IFMT(mode) == S_IFSOCK + +# Names for permission bits + +S_ISUID = 04000 +S_ISGID = 02000 +S_ENFMT = S_ISGID +S_ISVTX = 01000 +S_IREAD = 00400 +S_IWRITE = 00200 +S_IEXEC = 00100 +S_IRWXU = 00700 +S_IRUSR = 00400 +S_IWUSR = 00200 +S_IXUSR = 00100 +S_IRWXG = 00070 +S_IRGRP = 00040 +S_IWGRP = 00020 +S_IXGRP = 00010 +S_IRWXO = 00007 +S_IROTH = 00004 +S_IWOTH = 00002 +S_IXOTH = 00001 + +# Names for file flags + +UF_NODUMP = 0x00000001 +UF_IMMUTABLE = 0x00000002 +UF_APPEND = 0x00000004 +UF_OPAQUE = 0x00000008 +UF_NOUNLINK = 0x00000010 +UF_COMPRESSED = 0x00000020 # OS X: file is hfs-compressed +UF_HIDDEN = 0x00008000 # OS X: file should not be displayed +SF_ARCHIVED = 0x00010000 +SF_IMMUTABLE = 0x00020000 +SF_APPEND = 0x00040000 +SF_NOUNLINK = 0x00100000 +SF_SNAPSHOT = 0x00200000 diff --git a/src/main/resources/PythonLibs/string.py b/src/main/resources/PythonLibs/string.py new file mode 100644 index 0000000000000000000000000000000000000000..97278034a0fb8209d9602a682885ece73024f0be --- /dev/null +++ b/src/main/resources/PythonLibs/string.py @@ -0,0 +1,642 @@ +"""A collection of string operations (most are no longer used). + +Warning: most of the code you see here isn't normally used nowadays. +Beginning with Python 1.6, many of these functions are implemented as +methods on the standard string object. They used to be implemented by +a built-in module called strop, but strop is now obsolete itself. + +Public module variables: + +whitespace -- a string containing all characters considered whitespace +lowercase -- a string containing all characters considered lowercase letters +uppercase -- a string containing all characters considered uppercase letters +letters -- a string containing all characters considered letters +digits -- a string containing all characters considered decimal digits +hexdigits -- a string containing all characters considered hexadecimal digits +octdigits -- a string containing all characters considered octal digits +punctuation -- a string containing all characters considered punctuation +printable -- a string containing all characters considered printable + +""" + +# Some strings for ctype-style character classification +whitespace = ' \t\n\r\v\f' +lowercase = 'abcdefghijklmnopqrstuvwxyz' +uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +letters = lowercase + uppercase +ascii_lowercase = lowercase +ascii_uppercase = uppercase +ascii_letters = ascii_lowercase + ascii_uppercase +digits = '0123456789' +hexdigits = digits + 'abcdef' + 'ABCDEF' +octdigits = '01234567' +punctuation = """!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" +printable = digits + letters + punctuation + whitespace + +# Case conversion helpers +# Use str to convert Unicode literal in case of -U +l = map(chr, xrange(256)) +_idmap = str('').join(l) +del l + +# Functions which aren't available as string methods. + +# Capitalize the words in a string, e.g. " aBc dEf " -> "Abc Def". +def capwords(s, sep=None): + """capwords(s [,sep]) -> string + + Split the argument into words using split, capitalize each + word using capitalize, and join the capitalized words using + join. If the optional second argument sep is absent or None, + runs of whitespace characters are replaced by a single space + and leading and trailing whitespace are removed, otherwise + sep is used to split and join the words. + + """ + return (sep or ' ').join(x.capitalize() for x in s.split(sep)) + + +# Construct a translation string +_idmapL = None +def maketrans(fromstr, tostr): + """maketrans(frm, to) -> string + + Return a translation table (a string of 256 bytes long) + suitable for use in string.translate. The strings frm and to + must be of the same length. + + """ + if len(fromstr) != len(tostr): + raise ValueError, "maketrans arguments must have same length" + global _idmapL + if not _idmapL: + _idmapL = list(_idmap) + L = _idmapL[:] + fromstr = map(ord, fromstr) + for i in range(len(fromstr)): + L[fromstr[i]] = tostr[i] + return ''.join(L) + + + +#################################################################### +import re as _re + +class _multimap: + """Helper class for combining multiple mappings. + + Used by .{safe_,}substitute() to combine the mapping and keyword + arguments. + """ + def __init__(self, primary, secondary): + self._primary = primary + self._secondary = secondary + + def __getitem__(self, key): + try: + return self._primary[key] + except KeyError: + return self._secondary[key] + + +class _TemplateMetaclass(type): + pattern = r""" + %(delim)s(?: + (?P<escaped>%(delim)s) | # Escape sequence of two delimiters + (?P<named>%(id)s) | # delimiter and a Python identifier + {(?P<braced>%(id)s)} | # delimiter and a braced identifier + (?P<invalid>) # Other ill-formed delimiter exprs + ) + """ + + def __init__(cls, name, bases, dct): + super(_TemplateMetaclass, cls).__init__(name, bases, dct) + if 'pattern' in dct: + pattern = cls.pattern + else: + pattern = _TemplateMetaclass.pattern % { + 'delim' : _re.escape(cls.delimiter), + 'id' : cls.idpattern, + } + cls.pattern = _re.compile(pattern, _re.IGNORECASE | _re.VERBOSE) + + +class Template: + """A string class for supporting $-substitutions.""" + __metaclass__ = _TemplateMetaclass + + delimiter = '$' + idpattern = r'[_a-z][_a-z0-9]*' + + def __init__(self, template): + self.template = template + + # Search for $$, $identifier, ${identifier}, and any bare $'s + + def _invalid(self, mo): + i = mo.start('invalid') + lines = self.template[:i].splitlines(True) + if not lines: + colno = 1 + lineno = 1 + else: + colno = i - len(''.join(lines[:-1])) + lineno = len(lines) + raise ValueError('Invalid placeholder in string: line %d, col %d' % + (lineno, colno)) + + def substitute(self, *args, **kws): + if len(args) > 1: + raise TypeError('Too many positional arguments') + if not args: + mapping = kws + elif kws: + mapping = _multimap(kws, args[0]) + else: + mapping = args[0] + # Helper function for .sub() + def convert(mo): + # Check the most common path first. + named = mo.group('named') or mo.group('braced') + if named is not None: + val = mapping[named] + # We use this idiom instead of str() because the latter will + # fail if val is a Unicode containing non-ASCII characters. + return '%s' % (val,) + if mo.group('escaped') is not None: + return self.delimiter + if mo.group('invalid') is not None: + self._invalid(mo) + raise ValueError('Unrecognized named group in pattern', + self.pattern) + return self.pattern.sub(convert, self.template) + + def safe_substitute(self, *args, **kws): + if len(args) > 1: + raise TypeError('Too many positional arguments') + if not args: + mapping = kws + elif kws: + mapping = _multimap(kws, args[0]) + else: + mapping = args[0] + # Helper function for .sub() + def convert(mo): + named = mo.group('named') + if named is not None: + try: + # We use this idiom instead of str() because the latter + # will fail if val is a Unicode containing non-ASCII + return '%s' % (mapping[named],) + except KeyError: + return self.delimiter + named + braced = mo.group('braced') + if braced is not None: + try: + return '%s' % (mapping[braced],) + except KeyError: + return self.delimiter + '{' + braced + '}' + if mo.group('escaped') is not None: + return self.delimiter + if mo.group('invalid') is not None: + return self.delimiter + raise ValueError('Unrecognized named group in pattern', + self.pattern) + return self.pattern.sub(convert, self.template) + + + +#################################################################### +# NOTE: Everything below here is deprecated. Use string methods instead. +# This stuff will go away in Python 3.0. + +# Backward compatible names for exceptions +index_error = ValueError +atoi_error = ValueError +atof_error = ValueError +atol_error = ValueError + +# convert UPPER CASE letters to lower case +def lower(s): + """lower(s) -> string + + Return a copy of the string s converted to lowercase. + + """ + return s.lower() + +# Convert lower case letters to UPPER CASE +def upper(s): + """upper(s) -> string + + Return a copy of the string s converted to uppercase. + + """ + return s.upper() + +# Swap lower case letters and UPPER CASE +def swapcase(s): + """swapcase(s) -> string + + Return a copy of the string s with upper case characters + converted to lowercase and vice versa. + + """ + return s.swapcase() + +# Strip leading and trailing tabs and spaces +def strip(s, chars=None): + """strip(s [,chars]) -> string + + Return a copy of the string s with leading and trailing + whitespace removed. + If chars is given and not None, remove characters in chars instead. + If chars is unicode, S will be converted to unicode before stripping. + + """ + return s.strip(chars) + +# Strip leading tabs and spaces +def lstrip(s, chars=None): + """lstrip(s [,chars]) -> string + + Return a copy of the string s with leading whitespace removed. + If chars is given and not None, remove characters in chars instead. + + """ + return s.lstrip(chars) + +# Strip trailing tabs and spaces +def rstrip(s, chars=None): + """rstrip(s [,chars]) -> string + + Return a copy of the string s with trailing whitespace removed. + If chars is given and not None, remove characters in chars instead. + + """ + return s.rstrip(chars) + + +# Split a string into a list of space/tab-separated words +def split(s, sep=None, maxsplit=-1): + """split(s [,sep [,maxsplit]]) -> list of strings + + Return a list of the words in the string s, using sep as the + delimiter string. If maxsplit is given, splits at no more than + maxsplit places (resulting in at most maxsplit+1 words). If sep + is not specified or is None, any whitespace string is a separator. + + (split and splitfields are synonymous) + + """ + return s.split(sep, maxsplit) +splitfields = split + +# Split a string into a list of space/tab-separated words +def rsplit(s, sep=None, maxsplit=-1): + """rsplit(s [,sep [,maxsplit]]) -> list of strings + + Return a list of the words in the string s, using sep as the + delimiter string, starting at the end of the string and working + to the front. If maxsplit is given, at most maxsplit splits are + done. If sep is not specified or is None, any whitespace string + is a separator. + """ + return s.rsplit(sep, maxsplit) + +# Join fields with optional separator +def join(words, sep = ' '): + """join(list [,sep]) -> string + + Return a string composed of the words in list, with + intervening occurrences of sep. The default separator is a + single space. + + (joinfields and join are synonymous) + + """ + return sep.join(words) +joinfields = join + +# Find substring, raise exception if not found +def index(s, *args): + """index(s, sub [,start [,end]]) -> int + + Like find but raises ValueError when the substring is not found. + + """ + return s.index(*args) + +# Find last substring, raise exception if not found +def rindex(s, *args): + """rindex(s, sub [,start [,end]]) -> int + + Like rfind but raises ValueError when the substring is not found. + + """ + return s.rindex(*args) + +# Count non-overlapping occurrences of substring +def count(s, *args): + """count(s, sub[, start[,end]]) -> int + + Return the number of occurrences of substring sub in string + s[start:end]. Optional arguments start and end are + interpreted as in slice notation. + + """ + return s.count(*args) + +# Find substring, return -1 if not found +def find(s, *args): + """find(s, sub [,start [,end]]) -> in + + Return the lowest index in s where substring sub is found, + such that sub is contained within s[start,end]. Optional + arguments start and end are interpreted as in slice notation. + + Return -1 on failure. + + """ + return s.find(*args) + +# Find last substring, return -1 if not found +def rfind(s, *args): + """rfind(s, sub [,start [,end]]) -> int + + Return the highest index in s where substring sub is found, + such that sub is contained within s[start,end]. Optional + arguments start and end are interpreted as in slice notation. + + Return -1 on failure. + + """ + return s.rfind(*args) + +# for a bit of speed +_float = float +_int = int +_long = long + +# Convert string to float +def atof(s): + """atof(s) -> float + + Return the floating point number represented by the string s. + + """ + return _float(s) + + +# Convert string to integer +def atoi(s , base=10): + """atoi(s [,base]) -> int + + Return the integer represented by the string s in the given + base, which defaults to 10. The string s must consist of one + or more digits, possibly preceded by a sign. If base is 0, it + is chosen from the leading characters of s, 0 for octal, 0x or + 0X for hexadecimal. If base is 16, a preceding 0x or 0X is + accepted. + + """ + return _int(s, base) + + +# Convert string to long integer +def atol(s, base=10): + """atol(s [,base]) -> long + + Return the long integer represented by the string s in the + given base, which defaults to 10. The string s must consist + of one or more digits, possibly preceded by a sign. If base + is 0, it is chosen from the leading characters of s, 0 for + octal, 0x or 0X for hexadecimal. If base is 16, a preceding + 0x or 0X is accepted. A trailing L or l is not accepted, + unless base is 0. + + """ + return _long(s, base) + + +# Left-justify a string +def ljust(s, width, *args): + """ljust(s, width[, fillchar]) -> string + + Return a left-justified version of s, in a field of the + specified width, padded with spaces as needed. The string is + never truncated. If specified the fillchar is used instead of spaces. + + """ + return s.ljust(width, *args) + +# Right-justify a string +def rjust(s, width, *args): + """rjust(s, width[, fillchar]) -> string + + Return a right-justified version of s, in a field of the + specified width, padded with spaces as needed. The string is + never truncated. If specified the fillchar is used instead of spaces. + + """ + return s.rjust(width, *args) + +# Center a string +def center(s, width, *args): + """center(s, width[, fillchar]) -> string + + Return a center version of s, in a field of the specified + width. padded with spaces as needed. The string is never + truncated. If specified the fillchar is used instead of spaces. + + """ + return s.center(width, *args) + +# Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03' +# Decadent feature: the argument may be a string or a number +# (Use of this is deprecated; it should be a string as with ljust c.s.) +def zfill(x, width): + """zfill(x, width) -> string + + Pad a numeric string x with zeros on the left, to fill a field + of the specified width. The string x is never truncated. + + """ + if not isinstance(x, basestring): + x = repr(x) + return x.zfill(width) + +# Expand tabs in a string. +# Doesn't take non-printing chars into account, but does understand \n. +def expandtabs(s, tabsize=8): + """expandtabs(s [,tabsize]) -> string + + Return a copy of the string s with all tab characters replaced + by the appropriate number of spaces, depending on the current + column, and the tabsize (default 8). + + """ + return s.expandtabs(tabsize) + +# Character translation through look-up table. +def translate(s, table, deletions=""): + """translate(s,table [,deletions]) -> string + + Return a copy of the string s, where all characters occurring + in the optional argument deletions are removed, and the + remaining characters have been mapped through the given + translation table, which must be a string of length 256. The + deletions argument is not allowed for Unicode strings. + + """ + if deletions or table is None: + return s.translate(table, deletions) + else: + # Add s[:0] so that if s is Unicode and table is an 8-bit string, + # table is converted to Unicode. This means that table *cannot* + # be a dictionary -- for that feature, use u.translate() directly. + return s.translate(table + s[:0]) + +# Capitalize a string, e.g. "aBc dEf" -> "Abc def". +def capitalize(s): + """capitalize(s) -> string + + Return a copy of the string s with only its first character + capitalized. + + """ + return s.capitalize() + +# Substring replacement (global) +def replace(s, old, new, maxreplace=-1): + """replace (str, old, new[, maxreplace]) -> string + + Return a copy of string str with all occurrences of substring + old replaced by new. If the optional argument maxreplace is + given, only the first maxreplace occurrences are replaced. + + """ + return s.replace(old, new, maxreplace) + + +# Try importing optional built-in module "strop" -- if it exists, +# it redefines some string operations that are 100-1000 times faster. +# It also defines values for whitespace, lowercase and uppercase +# that match <ctype.h>'s definitions. + +try: + from strop import maketrans, lowercase, uppercase, whitespace + letters = lowercase + uppercase +except ImportError: + pass # Use the original versions + +######################################################################## +# the Formatter class +# see PEP 3101 for details and purpose of this class + +# The hard parts are reused from the C implementation. They're exposed as "_" +# prefixed methods of str and unicode. + +# The overall parser is implemented in str._formatter_parser. +# The field name parser is implemented in str._formatter_field_name_split + +class Formatter(object): + def format(self, format_string, *args, **kwargs): + return self.vformat(format_string, args, kwargs) + + def vformat(self, format_string, args, kwargs): + used_args = set() + result = self._vformat(format_string, args, kwargs, used_args, 2) + self.check_unused_args(used_args, args, kwargs) + return result + + def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): + if recursion_depth < 0: + raise ValueError('Max string recursion exceeded') + result = [] + for literal_text, field_name, format_spec, conversion in \ + self.parse(format_string): + + # output the literal text + if literal_text: + result.append(literal_text) + + # if there's a field, output it + if field_name is not None: + # this is some markup, find the object and do + # the formatting + + # given the field_name, find the object it references + # and the argument it came from + obj, arg_used = self.get_field(field_name, args, kwargs) + used_args.add(arg_used) + + # do any conversion on the resulting object + obj = self.convert_field(obj, conversion) + + # expand the format spec, if needed + format_spec = self._vformat(format_spec, args, kwargs, + used_args, recursion_depth-1) + + # format the object and append to the result + result.append(self.format_field(obj, format_spec)) + + return ''.join(result) + + + def get_value(self, key, args, kwargs): + if isinstance(key, (int, long)): + return args[key] + else: + return kwargs[key] + + + def check_unused_args(self, used_args, args, kwargs): + pass + + + def format_field(self, value, format_spec): + return format(value, format_spec) + + + def convert_field(self, value, conversion): + # do any conversion on the resulting object + if conversion is None: + return value + elif conversion == 's': + return str(value) + elif conversion == 'r': + return repr(value) + raise ValueError("Unknown conversion specifier {0!s}".format(conversion)) + + + # returns an iterable that contains tuples of the form: + # (literal_text, field_name, format_spec, conversion) + # literal_text can be zero length + # field_name can be None, in which case there's no + # object to format and output + # if field_name is not None, it is looked up, formatted + # with format_spec and conversion and then used + def parse(self, format_string): + return format_string._formatter_parser() + + + # given a field_name, find the object it references. + # field_name: the field being looked up, e.g. "0.name" + # or "lookup[3]" + # used_args: a set of which args have been used + # args, kwargs: as passed in to vformat + def get_field(self, field_name, args, kwargs): + first, rest = field_name._formatter_field_name_split() + + obj = self.get_value(first, args, kwargs) + + # loop through the rest of the field_name, doing + # getattr or getitem as needed + for is_attr, i in rest: + if is_attr: + obj = getattr(obj, i) + else: + obj = obj[i] + + return obj, first diff --git a/src/main/resources/PythonLibs/subprocess.py b/src/main/resources/PythonLibs/subprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..b969a16762171c4e4af8189ef65568eadb42d115 --- /dev/null +++ b/src/main/resources/PythonLibs/subprocess.py @@ -0,0 +1,1897 @@ +# subprocess - Subprocesses with accessible I/O streams +# +# For more information about this module, see PEP 324. +# +# This module should remain compatible with Python 2.2, see PEP 291. +# +# Copyright (c) 2003-2005 by Peter Astrand <astrand@lysator.liu.se> +# +# Licensed to PSF under a Contributor Agreement. +# See http://www.python.org/2.4/license for licensing details. + +r"""subprocess - Subprocesses with accessible I/O streams + +This module allows you to spawn processes, connect to their +input/output/error pipes, and obtain their return codes. This module +intends to replace several other, older modules and functions, like: + +os.system +os.spawn* +os.popen* +popen2.* +commands.* + +Information about how the subprocess module can be used to replace these +modules and functions can be found below. + + + +Using the subprocess module +=========================== +This module defines one class called Popen: + +class Popen(args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0): + + +Arguments are: + +args should be a string, or a sequence of program arguments. The +program to execute is normally the first item in the args sequence or +string, but can be explicitly set by using the executable argument. + +On UNIX, with shell=False (default): In this case, the Popen class +uses os.execvp() to execute the child program. args should normally +be a sequence. A string will be treated as a sequence with the string +as the only item (the program to execute). + +On UNIX, with shell=True: If args is a string, it specifies the +command string to execute through the shell. If args is a sequence, +the first item specifies the command string, and any additional items +will be treated as additional shell arguments. + +On Windows: the Popen class uses CreateProcess() to execute the child +program, which operates on strings. If args is a sequence, it will be +converted to a string using the list2cmdline method. Please note that +not all MS Windows applications interpret the command line the same +way: The list2cmdline is designed for applications using the same +rules as the MS C runtime. + +bufsize, if given, has the same meaning as the corresponding argument +to the built-in open() function: 0 means unbuffered, 1 means line +buffered, any other positive value means use a buffer of +(approximately) that size. A negative bufsize means to use the system +default, which usually means fully buffered. The default value for +bufsize is 0 (unbuffered). + +stdin, stdout and stderr specify the executed programs' standard +input, standard output and standard error file handles, respectively. +Valid values are PIPE, an existing file descriptor (a positive +integer), an existing file object, and None. PIPE indicates that a +new pipe to the child should be created. With None, no redirection +will occur; the child's file handles will be inherited from the +parent. Additionally, stderr can be STDOUT, which indicates that the +stderr data from the applications should be captured into the same +file handle as for stdout. + +If preexec_fn is set to a callable object, this object will be called +in the child process just before the child is executed. + +If close_fds is true, all file descriptors except 0, 1 and 2 will be +closed before the child process is executed. + +if shell is true, the specified command will be executed through the +shell. + +If cwd is not None, the current directory will be changed to cwd +before the child is executed. + +If env is not None, it defines the environment variables for the new +process. + +If universal_newlines is true, the file objects stdout and stderr are +opened as a text files, but lines may be terminated by any of '\n', +the Unix end-of-line convention, '\r', the Macintosh convention or +'\r\n', the Windows convention. All of these external representations +are seen as '\n' by the Python program. Note: This feature is only +available if Python is built with universal newline support (the +default). Also, the newlines attribute of the file objects stdout, +stdin and stderr are not updated by the communicate() method. + +The startupinfo and creationflags, if given, will be passed to the +underlying CreateProcess() function. They can specify things such as +appearance of the main window and priority for the new process. +(Windows only) + + +This module also defines some shortcut functions: + +call(*popenargs, **kwargs): + Run command with arguments. Wait for command to complete, then + return the returncode attribute. + + The arguments are the same as for the Popen constructor. Example: + + retcode = call(["ls", "-l"]) + +check_call(*popenargs, **kwargs): + Run command with arguments. Wait for command to complete. If the + exit code was zero then return, otherwise raise + CalledProcessError. The CalledProcessError object will have the + return code in the returncode attribute. + + The arguments are the same as for the Popen constructor. Example: + + check_call(["ls", "-l"]) + +check_output(*popenargs, **kwargs): + Run command with arguments and return its output as a byte string. + + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. + + The arguments are the same as for the Popen constructor. Example: + + output = check_output(["ls", "-l", "/dev/null"]) + + +Exceptions +---------- +Exceptions raised in the child process, before the new program has +started to execute, will be re-raised in the parent. Additionally, +the exception object will have one extra attribute called +'child_traceback', which is a string containing traceback information +from the childs point of view. + +The most common exception raised is OSError. This occurs, for +example, when trying to execute a non-existent file. Applications +should prepare for OSErrors. + +A ValueError will be raised if Popen is called with invalid arguments. + +check_call() and check_output() will raise CalledProcessError, if the +called process returns a non-zero return code. + + +Security +-------- +Unlike some other popen functions, this implementation will never call +/bin/sh implicitly. This means that all characters, including shell +metacharacters, can safely be passed to child processes. + + +Popen objects +============= +Instances of the Popen class have the following methods: + +poll() + Check if child process has terminated. Returns returncode + attribute. + +wait() + Wait for child process to terminate. Returns returncode attribute. + +communicate(input=None) + Interact with process: Send data to stdin. Read data from stdout + and stderr, until end-of-file is reached. Wait for process to + terminate. The optional input argument should be a string to be + sent to the child process, or None, if no data should be sent to + the child. + + communicate() returns a tuple (stdout, stderr). + + Note: The data read is buffered in memory, so do not use this + method if the data size is large or unlimited. + +The following attributes are also available: + +stdin + If the stdin argument is PIPE, this attribute is a file object + that provides input to the child process. Otherwise, it is None. + +stdout + If the stdout argument is PIPE, this attribute is a file object + that provides output from the child process. Otherwise, it is + None. + +stderr + If the stderr argument is PIPE, this attribute is file object that + provides error output from the child process. Otherwise, it is + None. + +pid + The process ID of the child process. + +returncode + The child return code. A None value indicates that the process + hasn't terminated yet. A negative value -N indicates that the + child was terminated by signal N (UNIX only). + + +Replacing older functions with the subprocess module +==================================================== +In this section, "a ==> b" means that b can be used as a replacement +for a. + +Note: All functions in this section fail (more or less) silently if +the executed program cannot be found; this module raises an OSError +exception. + +In the following examples, we assume that the subprocess module is +imported with "from subprocess import *". + + +Replacing /bin/sh shell backquote +--------------------------------- +output=`mycmd myarg` +==> +output = Popen(["mycmd", "myarg"], stdout=PIPE).communicate()[0] + + +Replacing shell pipe line +------------------------- +output=`dmesg | grep hda` +==> +p1 = Popen(["dmesg"], stdout=PIPE) +p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) +output = p2.communicate()[0] + + +Replacing os.system() +--------------------- +sts = os.system("mycmd" + " myarg") +==> +p = Popen("mycmd" + " myarg", shell=True) +pid, sts = os.waitpid(p.pid, 0) + +Note: + +* Calling the program through the shell is usually not required. + +* It's easier to look at the returncode attribute than the + exitstatus. + +A more real-world example would look like this: + +try: + retcode = call("mycmd" + " myarg", shell=True) + if retcode < 0: + print >>sys.stderr, "Child was terminated by signal", -retcode + else: + print >>sys.stderr, "Child returned", retcode +except OSError, e: + print >>sys.stderr, "Execution failed:", e + + +Replacing os.spawn* +------------------- +P_NOWAIT example: + +pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg") +==> +pid = Popen(["/bin/mycmd", "myarg"]).pid + + +P_WAIT example: + +retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg") +==> +retcode = call(["/bin/mycmd", "myarg"]) + + +Vector example: + +os.spawnvp(os.P_NOWAIT, path, args) +==> +Popen([path] + args[1:]) + + +Environment example: + +os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env) +==> +Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"}) + + +Replacing os.popen* +------------------- +pipe = os.popen("cmd", mode='r', bufsize) +==> +pipe = Popen("cmd", shell=True, bufsize=bufsize, stdout=PIPE).stdout + +pipe = os.popen("cmd", mode='w', bufsize) +==> +pipe = Popen("cmd", shell=True, bufsize=bufsize, stdin=PIPE).stdin + + +(child_stdin, child_stdout) = os.popen2("cmd", mode, bufsize) +==> +p = Popen("cmd", shell=True, bufsize=bufsize, + stdin=PIPE, stdout=PIPE, close_fds=True) +(child_stdin, child_stdout) = (p.stdin, p.stdout) + + +(child_stdin, + child_stdout, + child_stderr) = os.popen3("cmd", mode, bufsize) +==> +p = Popen("cmd", shell=True, bufsize=bufsize, + stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) +(child_stdin, + child_stdout, + child_stderr) = (p.stdin, p.stdout, p.stderr) + + +(child_stdin, child_stdout_and_stderr) = os.popen4("cmd", mode, + bufsize) +==> +p = Popen("cmd", shell=True, bufsize=bufsize, + stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) +(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout) + +On Unix, os.popen2, os.popen3 and os.popen4 also accept a sequence as +the command to execute, in which case arguments will be passed +directly to the program without shell intervention. This usage can be +replaced as follows: + +(child_stdin, child_stdout) = os.popen2(["/bin/ls", "-l"], mode, + bufsize) +==> +p = Popen(["/bin/ls", "-l"], bufsize=bufsize, stdin=PIPE, stdout=PIPE) +(child_stdin, child_stdout) = (p.stdin, p.stdout) + +Return code handling translates as follows: + +pipe = os.popen("cmd", 'w') +... +rc = pipe.close() +if rc is not None and rc % 256: + print "There were some errors" +==> +process = Popen("cmd", 'w', shell=True, stdin=PIPE) +... +process.stdin.close() +if process.wait() != 0: + print "There were some errors" + + +Replacing popen2.* +------------------ +(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode) +==> +p = Popen(["somestring"], shell=True, bufsize=bufsize + stdin=PIPE, stdout=PIPE, close_fds=True) +(child_stdout, child_stdin) = (p.stdout, p.stdin) + +On Unix, popen2 also accepts a sequence as the command to execute, in +which case arguments will be passed directly to the program without +shell intervention. This usage can be replaced as follows: + +(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, + mode) +==> +p = Popen(["mycmd", "myarg"], bufsize=bufsize, + stdin=PIPE, stdout=PIPE, close_fds=True) +(child_stdout, child_stdin) = (p.stdout, p.stdin) + +The popen2.Popen3 and popen2.Popen4 basically works as subprocess.Popen, +except that: + +* subprocess.Popen raises an exception if the execution fails +* the capturestderr argument is replaced with the stderr argument. +* stdin=PIPE and stdout=PIPE must be specified. +* popen2 closes all filedescriptors by default, but you have to specify + close_fds=True with subprocess.Popen. +""" + +import sys +mswindows = (sys.platform == "win32") +jython = sys.platform.startswith("java") + +import os +import types +import traceback +import signal + +# Exception classes used by this module. +class CalledProcessError(Exception): + """This exception is raised when a process run by check_call() or + check_output() returns a non-zero exit status. + The exit status will be stored in the returncode attribute; + check_output() will also store the output in the output attribute. + """ + def __init__(self, returncode, cmd, output=None): + self.returncode = returncode + self.cmd = cmd + self.output = output + def __str__(self): + return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) + + +if mswindows: + import threading + import msvcrt + import _subprocess + class STARTUPINFO: + dwFlags = 0 + hStdInput = None + hStdOutput = None + hStdError = None + wShowWindow = 0 + class pywintypes: + error = IOError +elif jython: + import errno + import threading + import java.io.File + import java.io.IOException + import java.lang.IllegalArgumentException + import java.lang.IllegalThreadStateException + import java.lang.ProcessBuilder + import java.lang.System + import java.lang.Thread + import java.nio.ByteBuffer + import org.python.core.io.RawIOBase + import org.python.core.io.StreamIO +else: + import select + _has_poll = hasattr(select, 'poll') + import errno + import fcntl + import gc + import pickle + + # When select or poll has indicated that the file is writable, + # we can write up to _PIPE_BUF bytes without risk of blocking. + # POSIX defines PIPE_BUF as >= 512. + _PIPE_BUF = getattr(select, 'PIPE_BUF', 512) + + +__all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", + "check_output", "CalledProcessError"] + +if mswindows: + from _subprocess import CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP + __all__.extend(["CREATE_NEW_CONSOLE", "CREATE_NEW_PROCESS_GROUP"]) +try: + MAXFD = os.sysconf("SC_OPEN_MAX") +except: + MAXFD = 256 + +_active = [] + +def _cleanup(): + for inst in _active[:]: + res = inst._internal_poll(_deadstate=sys.maxint) + if res is not None and res >= 0: + try: + _active.remove(inst) + except ValueError: + # This can happen if two threads create a new Popen instance. + # It's harmless that it was already removed, so ignore. + pass + +PIPE = -1 +STDOUT = -2 + + +def _eintr_retry_call(func, *args): + while True: + try: + return func(*args) + except OSError, e: + if e.errno == errno.EINTR: + continue + raise + + +def call(*popenargs, **kwargs): + """Run command with arguments. Wait for command to complete, then + return the returncode attribute. + + The arguments are the same as for the Popen constructor. Example: + + retcode = call(["ls", "-l"]) + """ + return Popen(*popenargs, **kwargs).wait() + + +def check_call(*popenargs, **kwargs): + """Run command with arguments. Wait for command to complete. If + the exit code was zero then return, otherwise raise + CalledProcessError. The CalledProcessError object will have the + return code in the returncode attribute. + + The arguments are the same as for the Popen constructor. Example: + + check_call(["ls", "-l"]) + """ + retcode = call(*popenargs, **kwargs) + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise CalledProcessError(retcode, cmd) + return 0 + + +def check_output(*popenargs, **kwargs): + r"""Run command with arguments and return its output as a byte string. + + If the exit code was non-zero it raises a CalledProcessError. The + CalledProcessError object will have the return code in the returncode + attribute and output in the output attribute. + + The arguments are the same as for the Popen constructor. Example: + + >>> check_output(["ls", "-l", "/dev/null"]) + 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' + + The stdout argument is not allowed as it is used internally. + To capture standard error in the result, use stderr=STDOUT. + + >>> check_output(["/bin/sh", "-c", + ... "ls -l non_existent_file ; exit 0"], + ... stderr=STDOUT) + 'ls: non_existent_file: No such file or directory\n' + """ + if 'stdout' in kwargs: + raise ValueError('stdout argument not allowed, it will be overridden.') + process = Popen(stdout=PIPE, *popenargs, **kwargs) + output, unused_err = process.communicate() + retcode = process.poll() + if retcode: + cmd = kwargs.get("args") + if cmd is None: + cmd = popenargs[0] + raise CalledProcessError(retcode, cmd, output=output) + return output + + +def list2cmdline(seq): + """ + Translate a sequence of arguments into a command line + string, using the same rules as the MS C runtime: + + 1) Arguments are delimited by white space, which is either a + space or a tab. + + 2) A string surrounded by double quotation marks is + interpreted as a single argument, regardless of white space + contained within. A quoted string can be embedded in an + argument. + + 3) A double quotation mark preceded by a backslash is + interpreted as a literal double quotation mark. + + 4) Backslashes are interpreted literally, unless they + immediately precede a double quotation mark. + + 5) If backslashes immediately precede a double quotation mark, + every pair of backslashes is interpreted as a literal + backslash. If the number of backslashes is odd, the last + backslash escapes the next double quotation mark as + described in rule 3. + """ + + # See + # http://msdn.microsoft.com/en-us/library/17w5ykft.aspx + # or search http://msdn.microsoft.com for + # "Parsing C++ Command-Line Arguments" + result = [] + needquote = False + for arg in seq: + bs_buf = [] + + # Add a space to separate this argument from the others + if result: + result.append(' ') + + needquote = (" " in arg) or ("\t" in arg) or not arg + if needquote: + result.append('"') + + for c in arg: + if c == '\\': + # Don't know if we need to double yet. + bs_buf.append(c) + elif c == '"': + # Double backslashes. + result.append('\\' * len(bs_buf)*2) + bs_buf = [] + result.append('\\"') + else: + # Normal char + if bs_buf: + result.extend(bs_buf) + bs_buf = [] + result.append(c) + + # Add remaining backslashes, if any. + if bs_buf: + result.extend(bs_buf) + + if needquote: + result.extend(bs_buf) + result.append('"') + + return ''.join(result) + + +if jython: + # Parse command line arguments for Windows + _win_oses = ['nt'] + + _cmdline2listimpl = None + _escape_args = None + _shell_command = None + + def _cmdline2list(cmdline): + """Build an argv list from a Microsoft shell style cmdline str + + The reverse of list2cmdline that follows the same MS C runtime + rules. + + Java's ProcessBuilder takes a List<String> cmdline that's joined + with a list2cmdline-like routine for Windows CreateProcess + (which takes a String cmdline). This process ruins String + cmdlines from the user with escapes or quotes. To avoid this we + first parse these cmdlines into an argv. + + Runtime.exec(String) is too naive and useless for this case. + """ + whitespace = ' \t' + # count of preceding '\' + bs_count = 0 + in_quotes = False + arg = [] + argv = [] + + for ch in cmdline: + if ch in whitespace and not in_quotes: + if arg: + # finalize arg and reset + argv.append(''.join(arg)) + arg = [] + bs_count = 0 + elif ch == '\\': + arg.append(ch) + bs_count += 1 + elif ch == '"': + if not bs_count % 2: + # Even number of '\' followed by a '"'. Place one + # '\' for every pair and treat '"' as a delimiter + if bs_count: + del arg[-(bs_count / 2):] + in_quotes = not in_quotes + else: + # Odd number of '\' followed by a '"'. Place one '\' + # for every pair and treat '"' as an escape sequence + # by the remaining '\' + del arg[-(bs_count / 2 + 1):] + arg.append(ch) + bs_count = 0 + else: + # regular char + arg.append(ch) + bs_count = 0 + + # A single trailing '"' delimiter yields an empty arg + if arg or in_quotes: + argv.append(''.join(arg)) + + return argv + + def _setup_platform(): + """Setup the shell command and the command line argument escape + function depending on the underlying platform + """ + global _cmdline2listimpl, _escape_args, _shell_command + + if os._name in _win_oses: + _cmdline2listimpl = _cmdline2list + _escape_args = lambda args: [list2cmdline([arg]) for arg in args] + else: + _cmdline2listimpl = lambda args: [args] + _escape_args = lambda args: args + + for shell_command in os._get_shell_commands(): + executable = shell_command[0] + if not os.path.isabs(executable): + import distutils.spawn + executable = distutils.spawn.find_executable(executable) + if not executable or not os.path.exists(executable): + continue + shell_command[0] = executable + _shell_command = shell_command + return + + if not _shell_command: + import warnings + warnings.warn('Unable to determine _shell_command for ' + 'underlying os: %s' % os._name, RuntimeWarning, 3) + _setup_platform() + + + class _CouplerThread(java.lang.Thread): + + """Couples a reader and writer RawIOBase. + + Streams data from the reader's read_func (a RawIOBase readinto + method) to the writer's write_func (a RawIOBase write method) in + a separate thread. Optionally calls close_func when finished + streaming or an exception occurs. + + This thread will fail safe when interrupted by Java's + Thread.interrupt. + """ + + # analagous to PC_PIPE_BUF, which is typically 512 or 4096 + bufsize = 4096 + + def __init__(self, name, read_func, write_func, close_func=None): + self.read_func = read_func + self.write_func = write_func + self.close_func = close_func + self.setName('%s-%s (%s)' % (self.__class__.__name__, id(self), + name)) + self.setDaemon(True) + + def run(self): + buf = java.nio.ByteBuffer.allocate(self.bufsize) + while True: + try: + count = self.read_func(buf) + if count < 1: + if self.close_func: + self.close_func() + break + buf.flip() + self.write_func(buf) + buf.flip() + except IOError, ioe: + if self.close_func: + try: + self.close_func() + except: + pass + # XXX: hack, should really be a + # ClosedByInterruptError(IOError) exception + if str(ioe) == \ + 'java.nio.channels.ClosedByInterruptException': + return + raise + + +class Popen(object): + def __init__(self, args, bufsize=0, executable=None, + stdin=None, stdout=None, stderr=None, + preexec_fn=None, close_fds=False, shell=False, + cwd=None, env=None, universal_newlines=False, + startupinfo=None, creationflags=0): + """Create new Popen instance.""" + _cleanup() + + self._child_created = False + if not isinstance(bufsize, (int, long)): + raise TypeError("bufsize must be an integer") + + if mswindows: + if preexec_fn is not None: + raise ValueError("preexec_fn is not supported on Windows " + "platforms") + if close_fds and (stdin is not None or stdout is not None or + stderr is not None): + raise ValueError("close_fds is not supported on Windows " + "platforms if you redirect stdin/stdout/stderr") + else: + # POSIX + if startupinfo is not None: + raise ValueError("startupinfo is only supported on Windows " + "platforms") + if creationflags != 0: + raise ValueError("creationflags is only supported on Windows " + "platforms") + if jython: + if preexec_fn is not None: + raise ValueError("preexec_fn is not supported on the Jython " + "platform") + + self.stdin = None + self.stdout = None + self.stderr = None + self.pid = None + self.returncode = None + self.universal_newlines = universal_newlines + + # Input and output objects. The general principle is like + # this: + # + # Parent Child + # ------ ----- + # p2cwrite ---stdin---> p2cread + # c2pread <--stdout--- c2pwrite + # errread <--stderr--- errwrite + # + # On POSIX, the child objects are file descriptors. On + # Windows, these are Windows file handles. The parent objects + # are file descriptors on both platforms. The parent objects + # are None when not using PIPEs. The child objects are None + # when not redirecting. + + (p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite) = self._get_handles(stdin, stdout, stderr) + + self._execute_child(args, executable, preexec_fn, close_fds, + cwd, env, universal_newlines, + startupinfo, creationflags, shell, + p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite) + + if mswindows: + if p2cwrite is not None: + p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0) + if c2pread is not None: + c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0) + if errread is not None: + errread = msvcrt.open_osfhandle(errread.Detach(), 0) + + if jython: + self._stdin_thread = None + self._stdout_thread = None + self._stderr_thread = None + + # 'ct' is for _CouplerThread + proc = self._process + ct2cwrite = org.python.core.io.StreamIO(proc.getOutputStream(), + True) + c2ctread = org.python.core.io.StreamIO(proc.getInputStream(), True) + cterrread = org.python.core.io.StreamIO(proc.getErrorStream(), + True) + + # Use the java.lang.Process streams for PIPE, otherwise + # direct the desired file to/from the java.lang.Process + # streams in a separate thread + if p2cwrite == PIPE: + p2cwrite = ct2cwrite + else: + if p2cread is None: + # Coupling stdin is not supported: there's no way to + # cleanly interrupt it if it blocks the + # _CouplerThread forever (we can Thread.interrupt() + # its _CouplerThread but that closes stdin's + # Channel) + pass + else: + self._stdin_thread = self._coupler_thread('stdin', + p2cread.readinto, + ct2cwrite.write, + ct2cwrite.close) + self._stdin_thread.start() + + if c2pread == PIPE: + c2pread = c2ctread + else: + if c2pwrite is None: + c2pwrite = org.python.core.io.StreamIO( + java.lang.System.out, False) + self._stdout_thread = self._coupler_thread('stdout', + c2ctread.readinto, + c2pwrite.write) + self._stdout_thread.start() + + if errread == PIPE: + errread = cterrread + elif not self._stderr_is_stdout(errwrite, c2pwrite): + if errwrite is None: + errwrite = org.python.core.io.StreamIO( + java.lang.System.err, False) + self._stderr_thread = self._coupler_thread('stderr', + cterrread.readinto, + errwrite.write) + self._stderr_thread.start() + + if p2cwrite is not None: + self.stdin = os.fdopen(p2cwrite, 'wb', bufsize) + if c2pread is not None: + if universal_newlines: + self.stdout = os.fdopen(c2pread, 'rU', bufsize) + else: + self.stdout = os.fdopen(c2pread, 'rb', bufsize) + if errread is not None: + if universal_newlines: + self.stderr = os.fdopen(errread, 'rU', bufsize) + else: + self.stderr = os.fdopen(errread, 'rb', bufsize) + + + def _translate_newlines(self, data): + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + return data + + + def __del__(self, _maxint=sys.maxint, _active=_active): + if not self._child_created: + # We didn't get to successfully create a child process. + return + # In case the child hasn't been waited on, check if it's done. + self._internal_poll(_deadstate=_maxint) + if self.returncode is None and _active is not None: + # Child is still running, keep us alive until we can wait on it. + _active.append(self) + + + def communicate(self, input=None): + """Interact with process: Send data to stdin. Read data from + stdout and stderr, until end-of-file is reached. Wait for + process to terminate. The optional input argument should be a + string to be sent to the child process, or None, if no data + should be sent to the child. + + communicate() returns a tuple (stdout, stderr).""" + + # Optimization: If we are only using one pipe, or no pipe at + # all, using select() or threads is unnecessary. + if [self.stdin, self.stdout, self.stderr].count(None) >= 2: + stdout = None + stderr = None + if self.stdin: + if input: + self.stdin.write(input) + self.stdin.close() + elif self.stdout: + stdout = self.stdout.read() + self.stdout.close() + elif self.stderr: + stderr = self.stderr.read() + self.stderr.close() + self.wait() + return (stdout, stderr) + + return self._communicate(input) + + + def poll(self): + return self._internal_poll() + + + if mswindows or jython: + # + # Windows and Jython shared methods + # + def _readerthread(self, fh, buffer): + buffer.append(fh.read()) + + + def _communicate(self, input): + stdout = None # Return + stderr = None # Return + + if self.stdout: + stdout = [] + stdout_thread = threading.Thread(target=self._readerthread, + args=(self.stdout, stdout)) + stdout_thread.setDaemon(True) + stdout_thread.start() + if self.stderr: + stderr = [] + stderr_thread = threading.Thread(target=self._readerthread, + args=(self.stderr, stderr)) + stderr_thread.setDaemon(True) + stderr_thread.start() + + if self.stdin: + if input is not None: + self.stdin.write(input) + self.stdin.close() + + if self.stdout: + stdout_thread.join() + if self.stderr: + stderr_thread.join() + + # All data exchanged. Translate lists into strings. + if stdout is not None: + stdout = stdout[0] + if stderr is not None: + stderr = stderr[0] + + # Translate newlines, if requested. We cannot let the file + # object do the translation: It is based on stdio, which is + # impossible to combine with select (unless forcing no + # buffering). + if self.universal_newlines and hasattr(file, 'newlines'): + if stdout: + stdout = self._translate_newlines(stdout) + if stderr: + stderr = self._translate_newlines(stderr) + + self.wait() + return (stdout, stderr) + + + if mswindows: + # + # Windows methods + # + def _get_handles(self, stdin, stdout, stderr): + """Construct and return tuple with IO objects: + p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite + """ + if stdin is None and stdout is None and stderr is None: + return (None, None, None, None, None, None) + + p2cread, p2cwrite = None, None + c2pread, c2pwrite = None, None + errread, errwrite = None, None + + if stdin is None: + p2cread = _subprocess.GetStdHandle(_subprocess.STD_INPUT_HANDLE) + if p2cread is None: + p2cread, _ = _subprocess.CreatePipe(None, 0) + elif stdin == PIPE: + p2cread, p2cwrite = _subprocess.CreatePipe(None, 0) + elif isinstance(stdin, int): + p2cread = msvcrt.get_osfhandle(stdin) + else: + # Assuming file-like object + p2cread = msvcrt.get_osfhandle(stdin.fileno()) + p2cread = self._make_inheritable(p2cread) + + if stdout is None: + c2pwrite = _subprocess.GetStdHandle(_subprocess.STD_OUTPUT_HANDLE) + if c2pwrite is None: + _, c2pwrite = _subprocess.CreatePipe(None, 0) + elif stdout == PIPE: + c2pread, c2pwrite = _subprocess.CreatePipe(None, 0) + elif isinstance(stdout, int): + c2pwrite = msvcrt.get_osfhandle(stdout) + else: + # Assuming file-like object + c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) + c2pwrite = self._make_inheritable(c2pwrite) + + if stderr is None: + errwrite = _subprocess.GetStdHandle(_subprocess.STD_ERROR_HANDLE) + if errwrite is None: + _, errwrite = _subprocess.CreatePipe(None, 0) + elif stderr == PIPE: + errread, errwrite = _subprocess.CreatePipe(None, 0) + elif stderr == STDOUT: + errwrite = c2pwrite + elif isinstance(stderr, int): + errwrite = msvcrt.get_osfhandle(stderr) + else: + # Assuming file-like object + errwrite = msvcrt.get_osfhandle(stderr.fileno()) + errwrite = self._make_inheritable(errwrite) + + return (p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite) + + + def _make_inheritable(self, handle): + """Return a duplicate of handle, which is inheritable""" + return _subprocess.DuplicateHandle(_subprocess.GetCurrentProcess(), + handle, _subprocess.GetCurrentProcess(), 0, 1, + _subprocess.DUPLICATE_SAME_ACCESS) + + + def _find_w9xpopen(self): + """Find and return absolut path to w9xpopen.exe""" + w9xpopen = os.path.join( + os.path.dirname(_subprocess.GetModuleFileName(0)), + "w9xpopen.exe") + if not os.path.exists(w9xpopen): + # Eeek - file-not-found - possibly an embedding + # situation - see if we can locate it in sys.exec_prefix + w9xpopen = os.path.join(os.path.dirname(sys.exec_prefix), + "w9xpopen.exe") + if not os.path.exists(w9xpopen): + raise RuntimeError("Cannot locate w9xpopen.exe, which is " + "needed for Popen to work with your " + "shell or platform.") + return w9xpopen + + + def _execute_child(self, args, executable, preexec_fn, close_fds, + cwd, env, universal_newlines, + startupinfo, creationflags, shell, + p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite): + """Execute program (MS Windows version)""" + + if not isinstance(args, types.StringTypes): + args = list2cmdline(args) + + # Process startup details + if startupinfo is None: + startupinfo = STARTUPINFO() + if None not in (p2cread, c2pwrite, errwrite): + startupinfo.dwFlags |= _subprocess.STARTF_USESTDHANDLES + startupinfo.hStdInput = p2cread + startupinfo.hStdOutput = c2pwrite + startupinfo.hStdError = errwrite + + if shell: + startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW + startupinfo.wShowWindow = _subprocess.SW_HIDE + comspec = os.environ.get("COMSPEC", "cmd.exe") + args = '{} /c "{}"'.format (comspec, args) + if (_subprocess.GetVersion() >= 0x80000000 or + os.path.basename(comspec).lower() == "command.com"): + # Win9x, or using command.com on NT. We need to + # use the w9xpopen intermediate program. For more + # information, see KB Q150956 + # (http://web.archive.org/web/20011105084002/http://support.microsoft.com/support/kb/articles/Q150/9/56.asp) + w9xpopen = self._find_w9xpopen() + args = '"%s" %s' % (w9xpopen, args) + # Not passing CREATE_NEW_CONSOLE has been known to + # cause random failures on win9x. Specifically a + # dialog: "Your program accessed mem currently in + # use at xxx" and a hopeful warning about the + # stability of your system. Cost is Ctrl+C wont + # kill children. + creationflags |= _subprocess.CREATE_NEW_CONSOLE + + # Start the process + try: + hp, ht, pid, tid = _subprocess.CreateProcess(executable, args, + # no special security + None, None, + int(not close_fds), + creationflags, + env, + cwd, + startupinfo) + except pywintypes.error, e: + # Translate pywintypes.error to WindowsError, which is + # a subclass of OSError. FIXME: We should really + # translate errno using _sys_errlist (or simliar), but + # how can this be done from Python? + raise WindowsError(*e.args) + finally: + # Child is launched. Close the parent's copy of those pipe + # handles that only the child should have open. You need + # to make sure that no handles to the write end of the + # output pipe are maintained in this process or else the + # pipe will not close when the child process exits and the + # ReadFile will hang. + if p2cread is not None: + p2cread.Close() + if c2pwrite is not None: + c2pwrite.Close() + if errwrite is not None: + errwrite.Close() + + # Retain the process handle, but close the thread handle + self._child_created = True + self._handle = hp + self.pid = pid + ht.Close() + + def _internal_poll(self, _deadstate=None, + _WaitForSingleObject=_subprocess.WaitForSingleObject, + _WAIT_OBJECT_0=_subprocess.WAIT_OBJECT_0, + _GetExitCodeProcess=_subprocess.GetExitCodeProcess): + """Check if child process has terminated. Returns returncode + attribute. + + This method is called by __del__, so it can only refer to objects + in its local scope. + + """ + if self.returncode is None: + if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0: + self.returncode = _GetExitCodeProcess(self._handle) + return self.returncode + + + def wait(self): + """Wait for child process to terminate. Returns returncode + attribute.""" + if self.returncode is None: + _subprocess.WaitForSingleObject(self._handle, + _subprocess.INFINITE) + self.returncode = _subprocess.GetExitCodeProcess(self._handle) + return self.returncode + + elif jython: + # + # Jython methods + # + def _get_handles(self, stdin, stdout, stderr): + """Construct and return tuple with IO objects: + p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite + """ + p2cread, p2cwrite = None, None + c2pread, c2pwrite = None, None + errread, errwrite = None, None + + if stdin is None: + pass + elif stdin == PIPE: + p2cwrite = PIPE + elif isinstance(stdin, org.python.core.io.RawIOBase): + p2cread = stdin + else: + # Assuming file-like object + p2cread = stdin.fileno() + + if stdout is None: + pass + elif stdout == PIPE: + c2pread = PIPE + elif isinstance(stdout, org.python.core.io.RawIOBase): + c2pwrite = stdout + else: + # Assuming file-like object + c2pwrite = stdout.fileno() + + if stderr is None: + pass + elif stderr == PIPE: + errread = PIPE + elif (stderr == STDOUT or + isinstance(stderr, org.python.core.io.RawIOBase)): + errwrite = stderr + else: + # Assuming file-like object + errwrite = stderr.fileno() + + return (p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite) + + + def _stderr_is_stdout(self, errwrite, c2pwrite): + """Determine if the subprocess' stderr should be redirected + to stdout + """ + return (errwrite == STDOUT or c2pwrite not in (None, PIPE) and + c2pwrite is errwrite) + + + def _coupler_thread(self, *args, **kwargs): + """Return a _CouplerThread""" + return _CouplerThread(*args, **kwargs) + + + def _setup_env(self, env, builder_env): + """Carefully merge env with ProcessBuilder's only + overwriting key/values that differ + + System.getenv (Map<String, String>) may be backed by + <byte[], byte[]> on UNIX platforms where these are really + bytes. ProcessBuilder's env inherits its contents and will + maintain those byte values (which may be butchered as + Strings) for the subprocess if they haven't been modified. + """ + # Determine what's safe to merge + merge_env = dict((key, value) for key, value in env.iteritems() + if key not in builder_env or + builder_env.get(key) != value) + + # Prune anything not in env + entries = builder_env.entrySet().iterator() + for entry in entries: + if entry.getKey() not in env: + entries.remove() + + builder_env.putAll(merge_env) + + + def _execute_child(self, args, executable, preexec_fn, close_fds, + cwd, env, universal_newlines, + startupinfo, creationflags, shell, + p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite): + """Execute program (Java version)""" + + if isinstance(args, types.StringTypes): + args = _cmdline2listimpl(args) + else: + args = list(args) + # NOTE: CPython posix (execv) will str() any unicode + # args first, maybe we should do the same on + # posix. Windows passes unicode through, however + if any(not isinstance(arg, (str, unicode)) for arg in args): + raise TypeError('args must contain only strings') + args = _escape_args(args) + + if shell: + args = _shell_command + args + + if executable is not None: + args[0] = executable + + builder = java.lang.ProcessBuilder(args) + # os.environ may be inherited for compatibility with CPython + self._setup_env(dict(os.environ if env is None else env), + builder.environment()) + + if cwd is None: + cwd = os.getcwd() + elif not os.path.exists(cwd): + raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), cwd) + elif not os.path.isdir(cwd): + raise OSError(errno.ENOTDIR, os.strerror(errno.ENOTDIR), cwd) + builder.directory(java.io.File(cwd)) + + # Let Java manage redirection of stderr to stdout (it's more + # accurate at doing so than _CouplerThreads). We redirect + # not only when stderr is marked as STDOUT, but also when + # c2pwrite is errwrite + if self._stderr_is_stdout(errwrite, c2pwrite): + builder.redirectErrorStream(True) + + try: + self._process = builder.start() + except (java.io.IOException, + java.lang.IllegalArgumentException), e: + raise OSError(e.getMessage() or e) + self._child_created = True + + + def poll(self, _deadstate=None): + """Check if child process has terminated. Returns returncode + attribute.""" + if self.returncode is None: + try: + self.returncode = self._process.exitValue() + except java.lang.IllegalThreadStateException: + pass + return self.returncode + + + def wait(self): + """Wait for child process to terminate. Returns returncode + attribute.""" + if self.returncode is None: + self.returncode = self._process.waitFor() + for coupler in (self._stdout_thread, self._stderr_thread): + if coupler: + coupler.join() + if self._stdin_thread: + # The stdin thread may be blocked forever, forcibly + # stop it + self._stdin_thread.interrupt() + return self.returncode + + def send_signal(self, sig): + """Send a signal to the process + """ + if sig == signal.SIGTERM: + self.terminate() + elif sig == signal.CTRL_C_EVENT: + os.kill(self.pid, signal.CTRL_C_EVENT) + elif sig == signal.CTRL_BREAK_EVENT: + os.kill(self.pid, signal.CTRL_BREAK_EVENT) + else: + raise ValueError("Unsupported signal: {}".format(sig)) + + def terminate(self): + """Terminates the process + """ + _subprocess.TerminateProcess(self._handle, 1) + + kill = terminate + + else: + # + # POSIX methods + # + def _get_handles(self, stdin, stdout, stderr): + """Construct and return tuple with IO objects: + p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite + """ + p2cread, p2cwrite = None, None + c2pread, c2pwrite = None, None + errread, errwrite = None, None + + if stdin is None: + pass + elif stdin == PIPE: + p2cread, p2cwrite = os.pipe() + elif isinstance(stdin, int): + p2cread = stdin + else: + # Assuming file-like object + p2cread = stdin.fileno() + + if stdout is None: + pass + elif stdout == PIPE: + c2pread, c2pwrite = os.pipe() + elif isinstance(stdout, int): + c2pwrite = stdout + else: + # Assuming file-like object + c2pwrite = stdout.fileno() + + if stderr is None: + pass + elif stderr == PIPE: + errread, errwrite = os.pipe() + elif stderr == STDOUT: + errwrite = c2pwrite + elif isinstance(stderr, int): + errwrite = stderr + else: + # Assuming file-like object + errwrite = stderr.fileno() + + return (p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite) + + + def _set_cloexec_flag(self, fd, cloexec=True): + try: + cloexec_flag = fcntl.FD_CLOEXEC + except AttributeError: + cloexec_flag = 1 + + old = fcntl.fcntl(fd, fcntl.F_GETFD) + if cloexec: + fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag) + else: + fcntl.fcntl(fd, fcntl.F_SETFD, old & ~cloexec_flag) + + + def _close_fds(self, but): + if hasattr(os, 'closerange'): + os.closerange(3, but) + os.closerange(but + 1, MAXFD) + else: + for i in xrange(3, MAXFD): + if i == but: + continue + try: + os.close(i) + except: + pass + + + def _execute_child(self, args, executable, preexec_fn, close_fds, + cwd, env, universal_newlines, + startupinfo, creationflags, shell, + p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite): + """Execute program (POSIX version)""" + + if isinstance(args, types.StringTypes): + args = [args] + else: + args = list(args) + + if shell: + args = ["/bin/sh", "-c"] + args + if executable: + args[0] = executable + + if executable is None: + executable = args[0] + + # For transferring possible exec failure from child to parent + # The first char specifies the exception type: 0 means + # OSError, 1 means some other error. + errpipe_read, errpipe_write = os.pipe() + try: + try: + self._set_cloexec_flag(errpipe_write) + + gc_was_enabled = gc.isenabled() + # Disable gc to avoid bug where gc -> file_dealloc -> + # write to stderr -> hang. http://bugs.python.org/issue1336 + gc.disable() + try: + self.pid = os.fork() + except: + if gc_was_enabled: + gc.enable() + raise + self._child_created = True + if self.pid == 0: + # Child + try: + # Close parent's pipe ends + if p2cwrite is not None: + os.close(p2cwrite) + if c2pread is not None: + os.close(c2pread) + if errread is not None: + os.close(errread) + os.close(errpipe_read) + + # Dup fds for child + def _dup2(a, b): + # dup2() removes the CLOEXEC flag but + # we must do it ourselves if dup2() + # would be a no-op (issue #10806). + if a == b: + self._set_cloexec_flag(a, False) + elif a is not None: + os.dup2(a, b) + _dup2(p2cread, 0) + _dup2(c2pwrite, 1) + _dup2(errwrite, 2) + + # Close pipe fds. Make sure we don't close the + # same fd more than once, or standard fds. + closed = { None } + for fd in [p2cread, c2pwrite, errwrite]: + if fd not in closed and fd > 2: + os.close(fd) + closed.add(fd) + + # Close all other fds, if asked for + if close_fds: + self._close_fds(but=errpipe_write) + + if cwd is not None: + os.chdir(cwd) + + if preexec_fn: + preexec_fn() + + if env is None: + os.execvp(executable, args) + else: + os.execvpe(executable, args, env) + + except: + exc_type, exc_value, tb = sys.exc_info() + # Save the traceback and attach it to the exception object + exc_lines = traceback.format_exception(exc_type, + exc_value, + tb) + exc_value.child_traceback = ''.join(exc_lines) + os.write(errpipe_write, pickle.dumps(exc_value)) + + # This exitcode won't be reported to applications, so it + # really doesn't matter what we return. + os._exit(255) + + # Parent + if gc_was_enabled: + gc.enable() + finally: + # be sure the FD is closed no matter what + os.close(errpipe_write) + + if p2cread is not None and p2cwrite is not None: + os.close(p2cread) + if c2pwrite is not None and c2pread is not None: + os.close(c2pwrite) + if errwrite is not None and errread is not None: + os.close(errwrite) + + # Wait for exec to fail or succeed; possibly raising exception + # Exception limited to 1M + data = _eintr_retry_call(os.read, errpipe_read, 1048576) + finally: + # be sure the FD is closed no matter what + os.close(errpipe_read) + + if data != "": + try: + _eintr_retry_call(os.waitpid, self.pid, 0) + except OSError as e: + if e.errno != errno.ECHILD: + raise + child_exception = pickle.loads(data) + for fd in (p2cwrite, c2pread, errread): + if fd is not None: + os.close(fd) + raise child_exception + + + def _handle_exitstatus(self, sts, _WIFSIGNALED=os.WIFSIGNALED, + _WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED, + _WEXITSTATUS=os.WEXITSTATUS): + # This method is called (indirectly) by __del__, so it cannot + # refer to anything outside of its local scope.""" + if _WIFSIGNALED(sts): + self.returncode = -_WTERMSIG(sts) + elif _WIFEXITED(sts): + self.returncode = _WEXITSTATUS(sts) + else: + # Should never happen + raise RuntimeError("Unknown child exit status!") + + + def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, + _WNOHANG=os.WNOHANG, _os_error=os.error): + """Check if child process has terminated. Returns returncode + attribute. + + This method is called by __del__, so it cannot reference anything + outside of the local scope (nor can any methods it calls). + + """ + if self.returncode is None: + try: + pid, sts = _waitpid(self.pid, _WNOHANG) + if pid == self.pid: + self._handle_exitstatus(sts) + except _os_error: + if _deadstate is not None: + self.returncode = _deadstate + return self.returncode + + + def wait(self): + """Wait for child process to terminate. Returns returncode + attribute.""" + if self.returncode is None: + try: + pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0) + except OSError as e: + if e.errno != errno.ECHILD: + raise + # This happens if SIGCLD is set to be ignored or waiting + # for child processes has otherwise been disabled for our + # process. This child is dead, we can't get the status. + sts = 0 + self._handle_exitstatus(sts) + return self.returncode + + + def _communicate(self, input): + if self.stdin: + # Flush stdio buffer. This might block, if the user has + # been writing to .stdin in an uncontrolled fashion. + self.stdin.flush() + if not input: + self.stdin.close() + + if _has_poll: + stdout, stderr = self._communicate_with_poll(input) + else: + stdout, stderr = self._communicate_with_select(input) + + # All data exchanged. Translate lists into strings. + if stdout is not None: + stdout = ''.join(stdout) + if stderr is not None: + stderr = ''.join(stderr) + + # Translate newlines, if requested. We cannot let the file + # object do the translation: It is based on stdio, which is + # impossible to combine with select (unless forcing no + # buffering). + if self.universal_newlines and hasattr(file, 'newlines'): + if stdout: + stdout = self._translate_newlines(stdout) + if stderr: + stderr = self._translate_newlines(stderr) + + self.wait() + return (stdout, stderr) + + + def _communicate_with_poll(self, input): + stdout = None # Return + stderr = None # Return + fd2file = {} + fd2output = {} + + poller = select.poll() + def register_and_append(file_obj, eventmask): + poller.register(file_obj.fileno(), eventmask) + fd2file[file_obj.fileno()] = file_obj + + def close_unregister_and_remove(fd): + poller.unregister(fd) + fd2file[fd].close() + fd2file.pop(fd) + + if self.stdin and input: + register_and_append(self.stdin, select.POLLOUT) + + select_POLLIN_POLLPRI = select.POLLIN | select.POLLPRI + if self.stdout: + register_and_append(self.stdout, select_POLLIN_POLLPRI) + fd2output[self.stdout.fileno()] = stdout = [] + if self.stderr: + register_and_append(self.stderr, select_POLLIN_POLLPRI) + fd2output[self.stderr.fileno()] = stderr = [] + + input_offset = 0 + while fd2file: + try: + ready = poller.poll() + except select.error, e: + if e.args[0] == errno.EINTR: + continue + raise + + for fd, mode in ready: + if mode & select.POLLOUT: + chunk = input[input_offset : input_offset + _PIPE_BUF] + input_offset += os.write(fd, chunk) + if input_offset >= len(input): + close_unregister_and_remove(fd) + elif mode & select_POLLIN_POLLPRI: + data = os.read(fd, 4096) + if not data: + close_unregister_and_remove(fd) + fd2output[fd].append(data) + else: + # Ignore hang up or errors. + close_unregister_and_remove(fd) + + return (stdout, stderr) + + + def _communicate_with_select(self, input): + read_set = [] + write_set = [] + stdout = None # Return + stderr = None # Return + + if self.stdin and input: + write_set.append(self.stdin) + if self.stdout: + read_set.append(self.stdout) + stdout = [] + if self.stderr: + read_set.append(self.stderr) + stderr = [] + + input_offset = 0 + while read_set or write_set: + try: + rlist, wlist, xlist = select.select(read_set, write_set, []) + except select.error, e: + if e.args[0] == errno.EINTR: + continue + raise + + if self.stdin in wlist: + chunk = input[input_offset : input_offset + _PIPE_BUF] + bytes_written = os.write(self.stdin.fileno(), chunk) + input_offset += bytes_written + if input_offset >= len(input): + self.stdin.close() + write_set.remove(self.stdin) + + if self.stdout in rlist: + data = os.read(self.stdout.fileno(), 1024) + if data == "": + self.stdout.close() + read_set.remove(self.stdout) + stdout.append(data) + + if self.stderr in rlist: + data = os.read(self.stderr.fileno(), 1024) + if data == "": + self.stderr.close() + read_set.remove(self.stderr) + stderr.append(data) + + return (stdout, stderr) + + + def send_signal(self, sig): + """Send a signal to the process + """ + os.kill(self.pid, sig) + + def terminate(self): + """Terminate the process with SIGTERM + """ + self.send_signal(signal.SIGTERM) + + def kill(self): + """Kill the process with SIGKILL + """ + self.send_signal(signal.SIGKILL) + + +def _demo_posix(): + # + # Example 1: Simple redirection: Get process list + # + plist = Popen(["ps"], stdout=PIPE).communicate()[0] + print "Process list:" + print plist + + # + # Example 2: Change uid before executing child + # + if os.getuid() == 0: + p = Popen(["id"], preexec_fn=lambda: os.setuid(100)) + p.wait() + + # + # Example 3: Connecting several subprocesses + # + print "Looking for 'hda'..." + p1 = Popen(["dmesg"], stdout=PIPE) + p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) + print repr(p2.communicate()[0]) + + # + # Example 4: Catch execution error + # + print + print "Trying a weird file..." + try: + print Popen(["/this/path/does/not/exist"]).communicate() + except OSError, e: + if e.errno == errno.ENOENT: + print "The file didn't exist. I thought so..." + print "Child traceback:" + print e.child_traceback + else: + print "Error", e.errno + else: + print >>sys.stderr, "Gosh. No error." + + +def _demo_windows(): + # + # Example 1: Connecting several subprocesses + # + print "Looking for 'PROMPT' in set output..." + p1 = Popen("set", stdout=PIPE, shell=True) + p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE) + print repr(p2.communicate()[0]) + + # + # Example 2: Simple execution of program + # + print "Executing calc..." + p = Popen("calc") + p.wait() + + +def _demo_jython(): + # + # Example 1: Return the number of processors on this machine + # + print "Running a jython subprocess to return the number of processors..." + p = Popen([sys.executable, "-c", + ('import sys;' + 'from java.lang import Runtime;' + 'sys.exit(Runtime.getRuntime().availableProcessors())')]) + print p.wait() + + # + # Example 2: Connecting several subprocesses + # + print "Connecting two jython subprocesses..." + p1 = Popen([sys.executable, "-c", + ('import os;' + 'print os.environ["foo"]')], env=dict(foo='bar'), + stdout=PIPE) + p2 = Popen([sys.executable, "-c", + ('import os, sys;' + 'their_foo = sys.stdin.read().strip();' + 'my_foo = os.environ["foo"];' + 'msg = "Their env\'s foo: %r, My env\'s foo: %r";' + 'print msg % (their_foo, my_foo)')], + env=dict(foo='baz'), stdin=p1.stdout, stdout=PIPE) + print p2.communicate()[0] + + +if __name__ == "__main__": + if mswindows: + _demo_windows() + elif jython: + _demo_jython() + else: + _demo_posix() diff --git a/src/main/resources/PythonLibs/symbol.py b/src/main/resources/PythonLibs/symbol.py new file mode 100644 index 0000000000000000000000000000000000000000..b4d4e13ab80994818070133698ad1ce5baa8fe36 --- /dev/null +++ b/src/main/resources/PythonLibs/symbol.py @@ -0,0 +1,114 @@ +#! /usr/bin/env python + +"""Non-terminal symbols of Python grammar (from "graminit.h").""" + +# This file is automatically generated; please don't muck it up! +# +# To update the symbols in this file, 'cd' to the top directory of +# the python source tree after building the interpreter and run: +# +# ./python Lib/symbol.py + +#--start constants-- +single_input = 256 +file_input = 257 +eval_input = 258 +decorator = 259 +decorators = 260 +decorated = 261 +funcdef = 262 +parameters = 263 +varargslist = 264 +fpdef = 265 +fplist = 266 +stmt = 267 +simple_stmt = 268 +small_stmt = 269 +expr_stmt = 270 +augassign = 271 +print_stmt = 272 +del_stmt = 273 +pass_stmt = 274 +flow_stmt = 275 +break_stmt = 276 +continue_stmt = 277 +return_stmt = 278 +yield_stmt = 279 +raise_stmt = 280 +import_stmt = 281 +import_name = 282 +import_from = 283 +import_as_name = 284 +dotted_as_name = 285 +import_as_names = 286 +dotted_as_names = 287 +dotted_name = 288 +global_stmt = 289 +exec_stmt = 290 +assert_stmt = 291 +compound_stmt = 292 +if_stmt = 293 +while_stmt = 294 +for_stmt = 295 +try_stmt = 296 +with_stmt = 297 +with_item = 298 +except_clause = 299 +suite = 300 +testlist_safe = 301 +old_test = 302 +old_lambdef = 303 +test = 304 +or_test = 305 +and_test = 306 +not_test = 307 +comparison = 308 +comp_op = 309 +expr = 310 +xor_expr = 311 +and_expr = 312 +shift_expr = 313 +arith_expr = 314 +term = 315 +factor = 316 +power = 317 +atom = 318 +listmaker = 319 +testlist_comp = 320 +lambdef = 321 +trailer = 322 +subscriptlist = 323 +subscript = 324 +sliceop = 325 +exprlist = 326 +testlist = 327 +dictorsetmaker = 328 +classdef = 329 +arglist = 330 +argument = 331 +list_iter = 332 +list_for = 333 +list_if = 334 +comp_iter = 335 +comp_for = 336 +comp_if = 337 +testlist1 = 338 +encoding_decl = 339 +yield_expr = 340 +#--end constants-- + +sym_name = {} +for _name, _value in globals().items(): + if type(_value) is type(0): + sym_name[_value] = _name + + +def main(): + import sys + import token + if len(sys.argv) == 1: + sys.argv = sys.argv + ["Include/graminit.h", "Lib/symbol.py"] + token.main() + +if __name__ == "__main__": + main() diff --git a/src/main/resources/PythonLibs/sysconfig.py b/src/main/resources/PythonLibs/sysconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..f5ab0dff4d7b18d1057eec4a3527f4396e07cbf1 --- /dev/null +++ b/src/main/resources/PythonLibs/sysconfig.py @@ -0,0 +1,713 @@ +"""Provide access to Python's configuration information. + +""" +import sys +import os +from os.path import pardir, realpath + +_INSTALL_SCHEMES = { + 'posix_prefix': { + 'stdlib': '{base}/lib/python{py_version_short}', + 'platstdlib': '{platbase}/lib/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', + 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', + 'include': '{base}/include/python{py_version_short}', + 'platinclude': '{platbase}/include/python{py_version_short}', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'posix_home': { + 'stdlib': '{base}/lib/python', + 'platstdlib': '{base}/lib/python', + 'purelib': '{base}/lib/python', + 'platlib': '{base}/lib/python', + 'include': '{base}/include/python', + 'platinclude': '{base}/include/python', + 'scripts': '{base}/bin', + 'data' : '{base}', + }, + 'nt': { + 'stdlib': '{base}/Lib', + 'platstdlib': '{base}/Lib', + 'purelib': '{base}/Lib/site-packages', + 'platlib': '{base}/Lib/site-packages', + 'include': '{base}/Include', + 'platinclude': '{base}/Include', + 'scripts': '{base}/Scripts', + 'data' : '{base}', + }, + 'os2': { + 'stdlib': '{base}/Lib', + 'platstdlib': '{base}/Lib', + 'purelib': '{base}/Lib/site-packages', + 'platlib': '{base}/Lib/site-packages', + 'include': '{base}/Include', + 'platinclude': '{base}/Include', + 'scripts': '{base}/Scripts', + 'data' : '{base}', + }, + 'os2_home': { + 'stdlib': '{userbase}/lib/python{py_version_short}', + 'platstdlib': '{userbase}/lib/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data' : '{userbase}', + }, + 'nt_user': { + 'stdlib': '{userbase}/Python{py_version_nodot}', + 'platstdlib': '{userbase}/Python{py_version_nodot}', + 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', + 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', + 'include': '{userbase}/Python{py_version_nodot}/Include', + 'scripts': '{userbase}/Scripts', + 'data' : '{userbase}', + }, + 'posix_user': { + 'stdlib': '{userbase}/lib/python{py_version_short}', + 'platstdlib': '{userbase}/lib/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data' : '{userbase}', + }, + 'osx_framework_user': { + 'stdlib': '{userbase}/lib/python', + 'platstdlib': '{userbase}/lib/python', + 'purelib': '{userbase}/lib/python/site-packages', + 'platlib': '{userbase}/lib/python/site-packages', + 'include': '{userbase}/include', + 'scripts': '{userbase}/bin', + 'data' : '{userbase}', + }, + 'java': { + 'stdlib': '{base}/lib/jython', + 'platstdlib': '{base}/lib/jython', + 'purelib': '{base}/lib/jython', + 'platlib': '{base}/lib/jython', + 'include': '{base}/include/jython', + 'platinclude': '{base}/include/jython', + 'scripts': '{base}/bin', + 'data' : '{base}', + }, + + 'java_user': { + 'stdlib': '{userbase}/lib/jython{py_version_short}', + 'platstdlib': '{userbase}/lib/jython{py_version_short}', + 'purelib': '{userbase}/lib/jython{py_version_short}/site-packages', + 'platlib': '{userbase}/lib/jython{py_version_short}/site-packages', + 'include': '{userbase}/include/jython{py_version_short}', + 'scripts': '{userbase}/bin', + 'data' : '{userbase}', + }, + } + +_SCHEME_KEYS = ('stdlib', 'platstdlib', 'purelib', 'platlib', 'include', + 'scripts', 'data') +_PY_VERSION = sys.version.split()[0] +_PY_VERSION_SHORT = sys.version[:3] +_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) + +def is_python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + _INSTALL_SCHEMES[scheme]['include'] = '{projectbase}/Include' + _INSTALL_SCHEMES[scheme]['platinclude'] = '{srcdir}' + +def _subst_vars(s, local_vars): + try: + return s.format(**local_vars) + except KeyError: + try: + return s.format(**os.environ) + except KeyError, var: + raise AttributeError('{%s}' % var) + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + + for key, value in _INSTALL_SCHEMES[scheme].items(): + if os.name in ('posix', 'nt', 'java'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + +def _get_default_scheme(): + if os.name == 'posix': + # the default scheme for posix is posix_prefix + return 'posix_prefix' + return os.name + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + return env_base if env_base else joinuser(base, "Python") + + if sys.platform == "darwin": + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + return env_base if env_base else \ + joinuser("~", "Library", framework, "%d.%d" + % (sys.version_info[:2])) + + return env_base if env_base else joinuser("~", ".local") + + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + import re + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile("([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with open(filename) as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + while notdone: + for name in notdone.keys(): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + else: + done[n] = item = "" + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + del notdone[name] + else: + # bogus variable reference; just drop it since we can't deal + del notdone[name] + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def _get_makefile_filename(): + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + return os.path.join(get_path('platstdlib'), "config", "Makefile") + + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + makefile = _get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except IOError, e: + msg = "invalid Python installation: unable to open %s" % makefile + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h) as f: + parse_config_h(f, vars) + except IOError, e: + msg = "invalid Python installation: unable to open %s" % config_h + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + import re + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: v = int(v) + except ValueError: pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + +def get_config_h_filename(): + """Returns the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + +def get_scheme_names(): + """Returns a tuple containing the schemes names.""" + schemes = _INSTALL_SCHEMES.keys() + schemes.sort() + return tuple(schemes) + +def get_path_names(): + """Returns a tuple containing the paths names.""" + return _SCHEME_KEYS + +def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): + """Returns a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + if expand: + return _expand_vars(scheme, vars) + else: + return _INSTALL_SCHEMES[scheme] + +def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): + """Returns a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + import re + global _CONFIG_VARS + if _CONFIG_VARS is None: + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # Distutils. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + _CONFIG_VARS['userbase'] = _getuserbase() + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = _PROJECT_BASE + try: + cwd = os.getcwd() + except OSError: + cwd = None + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != cwd): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _CONFIG_VARS[key] + flags = re.sub('-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _CONFIG_VARS[key] = flags + else: + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub('-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search('-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub('-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + import re + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # We can't use "platform.architecture()[0]" because a + # bootstrap problem. We use a dict to get an error + # if some suspicious happens. + bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} + machine += ".%s" % bitness[sys.maxint] + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile (r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if 1: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + try: + m = re.search( + r'<key>ProductUserVisibleVersion</key>\s*' + + r'<string>(.*?)</string>', f.read()) + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + finally: + f.close() + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if (macrelease + '.') >= '10.4.' and \ + '-arch' in get_config_vars().get('CFLAGS', '').strip(): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall('-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r"%(archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxint >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + # See 'i386' case + if sys.maxint >= 2**32: + machine = 'ppc64' + else: + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT diff --git a/src/main/resources/PythonLibs/tabnanny.py b/src/main/resources/PythonLibs/tabnanny.py new file mode 100644 index 0000000000000000000000000000000000000000..76665ac91a01d290f2771cb9ad6a9d15021f671c --- /dev/null +++ b/src/main/resources/PythonLibs/tabnanny.py @@ -0,0 +1,329 @@ +#! /usr/bin/env python + +"""The Tab Nanny despises ambiguous indentation. She knows no mercy. + +tabnanny -- Detection of ambiguous indentation + +For the time being this module is intended to be called as a script. +However it is possible to import it into an IDE and use the function +check() described below. + +Warning: The API provided by this module is likely to change in future +releases; such changes may not be backward compatible. +""" + +# Released to the public domain, by Tim Peters, 15 April 1998. + +# XXX Note: this is now a standard library module. +# XXX The API needs to undergo changes however; the current code is too +# XXX script-like. This will be addressed later. + +__version__ = "6" + +import os +import sys +import getopt +import tokenize +if not hasattr(tokenize, 'NL'): + raise ValueError("tokenize.NL doesn't exist -- tokenize module too old") + +__all__ = ["check", "NannyNag", "process_tokens"] + +verbose = 0 +filename_only = 0 + +def errprint(*args): + sep = "" + for arg in args: + sys.stderr.write(sep + str(arg)) + sep = " " + sys.stderr.write("\n") + +def main(): + global verbose, filename_only + try: + opts, args = getopt.getopt(sys.argv[1:], "qv") + except getopt.error, msg: + errprint(msg) + return + for o, a in opts: + if o == '-q': + filename_only = filename_only + 1 + if o == '-v': + verbose = verbose + 1 + if not args: + errprint("Usage:", sys.argv[0], "[-v] file_or_directory ...") + return + for arg in args: + check(arg) + +class NannyNag(Exception): + """ + Raised by tokeneater() if detecting an ambiguous indent. + Captured and handled in check(). + """ + def __init__(self, lineno, msg, line): + self.lineno, self.msg, self.line = lineno, msg, line + def get_lineno(self): + return self.lineno + def get_msg(self): + return self.msg + def get_line(self): + return self.line + +def check(file): + """check(file_or_dir) + + If file_or_dir is a directory and not a symbolic link, then recursively + descend the directory tree named by file_or_dir, checking all .py files + along the way. If file_or_dir is an ordinary Python source file, it is + checked for whitespace related problems. The diagnostic messages are + written to standard output using the print statement. + """ + + if os.path.isdir(file) and not os.path.islink(file): + if verbose: + print "%r: listing directory" % (file,) + names = os.listdir(file) + for name in names: + fullname = os.path.join(file, name) + if (os.path.isdir(fullname) and + not os.path.islink(fullname) or + os.path.normcase(name[-3:]) == ".py"): + check(fullname) + return + + try: + f = open(file) + except IOError, msg: + errprint("%r: I/O Error: %s" % (file, msg)) + return + + if verbose > 1: + print "checking %r ..." % file + + try: + process_tokens(tokenize.generate_tokens(f.readline)) + + except tokenize.TokenError, msg: + errprint("%r: Token Error: %s" % (file, msg)) + return + + except IndentationError, msg: + errprint("%r: Indentation Error: %s" % (file, msg)) + return + + except NannyNag, nag: + badline = nag.get_lineno() + line = nag.get_line() + if verbose: + print "%r: *** Line %d: trouble in tab city! ***" % (file, badline) + print "offending line: %r" % (line,) + print nag.get_msg() + else: + if ' ' in file: file = '"' + file + '"' + if filename_only: print file + else: print file, badline, repr(line) + return + + if verbose: + print "%r: Clean bill of health." % (file,) + +class Whitespace: + # the characters used for space and tab + S, T = ' \t' + + # members: + # raw + # the original string + # n + # the number of leading whitespace characters in raw + # nt + # the number of tabs in raw[:n] + # norm + # the normal form as a pair (count, trailing), where: + # count + # a tuple such that raw[:n] contains count[i] + # instances of S * i + T + # trailing + # the number of trailing spaces in raw[:n] + # It's A Theorem that m.indent_level(t) == + # n.indent_level(t) for all t >= 1 iff m.norm == n.norm. + # is_simple + # true iff raw[:n] is of the form (T*)(S*) + + def __init__(self, ws): + self.raw = ws + S, T = Whitespace.S, Whitespace.T + count = [] + b = n = nt = 0 + for ch in self.raw: + if ch == S: + n = n + 1 + b = b + 1 + elif ch == T: + n = n + 1 + nt = nt + 1 + if b >= len(count): + count = count + [0] * (b - len(count) + 1) + count[b] = count[b] + 1 + b = 0 + else: + break + self.n = n + self.nt = nt + self.norm = tuple(count), b + self.is_simple = len(count) <= 1 + + # return length of longest contiguous run of spaces (whether or not + # preceding a tab) + def longest_run_of_spaces(self): + count, trailing = self.norm + return max(len(count)-1, trailing) + + def indent_level(self, tabsize): + # count, il = self.norm + # for i in range(len(count)): + # if count[i]: + # il = il + (i/tabsize + 1)*tabsize * count[i] + # return il + + # quicker: + # il = trailing + sum (i/ts + 1)*ts*count[i] = + # trailing + ts * sum (i/ts + 1)*count[i] = + # trailing + ts * sum i/ts*count[i] + count[i] = + # trailing + ts * [(sum i/ts*count[i]) + (sum count[i])] = + # trailing + ts * [(sum i/ts*count[i]) + num_tabs] + # and note that i/ts*count[i] is 0 when i < ts + + count, trailing = self.norm + il = 0 + for i in range(tabsize, len(count)): + il = il + i/tabsize * count[i] + return trailing + tabsize * (il + self.nt) + + # return true iff self.indent_level(t) == other.indent_level(t) + # for all t >= 1 + def equal(self, other): + return self.norm == other.norm + + # return a list of tuples (ts, i1, i2) such that + # i1 == self.indent_level(ts) != other.indent_level(ts) == i2. + # Intended to be used after not self.equal(other) is known, in which + # case it will return at least one witnessing tab size. + def not_equal_witness(self, other): + n = max(self.longest_run_of_spaces(), + other.longest_run_of_spaces()) + 1 + a = [] + for ts in range(1, n+1): + if self.indent_level(ts) != other.indent_level(ts): + a.append( (ts, + self.indent_level(ts), + other.indent_level(ts)) ) + return a + + # Return True iff self.indent_level(t) < other.indent_level(t) + # for all t >= 1. + # The algorithm is due to Vincent Broman. + # Easy to prove it's correct. + # XXXpost that. + # Trivial to prove n is sharp (consider T vs ST). + # Unknown whether there's a faster general way. I suspected so at + # first, but no longer. + # For the special (but common!) case where M and N are both of the + # form (T*)(S*), M.less(N) iff M.len() < N.len() and + # M.num_tabs() <= N.num_tabs(). Proof is easy but kinda long-winded. + # XXXwrite that up. + # Note that M is of the form (T*)(S*) iff len(M.norm[0]) <= 1. + def less(self, other): + if self.n >= other.n: + return False + if self.is_simple and other.is_simple: + return self.nt <= other.nt + n = max(self.longest_run_of_spaces(), + other.longest_run_of_spaces()) + 1 + # the self.n >= other.n test already did it for ts=1 + for ts in range(2, n+1): + if self.indent_level(ts) >= other.indent_level(ts): + return False + return True + + # return a list of tuples (ts, i1, i2) such that + # i1 == self.indent_level(ts) >= other.indent_level(ts) == i2. + # Intended to be used after not self.less(other) is known, in which + # case it will return at least one witnessing tab size. + def not_less_witness(self, other): + n = max(self.longest_run_of_spaces(), + other.longest_run_of_spaces()) + 1 + a = [] + for ts in range(1, n+1): + if self.indent_level(ts) >= other.indent_level(ts): + a.append( (ts, + self.indent_level(ts), + other.indent_level(ts)) ) + return a + +def format_witnesses(w): + firsts = map(lambda tup: str(tup[0]), w) + prefix = "at tab size" + if len(w) > 1: + prefix = prefix + "s" + return prefix + " " + ', '.join(firsts) + +def process_tokens(tokens): + INDENT = tokenize.INDENT + DEDENT = tokenize.DEDENT + NEWLINE = tokenize.NEWLINE + JUNK = tokenize.COMMENT, tokenize.NL + indents = [Whitespace("")] + check_equal = 0 + + for (type, token, start, end, line) in tokens: + if type == NEWLINE: + # a program statement, or ENDMARKER, will eventually follow, + # after some (possibly empty) run of tokens of the form + # (NL | COMMENT)* (INDENT | DEDENT+)? + # If an INDENT appears, setting check_equal is wrong, and will + # be undone when we see the INDENT. + check_equal = 1 + + elif type == INDENT: + check_equal = 0 + thisguy = Whitespace(token) + if not indents[-1].less(thisguy): + witness = indents[-1].not_less_witness(thisguy) + msg = "indent not greater e.g. " + format_witnesses(witness) + raise NannyNag(start[0], msg, line) + indents.append(thisguy) + + elif type == DEDENT: + # there's nothing we need to check here! what's important is + # that when the run of DEDENTs ends, the indentation of the + # program statement (or ENDMARKER) that triggered the run is + # equal to what's left at the top of the indents stack + + # Ouch! This assert triggers if the last line of the source + # is indented *and* lacks a newline -- then DEDENTs pop out + # of thin air. + # assert check_equal # else no earlier NEWLINE, or an earlier INDENT + check_equal = 1 + + del indents[-1] + + elif check_equal and type not in JUNK: + # this is the first "real token" following a NEWLINE, so it + # must be the first token of the next program statement, or an + # ENDMARKER; the "line" argument exposes the leading whitespace + # for this statement; in the case of ENDMARKER, line is an empty + # string, so will properly match the empty string with which the + # "indents" stack was seeded + check_equal = 0 + thisguy = Whitespace(line) + if not indents[-1].equal(thisguy): + witness = indents[-1].not_equal_witness(thisguy) + msg = "indent not equal e.g. " + format_witnesses(witness) + raise NannyNag(start[0], msg, line) + + +if __name__ == '__main__': + main() diff --git a/src/main/resources/PythonLibs/tarfile.py b/src/main/resources/PythonLibs/tarfile.py new file mode 100644 index 0000000000000000000000000000000000000000..356705681dd611e220a95a231c9da6d1c32b596c --- /dev/null +++ b/src/main/resources/PythonLibs/tarfile.py @@ -0,0 +1,2592 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-1 -*- +#------------------------------------------------------------------- +# tarfile.py +#------------------------------------------------------------------- +# Copyright (C) 2002 Lars Gustäbel <lars@gustaebel.de> +# All rights reserved. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +"""Read from and write to tar format archives. +""" + +__version__ = "$Revision: 85213 $" +# $Source$ + +version = "0.9.0" +__author__ = "Lars Gustäbel (lars@gustaebel.de)" +__date__ = "$Date: 2010-10-04 08:37:53 -0700 (ma, 04 loka  2010) $" +__cvsid__ = "$Id: tarfile.py 85213 2010-10-04 15:37:53Z lars.gustaebel $" +__credits__ = "Gustavo Niemeyer, Niels Gustäbel, Richard Townsend." + +#--------- +# Imports +#--------- +import sys +import os +import shutil +import stat +import errno +import time +import struct +import copy +import re +import operator + +try: + import grp, pwd +except ImportError: + grp = pwd = None + +# from tarfile import * +__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] + +#--------------------------------------------------------- +# tar constants +#--------------------------------------------------------- +NUL = "\0" # the null character +BLOCKSIZE = 512 # length of processing blocks +RECORDSIZE = BLOCKSIZE * 20 # length of records +GNU_MAGIC = "ustar \0" # magic gnu tar string +POSIX_MAGIC = "ustar\x0000" # magic posix tar string + +LENGTH_NAME = 100 # maximum length of a filename +LENGTH_LINK = 100 # maximum length of a linkname +LENGTH_PREFIX = 155 # maximum length of the prefix field + +REGTYPE = "0" # regular file +AREGTYPE = "\0" # regular file +LNKTYPE = "1" # link (inside tarfile) +SYMTYPE = "2" # symbolic link +CHRTYPE = "3" # character special device +BLKTYPE = "4" # block special device +DIRTYPE = "5" # directory +FIFOTYPE = "6" # fifo special device +CONTTYPE = "7" # contiguous file + +GNUTYPE_LONGNAME = "L" # GNU tar longname +GNUTYPE_LONGLINK = "K" # GNU tar longlink +GNUTYPE_SPARSE = "S" # GNU tar sparse file + +XHDTYPE = "x" # POSIX.1-2001 extended header +XGLTYPE = "g" # POSIX.1-2001 global header +SOLARIS_XHDTYPE = "X" # Solaris extended header + +USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format +GNU_FORMAT = 1 # GNU tar format +PAX_FORMAT = 2 # POSIX.1-2001 (pax) format +DEFAULT_FORMAT = GNU_FORMAT + +#--------------------------------------------------------- +# tarfile constants +#--------------------------------------------------------- +# File types that tarfile supports: +SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, + SYMTYPE, DIRTYPE, FIFOTYPE, + CONTTYPE, CHRTYPE, BLKTYPE, + GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# File types that will be treated as a regular file. +REGULAR_TYPES = (REGTYPE, AREGTYPE, + CONTTYPE, GNUTYPE_SPARSE) + +# File types that are part of the GNU tar format. +GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# Fields from a pax header that override a TarInfo attribute. +PAX_FIELDS = ("path", "linkpath", "size", "mtime", + "uid", "gid", "uname", "gname") + +# Fields in a pax header that are numbers, all other fields +# are treated as strings. +PAX_NUMBER_FIELDS = { + "atime": float, + "ctime": float, + "mtime": float, + "uid": int, + "gid": int, + "size": int +} + +#--------------------------------------------------------- +# Bits used in the mode field, values in octal. +#--------------------------------------------------------- +S_IFLNK = 0120000 # symbolic link +S_IFREG = 0100000 # regular file +S_IFBLK = 0060000 # block device +S_IFDIR = 0040000 # directory +S_IFCHR = 0020000 # character device +S_IFIFO = 0010000 # fifo + +TSUID = 04000 # set UID on execution +TSGID = 02000 # set GID on execution +TSVTX = 01000 # reserved + +TUREAD = 0400 # read by owner +TUWRITE = 0200 # write by owner +TUEXEC = 0100 # execute/search by owner +TGREAD = 0040 # read by group +TGWRITE = 0020 # write by group +TGEXEC = 0010 # execute/search by group +TOREAD = 0004 # read by other +TOWRITE = 0002 # write by other +TOEXEC = 0001 # execute/search by other + +#--------------------------------------------------------- +# initialization +#--------------------------------------------------------- +ENCODING = sys.getfilesystemencoding() +if ENCODING is None: + ENCODING = sys.getdefaultencoding() + +#--------------------------------------------------------- +# Some useful functions +#--------------------------------------------------------- + +def stn(s, length): + """Convert a python string to a null-terminated string buffer. + """ + return s[:length] + (length - len(s)) * NUL + +def nts(s): + """Convert a null-terminated string field to a python string. + """ + # Use the string up to the first null char. + p = s.find("\0") + if p == -1: + return s + return s[:p] + +def nti(s): + """Convert a number field to a python number. + """ + # There are two possible encodings for a number field, see + # itn() below. + if s[0] != chr(0200): + try: + n = int(nts(s) or "0", 8) + except ValueError: + raise InvalidHeaderError("invalid header") + else: + n = 0L + for i in xrange(len(s) - 1): + n <<= 8 + n += ord(s[i + 1]) + return n + +def itn(n, digits=8, format=DEFAULT_FORMAT): + """Convert a python number to a number field. + """ + # POSIX 1003.1-1988 requires numbers to be encoded as a string of + # octal digits followed by a null-byte, this allows values up to + # (8**(digits-1))-1. GNU tar allows storing numbers greater than + # that if necessary. A leading 0200 byte indicates this particular + # encoding, the following digits-1 bytes are a big-endian + # representation. This allows values up to (256**(digits-1))-1. + if 0 <= n < 8 ** (digits - 1): + s = "%0*o" % (digits - 1, n) + NUL + else: + if format != GNU_FORMAT or n >= 256 ** (digits - 1): + raise ValueError("overflow in number field") + + if n < 0: + # XXX We mimic GNU tar's behaviour with negative numbers, + # this could raise OverflowError. + n = struct.unpack("L", struct.pack("l", n))[0] + + s = "" + for i in xrange(digits - 1): + s = chr(n & 0377) + s + n >>= 8 + s = chr(0200) + s + return s + +def uts(s, encoding, errors): + """Convert a unicode object to a string. + """ + if errors == "utf-8": + # An extra error handler similar to the -o invalid=UTF-8 option + # in POSIX.1-2001. Replace untranslatable characters with their + # UTF-8 representation. + try: + return s.encode(encoding, "strict") + except UnicodeEncodeError: + x = [] + for c in s: + try: + x.append(c.encode(encoding, "strict")) + except UnicodeEncodeError: + x.append(c.encode("utf8")) + return "".join(x) + else: + return s.encode(encoding, errors) + +def calc_chksums(buf): + """Calculate the checksum for a member's header by summing up all + characters except for the chksum field which is treated as if + it was filled with spaces. According to the GNU tar sources, + some tars (Sun and NeXT) calculate chksum with signed char, + which will be different if there are chars in the buffer with + the high bit set. So we calculate two checksums, unsigned and + signed. + """ + unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) + signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) + return unsigned_chksum, signed_chksum + +def copyfileobj(src, dst, length=None): + """Copy length bytes from fileobj src to fileobj dst. + If length is None, copy the entire content. + """ + if length == 0: + return + if length is None: + shutil.copyfileobj(src, dst) + return + + BUFSIZE = 16 * 1024 + blocks, remainder = divmod(length, BUFSIZE) + for b in xrange(blocks): + buf = src.read(BUFSIZE) + if len(buf) < BUFSIZE: + raise IOError("end of file reached") + dst.write(buf) + + if remainder != 0: + buf = src.read(remainder) + if len(buf) < remainder: + raise IOError("end of file reached") + dst.write(buf) + return + +filemode_table = ( + ((S_IFLNK, "l"), + (S_IFREG, "-"), + (S_IFBLK, "b"), + (S_IFDIR, "d"), + (S_IFCHR, "c"), + (S_IFIFO, "p")), + + ((TUREAD, "r"),), + ((TUWRITE, "w"),), + ((TUEXEC|TSUID, "s"), + (TSUID, "S"), + (TUEXEC, "x")), + + ((TGREAD, "r"),), + ((TGWRITE, "w"),), + ((TGEXEC|TSGID, "s"), + (TSGID, "S"), + (TGEXEC, "x")), + + ((TOREAD, "r"),), + ((TOWRITE, "w"),), + ((TOEXEC|TSVTX, "t"), + (TSVTX, "T"), + (TOEXEC, "x")) +) + +def filemode(mode): + """Convert a file's mode to a string of the form + -rwxrwxrwx. + Used by TarFile.list() + """ + perm = [] + for table in filemode_table: + for bit, char in table: + if mode & bit == bit: + perm.append(char) + break + else: + perm.append("-") + return "".join(perm) + +class TarError(Exception): + """Base exception.""" + pass +class ExtractError(TarError): + """General exception for extract errors.""" + pass +class ReadError(TarError): + """Exception for unreadble tar archives.""" + pass +class CompressionError(TarError): + """Exception for unavailable compression methods.""" + pass +class StreamError(TarError): + """Exception for unsupported operations on stream-like TarFiles.""" + pass +class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): + """Exception for invalid headers.""" + pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass + +#--------------------------- +# internal stream interface +#--------------------------- +class _LowLevelFile: + """Low-level file object. Supports reading and writing. + It is used instead of a regular file object for streaming + access. + """ + + def __init__(self, name, mode): + mode = { + "r": os.O_RDONLY, + "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + }[mode] + if hasattr(os, "O_BINARY"): + mode |= os.O_BINARY + self.fd = os.open(name, mode, 0666) + + def close(self): + os.close(self.fd) + + def read(self, size): + return os.read(self.fd, size) + + def write(self, s): + os.write(self.fd, s) + +class _Stream: + """Class that serves as an adapter between TarFile and + a stream-like object. The stream-like object only + needs to have a read() or write() method and is accessed + blockwise. Use of gzip or bzip2 compression is possible. + A stream-like object could be for example: sys.stdin, + sys.stdout, a socket, a tape device etc. + + _Stream is intended to be used only internally. + """ + + def __init__(self, name, mode, comptype, fileobj, bufsize): + """Construct a _Stream object. + """ + self._extfileobj = True + if fileobj is None: + fileobj = _LowLevelFile(name, mode) + self._extfileobj = False + + if comptype == '*': + # Enable transparent compression detection for the + # stream interface + fileobj = _StreamProxy(fileobj) + comptype = fileobj.getcomptype() + + self.name = name or "" + self.mode = mode + self.comptype = comptype + self.fileobj = fileobj + self.bufsize = bufsize + self.buf = "" + self.pos = 0L + self.closed = False + + if comptype == "gz": + try: + import zlib + except ImportError: + raise CompressionError("zlib module is not available") + self.zlib = zlib + self.crc = zlib.crc32("") & 0xffffffffL + if mode == "r": + self._init_read_gz() + else: + self._init_write_gz() + + if comptype == "bz2": + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + if mode == "r": + self.dbuf = "" + self.cmp = bz2.BZ2Decompressor() + else: + self.cmp = bz2.BZ2Compressor() + + def __del__(self): + if hasattr(self, "closed") and not self.closed: + self.close() + + def _init_write_gz(self): + """Initialize for writing with gzip compression. + """ + self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) + timestamp = struct.pack("<L", long(time.time())) + self.__write("\037\213\010\010%s\002\377" % timestamp) + if self.name.endswith(".gz"): + self.name = self.name[:-3] + self.__write(self.name + NUL) + + def write(self, s): + """Write string s to the stream. + """ + if self.comptype == "gz": + self.crc = self.zlib.crc32(s, self.crc) & 0xffffffffL + self.pos += len(s) + if self.comptype != "tar": + s = self.cmp.compress(s) + self.__write(s) + + def __write(self, s): + """Write string s to the stream if a whole new block + is ready to be written. + """ + self.buf += s + while len(self.buf) > self.bufsize: + self.fileobj.write(self.buf[:self.bufsize]) + self.buf = self.buf[self.bufsize:] + + def close(self): + """Close the _Stream object. No operation should be + done on it afterwards. + """ + if self.closed: + return + + if self.mode == "w" and self.comptype != "tar": + self.buf += self.cmp.flush() + + if self.mode == "w" and self.buf: + self.fileobj.write(self.buf) + self.buf = "" + if self.comptype == "gz": + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + self.fileobj.write(struct.pack("<L", self.crc & 0xffffffffL)) + self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFFL)) + + if not self._extfileobj: + self.fileobj.close() + + self.closed = True + + def _init_read_gz(self): + """Initialize for reading a gzip compressed fileobj. + """ + self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS) + self.dbuf = "" + + # taken from gzip.GzipFile with some alterations + if self.__read(2) != "\037\213": + raise ReadError("not a gzip file") + if self.__read(1) != "\010": + raise CompressionError("unsupported compression method") + + flag = ord(self.__read(1)) + self.__read(6) + + if flag & 4: + xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) + self.read(xlen) + if flag & 8: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 16: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 2: + self.__read(2) + + def tell(self): + """Return the stream's file pointer position. + """ + return self.pos + + def seek(self, pos=0): + """Set the stream's file pointer to pos. Negative seeking + is forbidden. + """ + if pos - self.pos >= 0: + blocks, remainder = divmod(pos - self.pos, self.bufsize) + for i in xrange(blocks): + self.read(self.bufsize) + self.read(remainder) + else: + raise StreamError("seeking backwards is not allowed") + return self.pos + + def read(self, size=None): + """Return the next size number of bytes from the stream. + If size is not defined, return all bytes of the stream + up to EOF. + """ + if size is None: + t = [] + while True: + buf = self._read(self.bufsize) + if not buf: + break + t.append(buf) + buf = "".join(t) + else: + buf = self._read(size) + self.pos += len(buf) + return buf + + def _read(self, size): + """Return size bytes from the stream. + """ + if self.comptype == "tar": + return self.__read(size) + + c = len(self.dbuf) + t = [self.dbuf] + while c < size: + buf = self.__read(self.bufsize) + if not buf: + break + try: + buf = self.cmp.decompress(buf) + except IOError: + raise ReadError("invalid compressed data") + t.append(buf) + c += len(buf) + t = "".join(t) + self.dbuf = t[size:] + return t[:size] + + def __read(self, size): + """Return size bytes from stream. If internal buffer is empty, + read another block from the stream. + """ + c = len(self.buf) + t = [self.buf] + while c < size: + buf = self.fileobj.read(self.bufsize) + if not buf: + break + t.append(buf) + c += len(buf) + t = "".join(t) + self.buf = t[size:] + return t[:size] +# class _Stream + +class _StreamProxy(object): + """Small proxy class that enables transparent compression + detection for the Stream interface (mode 'r|*'). + """ + + def __init__(self, fileobj): + self.fileobj = fileobj + self.buf = self.fileobj.read(BLOCKSIZE) + + def read(self, size): + self.read = self.fileobj.read + return self.buf + + def getcomptype(self): + if self.buf.startswith("\037\213\010"): + return "gz" + if self.buf.startswith("BZh91"): + return "bz2" + return "tar" + + def close(self): + self.fileobj.close() +# class StreamProxy + +class _BZ2Proxy(object): + """Small proxy class that enables external file object + support for "r:bz2" and "w:bz2" modes. This is actually + a workaround for a limitation in bz2 module's BZ2File + class which (unlike gzip.GzipFile) has no support for + a file object argument. + """ + + blocksize = 16 * 1024 + + def __init__(self, fileobj, mode): + self.fileobj = fileobj + self.mode = mode + self.name = getattr(self.fileobj, "name", None) + self.init() + + def init(self): + import bz2 + self.pos = 0 + if self.mode == "r": + self.bz2obj = bz2.BZ2Decompressor() + self.fileobj.seek(0) + self.buf = "" + else: + self.bz2obj = bz2.BZ2Compressor() + + def read(self, size): + b = [self.buf] + x = len(self.buf) + while x < size: + raw = self.fileobj.read(self.blocksize) + if not raw: + break + data = self.bz2obj.decompress(raw) + b.append(data) + x += len(data) + self.buf = "".join(b) + + buf = self.buf[:size] + self.buf = self.buf[size:] + self.pos += len(buf) + return buf + + def seek(self, pos): + if pos < self.pos: + self.init() + self.read(pos - self.pos) + + def tell(self): + return self.pos + + def write(self, data): + self.pos += len(data) + raw = self.bz2obj.compress(data) + self.fileobj.write(raw) + + def close(self): + if self.mode == "w": + raw = self.bz2obj.flush() + self.fileobj.write(raw) +# class _BZ2Proxy + +#------------------------ +# Extraction file object +#------------------------ +class _FileInFile(object): + """A thin wrapper around an existing file object that + provides a part of its data as an individual file + object. + """ + + def __init__(self, fileobj, offset, size, sparse=None): + self.fileobj = fileobj + self.offset = offset + self.size = size + self.sparse = sparse + self.position = 0 + + def tell(self): + """Return the current file position. + """ + return self.position + + def seek(self, position): + """Seek to a position in the file. + """ + self.position = position + + def read(self, size=None): + """Read data from the file. + """ + if size is None: + size = self.size - self.position + else: + size = min(size, self.size - self.position) + + if self.sparse is None: + return self.readnormal(size) + else: + return self.readsparse(size) + + def readnormal(self, size): + """Read operation for regular files. + """ + self.fileobj.seek(self.offset + self.position) + self.position += size + return self.fileobj.read(size) + + def readsparse(self, size): + """Read operation for sparse files. + """ + data = [] + while size > 0: + buf = self.readsparsesection(size) + if not buf: + break + size -= len(buf) + data.append(buf) + return "".join(data) + + def readsparsesection(self, size): + """Read a single section of a sparse file. + """ + section = self.sparse.find(self.position) + + if section is None: + return "" + + size = min(size, section.offset + section.size - self.position) + + if isinstance(section, _data): + realpos = section.realpos + self.position - section.offset + self.fileobj.seek(self.offset + realpos) + self.position += size + return self.fileobj.read(size) + else: + self.position += size + return NUL * size +#class _FileInFile + + +class ExFileObject(object): + """File-like object for reading an archive member. + Is returned by TarFile.extractfile(). + """ + blocksize = 1024 + + def __init__(self, tarfile, tarinfo): + self.fileobj = _FileInFile(tarfile.fileobj, + tarinfo.offset_data, + tarinfo.size, + getattr(tarinfo, "sparse", None)) + self.name = tarinfo.name + self.mode = "r" + self.closed = False + self.size = tarinfo.size + + self.position = 0 + self.buffer = "" + + def read(self, size=None): + """Read at most size bytes from the file. If size is not + present or None, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + buf = "" + if self.buffer: + if size is None: + buf = self.buffer + self.buffer = "" + else: + buf = self.buffer[:size] + self.buffer = self.buffer[size:] + + if size is None: + buf += self.fileobj.read() + else: + buf += self.fileobj.read(size - len(buf)) + + self.position += len(buf) + return buf + + def readline(self, size=-1): + """Read one entire line from the file. If size is present + and non-negative, return a string with at most that + size, which may be an incomplete line. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if "\n" in self.buffer: + pos = self.buffer.find("\n") + 1 + else: + buffers = [self.buffer] + while True: + buf = self.fileobj.read(self.blocksize) + buffers.append(buf) + if not buf or "\n" in buf: + self.buffer = "".join(buffers) + pos = self.buffer.find("\n") + 1 + if pos == 0: + # no newline found. + pos = len(self.buffer) + break + + if size != -1: + pos = min(size, pos) + + buf = self.buffer[:pos] + self.buffer = self.buffer[pos:] + self.position += len(buf) + return buf + + def readlines(self): + """Return a list with all remaining lines. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def tell(self): + """Return the current file position. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + return self.position + + def seek(self, pos, whence=os.SEEK_SET): + """Seek to a position in the file. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if whence == os.SEEK_SET: + self.position = min(max(pos, 0), self.size) + elif whence == os.SEEK_CUR: + if pos < 0: + self.position = max(self.position + pos, 0) + else: + self.position = min(self.position + pos, self.size) + elif whence == os.SEEK_END: + self.position = max(min(self.size + pos, self.size), 0) + else: + raise ValueError("Invalid argument") + + self.buffer = "" + self.fileobj.seek(self.position) + + def close(self): + """Close the file object. + """ + self.closed = True + + def __iter__(self): + """Get an iterator over the file's lines. + """ + while True: + line = self.readline() + if not line: + break + yield line +#class ExFileObject + +#------------------ +# Exported Classes +#------------------ +class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. + TarInfo objects are returned by TarFile.getmember(), + TarFile.getmembers() and TarFile.gettarinfo() and are + usually created internally. + """ + + def __init__(self, name=""): + """Construct a TarInfo object. name is the optional name + of the member. + """ + self.name = name # member name + self.mode = 0644 # file permissions + self.uid = 0 # user id + self.gid = 0 # group id + self.size = 0 # file size + self.mtime = 0 # modification time + self.chksum = 0 # header checksum + self.type = REGTYPE # member type + self.linkname = "" # link name + self.uname = "" # user name + self.gname = "" # group name + self.devmajor = 0 # device major number + self.devminor = 0 # device minor number + + self.offset = 0 # the tar header starts here + self.offset_data = 0 # the file's data starts here + + self.pax_headers = {} # pax header information + + # In pax headers the "name" and "linkname" field are called + # "path" and "linkpath". + def _getpath(self): + return self.name + def _setpath(self, name): + self.name = name + path = property(_getpath, _setpath) + + def _getlinkpath(self): + return self.linkname + def _setlinkpath(self, linkname): + self.linkname = linkname + linkpath = property(_getlinkpath, _setlinkpath) + + def __repr__(self): + return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + + def get_info(self, encoding, errors): + """Return the TarInfo's attributes as a dictionary. + """ + info = { + "name": self.name, + "mode": self.mode & 07777, + "uid": self.uid, + "gid": self.gid, + "size": self.size, + "mtime": self.mtime, + "chksum": self.chksum, + "type": self.type, + "linkname": self.linkname, + "uname": self.uname, + "gname": self.gname, + "devmajor": self.devmajor, + "devminor": self.devminor + } + + if info["type"] == DIRTYPE and not info["name"].endswith("/"): + info["name"] += "/" + + for key in ("name", "linkname", "uname", "gname"): + if type(info[key]) is unicode: + info[key] = info[key].encode(encoding, errors) + + return info + + def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="strict"): + """Return a tar header as a string of 512 byte blocks. + """ + info = self.get_info(encoding, errors) + + if format == USTAR_FORMAT: + return self.create_ustar_header(info) + elif format == GNU_FORMAT: + return self.create_gnu_header(info) + elif format == PAX_FORMAT: + return self.create_pax_header(info, encoding, errors) + else: + raise ValueError("invalid format") + + def create_ustar_header(self, info): + """Return the object as a ustar header block. + """ + info["magic"] = POSIX_MAGIC + + if len(info["linkname"]) > LENGTH_LINK: + raise ValueError("linkname is too long") + + if len(info["name"]) > LENGTH_NAME: + info["prefix"], info["name"] = self._posix_split_name(info["name"]) + + return self._create_header(info, USTAR_FORMAT) + + def create_gnu_header(self, info): + """Return the object as a GNU header block sequence. + """ + info["magic"] = GNU_MAGIC + + buf = "" + if len(info["linkname"]) > LENGTH_LINK: + buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK) + + if len(info["name"]) > LENGTH_NAME: + buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME) + + return buf + self._create_header(info, GNU_FORMAT) + + def create_pax_header(self, info, encoding, errors): + """Return the object as a ustar header block. If it cannot be + represented this way, prepend a pax extended header sequence + with supplement information. + """ + info["magic"] = POSIX_MAGIC + pax_headers = self.pax_headers.copy() + + # Test string fields for values that exceed the field length or cannot + # be represented in ASCII encoding. + for name, hname, length in ( + ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), + ("uname", "uname", 32), ("gname", "gname", 32)): + + if hname in pax_headers: + # The pax header has priority. + continue + + val = info[name].decode(encoding, errors) + + # Try to encode the string as ASCII. + try: + val.encode("ascii") + except UnicodeEncodeError: + pax_headers[hname] = val + continue + + if len(info[name]) > length: + pax_headers[hname] = val + + # Test number fields for values that exceed the field limit or values + # that like to be stored as float. + for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): + if name in pax_headers: + # The pax header has priority. Avoid overflow. + info[name] = 0 + continue + + val = info[name] + if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): + pax_headers[name] = unicode(val) + info[name] = 0 + + # Create a pax extended header if necessary. + if pax_headers: + buf = self._create_pax_generic_header(pax_headers) + else: + buf = "" + + return buf + self._create_header(info, USTAR_FORMAT) + + @classmethod + def create_pax_global_header(cls, pax_headers): + """Return the object as a pax global header block sequence. + """ + return cls._create_pax_generic_header(pax_headers, type=XGLTYPE) + + def _posix_split_name(self, name): + """Split a name longer than 100 chars into a prefix + and a name part. + """ + prefix = name[:LENGTH_PREFIX + 1] + while prefix and prefix[-1] != "/": + prefix = prefix[:-1] + + name = name[len(prefix):] + prefix = prefix[:-1] + + if not prefix or len(name) > LENGTH_NAME: + raise ValueError("name is too long") + return prefix, name + + @staticmethod + def _create_header(info, format): + """Return a header block. info is a dictionary with file + information, format must be one of the *_FORMAT constants. + """ + parts = [ + stn(info.get("name", ""), 100), + itn(info.get("mode", 0) & 07777, 8, format), + itn(info.get("uid", 0), 8, format), + itn(info.get("gid", 0), 8, format), + itn(info.get("size", 0), 12, format), + itn(info.get("mtime", 0), 12, format), + " ", # checksum field + info.get("type", REGTYPE), + stn(info.get("linkname", ""), 100), + stn(info.get("magic", POSIX_MAGIC), 8), + stn(info.get("uname", ""), 32), + stn(info.get("gname", ""), 32), + itn(info.get("devmajor", 0), 8, format), + itn(info.get("devminor", 0), 8, format), + stn(info.get("prefix", ""), 155) + ] + + buf = struct.pack("%ds" % BLOCKSIZE, "".join(parts)) + chksum = calc_chksums(buf[-BLOCKSIZE:])[0] + buf = buf[:-364] + "%06o\0" % chksum + buf[-357:] + return buf + + @staticmethod + def _create_payload(payload): + """Return the string payload filled with zero bytes + up to the next 512 byte border. + """ + blocks, remainder = divmod(len(payload), BLOCKSIZE) + if remainder > 0: + payload += (BLOCKSIZE - remainder) * NUL + return payload + + @classmethod + def _create_gnu_long_header(cls, name, type): + """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence + for name. + """ + name += NUL + + info = {} + info["name"] = "././@LongLink" + info["type"] = type + info["size"] = len(name) + info["magic"] = GNU_MAGIC + + # create extended header + name blocks. + return cls._create_header(info, USTAR_FORMAT) + \ + cls._create_payload(name) + + @classmethod + def _create_pax_generic_header(cls, pax_headers, type=XHDTYPE): + """Return a POSIX.1-2001 extended or global header sequence + that contains a list of keyword, value pairs. The values + must be unicode objects. + """ + records = [] + for keyword, value in pax_headers.iteritems(): + keyword = keyword.encode("utf8") + value = value.encode("utf8") + l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' + n = p = 0 + while True: + n = l + len(str(p)) + if n == p: + break + p = n + records.append("%d %s=%s\n" % (p, keyword, value)) + records = "".join(records) + + # We use a hardcoded "././@PaxHeader" name like star does + # instead of the one that POSIX recommends. + info = {} + info["name"] = "././@PaxHeader" + info["type"] = type + info["size"] = len(records) + info["magic"] = POSIX_MAGIC + + # Create pax header + record blocks. + return cls._create_header(info, USTAR_FORMAT) + \ + cls._create_payload(records) + + @classmethod + def frombuf(cls, buf): + """Construct a TarInfo object from a 512 byte string buffer. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") + if len(buf) != BLOCKSIZE: + raise TruncatedHeaderError("truncated header") + if buf.count(NUL) == BLOCKSIZE: + raise EOFHeaderError("end of file header") + + chksum = nti(buf[148:156]) + if chksum not in calc_chksums(buf): + raise InvalidHeaderError("bad checksum") + + obj = cls() + obj.buf = buf + obj.name = nts(buf[0:100]) + obj.mode = nti(buf[100:108]) + obj.uid = nti(buf[108:116]) + obj.gid = nti(buf[116:124]) + obj.size = nti(buf[124:136]) + obj.mtime = nti(buf[136:148]) + obj.chksum = chksum + obj.type = buf[156:157] + obj.linkname = nts(buf[157:257]) + obj.uname = nts(buf[265:297]) + obj.gname = nts(buf[297:329]) + obj.devmajor = nti(buf[329:337]) + obj.devminor = nti(buf[337:345]) + prefix = nts(buf[345:500]) + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. + if obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # Remove redundant slashes from directories. + if obj.isdir(): + obj.name = obj.name.rstrip("/") + + # Reconstruct a ustar longname. + if prefix and obj.type not in GNU_TYPES: + obj.name = prefix + "/" + obj.name + return obj + + @classmethod + def fromtarfile(cls, tarfile): + """Return the next TarInfo object from TarFile object + tarfile. + """ + buf = tarfile.fileobj.read(BLOCKSIZE) + obj = cls.frombuf(buf) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + + #-------------------------------------------------------------------------- + # The following are methods that are called depending on the type of a + # member. The entry point is _proc_member() which can be overridden in a + # subclass to add custom _proc_*() methods. A _proc_*() method MUST + # implement the following + # operations: + # 1. Set self.offset_data to the position where the data blocks begin, + # if there is data that follows. + # 2. Set tarfile.offset to the position where the next member's header will + # begin. + # 3. Return self or another valid TarInfo object. + def _proc_member(self, tarfile): + """Choose the right processing method depending on + the type and call it. + """ + if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): + return self._proc_gnulong(tarfile) + elif self.type == GNUTYPE_SPARSE: + return self._proc_sparse(tarfile) + elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): + return self._proc_pax(tarfile) + else: + return self._proc_builtin(tarfile) + + def _proc_builtin(self, tarfile): + """Process a builtin type or an unknown type which + will be treated as a regular file. + """ + self.offset_data = tarfile.fileobj.tell() + offset = self.offset_data + if self.isreg() or self.type not in SUPPORTED_TYPES: + # Skip the following data blocks. + offset += self._block(self.size) + tarfile.offset = offset + + # Patch the TarInfo object with saved global + # header information. + self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) + + return self + + def _proc_gnulong(self, tarfile): + """Process the blocks that hold a GNU longname + or longlink member. + """ + buf = tarfile.fileobj.read(self._block(self.size)) + + # Fetch the next header and process it. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Patch the TarInfo object from the next header with + # the longname information. + next.offset = self.offset + if self.type == GNUTYPE_LONGNAME: + next.name = nts(buf) + elif self.type == GNUTYPE_LONGLINK: + next.linkname = nts(buf) + + return next + + def _proc_sparse(self, tarfile): + """Process a GNU sparse header plus extra headers. + """ + buf = self.buf + sp = _ringbuffer() + pos = 386 + lastpos = 0L + realpos = 0L + # There are 4 possible sparse structs in the + # first header. + for i in xrange(4): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset > lastpos: + sp.append(_hole(lastpos, offset - lastpos)) + sp.append(_data(offset, numbytes, realpos)) + realpos += numbytes + lastpos = offset + numbytes + pos += 24 + + isextended = ord(buf[482]) + origsize = nti(buf[483:495]) + + # If the isextended flag is given, + # there are extra headers to process. + while isextended == 1: + buf = tarfile.fileobj.read(BLOCKSIZE) + pos = 0 + for i in xrange(21): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset > lastpos: + sp.append(_hole(lastpos, offset - lastpos)) + sp.append(_data(offset, numbytes, realpos)) + realpos += numbytes + lastpos = offset + numbytes + pos += 24 + isextended = ord(buf[504]) + + if lastpos < origsize: + sp.append(_hole(lastpos, origsize - lastpos)) + + self.sparse = sp + + self.offset_data = tarfile.fileobj.tell() + tarfile.offset = self.offset_data + self._block(self.size) + self.size = origsize + + return self + + def _proc_pax(self, tarfile): + """Process an extended or global header as described in + POSIX.1-2001. + """ + # Read the header information. + buf = tarfile.fileobj.read(self._block(self.size)) + + # A pax header stores supplemental information for either + # the following file (extended) or all following files + # (global). + if self.type == XGLTYPE: + pax_headers = tarfile.pax_headers + else: + pax_headers = tarfile.pax_headers.copy() + + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and + # the newline. keyword and value are both UTF-8 encoded strings. + regex = re.compile(r"(\d+) ([^=]+)=", re.U) + pos = 0 + while True: + match = regex.match(buf, pos) + if not match: + break + + length, keyword = match.groups() + length = int(length) + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + keyword = keyword.decode("utf8") + value = value.decode("utf8") + + pax_headers[keyword] = value + pos += length + + # Fetch the next header. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + if self.type in (XHDTYPE, SOLARIS_XHDTYPE): + # Patch the TarInfo object with the extended header info. + next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) + next.offset = self.offset + + if "size" in pax_headers: + # If the extended header replaces the size field, + # we need to recalculate the offset where the next + # header starts. + offset = next.offset_data + if next.isreg() or next.type not in SUPPORTED_TYPES: + offset += next._block(next.size) + tarfile.offset = offset + + return next + + def _apply_pax_info(self, pax_headers, encoding, errors): + """Replace fields with supplemental information from a previous + pax extended or global header. + """ + for keyword, value in pax_headers.iteritems(): + if keyword not in PAX_FIELDS: + continue + + if keyword == "path": + value = value.rstrip("/") + + if keyword in PAX_NUMBER_FIELDS: + try: + value = PAX_NUMBER_FIELDS[keyword](value) + except ValueError: + value = 0 + else: + value = uts(value, encoding, errors) + + setattr(self, keyword, value) + + self.pax_headers = pax_headers.copy() + + def _block(self, count): + """Round up a byte count by BLOCKSIZE and return it, + e.g. _block(834) => 1024. + """ + blocks, remainder = divmod(count, BLOCKSIZE) + if remainder: + blocks += 1 + return blocks * BLOCKSIZE + + def isreg(self): + return self.type in REGULAR_TYPES + def isfile(self): + return self.isreg() + def isdir(self): + return self.type == DIRTYPE + def issym(self): + return self.type == SYMTYPE + def islnk(self): + return self.type == LNKTYPE + def ischr(self): + return self.type == CHRTYPE + def isblk(self): + return self.type == BLKTYPE + def isfifo(self): + return self.type == FIFOTYPE + def issparse(self): + return self.type == GNUTYPE_SPARSE + def isdev(self): + return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) +# class TarInfo + +class TarFile(object): + """The TarFile Class provides an interface to tar archives. + """ + + debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) + + dereference = False # If true, add content of linked file to the + # tar file, else the link. + + ignore_zeros = False # If true, skips empty or invalid blocks and + # continues processing. + + errorlevel = 1 # If 0, fatal errors only appear in debug + # messages (if debug >= 0). If > 0, errors + # are passed to the caller as exceptions. + + format = DEFAULT_FORMAT # The format to use when creating an archive. + + encoding = ENCODING # Encoding for 8-bit character strings. + + errors = None # Error handler for unicode conversion. + + tarinfo = TarInfo # The default TarInfo class to use. + + fileobject = ExFileObject # The default ExFileObject class to use. + + def __init__(self, name=None, mode="r", fileobj=None, format=None, + tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, + errors=None, pax_headers=None, debug=None, errorlevel=None): + """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to + read from an existing archive, 'a' to append data to an existing + file or 'w' to create a new file overwriting an existing one. `mode' + defaults to 'r'. + If `fileobj' is given, it is used for reading or writing data. If it + can be determined, `mode' is overridden by `fileobj's mode. + `fileobj' is not closed, when TarFile is closed. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + self.mode = mode + self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + + if not fileobj: + if self.mode == "a" and not os.path.exists(name): + # Create nonexistent files in append mode. + self.mode = "w" + self._mode = "wb" + fileobj = bltn_open(name, self._mode) + self._extfileobj = False + else: + if name is None and hasattr(fileobj, "name"): + name = fileobj.name + if hasattr(fileobj, "mode"): + self._mode = fileobj.mode + self._extfileobj = True + self.name = os.path.abspath(name) if name else None + self.fileobj = fileobj + + # Init attributes. + if format is not None: + self.format = format + if tarinfo is not None: + self.tarinfo = tarinfo + if dereference is not None: + self.dereference = dereference + if ignore_zeros is not None: + self.ignore_zeros = ignore_zeros + if encoding is not None: + self.encoding = encoding + + if errors is not None: + self.errors = errors + elif mode == "r": + self.errors = "utf-8" + else: + self.errors = "strict" + + if pax_headers is not None and self.format == PAX_FORMAT: + self.pax_headers = pax_headers + else: + self.pax_headers = {} + + if debug is not None: + self.debug = debug + if errorlevel is not None: + self.errorlevel = errorlevel + + # Init datastructures. + self.closed = False + self.members = [] # list of members as TarInfo objects + self._loaded = False # flag if all members have been read + self.offset = self.fileobj.tell() + # current position in the archive file + self.inodes = {} # dictionary caching the inodes of + # archive members already added + + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + while True: + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) + break + except HeaderError, e: + raise ReadError(str(e)) + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + def _getposix(self): + return self.format == USTAR_FORMAT + def _setposix(self, value): + import warnings + warnings.warn("use the format attribute instead", DeprecationWarning, + 2) + if value: + self.format = USTAR_FORMAT + else: + self.format = GNU_FORMAT + posix = property(_getposix, _setposix) + + #-------------------------------------------------------------------------- + # Below are the classmethods which act as alternate constructors to the + # TarFile class. The open() method is the only one that is needed for + # public use; it is the "super"-constructor and is able to select an + # adequate "sub"-constructor for a particular compression using the mapping + # from OPEN_METH. + # + # This concept allows one to subclass TarFile without losing the comfort of + # the super-constructor. A sub-constructor is registered and made available + # by adding it to the mapping in OPEN_METH. + + @classmethod + def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): + """Open a tar archive for reading, writing or appending. Return + an appropriate TarFile class. + + mode: + 'r' or 'r:*' open for reading with transparent compression + 'r:' open for reading exclusively uncompressed + 'r:gz' open for reading with gzip compression + 'r:bz2' open for reading with bzip2 compression + 'a' or 'a:' open for appending, creating the file if necessary + 'w' or 'w:' open for writing without compression + 'w:gz' open for writing with gzip compression + 'w:bz2' open for writing with bzip2 compression + + 'r|*' open a stream of tar blocks with transparent compression + 'r|' open an uncompressed stream of tar blocks for reading + 'r|gz' open a gzip compressed stream of tar blocks + 'r|bz2' open a bzip2 compressed stream of tar blocks + 'w|' open an uncompressed stream for writing + 'w|gz' open a gzip compressed stream for writing + 'w|bz2' open a bzip2 compressed stream for writing + """ + + if not name and not fileobj: + raise ValueError("nothing to open") + + if mode in ("r", "r:*"): + # Find out which *open() is appropriate for opening the file. + for comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + if fileobj is not None: + saved_pos = fileobj.tell() + try: + return func(name, "r", fileobj, **kwargs) + except (ReadError, CompressionError), e: + if fileobj is not None: + fileobj.seek(saved_pos) + continue + raise ReadError("file could not be opened successfully") + + elif ":" in mode: + filemode, comptype = mode.split(":", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + # Select the *open() function according to + # given compression. + if comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + else: + raise CompressionError("unknown compression type %r" % comptype) + return func(name, filemode, fileobj, **kwargs) + + elif "|" in mode: + filemode, comptype = mode.split("|", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + if filemode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + t = cls(name, filemode, + _Stream(name, filemode, comptype, fileobj, bufsize), + **kwargs) + t._extfileobj = False + return t + + elif mode in "aw": + return cls.taropen(name, mode, fileobj, **kwargs) + + raise ValueError("undiscernible mode") + + @classmethod + def taropen(cls, name, mode="r", fileobj=None, **kwargs): + """Open uncompressed tar archive name for reading or writing. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + return cls(name, mode, fileobj, **kwargs) + + @classmethod + def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open gzip compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + try: + import gzip + gzip.GzipFile + except (ImportError, AttributeError): + raise CompressionError("gzip module is not available") + + fileobj = gzip.GzipFile(name, mode, compresslevel, fileobj) + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except IOError: + fileobj.close() + raise ReadError("not a gzip file") + t._extfileobj = False + return t + + @classmethod + def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open bzip2 compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'.") + + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + + if fileobj is not None: + fileobj = _BZ2Proxy(fileobj, mode) + extfileobj = True + else: + fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) + extfileobj = False + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except (IOError, EOFError): + if not extfileobj: + fileobj.close() + raise ReadError("not a bzip2 file") + t._extfileobj = False + return t + + # All *open() methods are registered here. + OPEN_METH = { + "tar": "taropen", # uncompressed tar + "gz": "gzopen", # gzip compressed tar + "bz2": "bz2open" # bzip2 compressed tar + } + + #-------------------------------------------------------------------------- + # The public methods which TarFile provides: + + def close(self): + """Close the TarFile. In write-mode, two finishing zero blocks are + appended to the archive. + """ + if self.closed: + return + + if self.mode in "aw": + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + + if not self._extfileobj: + self.fileobj.close() + self.closed = True + + def getmember(self, name): + """Return a TarInfo object for member `name'. If `name' can not be + found in the archive, KeyError is raised. If a member occurs more + than once in the archive, its last occurrence is assumed to be the + most up-to-date version. + """ + tarinfo = self._getmember(name) + if tarinfo is None: + raise KeyError("filename %r not found" % name) + return tarinfo + + def getmembers(self): + """Return the members of the archive as a list of TarInfo objects. The + list has the same order as the members in the archive. + """ + self._check() + if not self._loaded: # if we want to obtain a list of + self._load() # all members, we first have to + # scan the whole archive. + return self.members + + def getnames(self): + """Return the members of the archive as a list of their names. It has + the same order as the list returned by getmembers(). + """ + return [tarinfo.name for tarinfo in self.getmembers()] + + def gettarinfo(self, name=None, arcname=None, fileobj=None): + """Create a TarInfo object for either the file `name' or the file + object `fileobj' (using os.fstat on its file descriptor). You can + modify some of the TarInfo's attributes before you add it using + addfile(). If given, `arcname' specifies an alternative name for the + file in the archive. + """ + self._check("aw") + + # When fileobj is given, replace name by + # fileobj's real name. + if fileobj is not None: + name = fileobj.name + + # Building the name of the member in the archive. + # Backward slashes are converted to forward slashes, + # Absolute paths are turned to relative paths. + if arcname is None: + arcname = name + drv, arcname = os.path.splitdrive(arcname) + arcname = arcname.replace(os.sep, "/") + arcname = arcname.lstrip("/") + + # Now, fill the TarInfo object with + # information specific for the file. + tarinfo = self.tarinfo() + tarinfo.tarfile = self + + # Use os.stat or os.lstat, depending on platform + # and if symlinks shall be resolved. + if fileobj is None: + if hasattr(os, "lstat") and not self.dereference: + statres = os.lstat(name) + else: + statres = os.stat(name) + else: + statres = os.fstat(fileobj.fileno()) + linkname = "" + + stmd = statres.st_mode + if stat.S_ISREG(stmd): + inode = (statres.st_ino, statres.st_dev) + if not self.dereference and statres.st_nlink > 1 and \ + inode in self.inodes and arcname != self.inodes[inode]: + # Is it a hardlink to an already + # archived file? + type = LNKTYPE + linkname = self.inodes[inode] + else: + # The inode is added only if its valid. + # For win32 it is always 0. + type = REGTYPE + if inode[0]: + self.inodes[inode] = arcname + elif stat.S_ISDIR(stmd): + type = DIRTYPE + elif stat.S_ISFIFO(stmd): + type = FIFOTYPE + elif stat.S_ISLNK(stmd): + type = SYMTYPE + linkname = os.readlink(name) + elif stat.S_ISCHR(stmd): + type = CHRTYPE + elif stat.S_ISBLK(stmd): + type = BLKTYPE + else: + return None + + # Fill the TarInfo object with all + # information we can get. + tarinfo.name = arcname + tarinfo.mode = stmd + tarinfo.uid = statres.st_uid + tarinfo.gid = statres.st_gid + if type == REGTYPE: + tarinfo.size = statres.st_size + else: + tarinfo.size = 0L + tarinfo.mtime = statres.st_mtime + tarinfo.type = type + tarinfo.linkname = linkname + if pwd: + try: + tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] + except KeyError: + pass + if grp: + try: + tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] + except KeyError: + pass + + if type in (CHRTYPE, BLKTYPE): + if hasattr(os, "major") and hasattr(os, "minor"): + tarinfo.devmajor = os.major(statres.st_rdev) + tarinfo.devminor = os.minor(statres.st_rdev) + return tarinfo + + def list(self, verbose=True): + """Print a table of contents to sys.stdout. If `verbose' is False, only + the names of the members are printed. If it is True, an `ls -l'-like + output is produced. + """ + self._check() + + for tarinfo in self: + if verbose: + print filemode(tarinfo.mode), + print "%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid), + if tarinfo.ischr() or tarinfo.isblk(): + print "%10s" % ("%d,%d" \ + % (tarinfo.devmajor, tarinfo.devminor)), + else: + print "%10d" % tarinfo.size, + print "%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6], + + print tarinfo.name + ("/" if tarinfo.isdir() else ""), + + if verbose: + if tarinfo.issym(): + print "->", tarinfo.linkname, + if tarinfo.islnk(): + print "link to", tarinfo.linkname, + print + + def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): + """Add the file `name' to the archive. `name' may be any type of file + (directory, fifo, symbolic link, etc.). If given, `arcname' + specifies an alternative name for the file in the archive. + Directories are added recursively by default. This can be avoided by + setting `recursive' to False. `exclude' is a function that should + return True for each filename to be excluded. `filter' is a function + that expects a TarInfo object argument and returns the changed + TarInfo object, if it returns None the TarInfo object will be + excluded from the archive. + """ + self._check("aw") + + if arcname is None: + arcname = name + + # Exclude pathnames. + if exclude is not None: + import warnings + warnings.warn("use the filter argument instead", + DeprecationWarning, 2) + if exclude(name): + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Skip if somebody tries to archive the archive... + if self.name is not None and os.path.abspath(name) == self.name: + self._dbg(2, "tarfile: Skipped %r" % name) + return + + self._dbg(1, name) + + # Create a TarInfo object from the file. + tarinfo = self.gettarinfo(name, arcname) + + if tarinfo is None: + self._dbg(1, "tarfile: Unsupported type %r" % name) + return + + # Change or exclude the TarInfo object. + if filter is not None: + tarinfo = filter(tarinfo) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Append the tar header and data to the archive. + if tarinfo.isreg(): + f = bltn_open(name, "rb") + self.addfile(tarinfo, f) + f.close() + + elif tarinfo.isdir(): + self.addfile(tarinfo) + if recursive: + for f in os.listdir(name): + self.add(os.path.join(name, f), os.path.join(arcname, f), + recursive, exclude, filter) + + else: + self.addfile(tarinfo) + + def addfile(self, tarinfo, fileobj=None): + """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is + given, tarinfo.size bytes are read from it and added to the archive. + You can create TarInfo objects using gettarinfo(). + On Windows platforms, `fileobj' should always be opened with mode + 'rb' to avoid irritation about the file size. + """ + self._check("aw") + + tarinfo = copy.copy(tarinfo) + + buf = tarinfo.tobuf(self.format, self.encoding, self.errors) + self.fileobj.write(buf) + self.offset += len(buf) + + # If there's data to follow, append it. + if fileobj is not None: + copyfileobj(fileobj, self.fileobj, tarinfo.size) + blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) + if remainder > 0: + self.fileobj.write(NUL * (BLOCKSIZE - remainder)) + blocks += 1 + self.offset += blocks * BLOCKSIZE + + self.members.append(tarinfo) + + def extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 0700 + self.extract(tarinfo, path) + + # Reverse sort directories. + directories.sort(key=operator.attrgetter('name')) + directories.reverse() + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError, e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extract(self, member, path=""): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a TarInfo object. You can + specify a different directory using `path'. + """ + self._check("r") + + if isinstance(member, basestring): + tarinfo = self.getmember(member) + else: + tarinfo = member + + # Prepare the link target for makelink(). + if tarinfo.islnk(): + tarinfo._link_target = os.path.join(path, tarinfo.linkname) + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name)) + except EnvironmentError, e: + if self.errorlevel > 0: + raise + else: + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) + else: + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + except ExtractError, e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extractfile(self, member): + """Extract a member from the archive as a file object. `member' may be + a filename or a TarInfo object. If `member' is a regular file, a + file-like object is returned. If `member' is a link, a file-like + object is constructed from the link's target. If `member' is none of + the above, None is returned. + The file-like object is read-only and provides the following + methods: read(), readline(), readlines(), seek() and tell() + """ + self._check("r") + + if isinstance(member, basestring): + tarinfo = self.getmember(member) + else: + tarinfo = member + + if tarinfo.isreg(): + return self.fileobject(self, tarinfo) + + elif tarinfo.type not in SUPPORTED_TYPES: + # If a member's type is unknown, it is treated as a + # regular file. + return self.fileobject(self, tarinfo) + + elif tarinfo.islnk() or tarinfo.issym(): + if isinstance(self.fileobj, _Stream): + # A small but ugly workaround for the case that someone tries + # to extract a (sym)link as a file-object from a non-seekable + # stream of tar blocks. + raise StreamError("cannot extract (sym)link as file object") + else: + # A (sym)link's file object is its target's file object. + return self.extractfile(self._find_link_target(tarinfo)) + else: + # If there's no data associated with the member (directory, chrdev, + # blkdev, etc.), return None instead of a file object. + return None + + def _extract_member(self, tarinfo, targetpath): + """Extract the TarInfo object tarinfo to a physical + file called targetpath. + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing + # forward slashes to platform specific separators. + targetpath = targetpath.rstrip("/") + targetpath = targetpath.replace("/", os.sep) + + # Create all upper directories. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + # Create directories that are not part of the archive with + # default permissions. + os.makedirs(upperdirs) + + if tarinfo.islnk() or tarinfo.issym(): + self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) + else: + self._dbg(1, tarinfo.name) + + if tarinfo.isreg(): + self.makefile(tarinfo, targetpath) + elif tarinfo.isdir(): + self.makedir(tarinfo, targetpath) + elif tarinfo.isfifo(): + self.makefifo(tarinfo, targetpath) + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): + self.makelink(tarinfo, targetpath) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: + self.makefile(tarinfo, targetpath) + + self.chown(tarinfo, targetpath) + if not tarinfo.issym(): + self.chmod(tarinfo, targetpath) + self.utime(tarinfo, targetpath) + + #-------------------------------------------------------------------------- + # Below are the different file methods. They are called via + # _extract_member() when extract() is called. They can be replaced in a + # subclass to implement other functionality. + + def makedir(self, tarinfo, targetpath): + """Make a directory called targetpath. + """ + try: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0700) + except EnvironmentError, e: + if e.errno != errno.EEXIST: + raise + + def makefile(self, tarinfo, targetpath): + """Make a file called targetpath. + """ + source = self.extractfile(tarinfo) + target = bltn_open(targetpath, "wb") + copyfileobj(source, target) + source.close() + target.close() + + def makeunknown(self, tarinfo, targetpath): + """Make a file from a TarInfo object with an unknown type + at targetpath. + """ + self.makefile(tarinfo, targetpath) + self._dbg(1, "tarfile: Unknown file type %r, " \ + "extracted as regular file." % tarinfo.type) + + def makefifo(self, tarinfo, targetpath): + """Make a fifo called targetpath. + """ + if hasattr(os, "mkfifo"): + os.mkfifo(targetpath) + else: + raise ExtractError("fifo not supported by system") + + def makedev(self, tarinfo, targetpath): + """Make a character or block device called targetpath. + """ + if not hasattr(os, "mknod") or not hasattr(os, "makedev"): + raise ExtractError("special devices not supported by system") + + mode = tarinfo.mode + if tarinfo.isblk(): + mode |= stat.S_IFBLK + else: + mode |= stat.S_IFCHR + + os.mknod(targetpath, mode, + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. + """ + if hasattr(os, "symlink") and hasattr(os, "link"): + # For systems that support symbolic and hard links. + if tarinfo.issym(): + os.symlink(tarinfo.linkname, targetpath) + else: + # See extract(). + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), targetpath) + else: + try: + self._extract_member(self._find_link_target(tarinfo), targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") + + def chown(self, tarinfo, targetpath): + """Set owner of targetpath according to tarinfo. + """ + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + try: + g = grp.getgrgid(tarinfo.gid)[2] + except KeyError: + g = os.getgid() + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + try: + u = pwd.getpwuid(tarinfo.uid)[2] + except KeyError: + u = os.getuid() + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError, e: + raise ExtractError("could not change owner") + + def chmod(self, tarinfo, targetpath): + """Set file permissions of targetpath according to tarinfo. + """ + if hasattr(os, 'chmod'): + try: + os.chmod(targetpath, tarinfo.mode) + except EnvironmentError, e: + raise ExtractError("could not change mode") + + def utime(self, tarinfo, targetpath): + """Set modification time of targetpath according to tarinfo. + """ + if not hasattr(os, 'utime'): + return + try: + os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + except EnvironmentError, e: + raise ExtractError("could not change modification time") + + #-------------------------------------------------------------------------- + def next(self): + """Return the next member of the archive as a TarInfo object, when + TarFile is opened for reading. Return None if there is no more + available. + """ + self._check("ra") + if self.firstmember is not None: + m = self.firstmember + self.firstmember = None + return m + + # Read the next block. + self.fileobj.seek(self.offset) + tarinfo = None + while True: + try: + tarinfo = self.tarinfo.fromtarfile(self) + except EOFHeaderError, e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + except InvalidHeaderError, e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError, e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError, e: + raise ReadError(str(e)) + break + + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + + return tarinfo + + #-------------------------------------------------------------------------- + # Little helper methods: + + def _getmember(self, name, tarinfo=None, normalize=False): + """Find an archive member by name from bottom to top. + If tarinfo is given, it is used as the starting point. + """ + # Ensure that all members have been loaded. + members = self.getmembers() + + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] + + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member + + def _load(self): + """Read through the entire archive file and look for readable + members. + """ + while True: + tarinfo = self.next() + if tarinfo is None: + break + self._loaded = True + + def _check(self, mode=None): + """Check if TarFile is still open, and if the operation's mode + corresponds to TarFile's mode. + """ + if self.closed: + raise IOError("%s is closed" % self.__class__.__name__) + if mode is not None and self.mode not in mode: + raise IOError("bad operation for mode %r" % self.mode) + + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + + def __iter__(self): + """Provide an iterator object. + """ + if self._loaded: + return iter(self.members) + else: + return TarIter(self) + + def _dbg(self, level, msg): + """Write debugging output to sys.stderr. + """ + if level <= self.debug: + print >> sys.stderr, msg + + def __enter__(self): + self._check() + return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + # An exception occurred. We must not call close() because + # it would try to write end-of-archive blocks and padding. + if not self._extfileobj: + self.fileobj.close() + self.closed = True +# class TarFile + +class TarIter: + """Iterator Class. + + for tarinfo in TarFile(...): + suite... + """ + + def __init__(self, tarfile): + """Construct a TarIter object. + """ + self.tarfile = tarfile + self.index = 0 + def __iter__(self): + """Return iterator object. + """ + return self + def next(self): + """Return the next item using TarFile's next() method. + When all members have been read, set TarFile as _loaded. + """ + # Fix for SF #1100429: Under rare circumstances it can + # happen that getmembers() is called during iteration, + # which will cause TarIter to stop prematurely. + if not self.tarfile._loaded: + tarinfo = self.tarfile.next() + if not tarinfo: + self.tarfile._loaded = True + raise StopIteration + else: + try: + tarinfo = self.tarfile.members[self.index] + except IndexError: + raise StopIteration + self.index += 1 + return tarinfo + +# Helper classes for sparse file support +class _section: + """Base class for _data and _hole. + """ + def __init__(self, offset, size): + self.offset = offset + self.size = size + def __contains__(self, offset): + return self.offset <= offset < self.offset + self.size + +class _data(_section): + """Represent a data section in a sparse file. + """ + def __init__(self, offset, size, realpos): + _section.__init__(self, offset, size) + self.realpos = realpos + +class _hole(_section): + """Represent a hole section in a sparse file. + """ + pass + +class _ringbuffer(list): + """Ringbuffer class which increases performance + over a regular list. + """ + def __init__(self): + self.idx = 0 + def find(self, offset): + idx = self.idx + while True: + item = self[idx] + if offset in item: + break + idx += 1 + if idx == len(self): + idx = 0 + if idx == self.idx: + # End of File + return None + self.idx = idx + return item + +#--------------------------------------------- +# zipfile compatible TarFile class +#--------------------------------------------- +TAR_PLAIN = 0 # zipfile.ZIP_STORED +TAR_GZIPPED = 8 # zipfile.ZIP_DEFLATED +class TarFileCompat: + """TarFile class compatible with standard module zipfile's + ZipFile class. + """ + def __init__(self, file, mode="r", compression=TAR_PLAIN): + from warnings import warnpy3k + warnpy3k("the TarFileCompat class has been removed in Python 3.0", + stacklevel=2) + if compression == TAR_PLAIN: + self.tarfile = TarFile.taropen(file, mode) + elif compression == TAR_GZIPPED: + self.tarfile = TarFile.gzopen(file, mode) + else: + raise ValueError("unknown compression constant") + if mode[0:1] == "r": + members = self.tarfile.getmembers() + for m in members: + m.filename = m.name + m.file_size = m.size + m.date_time = time.gmtime(m.mtime)[:6] + def namelist(self): + return map(lambda m: m.name, self.infolist()) + def infolist(self): + return filter(lambda m: m.type in REGULAR_TYPES, + self.tarfile.getmembers()) + def printdir(self): + self.tarfile.list() + def testzip(self): + return + def getinfo(self, name): + return self.tarfile.getmember(name) + def read(self, name): + return self.tarfile.extractfile(self.tarfile.getmember(name)).read() + def write(self, filename, arcname=None, compress_type=None): + self.tarfile.add(filename, arcname) + def writestr(self, zinfo, bytes): + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + import calendar + tinfo = TarInfo(zinfo.filename) + tinfo.size = len(bytes) + tinfo.mtime = calendar.timegm(zinfo.date_time) + self.tarfile.addfile(tinfo, StringIO(bytes)) + def close(self): + self.tarfile.close() +#class TarFileCompat + +#-------------------- +# exported functions +#-------------------- +def is_tarfile(name): + """Return True if name points to a tar archive that we + are able to handle, else return False. + """ + try: + t = open(name) + t.close() + return True + except TarError: + return False + +bltn_open = open +open = TarFile.open diff --git a/src/main/resources/PythonLibs/telnetlib.py b/src/main/resources/PythonLibs/telnetlib.py new file mode 100644 index 0000000000000000000000000000000000000000..e037f09894c85fc6568899143e380122b1249af1 --- /dev/null +++ b/src/main/resources/PythonLibs/telnetlib.py @@ -0,0 +1,664 @@ +r"""TELNET client class. + +Based on RFC 854: TELNET Protocol Specification, by J. Postel and +J. Reynolds + +Example: + +>>> from telnetlib import Telnet +>>> tn = Telnet('www.python.org', 79) # connect to finger port +>>> tn.write('guido\r\n') +>>> print tn.read_all() +Login Name TTY Idle When Where +guido Guido van Rossum pts/2 <Dec 2 11:10> snag.cnri.reston.. + +>>> + +Note that read_all() won't read until eof -- it just reads some data +-- but it guarantees to read at least one byte unless EOF is hit. + +It is possible to pass a Telnet object to select.select() in order to +wait until more data is available. Note that in this case, +read_eager() may return '' even if there was data on the socket, +because the protocol negotiation may have eaten the data. This is why +EOFError is needed in some cases to distinguish between "no data" and +"connection closed" (since the socket also appears ready for reading +when it is closed). + +To do: +- option negotiation +- timeout should be intrinsic to the connection object instead of an + option on one of the read calls only + +""" + + +# Imported modules +import sys +import socket +import select +import os +if os.name == 'java': + from select import cpython_compatible_select as select +else: + from select import select +del os + + +__all__ = ["Telnet"] + +# Tunable parameters +DEBUGLEVEL = 0 + +# Telnet protocol defaults +TELNET_PORT = 23 + +# Telnet protocol characters (don't change) +IAC = chr(255) # "Interpret As Command" +DONT = chr(254) +DO = chr(253) +WONT = chr(252) +WILL = chr(251) +theNULL = chr(0) + +SE = chr(240) # Subnegotiation End +NOP = chr(241) # No Operation +DM = chr(242) # Data Mark +BRK = chr(243) # Break +IP = chr(244) # Interrupt process +AO = chr(245) # Abort output +AYT = chr(246) # Are You There +EC = chr(247) # Erase Character +EL = chr(248) # Erase Line +GA = chr(249) # Go Ahead +SB = chr(250) # Subnegotiation Begin + + +# Telnet protocol options code (don't change) +# These ones all come from arpa/telnet.h +BINARY = chr(0) # 8-bit data path +ECHO = chr(1) # echo +RCP = chr(2) # prepare to reconnect +SGA = chr(3) # suppress go ahead +NAMS = chr(4) # approximate message size +STATUS = chr(5) # give status +TM = chr(6) # timing mark +RCTE = chr(7) # remote controlled transmission and echo +NAOL = chr(8) # negotiate about output line width +NAOP = chr(9) # negotiate about output page size +NAOCRD = chr(10) # negotiate about CR disposition +NAOHTS = chr(11) # negotiate about horizontal tabstops +NAOHTD = chr(12) # negotiate about horizontal tab disposition +NAOFFD = chr(13) # negotiate about formfeed disposition +NAOVTS = chr(14) # negotiate about vertical tab stops +NAOVTD = chr(15) # negotiate about vertical tab disposition +NAOLFD = chr(16) # negotiate about output LF disposition +XASCII = chr(17) # extended ascii character set +LOGOUT = chr(18) # force logout +BM = chr(19) # byte macro +DET = chr(20) # data entry terminal +SUPDUP = chr(21) # supdup protocol +SUPDUPOUTPUT = chr(22) # supdup output +SNDLOC = chr(23) # send location +TTYPE = chr(24) # terminal type +EOR = chr(25) # end or record +TUID = chr(26) # TACACS user identification +OUTMRK = chr(27) # output marking +TTYLOC = chr(28) # terminal location number +VT3270REGIME = chr(29) # 3270 regime +X3PAD = chr(30) # X.3 PAD +NAWS = chr(31) # window size +TSPEED = chr(32) # terminal speed +LFLOW = chr(33) # remote flow control +LINEMODE = chr(34) # Linemode option +XDISPLOC = chr(35) # X Display Location +OLD_ENVIRON = chr(36) # Old - Environment variables +AUTHENTICATION = chr(37) # Authenticate +ENCRYPT = chr(38) # Encryption option +NEW_ENVIRON = chr(39) # New - Environment variables +# the following ones come from +# http://www.iana.org/assignments/telnet-options +# Unfortunately, that document does not assign identifiers +# to all of them, so we are making them up +TN3270E = chr(40) # TN3270E +XAUTH = chr(41) # XAUTH +CHARSET = chr(42) # CHARSET +RSP = chr(43) # Telnet Remote Serial Port +COM_PORT_OPTION = chr(44) # Com Port Control Option +SUPPRESS_LOCAL_ECHO = chr(45) # Telnet Suppress Local Echo +TLS = chr(46) # Telnet Start TLS +KERMIT = chr(47) # KERMIT +SEND_URL = chr(48) # SEND-URL +FORWARD_X = chr(49) # FORWARD_X +PRAGMA_LOGON = chr(138) # TELOPT PRAGMA LOGON +SSPI_LOGON = chr(139) # TELOPT SSPI LOGON +PRAGMA_HEARTBEAT = chr(140) # TELOPT PRAGMA HEARTBEAT +EXOPL = chr(255) # Extended-Options-List +NOOPT = chr(0) + +class Telnet: + + """Telnet interface class. + + An instance of this class represents a connection to a telnet + server. The instance is initially not connected; the open() + method must be used to establish a connection. Alternatively, the + host name and optional port number can be passed to the + constructor, too. + + Don't try to reopen an already connected instance. + + This class has many read_*() methods. Note that some of them + raise EOFError when the end of the connection is read, because + they can return an empty string for other reasons. See the + individual doc strings. + + read_until(expected, [timeout]) + Read until the expected string has been seen, or a timeout is + hit (default is no timeout); may block. + + read_all() + Read all data until EOF; may block. + + read_some() + Read at least one byte or EOF; may block. + + read_very_eager() + Read all data available already queued or on the socket, + without blocking. + + read_eager() + Read either data already queued or some data available on the + socket, without blocking. + + read_lazy() + Read all data in the raw queue (processing it first), without + doing any socket I/O. + + read_very_lazy() + Reads all data in the cooked queue, without doing any socket + I/O. + + read_sb_data() + Reads available data between SB ... SE sequence. Don't block. + + set_option_negotiation_callback(callback) + Each time a telnet option is read on the input flow, this callback + (if set) is called with the following parameters : + callback(telnet socket, command, option) + option will be chr(0) when there is no option. + No other action is done afterwards by telnetlib. + + """ + + def __init__(self, host=None, port=0, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + """Constructor. + + When called without arguments, create an unconnected instance. + With a hostname argument, it connects the instance; port number + and timeout are optional. + """ + self.debuglevel = DEBUGLEVEL + self.host = host + self.port = port + self.timeout = timeout + self.sock = None + self.rawq = '' + self.irawq = 0 + self.cookedq = '' + self.eof = 0 + self.iacseq = '' # Buffer for IAC sequence. + self.sb = 0 # flag for SB and SE sequence. + self.sbdataq = '' + self.option_callback = None + if host is not None: + self.open(host, port, timeout) + + def open(self, host, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + """Connect to a host. + + The optional second argument is the port number, which + defaults to the standard telnet port (23). + + Don't try to reopen an already connected instance. + """ + self.eof = 0 + if not port: + port = TELNET_PORT + self.host = host + self.port = port + self.timeout = timeout + self.sock = socket.create_connection((host, port), timeout) + + def __del__(self): + """Destructor -- close the connection.""" + self.close() + + def msg(self, msg, *args): + """Print a debug message, when the debug level is > 0. + + If extra arguments are present, they are substituted in the + message using the standard string formatting operator. + + """ + if self.debuglevel > 0: + print 'Telnet(%s,%s):' % (self.host, self.port), + if args: + print msg % args + else: + print msg + + def set_debuglevel(self, debuglevel): + """Set the debug level. + + The higher it is, the more debug output you get (on sys.stdout). + + """ + self.debuglevel = debuglevel + + def close(self): + """Close the connection.""" + if self.sock: + self.sock.close() + self.sock = 0 + self.eof = 1 + self.iacseq = '' + self.sb = 0 + + def get_socket(self): + """Return the socket object used internally.""" + return self.sock + + def fileno(self): + """Return the fileno() of the socket object used internally.""" + return self.sock.fileno() + + def write(self, buffer): + """Write a string to the socket, doubling any IAC characters. + + Can block if the connection is blocked. May raise + socket.error if the connection is closed. + + """ + if IAC in buffer: + buffer = buffer.replace(IAC, IAC+IAC) + self.msg("send %r", buffer) + self.sock.sendall(buffer) + + def read_until(self, match, timeout=None): + """Read until a given string is encountered or until timeout. + + When no match is found, return whatever is available instead, + possibly the empty string. Raise EOFError if the connection + is closed and no cooked data is available. + + """ + n = len(match) + self.process_rawq() + i = self.cookedq.find(match) + if i >= 0: + i = i+n + buf = self.cookedq[:i] + self.cookedq = self.cookedq[i:] + return buf + s_reply = ([self], [], []) + s_args = s_reply + if timeout is not None: + s_args = s_args + (timeout,) + from time import time + time_start = time() + while not self.eof and select(*s_args) == s_reply: + i = max(0, len(self.cookedq)-n) + self.fill_rawq() + self.process_rawq() + i = self.cookedq.find(match, i) + if i >= 0: + i = i+n + buf = self.cookedq[:i] + self.cookedq = self.cookedq[i:] + return buf + if timeout is not None: + elapsed = time() - time_start + if elapsed >= timeout: + break + s_args = s_reply + (timeout-elapsed,) + return self.read_very_lazy() + + def read_all(self): + """Read all data until EOF; block until connection closed.""" + self.process_rawq() + while not self.eof: + self.fill_rawq() + self.process_rawq() + buf = self.cookedq + self.cookedq = '' + return buf + + def read_some(self): + """Read at least one byte of cooked data unless EOF is hit. + + Return '' if EOF is hit. Block if no data is immediately + available. + + """ + self.process_rawq() + while not self.cookedq and not self.eof: + self.fill_rawq() + self.process_rawq() + buf = self.cookedq + self.cookedq = '' + return buf + + def read_very_eager(self): + """Read everything that's possible without blocking in I/O (eager). + + Raise EOFError if connection closed and no cooked data + available. Return '' if no cooked data available otherwise. + Don't block unless in the midst of an IAC sequence. + + """ + self.process_rawq() + while not self.eof and self.sock_avail(): + self.fill_rawq() + self.process_rawq() + return self.read_very_lazy() + + def read_eager(self): + """Read readily available data. + + Raise EOFError if connection closed and no cooked data + available. Return '' if no cooked data available otherwise. + Don't block unless in the midst of an IAC sequence. + + """ + self.process_rawq() + while not self.cookedq and not self.eof and self.sock_avail(): + self.fill_rawq() + self.process_rawq() + return self.read_very_lazy() + + def read_lazy(self): + """Process and return data that's already in the queues (lazy). + + Raise EOFError if connection closed and no data available. + Return '' if no cooked data available otherwise. Don't block + unless in the midst of an IAC sequence. + + """ + self.process_rawq() + return self.read_very_lazy() + + def read_very_lazy(self): + """Return any data available in the cooked queue (very lazy). + + Raise EOFError if connection closed and no data available. + Return '' if no cooked data available otherwise. Don't block. + + """ + buf = self.cookedq + self.cookedq = '' + if not buf and self.eof and not self.rawq: + raise EOFError, 'telnet connection closed' + return buf + + def read_sb_data(self): + """Return any data available in the SB ... SE queue. + + Return '' if no SB ... SE available. Should only be called + after seeing a SB or SE command. When a new SB command is + found, old unread SB data will be discarded. Don't block. + + """ + buf = self.sbdataq + self.sbdataq = '' + return buf + + def set_option_negotiation_callback(self, callback): + """Provide a callback function called after each receipt of a telnet option.""" + self.option_callback = callback + + def process_rawq(self): + """Transfer from raw queue to cooked queue. + + Set self.eof when connection is closed. Don't block unless in + the midst of an IAC sequence. + + """ + buf = ['', ''] + try: + while self.rawq: + c = self.rawq_getchar() + if not self.iacseq: + if c == theNULL: + continue + if c == "\021": + continue + if c != IAC: + buf[self.sb] = buf[self.sb] + c + continue + else: + self.iacseq += c + elif len(self.iacseq) == 1: + # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]' + if c in (DO, DONT, WILL, WONT): + self.iacseq += c + continue + + self.iacseq = '' + if c == IAC: + buf[self.sb] = buf[self.sb] + c + else: + if c == SB: # SB ... SE start. + self.sb = 1 + self.sbdataq = '' + elif c == SE: + self.sb = 0 + self.sbdataq = self.sbdataq + buf[1] + buf[1] = '' + if self.option_callback: + # Callback is supposed to look into + # the sbdataq + self.option_callback(self.sock, c, NOOPT) + else: + # We can't offer automatic processing of + # suboptions. Alas, we should not get any + # unless we did a WILL/DO before. + self.msg('IAC %d not recognized' % ord(c)) + elif len(self.iacseq) == 2: + cmd = self.iacseq[1] + self.iacseq = '' + opt = c + if cmd in (DO, DONT): + self.msg('IAC %s %d', + cmd == DO and 'DO' or 'DONT', ord(opt)) + if self.option_callback: + self.option_callback(self.sock, cmd, opt) + else: + self.sock.sendall(IAC + WONT + opt) + elif cmd in (WILL, WONT): + self.msg('IAC %s %d', + cmd == WILL and 'WILL' or 'WONT', ord(opt)) + if self.option_callback: + self.option_callback(self.sock, cmd, opt) + else: + self.sock.sendall(IAC + DONT + opt) + except EOFError: # raised by self.rawq_getchar() + self.iacseq = '' # Reset on EOF + self.sb = 0 + pass + self.cookedq = self.cookedq + buf[0] + self.sbdataq = self.sbdataq + buf[1] + + def rawq_getchar(self): + """Get next char from raw queue. + + Block if no data is immediately available. Raise EOFError + when connection is closed. + + """ + if not self.rawq: + self.fill_rawq() + if self.eof: + raise EOFError + c = self.rawq[self.irawq] + self.irawq = self.irawq + 1 + if self.irawq >= len(self.rawq): + self.rawq = '' + self.irawq = 0 + return c + + def fill_rawq(self): + """Fill raw queue from exactly one recv() system call. + + Block if no data is immediately available. Set self.eof when + connection is closed. + + """ + if self.irawq >= len(self.rawq): + self.rawq = '' + self.irawq = 0 + # The buffer size should be fairly small so as to avoid quadratic + # behavior in process_rawq() above + buf = self.sock.recv(50) + self.msg("recv %r", buf) + self.eof = (not buf) + self.rawq = self.rawq + buf + + def sock_avail(self): + """Test whether data is available on the socket.""" + return select([self], [], [], 0) == ([self], [], []) + + def interact(self): + """Interaction function, emulates a very dumb telnet client.""" + if sys.platform == "win32": + self.mt_interact() + return + while 1: + rfd, wfd, xfd = select([self, sys.stdin], [], []) + if self in rfd: + try: + text = self.read_eager() + except EOFError: + print '*** Connection closed by remote host ***' + break + if text: + sys.stdout.write(text) + sys.stdout.flush() + if sys.stdin in rfd: + line = sys.stdin.readline() + if not line: + break + self.write(line) + + def mt_interact(self): + """Multithreaded version of interact().""" + import thread + thread.start_new_thread(self.listener, ()) + while 1: + line = sys.stdin.readline() + if not line: + break + self.write(line) + + def listener(self): + """Helper for mt_interact() -- this executes in the other thread.""" + while 1: + try: + data = self.read_eager() + except EOFError: + print '*** Connection closed by remote host ***' + return + if data: + sys.stdout.write(data) + else: + sys.stdout.flush() + + def expect(self, list, timeout=None): + """Read until one from a list of a regular expressions matches. + + The first argument is a list of regular expressions, either + compiled (re.RegexObject instances) or uncompiled (strings). + The optional second argument is a timeout, in seconds; default + is no timeout. + + Return a tuple of three items: the index in the list of the + first regular expression that matches; the match object + returned; and the text read up till and including the match. + + If EOF is read and no text was read, raise EOFError. + Otherwise, when nothing matches, return (-1, None, text) where + text is the text received so far (may be the empty string if a + timeout happened). + + If a regular expression ends with a greedy match (e.g. '.*') + or if more than one expression can match the same input, the + results are undeterministic, and may depend on the I/O timing. + + """ + re = None + list = list[:] + indices = range(len(list)) + for i in indices: + if not hasattr(list[i], "search"): + if not re: import re + list[i] = re.compile(list[i]) + if timeout is not None: + from time import time + time_start = time() + while 1: + self.process_rawq() + for i in indices: + m = list[i].search(self.cookedq) + if m: + e = m.end() + text = self.cookedq[:e] + self.cookedq = self.cookedq[e:] + return (i, m, text) + if self.eof: + break + if timeout is not None: + elapsed = time() - time_start + if elapsed >= timeout: + break + s_args = ([self.fileno()], [], [], timeout-elapsed) + r, w, x = select(*s_args) + if not r: + break + self.fill_rawq() + text = self.read_very_lazy() + if not text and self.eof: + raise EOFError + return (-1, None, text) + + +def test(): + """Test program for telnetlib. + + Usage: python telnetlib.py [-d] ... [host [port]] + + Default host is localhost; default port is 23. + + """ + debuglevel = 0 + while sys.argv[1:] and sys.argv[1] == '-d': + debuglevel = debuglevel+1 + del sys.argv[1] + host = 'localhost' + if sys.argv[1:]: + host = sys.argv[1] + port = 0 + if sys.argv[2:]: + portstr = sys.argv[2] + try: + port = int(portstr) + except ValueError: + port = socket.getservbyname(portstr, 'tcp') + tn = Telnet() + tn.set_debuglevel(debuglevel) + tn.open(host, port, timeout=0.5) + tn.interact() + tn.close() + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/tempfile.py b/src/main/resources/PythonLibs/tempfile.py new file mode 100644 index 0000000000000000000000000000000000000000..90e595e7868f938b9762b36bbe5c29883371d898 --- /dev/null +++ b/src/main/resources/PythonLibs/tempfile.py @@ -0,0 +1,618 @@ +"""Temporary files. + +This module provides generic, low- and high-level interfaces for +creating temporary files and directories. The interfaces listed +as "safe" just below can be used without fear of race conditions. +Those listed as "unsafe" cannot, and are provided for backward +compatibility only. + +This module also provides some data items to the user: + + TMP_MAX - maximum number of names that will be tried before + giving up. + template - the default prefix for all temporary names. + You may change this to control the default prefix. + tempdir - If this is set to a string before the first use of + any routine from this module, it will be considered as + another candidate location to store temporary files. +""" + +__all__ = [ + "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces + "SpooledTemporaryFile", + "mkstemp", "mkdtemp", # low level safe interfaces + "mktemp", # deprecated unsafe interface + "TMP_MAX", "gettempprefix", # constants + "tempdir", "gettempdir" + ] + + +# Imports. + +import os as _os +import errno as _errno +from random import Random as _Random + +try: + from cStringIO import StringIO as _StringIO +except ImportError: + from StringIO import StringIO as _StringIO + +try: + import fcntl as _fcntl +except ImportError: + def _set_cloexec(fd): + pass +else: + def _set_cloexec(fd): + try: + flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0) + except IOError: + pass + else: + # flags read successfully, modify + flags |= _fcntl.FD_CLOEXEC + _fcntl.fcntl(fd, _fcntl.F_SETFD, flags) + + +try: + import thread as _thread +except ImportError: + import dummy_thread as _thread +_allocate_lock = _thread.allocate_lock + +_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL +if hasattr(_os, 'O_NOINHERIT'): + _text_openflags |= _os.O_NOINHERIT +if hasattr(_os, 'O_NOFOLLOW'): + _text_openflags |= _os.O_NOFOLLOW + +_bin_openflags = _text_openflags +if hasattr(_os, 'O_BINARY'): + _bin_openflags |= _os.O_BINARY + +if hasattr(_os, 'TMP_MAX'): + TMP_MAX = _os.TMP_MAX +else: + TMP_MAX = 10000 + +template = "tmp" + +# Internal routines. + +_once_lock = _allocate_lock() + +if hasattr(_os, "lstat"): + _stat = _os.lstat +elif hasattr(_os, "stat"): + _stat = _os.stat +else: + # Fallback. All we need is something that raises os.error if the + # file doesn't exist. + def _stat(fn): + try: + f = open(fn) + except IOError: + raise _os.error + f.close() + +def _exists(fn): + try: + _stat(fn) + except _os.error: + return False + else: + return True + +class _RandomNameSequence: + """An instance of _RandomNameSequence generates an endless + sequence of unpredictable strings which can safely be incorporated + into file names. Each string is six characters long. Multiple + threads can safely use the same instance at the same time. + + _RandomNameSequence is an iterator.""" + + characters = ("abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "0123456789_") + + def __init__(self): + self.mutex = _allocate_lock() + self.normcase = _os.path.normcase + + @property + def rng(self): + if _os.sys.platform.startswith("java"): + #A JVM run cannot determine or change its pid so dummy this. + cur_pid = 1 + else: + cur_pid = _os.getpid() + + if cur_pid != getattr(self, '_rng_pid', None): + self._rng = _Random() + self._rng_pid = cur_pid + return self._rng + + def __iter__(self): + return self + + def next(self): + m = self.mutex + c = self.characters + choose = self.rng.choice + + m.acquire() + try: + letters = [choose(c) for dummy in "123456"] + finally: + m.release() + + return self.normcase(''.join(letters)) + +def _candidate_tempdir_list(): + """Generate a list of candidate temporary directories which + _get_default_tempdir will try.""" + + dirlist = [] + + # First, try the environment. + for envname in 'TMPDIR', 'TEMP', 'TMP': + dirname = _os.getenv(envname) + if dirname: dirlist.append(dirname) + + # Failing that, try OS-specific locations. + if _os.name == 'riscos': + dirname = _os.getenv('Wimp$ScrapDir') + if dirname: dirlist.append(dirname) + elif _os.name == 'nt': + dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) + else: + dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) + + # As a last resort, the current directory. + try: + dirlist.append(_os.getcwd()) + except (AttributeError, _os.error): + dirlist.append(_os.curdir) + + return dirlist + +def _get_default_tempdir(): + """Calculate the default directory to use for temporary files. + This routine should be called exactly once. + + We determine whether or not a candidate temp dir is usable by + trying to create and write to a file in that directory. If this + is successful, the test file is deleted. To prevent denial of + service, the name of the test file must be randomized.""" + + namer = _RandomNameSequence() + dirlist = _candidate_tempdir_list() + flags = _text_openflags + + for dir in dirlist: + if dir != _os.curdir: + dir = _os.path.normcase(_os.path.abspath(dir)) + # Try only a few names per directory. + for seq in xrange(100): + name = namer.next() + filename = _os.path.join(dir, name) + try: + fd = _os.open(filename, flags, 0600) + fp = _os.fdopen(fd, 'w') + fp.write('blat') + fp.close() + _os.unlink(filename) + del fp, fd + return dir + except (OSError, IOError), e: + if e[0] != _errno.EEXIST: + break # no point trying more names in this directory + pass + raise IOError, (_errno.ENOENT, + ("No usable temporary directory found in %s" % dirlist)) + +_name_sequence = None + +def _get_candidate_names(): + """Common setup sequence for all user-callable interfaces.""" + + global _name_sequence + if _name_sequence is None: + _once_lock.acquire() + try: + if _name_sequence is None: + _name_sequence = _RandomNameSequence() + finally: + _once_lock.release() + return _name_sequence + + +def _mkstemp_inner(dir, pre, suf, flags): + """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" + + names = _get_candidate_names() + + for seq in xrange(TMP_MAX): + name = names.next() + file = _os.path.join(dir, pre + name + suf) + try: + fd = _os.open(file, flags, 0600) + _set_cloexec(fd) + return (fd, _os.path.abspath(file)) + except OSError, e: + if e.errno == _errno.EEXIST: + continue # try again + raise + + raise IOError, (_errno.EEXIST, "No usable temporary file name found") + + +# User visible interfaces. + +def gettempprefix(): + """Accessor for tempdir.template.""" + return template + +tempdir = None + +def gettempdir(): + """Accessor for tempfile.tempdir.""" + global tempdir + if tempdir is None: + _once_lock.acquire() + try: + if tempdir is None: + tempdir = _get_default_tempdir() + finally: + _once_lock.release() + return tempdir + +def mkstemp(suffix="", prefix=template, dir=None, text=False): + """User-callable function to create and return a unique temporary + file. The return value is a pair (fd, name) where fd is the + file descriptor returned by os.open, and name is the filename. + + If 'suffix' is specified, the file name will end with that suffix, + otherwise there will be no suffix. + + If 'prefix' is specified, the file name will begin with that prefix, + otherwise a default prefix is used. + + If 'dir' is specified, the file will be created in that directory, + otherwise a default directory is used. + + If 'text' is specified and true, the file is opened in text + mode. Else (the default) the file is opened in binary mode. On + some operating systems, this makes no difference. + + The file is readable and writable only by the creating user ID. + If the operating system uses permission bits to indicate whether a + file is executable, the file is executable by no one. The file + descriptor is not inherited by children of this process. + + Caller is responsible for deleting the file when done with it. + """ + + if dir is None: + dir = gettempdir() + + if text: + flags = _text_openflags + else: + flags = _bin_openflags + + return _mkstemp_inner(dir, prefix, suffix, flags) + + +def mkdtemp(suffix="", prefix=template, dir=None): + """User-callable function to create and return a unique temporary + directory. The return value is the pathname of the directory. + + Arguments are as for mkstemp, except that the 'text' argument is + not accepted. + + The directory is readable, writable, and searchable only by the + creating user. + + Caller is responsible for deleting the directory when done with it. + """ + + if dir is None: + dir = gettempdir() + + names = _get_candidate_names() + + for seq in xrange(TMP_MAX): + name = names.next() + file = _os.path.join(dir, prefix + name + suffix) + try: + _os.mkdir(file, 0700) + return file + except OSError, e: + if e.errno == _errno.EEXIST: + continue # try again + raise + + raise IOError, (_errno.EEXIST, "No usable temporary directory name found") + +def mktemp(suffix="", prefix=template, dir=None): + """User-callable function to return a unique temporary file name. The + file is not created. + + Arguments are as for mkstemp, except that the 'text' argument is + not accepted. + + This function is unsafe and should not be used. The file name + refers to a file that did not exist at some point, but by the time + you get around to creating it, someone else may have beaten you to + the punch. + """ + +## from warnings import warn as _warn +## _warn("mktemp is a potential security risk to your program", +## RuntimeWarning, stacklevel=2) + + if dir is None: + dir = gettempdir() + + names = _get_candidate_names() + for seq in xrange(TMP_MAX): + name = names.next() + file = _os.path.join(dir, prefix + name + suffix) + if not _exists(file): + return file + + raise IOError, (_errno.EEXIST, "No usable temporary filename found") + + +class _TemporaryFileWrapper: + """Temporary file wrapper + + This class provides a wrapper around files opened for + temporary use. In particular, it seeks to automatically + remove the file when it is no longer needed. + """ + + def __init__(self, file, name, delete=True): + self.file = file + self.name = name + self.close_called = False + self.delete = delete + + def __getattr__(self, name): + # Attribute lookups are delegated to the underlying file + # and cached for non-numeric results + # (i.e. methods are cached, closed and friends are not) + file = self.__dict__['file'] + a = getattr(file, name) + if not issubclass(type(a), type(0)): + setattr(self, name, a) + return a + + # The underlying __enter__ method returns the wrong object + # (self.file) so override it to return the wrapper + def __enter__(self): + self.file.__enter__() + return self + + # NT provides delete-on-close as a primitive, so we don't need + # the wrapper to do anything special. We still use it so that + # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. + if _os.name != 'nt': + # Cache the unlinker so we don't get spurious errors at + # shutdown when the module-level "os" is None'd out. Note + # that this must be referenced as self.unlink, because the + # name TemporaryFileWrapper may also get None'd out before + # __del__ is called. + unlink = _os.unlink + + def close(self): + if not self.close_called: + self.close_called = True + self.file.close() + if self.delete: + self.unlink(self.name) + + def __del__(self): + self.close() + + # Need to trap __exit__ as well to ensure the file gets + # deleted when used in a with statement + def __exit__(self, exc, value, tb): + result = self.file.__exit__(exc, value, tb) + self.close() + return result + else: + def __exit__(self, exc, value, tb): + self.file.__exit__(exc, value, tb) + + +def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="", + prefix=template, dir=None, delete=True): + """Create and return a temporary file. + Arguments: + 'prefix', 'suffix', 'dir' -- as for mkstemp. + 'mode' -- the mode argument to os.fdopen (default "w+b"). + 'bufsize' -- the buffer size argument to os.fdopen (default -1). + 'delete' -- whether the file is deleted on close (default True). + The file is created as mkstemp() would do it. + + Returns an object with a file-like interface; the name of the file + is accessible as file.name. The file will be automatically deleted + when it is closed unless the 'delete' argument is set to False. + """ + + if dir is None: + dir = gettempdir() + + if 'b' in mode: + flags = _bin_openflags + else: + flags = _text_openflags + + # Setting O_TEMPORARY in the flags causes the OS to delete + # the file when it is closed. This is only supported by Windows. + if _os.name == 'nt' and delete: + flags |= _os.O_TEMPORARY + + (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) + file = _os.fdopen(fd, mode, bufsize) + return _TemporaryFileWrapper(file, name, delete) + +if _os.name != 'posix' or _os.sys.platform == 'cygwin': + # On non-POSIX and Cygwin systems, assume that we cannot unlink a file + # while it is open. + TemporaryFile = NamedTemporaryFile + +else: + def TemporaryFile(mode='w+b', bufsize=-1, suffix="", + prefix=template, dir=None): + """Create and return a temporary file. + Arguments: + 'prefix', 'suffix', 'dir' -- as for mkstemp. + 'mode' -- the mode argument to os.fdopen (default "w+b"). + 'bufsize' -- the buffer size argument to os.fdopen (default -1). + The file is created as mkstemp() would do it. + + Returns an object with a file-like interface. The file has no + name, and will cease to exist when it is closed. + """ + + if dir is None: + dir = gettempdir() + + if 'b' in mode: + flags = _bin_openflags + else: + flags = _text_openflags + + (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) + try: + _os.unlink(name) + return _os.fdopen(fd, mode, bufsize) + except: + _os.close(fd) + raise + +class SpooledTemporaryFile: + """Temporary file wrapper, specialized to switch from + StringIO to a real file when it exceeds a certain size or + when a fileno is needed. + """ + _rolled = False + + def __init__(self, max_size=0, mode='w+b', bufsize=-1, + suffix="", prefix=template, dir=None): + self._file = _StringIO() + self._max_size = max_size + self._rolled = False + self._TemporaryFileArgs = (mode, bufsize, suffix, prefix, dir) + + def _check(self, file): + if self._rolled: return + max_size = self._max_size + if max_size and file.tell() > max_size: + self.rollover() + + def rollover(self): + if self._rolled: return + file = self._file + newfile = self._file = TemporaryFile(*self._TemporaryFileArgs) + del self._TemporaryFileArgs + + newfile.write(file.getvalue()) + newfile.seek(file.tell(), 0) + + self._rolled = True + + # The method caching trick from NamedTemporaryFile + # won't work here, because _file may change from a + # _StringIO instance to a real file. So we list + # all the methods directly. + + # Context management protocol + def __enter__(self): + if self._file.closed: + raise ValueError("Cannot enter context with closed file") + return self + + def __exit__(self, exc, value, tb): + self._file.close() + + # file protocol + def __iter__(self): + return self._file.__iter__() + + def close(self): + self._file.close() + + @property + def closed(self): + return self._file.closed + + @property + def encoding(self): + return self._file.encoding + + def fileno(self): + self.rollover() + return self._file.fileno() + + def flush(self): + self._file.flush() + + def isatty(self): + return self._file.isatty() + + @property + def mode(self): + return self._file.mode + + @property + def name(self): + return self._file.name + + @property + def newlines(self): + return self._file.newlines + + def next(self): + return self._file.next + + def read(self, *args): + return self._file.read(*args) + + def readline(self, *args): + return self._file.readline(*args) + + def readlines(self, *args): + return self._file.readlines(*args) + + def seek(self, *args): + self._file.seek(*args) + + @property + def softspace(self): + return self._file.softspace + + def tell(self): + return self._file.tell() + + def truncate(self): + self._file.truncate() + + def write(self, s): + file = self._file + rv = file.write(s) + self._check(file) + return rv + + def writelines(self, iterable): + file = self._file + rv = file.writelines(iterable) + self._check(file) + return rv + + def xreadlines(self, *args): + return self._file.xreadlines(*args) diff --git a/src/main/resources/PythonLibs/textwrap.py b/src/main/resources/PythonLibs/textwrap.py new file mode 100644 index 0000000000000000000000000000000000000000..62ea0b48e6c18955c08a43805067c072387fee61 --- /dev/null +++ b/src/main/resources/PythonLibs/textwrap.py @@ -0,0 +1,425 @@ +"""Text wrapping and filling. +""" + +# Copyright (C) 1999-2001 Gregory P. Ward. +# Copyright (C) 2002, 2003 Python Software Foundation. +# Written by Greg Ward <gward@python.net> + +__revision__ = "$Id$" + +import string, re + +try: + _unicode = unicode +except NameError: + # If Python is built without Unicode support, the unicode type + # will not exist. Fake one. + class _unicode(object): + pass + +# Do the right thing with boolean values for all known Python versions +# (so this module can be copied to projects that don't depend on Python +# 2.3, e.g. Optik and Docutils) by uncommenting the block of code below. +#try: +# True, False +#except NameError: +# (True, False) = (1, 0) + +__all__ = ['TextWrapper', 'wrap', 'fill', 'dedent'] + +# Hardcode the recognized whitespace characters to the US-ASCII +# whitespace characters. The main reason for doing this is that in +# ISO-8859-1, 0xa0 is non-breaking whitespace, so in certain locales +# that character winds up in string.whitespace. Respecting +# string.whitespace in those cases would 1) make textwrap treat 0xa0 the +# same as any other whitespace char, which is clearly wrong (it's a +# *non-breaking* space), 2) possibly cause problems with Unicode, +# since 0xa0 is not in range(128). +_whitespace = '\t\n\x0b\x0c\r ' + +class TextWrapper: + """ + Object for wrapping/filling text. The public interface consists of + the wrap() and fill() methods; the other methods are just there for + subclasses to override in order to tweak the default behaviour. + If you want to completely replace the main wrapping algorithm, + you'll probably have to override _wrap_chunks(). + + Several instance attributes control various aspects of wrapping: + width (default: 70) + the maximum width of wrapped lines (unless break_long_words + is false) + initial_indent (default: "") + string that will be prepended to the first line of wrapped + output. Counts towards the line's width. + subsequent_indent (default: "") + string that will be prepended to all lines save the first + of wrapped output; also counts towards each line's width. + expand_tabs (default: true) + Expand tabs in input text to spaces before further processing. + Each tab will become 1 .. 8 spaces, depending on its position in + its line. If false, each tab is treated as a single character. + replace_whitespace (default: true) + Replace all whitespace characters in the input text by spaces + after tab expansion. Note that if expand_tabs is false and + replace_whitespace is true, every tab will be converted to a + single space! + fix_sentence_endings (default: false) + Ensure that sentence-ending punctuation is always followed + by two spaces. Off by default because the algorithm is + (unavoidably) imperfect. + break_long_words (default: true) + Break words longer than 'width'. If false, those words will not + be broken, and some lines might be longer than 'width'. + break_on_hyphens (default: true) + Allow breaking hyphenated words. If true, wrapping will occur + preferably on whitespaces and right after hyphens part of + compound words. + drop_whitespace (default: true) + Drop leading and trailing whitespace from lines. + """ + + whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace)) + + unicode_whitespace_trans = {} + uspace = ord(u' ') + for x in map(ord, _whitespace): + unicode_whitespace_trans[x] = uspace + + # This funky little regex is just the trick for splitting + # text up into word-wrappable chunks. E.g. + # "Hello there -- you goof-ball, use the -b option!" + # splits into + # Hello/ /there/ /--/ /you/ /goof-/ball,/ /use/ /the/ /-b/ /option! + # (after stripping out empty strings). + wordsep_re = re.compile( + r'(\s+|' # any whitespace + r'[^\s\w]*\w+[^0-9\W]-(?=\w+[^0-9\W])|' # hyphenated words + r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') # em-dash + + # This less funky little regex just split on recognized spaces. E.g. + # "Hello there -- you goof-ball, use the -b option!" + # splits into + # Hello/ /there/ /--/ /you/ /goof-ball,/ /use/ /the/ /-b/ /option!/ + wordsep_simple_re = re.compile(r'(\s+)') + + # XXX this is not locale- or charset-aware -- string.lowercase + # is US-ASCII only (and therefore English-only) + sentence_end_re = re.compile(r'[%s]' # lowercase letter + r'[\.\!\?]' # sentence-ending punct. + r'[\"\']?' # optional end-of-quote + r'\Z' # end of chunk + % string.lowercase) + + + def __init__(self, + width=70, + initial_indent="", + subsequent_indent="", + expand_tabs=True, + replace_whitespace=True, + fix_sentence_endings=False, + break_long_words=True, + drop_whitespace=True, + break_on_hyphens=True): + self.width = width + self.initial_indent = initial_indent + self.subsequent_indent = subsequent_indent + self.expand_tabs = expand_tabs + self.replace_whitespace = replace_whitespace + self.fix_sentence_endings = fix_sentence_endings + self.break_long_words = break_long_words + self.drop_whitespace = drop_whitespace + self.break_on_hyphens = break_on_hyphens + + # recompile the regexes for Unicode mode -- done in this clumsy way for + # backwards compatibility because it's rather common to monkey-patch + # the TextWrapper class' wordsep_re attribute. + self.wordsep_re_uni = re.compile(self.wordsep_re.pattern, re.U) + self.wordsep_simple_re_uni = re.compile( + self.wordsep_simple_re.pattern, re.U) + + + # -- Private methods ----------------------------------------------- + # (possibly useful for subclasses to override) + + def _munge_whitespace(self, text): + """_munge_whitespace(text : string) -> string + + Munge whitespace in text: expand tabs and convert all other + whitespace characters to spaces. Eg. " foo\tbar\n\nbaz" + becomes " foo bar baz". + """ + if self.expand_tabs: + text = text.expandtabs() + if self.replace_whitespace: + if isinstance(text, str): + text = text.translate(self.whitespace_trans) + elif isinstance(text, _unicode): + text = text.translate(self.unicode_whitespace_trans) + return text + + + def _split(self, text): + """_split(text : string) -> [string] + + Split the text to wrap into indivisible chunks. Chunks are + not quite the same as words; see _wrap_chunks() for full + details. As an example, the text + Look, goof-ball -- use the -b option! + breaks into the following chunks: + 'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ', + 'use', ' ', 'the', ' ', '-b', ' ', 'option!' + if break_on_hyphens is True, or in: + 'Look,', ' ', 'goof-ball', ' ', '--', ' ', + 'use', ' ', 'the', ' ', '-b', ' ', option!' + otherwise. + """ + if isinstance(text, _unicode): + if self.break_on_hyphens: + pat = self.wordsep_re_uni + else: + pat = self.wordsep_simple_re_uni + else: + if self.break_on_hyphens: + pat = self.wordsep_re + else: + pat = self.wordsep_simple_re + chunks = pat.split(text) + chunks = filter(None, chunks) # remove empty chunks + return chunks + + def _fix_sentence_endings(self, chunks): + """_fix_sentence_endings(chunks : [string]) + + Correct for sentence endings buried in 'chunks'. Eg. when the + original text contains "... foo.\nBar ...", munge_whitespace() + and split() will convert that to [..., "foo.", " ", "Bar", ...] + which has one too few spaces; this method simply changes the one + space to two. + """ + i = 0 + patsearch = self.sentence_end_re.search + while i < len(chunks)-1: + if chunks[i+1] == " " and patsearch(chunks[i]): + chunks[i+1] = " " + i += 2 + else: + i += 1 + + def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width): + """_handle_long_word(chunks : [string], + cur_line : [string], + cur_len : int, width : int) + + Handle a chunk of text (most likely a word, not whitespace) that + is too long to fit in any line. + """ + # Figure out when indent is larger than the specified width, and make + # sure at least one character is stripped off on every pass + if width < 1: + space_left = 1 + else: + space_left = width - cur_len + + # If we're allowed to break long words, then do so: put as much + # of the next chunk onto the current line as will fit. + if self.break_long_words: + cur_line.append(reversed_chunks[-1][:space_left]) + reversed_chunks[-1] = reversed_chunks[-1][space_left:] + + # Otherwise, we have to preserve the long word intact. Only add + # it to the current line if there's nothing already there -- + # that minimizes how much we violate the width constraint. + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + # If we're not allowed to break long words, and there's already + # text on the current line, do nothing. Next time through the + # main loop of _wrap_chunks(), we'll wind up here again, but + # cur_len will be zero, so the next line will be entirely + # devoted to the long word that we can't handle right now. + + def _wrap_chunks(self, chunks): + """_wrap_chunks(chunks : [string]) -> [string] + + Wrap a sequence of text chunks and return a list of lines of + length 'self.width' or less. (If 'break_long_words' is false, + some lines may be longer than this.) Chunks correspond roughly + to words and the whitespace between them: each chunk is + indivisible (modulo 'break_long_words'), but a line break can + come between any two chunks. Chunks should not have internal + whitespace; ie. a chunk is either all whitespace or a "word". + Whitespace chunks will be removed from the beginning and end of + lines, but apart from that whitespace is preserved. + """ + lines = [] + if self.width <= 0: + raise ValueError("invalid width %r (must be > 0)" % self.width) + + # Arrange in reverse order so items can be efficiently popped + # from a stack of chucks. + chunks.reverse() + + while chunks: + + # Start the list of chunks that will make up the current line. + # cur_len is just the length of all the chunks in cur_line. + cur_line = [] + cur_len = 0 + + # Figure out which static string will prefix this line. + if lines: + indent = self.subsequent_indent + else: + indent = self.initial_indent + + # Maximum width for this line. + width = self.width - len(indent) + + # First chunk on line is whitespace -- drop it, unless this + # is the very beginning of the text (ie. no lines started yet). + if self.drop_whitespace and chunks[-1].strip() == '' and lines: + del chunks[-1] + + while chunks: + l = len(chunks[-1]) + + # Can at least squeeze this chunk onto the current line. + if cur_len + l <= width: + cur_line.append(chunks.pop()) + cur_len += l + + # Nope, this line is full. + else: + break + + # The current line is full, and the next chunk is too big to + # fit on *any* line (not just this one). + if chunks and len(chunks[-1]) > width: + self._handle_long_word(chunks, cur_line, cur_len, width) + + # If the last chunk on this line is all whitespace, drop it. + if self.drop_whitespace and cur_line and cur_line[-1].strip() == '': + del cur_line[-1] + + # Convert current line back to a string and store it in list + # of all lines (return value). + if cur_line: + lines.append(indent + ''.join(cur_line)) + + return lines + + + # -- Public interface ---------------------------------------------- + + def wrap(self, text): + """wrap(text : string) -> [string] + + Reformat the single paragraph in 'text' so it fits in lines of + no more than 'self.width' columns, and return a list of wrapped + lines. Tabs in 'text' are expanded with string.expandtabs(), + and all other whitespace characters (including newline) are + converted to space. + """ + text = self._munge_whitespace(text) + chunks = self._split(text) + if self.fix_sentence_endings: + self._fix_sentence_endings(chunks) + return self._wrap_chunks(chunks) + + def fill(self, text): + """fill(text : string) -> string + + Reformat the single paragraph in 'text' to fit in lines of no + more than 'self.width' columns, and return a new string + containing the entire wrapped paragraph. + """ + return "\n".join(self.wrap(text)) + + +# -- Convenience interface --------------------------------------------- + +def wrap(text, width=70, **kwargs): + """Wrap a single paragraph of text, returning a list of wrapped lines. + + Reformat the single paragraph in 'text' so it fits in lines of no + more than 'width' columns, and return a list of wrapped lines. By + default, tabs in 'text' are expanded with string.expandtabs(), and + all other whitespace characters (including newline) are converted to + space. See TextWrapper class for available keyword args to customize + wrapping behaviour. + """ + w = TextWrapper(width=width, **kwargs) + return w.wrap(text) + +def fill(text, width=70, **kwargs): + """Fill a single paragraph of text, returning a new string. + + Reformat the single paragraph in 'text' to fit in lines of no more + than 'width' columns, and return a new string containing the entire + wrapped paragraph. As with wrap(), tabs are expanded and other + whitespace characters converted to space. See TextWrapper class for + available keyword args to customize wrapping behaviour. + """ + w = TextWrapper(width=width, **kwargs) + return w.fill(text) + + +# -- Loosely related functionality ------------------------------------- + +_whitespace_only_re = re.compile('^[ \t]+$', re.MULTILINE) +_leading_whitespace_re = re.compile('(^[ \t]*)(?:[^ \t\n])', re.MULTILINE) + +def dedent(text): + """Remove any common leading whitespace from every line in `text`. + + This can be used to make triple-quoted strings line up with the left + edge of the display, while still presenting them in the source code + in indented form. + + Note that tabs and spaces are both treated as whitespace, but they + are not equal: the lines " hello" and "\thello" are + considered to have no common leading whitespace. (This behaviour is + new in Python 2.5; older versions of this module incorrectly + expanded tabs before searching for common leading whitespace.) + """ + # Look for the longest leading string of spaces and tabs common to + # all lines. + margin = None + text = _whitespace_only_re.sub('', text) + indents = _leading_whitespace_re.findall(text) + for indent in indents: + if margin is None: + margin = indent + + # Current line more deeply indented than previous winner: + # no change (previous winner is still on top). + elif indent.startswith(margin): + pass + + # Current line consistent with and no deeper than previous winner: + # it's the new winner. + elif margin.startswith(indent): + margin = indent + + # Current line and previous winner have no common whitespace: + # there is no margin. + else: + margin = "" + break + + # sanity check (testing/debugging only) + if 0 and margin: + for line in text.split("\n"): + assert not line or line.startswith(margin), \ + "line = %r, margin = %r" % (line, margin) + + if margin: + text = re.sub(r'(?m)^' + margin, '', text) + return text + +if __name__ == "__main__": + #print dedent("\tfoo\n\tbar") + #print dedent(" \thello there\n \t how are you?") + print dedent("Hello there.\n This is indented.") diff --git a/src/main/resources/PythonLibs/this.py b/src/main/resources/PythonLibs/this.py new file mode 100644 index 0000000000000000000000000000000000000000..37754b785ab17820732e8ce0b0f0c543ef075b12 --- /dev/null +++ b/src/main/resources/PythonLibs/this.py @@ -0,0 +1,28 @@ +s = """Gur Mra bs Clguba, ol Gvz Crgref + +Ornhgvshy vf orggre guna htyl. +Rkcyvpvg vf orggre guna vzcyvpvg. +Fvzcyr vf orggre guna pbzcyrk. +Pbzcyrk vf orggre guna pbzcyvpngrq. +Syng vf orggre guna arfgrq. +Fcnefr vf orggre guna qrafr. +Ernqnovyvgl pbhagf. +Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf. +Nygubhtu cenpgvpnyvgl orngf chevgl. +Reebef fubhyq arire cnff fvyragyl. +Hayrff rkcyvpvgyl fvyraprq. +Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff. +Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg. +Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu. +Abj vf orggre guna arire. +Nygubhtu arire vf bsgra orggre guna *evtug* abj. +Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn. +Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn. +Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!""" + +d = {} +for c in (65, 97): + for i in range(26): + d[chr(i+c)] = chr((i+13) % 26 + c) + +print "".join([d.get(c, c) for c in s]) diff --git a/src/main/resources/PythonLibs/threading.py b/src/main/resources/PythonLibs/threading.py new file mode 100644 index 0000000000000000000000000000000000000000..6870b69fc9ad54b10dd30d537b2eeb0f834c6868 --- /dev/null +++ b/src/main/resources/PythonLibs/threading.py @@ -0,0 +1,428 @@ +from java.lang import InterruptedException +from java.util import Collections, WeakHashMap +from java.util.concurrent import Semaphore, CyclicBarrier +from java.util.concurrent.locks import ReentrantLock +from org.python.util import jython +from org.python.core import Py +from thread import _newFunctionThread +from thread import _local as local +from _threading import Lock, RLock, Condition, _Lock, _RLock, _threads, _active, _jthread_to_pythread, _register_thread, _unregister_thread +import java.lang.Thread +import sys as _sys +from traceback import print_exc as _print_exc + +# Rename some stuff so "from threading import *" is safe +__all__ = ['activeCount', 'active_count', 'Condition', 'currentThread', + 'current_thread', 'enumerate', 'Event', + 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', + 'Timer', 'setprofile', 'settrace', 'local', 'stack_size'] + +_VERBOSE = False + +if __debug__: + + class _Verbose(object): + + def __init__(self, verbose=None): + if verbose is None: + verbose = _VERBOSE + self.__verbose = verbose + + def _note(self, format, *args): + if self.__verbose: + format = format % args + format = "%s: %s\n" % ( + currentThread().getName(), format) + _sys.stderr.write(format) + +else: + # Disable this when using "python -O" + class _Verbose(object): + def __init__(self, verbose=None): + pass + def _note(self, *args): + pass + +# Support for profile and trace hooks + +_profile_hook = None +_trace_hook = None + +def setprofile(func): + global _profile_hook + _profile_hook = func + +def settrace(func): + global _trace_hook + _trace_hook = func + + +class Semaphore(object): + def __init__(self, value=1): + if value < 0: + raise ValueError("Semaphore initial value must be >= 0") + self._semaphore = java.util.concurrent.Semaphore(value) + + def acquire(self, blocking=True): + if blocking: + self._semaphore.acquire() + return True + else: + return self._semaphore.tryAcquire() + + def __enter__(self): + self.acquire() + return self + + def release(self): + self._semaphore.release() + + def __exit__(self, t, v, tb): + self.release() + + +ThreadStates = { + java.lang.Thread.State.NEW : 'initial', + java.lang.Thread.State.RUNNABLE: 'started', + java.lang.Thread.State.BLOCKED: 'started', + java.lang.Thread.State.WAITING: 'started', + java.lang.Thread.State.TIMED_WAITING: 'started', + java.lang.Thread.State.TERMINATED: 'stopped', +} + +class JavaThread(object): + def __init__(self, thread): + self._thread = thread + _register_thread(thread, self) + + def __repr__(self): + _thread = self._thread + status = ThreadStates[_thread.getState()] + if _thread.isDaemon(): status + " daemon" + return "<%s(%s, %s %s)>" % (self.__class__.__name__, self.getName(), status, self.ident) + + def __eq__(self, other): + if isinstance(other, JavaThread): + return self._thread == other._thread + else: + return False + + def __ne__(self, other): + return not self.__eq__(other) + + def start(self): + self._thread.start() + + def run(self): + self._thread.run() + + def join(self, timeout=None): + if timeout: + millis = timeout * 1000. + millis_int = int(millis) + nanos = int((millis - millis_int) * 1e6) + self._thread.join(millis_int, nanos) + else: + self._thread.join() + + def ident(self): + return self._thread.getId() + + ident = property(ident) + + def getName(self): + return self._thread.getName() + + def setName(self, name): + self._thread.setName(str(name)) + + name = property(getName, setName) + + def isAlive(self): + return self._thread.isAlive() + + is_alive = isAlive + + def isDaemon(self): + return self._thread.isDaemon() + + def setDaemon(self, daemonic): + self._thread.setDaemon(bool(daemonic)) + + def __tojava__(self, c): + if isinstance(self._thread, c): + return self._thread + if isinstance(self, c): + return self + return Py.NoConversion + + +class Thread(JavaThread): + def __init__(self, group=None, target=None, name=None, args=None, kwargs=None): + assert group is None, "group argument must be None for now" + _thread = self._create_thread() + JavaThread.__init__(self, _thread) + if args is None: + args = () + if kwargs is None: + kwargs = {} + self._target = target + self._args = args + self._kwargs = kwargs + if name: + self._thread.setName(str(name)) + + def _create_thread(self): + return _newFunctionThread(self.__bootstrap, ()) + + def run(self): + if self._target: + self._target(*self._args, **self._kwargs) + + def __bootstrap(self): + try: + if _trace_hook: + _sys.settrace(_trace_hook) + if _profile_hook: + _sys.setprofile(_profile_hook) + try: + self.run() + except SystemExit: + pass + except InterruptedException: + # Quiet InterruptedExceptions if they're caused by + # _systemrestart + if not jython.shouldRestart: + raise + except: + # If sys.stderr is no more (most likely from interpreter + # shutdown) use self.__stderr. Otherwise still use sys (as in + # _sys) in case sys.stderr was redefined. + if _sys: + _sys.stderr.write("Exception in thread %s:" % + self.getName()) + _print_exc(file=_sys.stderr) + else: + # Do the best job possible w/o a huge amt. of code to + # approx. a traceback stack trace + exc_type, exc_value, exc_tb = self.__exc_info() + try: + print>>self.__stderr, ( + "Exception in thread " + self.getName() + + " (most likely raised during interpreter shutdown):") + print>>self.__stderr, ( + "Traceback (most recent call last):") + while exc_tb: + print>>self.__stderr, ( + ' File "%s", line %s, in %s' % + (exc_tb.tb_frame.f_code.co_filename, + exc_tb.tb_lineno, + exc_tb.tb_frame.f_code.co_name)) + exc_tb = exc_tb.tb_next + print>>self.__stderr, ("%s: %s" % (exc_type, exc_value)) + # Make sure that exc_tb gets deleted since it is a memory + # hog; deleting everything else is just for thoroughness + finally: + del exc_type, exc_value, exc_tb + + finally: + self.__stop() + try: + self.__delete() + except: + pass + + def __stop(self): + pass + + def __delete(self): + _unregister_thread(self._thread) + + +class _MainThread(Thread): + def __init__(self): + Thread.__init__(self, name="MainThread") + import atexit + atexit.register(self.__exitfunc) + + def _create_thread(self): + return java.lang.Thread.currentThread() + + def _set_daemon(self): + return False + + def __exitfunc(self): + _unregister_thread(self._thread) + t = _pickSomeNonDaemonThread() + while t: + t.join() + t = _pickSomeNonDaemonThread() + +def _pickSomeNonDaemonThread(): + for t in enumerate(): + if not t.isDaemon() and t.isAlive(): + return t + return None + +def currentThread(): + jthread = java.lang.Thread.currentThread() + pythread = _jthread_to_pythread[jthread] + if pythread is None: + pythread = JavaThread(jthread) + return pythread + +current_thread = currentThread + +def activeCount(): + return len(_threads) + +active_count = activeCount + +def enumerate(): + return _threads.values() + +from thread import stack_size + + +_MainThread() + + +###################################################################### +# pure Python code from CPythonLib/threading.py + +# The timer class was contributed by Itamar Shtull-Trauring + +def Timer(*args, **kwargs): + return _Timer(*args, **kwargs) + +class _Timer(Thread): + """Call a function after a specified number of seconds: + + t = Timer(30.0, f, args=[], kwargs={}) + t.start() + t.cancel() # stop the timer's action if it's still waiting + """ + + def __init__(self, interval, function, args=[], kwargs={}): + Thread.__init__(self) + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.finished = Event() + + def cancel(self): + """Stop the timer if it hasn't finished yet""" + self.finished.set() + + def run(self): + self.finished.wait(self.interval) + if not self.finished.isSet(): + self.function(*self.args, **self.kwargs) + self.finished.set() + + +# NOT USED except by BoundedSemaphore +class _Semaphore(_Verbose): + + # After Tim Peters' semaphore class, but not quite the same (no maximum) + + def __init__(self, value=1, verbose=None): + assert value >= 0, "Semaphore initial value must be >= 0" + _Verbose.__init__(self, verbose) + self.__cond = Condition(Lock()) + self.__value = value + + def acquire(self, blocking=1): + rc = False + self.__cond.acquire() + while self.__value == 0: + if not blocking: + break + if __debug__: + self._note("%s.acquire(%s): blocked waiting, value=%s", + self, blocking, self.__value) + self.__cond.wait() + else: + self.__value = self.__value - 1 + if __debug__: + self._note("%s.acquire: success, value=%s", + self, self.__value) + rc = True + self.__cond.release() + return rc + + def release(self): + self.__cond.acquire() + self.__value = self.__value + 1 + if __debug__: + self._note("%s.release: success, value=%s", + self, self.__value) + self.__cond.notify() + self.__cond.release() + + +def BoundedSemaphore(*args, **kwargs): + return _BoundedSemaphore(*args, **kwargs) + +class _BoundedSemaphore(_Semaphore): + """Semaphore that checks that # releases is <= # acquires""" + def __init__(self, value=1, verbose=None): + _Semaphore.__init__(self, value, verbose) + self._initial_value = value + + def __enter__(self): + self.acquire() + return self + + def release(self): + if self._Semaphore__value >= self._initial_value: + raise ValueError, "Semaphore released too many times" + return _Semaphore.release(self) + + def __exit__(self, t, v, tb): + self.release() + + +def Event(*args, **kwargs): + return _Event(*args, **kwargs) + +class _Event(_Verbose): + + # After Tim Peters' event class (without is_posted()) + + def __init__(self, verbose=None): + _Verbose.__init__(self, verbose) + self.__cond = Condition(Lock()) + self.__flag = False + + def isSet(self): + return self.__flag + + is_set = isSet + + def set(self): + self.__cond.acquire() + try: + self.__flag = True + self.__cond.notifyAll() + finally: + self.__cond.release() + + def clear(self): + self.__cond.acquire() + try: + self.__flag = False + finally: + self.__cond.release() + + def wait(self, timeout=None): + self.__cond.acquire() + try: + if not self.__flag: + self.__cond.wait(timeout) + # Issue 2005: Since CPython 2.7, threading.Event.wait(timeout) returns boolean. + # The function should return False if timeout is reached before the event is set. + return self.__flag + finally: + self.__cond.release() diff --git a/src/main/resources/PythonLibs/timeit.py b/src/main/resources/PythonLibs/timeit.py new file mode 100644 index 0000000000000000000000000000000000000000..3725282ac6106e43116605bb630096c5e360cee7 --- /dev/null +++ b/src/main/resources/PythonLibs/timeit.py @@ -0,0 +1,331 @@ +#! /usr/bin/env python + +"""Tool for measuring execution time of small code snippets. + +This module avoids a number of common traps for measuring execution +times. See also Tim Peters' introduction to the Algorithms chapter in +the Python Cookbook, published by O'Reilly. + +Library usage: see the Timer class. + +Command line usage: + python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [--] [statement] + +Options: + -n/--number N: how many times to execute 'statement' (default: see below) + -r/--repeat N: how many times to repeat the timer (default 3) + -s/--setup S: statement to be executed once initially (default 'pass') + -t/--time: use time.time() (default on Unix) + -c/--clock: use time.clock() (default on Windows) + -v/--verbose: print raw timing results; repeat for more digits precision + -h/--help: print this usage message and exit + --: separate options from statement, use when statement starts with - + statement: statement to be timed (default 'pass') + +A multi-line statement may be given by specifying each line as a +separate argument; indented lines are possible by enclosing an +argument in quotes and using leading spaces. Multiple -s options are +treated similarly. + +If -n is not given, a suitable number of loops is calculated by trying +successive powers of 10 until the total time is at least 0.2 seconds. + +The difference in default timer function is because on Windows, +clock() has microsecond granularity but time()'s granularity is 1/60th +of a second; on Unix, clock() has 1/100th of a second granularity and +time() is much more precise. On either platform, the default timer +functions measure wall clock time, not the CPU time. This means that +other processes running on the same computer may interfere with the +timing. The best thing to do when accurate timing is necessary is to +repeat the timing a few times and use the best time. The -r option is +good for this; the default of 3 repetitions is probably enough in most +cases. On Unix, you can use clock() to measure CPU time. + +Note: there is a certain baseline overhead associated with executing a +pass statement. The code here doesn't try to hide it, but you should +be aware of it. The baseline overhead can be measured by invoking the +program without arguments. + +The baseline overhead differs between Python versions! Also, to +fairly compare older Python versions to Python 2.3, you may want to +use python -O for the older versions to avoid timing SET_LINENO +instructions. +""" + +import gc +import sys +import time +try: + import itertools +except ImportError: + # Must be an older Python version (see timeit() below) + itertools = None + +__all__ = ["Timer"] + +dummy_src_name = "<timeit-src>" +default_number = 1000000 +default_repeat = 3 + +if sys.platform == "win32": + # On Windows, the best timer is time.clock() + default_timer = time.clock +else: + # On most other platforms the best timer is time.time() + default_timer = time.time + +# Don't change the indentation of the template; the reindent() calls +# in Timer.__init__() depend on setup being indented 4 spaces and stmt +# being indented 8 spaces. +template = """ +def inner(_it, _timer): + %(setup)s + _t0 = _timer() + for _i in _it: + %(stmt)s + _t1 = _timer() + return _t1 - _t0 +""" + +def reindent(src, indent): + """Helper to reindent a multi-line statement.""" + return src.replace("\n", "\n" + " "*indent) + +def _template_func(setup, func): + """Create a timer function. Used if the "statement" is a callable.""" + def inner(_it, _timer, _func=func): + setup() + _t0 = _timer() + for _i in _it: + _func() + _t1 = _timer() + return _t1 - _t0 + return inner + +class Timer: + """Class for timing execution speed of small code snippets. + + The constructor takes a statement to be timed, an additional + statement used for setup, and a timer function. Both statements + default to 'pass'; the timer function is platform-dependent (see + module doc string). + + To measure the execution time of the first statement, use the + timeit() method. The repeat() method is a convenience to call + timeit() multiple times and return a list of results. + + The statements may contain newlines, as long as they don't contain + multi-line string literals. + """ + + def __init__(self, stmt="pass", setup="pass", timer=default_timer): + """Constructor. See class doc string.""" + self.timer = timer + ns = {} + if isinstance(stmt, basestring): + stmt = reindent(stmt, 8) + if isinstance(setup, basestring): + setup = reindent(setup, 4) + src = template % {'stmt': stmt, 'setup': setup} + elif hasattr(setup, '__call__'): + src = template % {'stmt': stmt, 'setup': '_setup()'} + ns['_setup'] = setup + else: + raise ValueError("setup is neither a string nor callable") + self.src = src # Save for traceback display + code = compile(src, dummy_src_name, "exec") + exec code in globals(), ns + self.inner = ns["inner"] + elif hasattr(stmt, '__call__'): + self.src = None + if isinstance(setup, basestring): + _setup = setup + def setup(): + exec _setup in globals(), ns + elif not hasattr(setup, '__call__'): + raise ValueError("setup is neither a string nor callable") + self.inner = _template_func(setup, stmt) + else: + raise ValueError("stmt is neither a string nor callable") + + def print_exc(self, file=None): + """Helper to print a traceback from the timed code. + + Typical use: + + t = Timer(...) # outside the try/except + try: + t.timeit(...) # or t.repeat(...) + except: + t.print_exc() + + The advantage over the standard traceback is that source lines + in the compiled template will be displayed. + + The optional file argument directs where the traceback is + sent; it defaults to sys.stderr. + """ + import linecache, traceback + if self.src is not None: + linecache.cache[dummy_src_name] = (len(self.src), + None, + self.src.split("\n"), + dummy_src_name) + # else the source is already stored somewhere else + + traceback.print_exc(file=file) + + def timeit(self, number=default_number): + """Time 'number' executions of the main statement. + + To be precise, this executes the setup statement once, and + then returns the time it takes to execute the main statement + a number of times, as a float measured in seconds. The + argument is the number of times through the loop, defaulting + to one million. The main statement, the setup statement and + the timer function to be used are passed to the constructor. + """ + if itertools: + it = itertools.repeat(None, number) + else: + it = [None] * number + gcold = gc.isenabled() + try: + gc.disable() + except NotImplementedError: + pass # ignore on platforms like Jython + timing = self.inner(it, self.timer) + if gcold: + gc.enable() + return timing + + def repeat(self, repeat=default_repeat, number=default_number): + """Call timeit() a few times. + + This is a convenience function that calls the timeit() + repeatedly, returning a list of results. The first argument + specifies how many times to call timeit(), defaulting to 3; + the second argument specifies the timer argument, defaulting + to one million. + + Note: it's tempting to calculate mean and standard deviation + from the result vector and report these. However, this is not + very useful. In a typical case, the lowest value gives a + lower bound for how fast your machine can run the given code + snippet; higher values in the result vector are typically not + caused by variability in Python's speed, but by other + processes interfering with your timing accuracy. So the min() + of the result is probably the only number you should be + interested in. After that, you should look at the entire + vector and apply common sense rather than statistics. + """ + r = [] + for i in range(repeat): + t = self.timeit(number) + r.append(t) + return r + +def timeit(stmt="pass", setup="pass", timer=default_timer, + number=default_number): + """Convenience function to create Timer object and call timeit method.""" + return Timer(stmt, setup, timer).timeit(number) + +def repeat(stmt="pass", setup="pass", timer=default_timer, + repeat=default_repeat, number=default_number): + """Convenience function to create Timer object and call repeat method.""" + return Timer(stmt, setup, timer).repeat(repeat, number) + +def main(args=None): + """Main program, used when run as a script. + + The optional argument specifies the command line to be parsed, + defaulting to sys.argv[1:]. + + The return value is an exit code to be passed to sys.exit(); it + may be None to indicate success. + + When an exception happens during timing, a traceback is printed to + stderr and the return value is 1. Exceptions at other times + (including the template compilation) are not caught. + """ + if args is None: + args = sys.argv[1:] + import getopt + try: + opts, args = getopt.getopt(args, "n:s:r:tcvh", + ["number=", "setup=", "repeat=", + "time", "clock", "verbose", "help"]) + except getopt.error, err: + print err + print "use -h/--help for command line help" + return 2 + timer = default_timer + stmt = "\n".join(args) or "pass" + number = 0 # auto-determine + setup = [] + repeat = default_repeat + verbose = 0 + precision = 3 + for o, a in opts: + if o in ("-n", "--number"): + number = int(a) + if o in ("-s", "--setup"): + setup.append(a) + if o in ("-r", "--repeat"): + repeat = int(a) + if repeat <= 0: + repeat = 1 + if o in ("-t", "--time"): + timer = time.time + if o in ("-c", "--clock"): + timer = time.clock + if o in ("-v", "--verbose"): + if verbose: + precision += 1 + verbose += 1 + if o in ("-h", "--help"): + print __doc__, + return 0 + setup = "\n".join(setup) or "pass" + # Include the current directory, so that local imports work (sys.path + # contains the directory of this script, rather than the current + # directory) + import os + sys.path.insert(0, os.curdir) + t = Timer(stmt, setup, timer) + if number == 0: + # determine number so that 0.2 <= total time < 2.0 + for i in range(1, 10): + number = 10**i + try: + x = t.timeit(number) + except: + t.print_exc() + return 1 + if verbose: + print "%d loops -> %.*g secs" % (number, precision, x) + if x >= 0.2: + break + try: + r = t.repeat(repeat, number) + except: + t.print_exc() + return 1 + best = min(r) + if verbose: + print "raw times:", " ".join(["%.*g" % (precision, x) for x in r]) + print "%d loops," % number, + usec = best * 1e6 / number + if usec < 1000: + print "best of %d: %.*g usec per loop" % (repeat, precision, usec) + else: + msec = usec / 1000 + if msec < 1000: + print "best of %d: %.*g msec per loop" % (repeat, precision, msec) + else: + sec = msec / 1000 + print "best of %d: %.*g sec per loop" % (repeat, precision, sec) + return None + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/main/resources/PythonLibs/token.py b/src/main/resources/PythonLibs/token.py new file mode 100644 index 0000000000000000000000000000000000000000..34abf62016ac9ca377dd9c2313eda62b6c0f3d42 --- /dev/null +++ b/src/main/resources/PythonLibs/token.py @@ -0,0 +1,142 @@ +#! /usr/bin/env python + +"""Token constants (from "token.h").""" + +# This file is automatically generated; please don't muck it up! +# +# To update the symbols in this file, 'cd' to the top directory of +# the python source tree after building the interpreter and run: +# +# ./python Lib/token.py + +#--start constants-- +ENDMARKER = 0 +NAME = 1 +NUMBER = 2 +STRING = 3 +NEWLINE = 4 +INDENT = 5 +DEDENT = 6 +LPAR = 7 +RPAR = 8 +LSQB = 9 +RSQB = 10 +COLON = 11 +COMMA = 12 +SEMI = 13 +PLUS = 14 +MINUS = 15 +STAR = 16 +SLASH = 17 +VBAR = 18 +AMPER = 19 +LESS = 20 +GREATER = 21 +EQUAL = 22 +DOT = 23 +PERCENT = 24 +BACKQUOTE = 25 +LBRACE = 26 +RBRACE = 27 +EQEQUAL = 28 +NOTEQUAL = 29 +LESSEQUAL = 30 +GREATEREQUAL = 31 +TILDE = 32 +CIRCUMFLEX = 33 +LEFTSHIFT = 34 +RIGHTSHIFT = 35 +DOUBLESTAR = 36 +PLUSEQUAL = 37 +MINEQUAL = 38 +STAREQUAL = 39 +SLASHEQUAL = 40 +PERCENTEQUAL = 41 +AMPEREQUAL = 42 +VBAREQUAL = 43 +CIRCUMFLEXEQUAL = 44 +LEFTSHIFTEQUAL = 45 +RIGHTSHIFTEQUAL = 46 +DOUBLESTAREQUAL = 47 +DOUBLESLASH = 48 +DOUBLESLASHEQUAL = 49 +AT = 50 +OP = 51 +ERRORTOKEN = 52 +N_TOKENS = 53 +NT_OFFSET = 256 +#--end constants-- + +tok_name = {} +for _name, _value in globals().items(): + if type(_value) is type(0): + tok_name[_value] = _name +del _name, _value + + +def ISTERMINAL(x): + return x < NT_OFFSET + +def ISNONTERMINAL(x): + return x >= NT_OFFSET + +def ISEOF(x): + return x == ENDMARKER + + +def main(): + import re + import sys + args = sys.argv[1:] + inFileName = args and args[0] or "Include/token.h" + outFileName = "Lib/token.py" + if len(args) > 1: + outFileName = args[1] + try: + fp = open(inFileName) + except IOError, err: + sys.stdout.write("I/O error: %s\n" % str(err)) + sys.exit(1) + lines = fp.read().split("\n") + fp.close() + prog = re.compile( + "#define[ \t][ \t]*([A-Z0-9][A-Z0-9_]*)[ \t][ \t]*([0-9][0-9]*)", + re.IGNORECASE) + tokens = {} + for line in lines: + match = prog.match(line) + if match: + name, val = match.group(1, 2) + val = int(val) + tokens[val] = name # reverse so we can sort them... + keys = tokens.keys() + keys.sort() + # load the output skeleton from the target: + try: + fp = open(outFileName) + except IOError, err: + sys.stderr.write("I/O error: %s\n" % str(err)) + sys.exit(2) + format = fp.read().split("\n") + fp.close() + try: + start = format.index("#--start constants--") + 1 + end = format.index("#--end constants--") + except ValueError: + sys.stderr.write("target does not contain format markers") + sys.exit(3) + lines = [] + for val in keys: + lines.append("%s = %d" % (tokens[val], val)) + format[start:end] = lines + try: + fp = open(outFileName, 'w') + except IOError, err: + sys.stderr.write("I/O error: %s\n" % str(err)) + sys.exit(4) + fp.write("\n".join(format)) + fp.close() + + +if __name__ == "__main__": + main() diff --git a/src/main/resources/PythonLibs/tokenize.py b/src/main/resources/PythonLibs/tokenize.py new file mode 100644 index 0000000000000000000000000000000000000000..ca7b07493cfe0b30979b172f225bee8b5a814e33 --- /dev/null +++ b/src/main/resources/PythonLibs/tokenize.py @@ -0,0 +1,426 @@ +"""Tokenization help for Python programs. + +generate_tokens(readline) is a generator that breaks a stream of +text into Python tokens. It accepts a readline-like method which is called +repeatedly to get the next line of input (or "" for EOF). It generates +5-tuples with these members: + + the token type (see token.py) + the token (a string) + the starting (row, column) indices of the token (a 2-tuple of ints) + the ending (row, column) indices of the token (a 2-tuple of ints) + the original line (string) + +It is designed to match the working of the Python tokenizer exactly, except +that it produces COMMENT tokens for comments and gives type OP for all +operators + +Older entry points + tokenize_loop(readline, tokeneater) + tokenize(readline, tokeneater=printtoken) +are the same, except instead of generating tokens, tokeneater is a callback +function to which the 5 fields described above are passed as 5 arguments, +each time a new token is found.""" + +__author__ = 'Ka-Ping Yee <ping@lfw.org>' +__credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, ' + 'Skip Montanaro, Raymond Hettinger') + +import string, re +from token import * + +import token +__all__ = [x for x in dir(token) if not x.startswith("_")] +__all__ += ["COMMENT", "tokenize", "generate_tokens", "NL", "untokenize"] +del x +del token + +COMMENT = N_TOKENS +tok_name[COMMENT] = 'COMMENT' +NL = N_TOKENS + 1 +tok_name[NL] = 'NL' +N_TOKENS += 2 + +def group(*choices): return '(' + '|'.join(choices) + ')' +def any(*choices): return group(*choices) + '*' +def maybe(*choices): return group(*choices) + '?' + +Whitespace = r'[ \f\t]*' +Comment = r'#[^\r\n]*' +Ignore = Whitespace + any(r'\\\r?\n' + Whitespace) + maybe(Comment) +Name = r'[a-zA-Z_]\w*' + +Hexnumber = r'0[xX][\da-fA-F]+[lL]?' +Octnumber = r'(0[oO][0-7]+)|(0[0-7]*)[lL]?' +Binnumber = r'0[bB][01]+[lL]?' +Decnumber = r'[1-9]\d*[lL]?' +Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber) +Exponent = r'[eE][-+]?\d+' +Pointfloat = group(r'\d+\.\d*', r'\.\d+') + maybe(Exponent) +Expfloat = r'\d+' + Exponent +Floatnumber = group(Pointfloat, Expfloat) +Imagnumber = group(r'\d+[jJ]', Floatnumber + r'[jJ]') +Number = group(Imagnumber, Floatnumber, Intnumber) + +# Tail end of ' string. +Single = r"[^'\\]*(?:\\.[^'\\]*)*'" +# Tail end of " string. +Double = r'[^"\\]*(?:\\.[^"\\]*)*"' +# Tail end of ''' string. +Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''" +# Tail end of """ string. +Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""' +Triple = group("[uUbB]?[rR]?'''", '[uUbB]?[rR]?"""') +# Single-line ' or " string. +String = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*'", + r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*"') + +# Because of leftmost-then-longest match semantics, be sure to put the +# longest operators first (e.g., if = came before ==, == would get +# recognized as two instances of =). +Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", + r"//=?", + r"[+\-*/%&|^=<>]=?", + r"~") + +Bracket = '[][(){}]' +Special = group(r'\r?\n', r'[:;.,`@]') +Funny = group(Operator, Bracket, Special) + +PlainToken = group(Number, Funny, String, Name) +Token = Ignore + PlainToken + +# First (or only) line of ' or " string. +ContStr = group(r"[uUbB]?[rR]?'[^\n'\\]*(?:\\.[^\n'\\]*)*" + + group("'", r'\\\r?\n'), + r'[uUbB]?[rR]?"[^\n"\\]*(?:\\.[^\n"\\]*)*' + + group('"', r'\\\r?\n')) +PseudoExtras = group(r'\\\r?\n|\Z', Comment, Triple) +PseudoToken = Whitespace + group(PseudoExtras, Number, Funny, ContStr, Name) + +tokenprog, pseudoprog, single3prog, double3prog = map( + re.compile, (Token, PseudoToken, Single3, Double3)) +endprogs = {"'": re.compile(Single), '"': re.compile(Double), + "'''": single3prog, '"""': double3prog, + "r'''": single3prog, 'r"""': double3prog, + "u'''": single3prog, 'u"""': double3prog, + "ur'''": single3prog, 'ur"""': double3prog, + "R'''": single3prog, 'R"""': double3prog, + "U'''": single3prog, 'U"""': double3prog, + "uR'''": single3prog, 'uR"""': double3prog, + "Ur'''": single3prog, 'Ur"""': double3prog, + "UR'''": single3prog, 'UR"""': double3prog, + "b'''": single3prog, 'b"""': double3prog, + "br'''": single3prog, 'br"""': double3prog, + "B'''": single3prog, 'B"""': double3prog, + "bR'''": single3prog, 'bR"""': double3prog, + "Br'''": single3prog, 'Br"""': double3prog, + "BR'''": single3prog, 'BR"""': double3prog, + 'r': None, 'R': None, 'u': None, 'U': None, + 'b': None, 'B': None} + +triple_quoted = {} +for t in ("'''", '"""', + "r'''", 'r"""', "R'''", 'R"""', + "u'''", 'u"""', "U'''", 'U"""', + "ur'''", 'ur"""', "Ur'''", 'Ur"""', + "uR'''", 'uR"""', "UR'''", 'UR"""', + "b'''", 'b"""', "B'''", 'B"""', + "br'''", 'br"""', "Br'''", 'Br"""', + "bR'''", 'bR"""', "BR'''", 'BR"""'): + triple_quoted[t] = t +single_quoted = {} +for t in ("'", '"', + "r'", 'r"', "R'", 'R"', + "u'", 'u"', "U'", 'U"', + "ur'", 'ur"', "Ur'", 'Ur"', + "uR'", 'uR"', "UR'", 'UR"', + "b'", 'b"', "B'", 'B"', + "br'", 'br"', "Br'", 'Br"', + "bR'", 'bR"', "BR'", 'BR"' ): + single_quoted[t] = t + +tabsize = 8 + +class TokenError(Exception): pass + +class StopTokenizing(Exception): pass + +def printtoken(type, token, srow_scol, erow_ecol, line): # for testing + srow, scol = srow_scol + erow, ecol = erow_ecol + print "%d,%d-%d,%d:\t%s\t%s" % \ + (srow, scol, erow, ecol, tok_name[type], repr(token)) + +def tokenize(readline, tokeneater=printtoken): + """ + The tokenize() function accepts two parameters: one representing the + input stream, and one providing an output mechanism for tokenize(). + + The first parameter, readline, must be a callable object which provides + the same interface as the readline() method of built-in file objects. + Each call to the function should return one line of input as a string. + + The second parameter, tokeneater, must also be a callable object. It is + called once for each token, with five arguments, corresponding to the + tuples generated by generate_tokens(). + """ + try: + tokenize_loop(readline, tokeneater) + except StopTokenizing: + pass + +# backwards compatible interface +def tokenize_loop(readline, tokeneater): + for token_info in generate_tokens(readline): + tokeneater(*token_info) + +class Untokenizer: + + def __init__(self): + self.tokens = [] + self.prev_row = 1 + self.prev_col = 0 + + def add_whitespace(self, start): + row, col = start + assert row <= self.prev_row + col_offset = col - self.prev_col + if col_offset: + self.tokens.append(" " * col_offset) + + def untokenize(self, iterable): + for t in iterable: + if len(t) == 2: + self.compat(t, iterable) + break + tok_type, token, start, end, line = t + self.add_whitespace(start) + self.tokens.append(token) + self.prev_row, self.prev_col = end + if tok_type in (NEWLINE, NL): + self.prev_row += 1 + self.prev_col = 0 + return "".join(self.tokens) + + def compat(self, token, iterable): + startline = False + indents = [] + toks_append = self.tokens.append + toknum, tokval = token + if toknum in (NAME, NUMBER): + tokval += ' ' + if toknum in (NEWLINE, NL): + startline = True + prevstring = False + for tok in iterable: + toknum, tokval = tok[:2] + + if toknum in (NAME, NUMBER): + tokval += ' ' + + # Insert a space between two consecutive strings + if toknum == STRING: + if prevstring: + tokval = ' ' + tokval + prevstring = True + else: + prevstring = False + + if toknum == INDENT: + indents.append(tokval) + continue + elif toknum == DEDENT: + indents.pop() + continue + elif toknum in (NEWLINE, NL): + startline = True + elif startline and indents: + toks_append(indents[-1]) + startline = False + toks_append(tokval) + +def untokenize(iterable): + """Transform tokens back into Python source code. + + Each element returned by the iterable must be a token sequence + with at least two elements, a token number and token value. If + only two tokens are passed, the resulting output is poor. + + Round-trip invariant for full input: + Untokenized source will match input source exactly + + Round-trip invariant for limited intput: + # Output text will tokenize the back to the input + t1 = [tok[:2] for tok in generate_tokens(f.readline)] + newcode = untokenize(t1) + readline = iter(newcode.splitlines(1)).next + t2 = [tok[:2] for tok in generate_tokens(readline)] + assert t1 == t2 + """ + ut = Untokenizer() + return ut.untokenize(iterable) + +def generate_tokens(readline): + """ + The generate_tokens() generator requires one argment, readline, which + must be a callable object which provides the same interface as the + readline() method of built-in file objects. Each call to the function + should return one line of input as a string. Alternately, readline + can be a callable function terminating with StopIteration: + readline = open(myfile).next # Example of alternate readline + + The generator produces 5-tuples with these members: the token type; the + token string; a 2-tuple (srow, scol) of ints specifying the row and + column where the token begins in the source; a 2-tuple (erow, ecol) of + ints specifying the row and column where the token ends in the source; + and the line on which the token was found. The line passed is the + logical line; continuation lines are included. + """ + lnum = parenlev = continued = 0 + namechars, numchars = string.ascii_letters + '_', '0123456789' + contstr, needcont = '', 0 + contline = None + indents = [0] + + while 1: # loop over lines in stream + try: + line = readline() + except StopIteration: + line = '' + lnum += 1 + pos, max = 0, len(line) + + if contstr: # continued string + if not line: + raise TokenError, ("EOF in multi-line string", strstart) + endmatch = endprog.match(line) + if endmatch: + pos = end = endmatch.end(0) + yield (STRING, contstr + line[:end], + strstart, (lnum, end), contline + line) + contstr, needcont = '', 0 + contline = None + elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': + yield (ERRORTOKEN, contstr + line, + strstart, (lnum, len(line)), contline) + contstr = '' + contline = None + continue + else: + contstr = contstr + line + contline = contline + line + continue + + elif parenlev == 0 and not continued: # new statement + if not line: break + column = 0 + while pos < max: # measure leading whitespace + if line[pos] == ' ': + column += 1 + elif line[pos] == '\t': + column = (column//tabsize + 1)*tabsize + elif line[pos] == '\f': + column = 0 + else: + break + pos += 1 + if pos == max: + break + + if line[pos] in '#\r\n': # skip comments or blank lines + if line[pos] == '#': + comment_token = line[pos:].rstrip('\r\n') + nl_pos = pos + len(comment_token) + yield (COMMENT, comment_token, + (lnum, pos), (lnum, pos + len(comment_token)), line) + yield (NL, line[nl_pos:], + (lnum, nl_pos), (lnum, len(line)), line) + else: + yield ((NL, COMMENT)[line[pos] == '#'], line[pos:], + (lnum, pos), (lnum, len(line)), line) + continue + + if column > indents[-1]: # count indents or dedents + indents.append(column) + yield (INDENT, line[:pos], (lnum, 0), (lnum, pos), line) + while column < indents[-1]: + if column not in indents: + raise IndentationError( + "unindent does not match any outer indentation level", + ("<tokenize>", lnum, pos, line)) + indents = indents[:-1] + yield (DEDENT, '', (lnum, pos), (lnum, pos), line) + + else: # continued statement + if not line: + raise TokenError, ("EOF in multi-line statement", (lnum, 0)) + continued = 0 + + while pos < max: + pseudomatch = pseudoprog.match(line, pos) + if pseudomatch: # scan for tokens + start, end = pseudomatch.span(1) + spos, epos, pos = (lnum, start), (lnum, end), end + if start == end: + continue + token, initial = line[start:end], line[start] + + if initial in numchars or \ + (initial == '.' and token != '.'): # ordinary number + yield (NUMBER, token, spos, epos, line) + elif initial in '\r\n': + yield (NL if parenlev > 0 else NEWLINE, + token, spos, epos, line) + elif initial == '#': + assert not token.endswith("\n") + yield (COMMENT, token, spos, epos, line) + elif token in triple_quoted: + endprog = endprogs[token] + endmatch = endprog.match(line, pos) + if endmatch: # all on one line + pos = endmatch.end(0) + token = line[start:pos] + yield (STRING, token, spos, (lnum, pos), line) + else: + strstart = (lnum, start) # multiple lines + contstr = line[start:] + contline = line + break + elif initial in single_quoted or \ + token[:2] in single_quoted or \ + token[:3] in single_quoted: + if token[-1] == '\n': # continued string + strstart = (lnum, start) + endprog = (endprogs[initial] or endprogs[token[1]] or + endprogs[token[2]]) + contstr, needcont = line[start:], 1 + contline = line + break + else: # ordinary string + yield (STRING, token, spos, epos, line) + elif initial in namechars: # ordinary name + yield (NAME, token, spos, epos, line) + elif initial == '\\': # continued stmt + continued = 1 + else: + if initial in '([{': + parenlev += 1 + elif initial in ')]}': + parenlev -= 1 + yield (OP, token, spos, epos, line) + else: + yield (ERRORTOKEN, line[pos], + (lnum, pos), (lnum, pos+1), line) + pos += 1 + + for indent in indents[1:]: # pop remaining indent levels + yield (DEDENT, '', (lnum, 0), (lnum, 0), '') + yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') + +if __name__ == '__main__': # testing + import sys + if len(sys.argv) > 1: + tokenize(open(sys.argv[1]).readline) + else: + tokenize(sys.stdin.readline) diff --git a/src/main/resources/PythonLibs/trace.py b/src/main/resources/PythonLibs/trace.py new file mode 100644 index 0000000000000000000000000000000000000000..38a13e2a9f0fa92ddcfec3c92022c355a3a4a943 --- /dev/null +++ b/src/main/resources/PythonLibs/trace.py @@ -0,0 +1,819 @@ +#!/usr/bin/env python + +# portions copyright 2001, Autonomous Zones Industries, Inc., all rights... +# err... reserved and offered to the public under the terms of the +# Python 2.2 license. +# Author: Zooko O'Whielacronx +# http://zooko.com/ +# mailto:zooko@zooko.com +# +# Copyright 2000, Mojam Media, Inc., all rights reserved. +# Author: Skip Montanaro +# +# Copyright 1999, Bioreason, Inc., all rights reserved. +# Author: Andrew Dalke +# +# Copyright 1995-1997, Automatrix, Inc., all rights reserved. +# Author: Skip Montanaro +# +# Copyright 1991-1995, Stichting Mathematisch Centrum, all rights reserved. +# +# +# Permission to use, copy, modify, and distribute this Python software and +# its associated documentation for any purpose without fee is hereby +# granted, provided that the above copyright notice appears in all copies, +# and that both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of neither Automatrix, +# Bioreason or Mojam Media be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior permission. +# +"""program/module to trace Python program or function execution + +Sample use, command line: + trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs + trace.py -t --ignore-dir '$prefix' spam.py eggs + trace.py --trackcalls spam.py eggs + +Sample use, programmatically + import sys + + # create a Trace object, telling it what to ignore, and whether to + # do tracing or line-counting or both. + tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0, + count=1) + # run the new command using the given tracer + tracer.run('main()') + # make a report, placing output in /tmp + r = tracer.results() + r.write_results(show_missing=True, coverdir="/tmp") +""" + +import linecache +import os +import re +import sys +import time +import token +import tokenize +import inspect +import gc +import dis +try: + import cPickle + pickle = cPickle +except ImportError: + import pickle + +try: + import threading +except ImportError: + _settrace = sys.settrace + + def _unsettrace(): + sys.settrace(None) +else: + def _settrace(func): + threading.settrace(func) + sys.settrace(func) + + def _unsettrace(): + sys.settrace(None) + threading.settrace(None) + +def usage(outfile): + outfile.write("""Usage: %s [OPTIONS] <file> [ARGS] + +Meta-options: +--help Display this help then exit. +--version Output version information then exit. + +Otherwise, exactly one of the following three options must be given: +-t, --trace Print each line to sys.stdout before it is executed. +-c, --count Count the number of times each line is executed + and write the counts to <module>.cover for each + module executed, in the module's directory. + See also `--coverdir', `--file', `--no-report' below. +-l, --listfuncs Keep track of which functions are executed at least + once and write the results to sys.stdout after the + program exits. +-T, --trackcalls Keep track of caller/called pairs and write the + results to sys.stdout after the program exits. +-r, --report Generate a report from a counts file; do not execute + any code. `--file' must specify the results file to + read, which must have been created in a previous run + with `--count --file=FILE'. + +Modifiers: +-f, --file=<file> File to accumulate counts over several runs. +-R, --no-report Do not generate the coverage report files. + Useful if you want to accumulate over several runs. +-C, --coverdir=<dir> Directory where the report files. The coverage + report for <package>.<module> is written to file + <dir>/<package>/<module>.cover. +-m, --missing Annotate executable lines that were not executed + with '>>>>>> '. +-s, --summary Write a brief summary on stdout for each file. + (Can only be used with --count or --report.) +-g, --timing Prefix each line with the time since the program started. + Only used while tracing. + +Filters, may be repeated multiple times: +--ignore-module=<mod> Ignore the given module(s) and its submodules + (if it is a package). Accepts comma separated + list of module names +--ignore-dir=<dir> Ignore files in the given directory (multiple + directories can be joined by os.pathsep). +""" % sys.argv[0]) + +PRAGMA_NOCOVER = "#pragma NO COVER" + +# Simple rx to find lines with no code. +rx_blank = re.compile(r'^\s*(#.*)?$') + +class Ignore: + def __init__(self, modules = None, dirs = None): + self._mods = modules or [] + self._dirs = dirs or [] + + self._dirs = map(os.path.normpath, self._dirs) + self._ignore = { '<string>': 1 } + + def names(self, filename, modulename): + if modulename in self._ignore: + return self._ignore[modulename] + + # haven't seen this one before, so see if the module name is + # on the ignore list. Need to take some care since ignoring + # "cmp" musn't mean ignoring "cmpcache" but ignoring + # "Spam" must also mean ignoring "Spam.Eggs". + for mod in self._mods: + if mod == modulename: # Identical names, so ignore + self._ignore[modulename] = 1 + return 1 + # check if the module is a proper submodule of something on + # the ignore list + n = len(mod) + # (will not overflow since if the first n characters are the + # same and the name has not already occurred, then the size + # of "name" is greater than that of "mod") + if mod == modulename[:n] and modulename[n] == '.': + self._ignore[modulename] = 1 + return 1 + + # Now check that __file__ isn't in one of the directories + if filename is None: + # must be a built-in, so we must ignore + self._ignore[modulename] = 1 + return 1 + + # Ignore a file when it contains one of the ignorable paths + for d in self._dirs: + # The '+ os.sep' is to ensure that d is a parent directory, + # as compared to cases like: + # d = "/usr/local" + # filename = "/usr/local.py" + # or + # d = "/usr/local.py" + # filename = "/usr/local.py" + if filename.startswith(d + os.sep): + self._ignore[modulename] = 1 + return 1 + + # Tried the different ways, so we don't ignore this module + self._ignore[modulename] = 0 + return 0 + +def modname(path): + """Return a plausible module name for the patch.""" + + base = os.path.basename(path) + filename, ext = os.path.splitext(base) + return filename + +def fullmodname(path): + """Return a plausible module name for the path.""" + + # If the file 'path' is part of a package, then the filename isn't + # enough to uniquely identify it. Try to do the right thing by + # looking in sys.path for the longest matching prefix. We'll + # assume that the rest is the package name. + + comparepath = os.path.normcase(path) + longest = "" + for dir in sys.path: + dir = os.path.normcase(dir) + if comparepath.startswith(dir) and comparepath[len(dir)] == os.sep: + if len(dir) > len(longest): + longest = dir + + if longest: + base = path[len(longest) + 1:] + else: + base = path + # the drive letter is never part of the module name + drive, base = os.path.splitdrive(base) + base = base.replace(os.sep, ".") + if os.altsep: + base = base.replace(os.altsep, ".") + filename, ext = os.path.splitext(base) + return filename.lstrip(".") + +class CoverageResults: + def __init__(self, counts=None, calledfuncs=None, infile=None, + callers=None, outfile=None): + self.counts = counts + if self.counts is None: + self.counts = {} + self.counter = self.counts.copy() # map (filename, lineno) to count + self.calledfuncs = calledfuncs + if self.calledfuncs is None: + self.calledfuncs = {} + self.calledfuncs = self.calledfuncs.copy() + self.callers = callers + if self.callers is None: + self.callers = {} + self.callers = self.callers.copy() + self.infile = infile + self.outfile = outfile + if self.infile: + # Try to merge existing counts file. + try: + counts, calledfuncs, callers = \ + pickle.load(open(self.infile, 'rb')) + self.update(self.__class__(counts, calledfuncs, callers)) + except (IOError, EOFError, ValueError), err: + print >> sys.stderr, ("Skipping counts file %r: %s" + % (self.infile, err)) + + def update(self, other): + """Merge in the data from another CoverageResults""" + counts = self.counts + calledfuncs = self.calledfuncs + callers = self.callers + other_counts = other.counts + other_calledfuncs = other.calledfuncs + other_callers = other.callers + + for key in other_counts.keys(): + counts[key] = counts.get(key, 0) + other_counts[key] + + for key in other_calledfuncs.keys(): + calledfuncs[key] = 1 + + for key in other_callers.keys(): + callers[key] = 1 + + def write_results(self, show_missing=True, summary=False, coverdir=None): + """ + @param coverdir + """ + if self.calledfuncs: + print + print "functions called:" + calls = self.calledfuncs.keys() + calls.sort() + for filename, modulename, funcname in calls: + print ("filename: %s, modulename: %s, funcname: %s" + % (filename, modulename, funcname)) + + if self.callers: + print + print "calling relationships:" + calls = self.callers.keys() + calls.sort() + lastfile = lastcfile = "" + for ((pfile, pmod, pfunc), (cfile, cmod, cfunc)) in calls: + if pfile != lastfile: + print + print "***", pfile, "***" + lastfile = pfile + lastcfile = "" + if cfile != pfile and lastcfile != cfile: + print " -->", cfile + lastcfile = cfile + print " %s.%s -> %s.%s" % (pmod, pfunc, cmod, cfunc) + + # turn the counts data ("(filename, lineno) = count") into something + # accessible on a per-file basis + per_file = {} + for filename, lineno in self.counts.keys(): + lines_hit = per_file[filename] = per_file.get(filename, {}) + lines_hit[lineno] = self.counts[(filename, lineno)] + + # accumulate summary info, if needed + sums = {} + + for filename, count in per_file.iteritems(): + # skip some "files" we don't care about... + if filename == "<string>": + continue + if filename.startswith("<doctest "): + continue + + if filename.endswith((".pyc", ".pyo")): + filename = filename[:-1] + + if coverdir is None: + dir = os.path.dirname(os.path.abspath(filename)) + modulename = modname(filename) + else: + dir = coverdir + if not os.path.exists(dir): + os.makedirs(dir) + modulename = fullmodname(filename) + + # If desired, get a list of the line numbers which represent + # executable content (returned as a dict for better lookup speed) + if show_missing: + lnotab = find_executable_linenos(filename) + else: + lnotab = {} + + source = linecache.getlines(filename) + coverpath = os.path.join(dir, modulename + ".cover") + n_hits, n_lines = self.write_results_file(coverpath, source, + lnotab, count) + + if summary and n_lines: + percent = 100 * n_hits // n_lines + sums[modulename] = n_lines, percent, modulename, filename + + if summary and sums: + mods = sums.keys() + mods.sort() + print "lines cov% module (path)" + for m in mods: + n_lines, percent, modulename, filename = sums[m] + print "%5d %3d%% %s (%s)" % sums[m] + + if self.outfile: + # try and store counts and module info into self.outfile + try: + pickle.dump((self.counts, self.calledfuncs, self.callers), + open(self.outfile, 'wb'), 1) + except IOError, err: + print >> sys.stderr, "Can't save counts files because %s" % err + + def write_results_file(self, path, lines, lnotab, lines_hit): + """Return a coverage results file in path.""" + + try: + outfile = open(path, "w") + except IOError, err: + print >> sys.stderr, ("trace: Could not open %r for writing: %s" + "- skipping" % (path, err)) + return 0, 0 + + n_lines = 0 + n_hits = 0 + for i, line in enumerate(lines): + lineno = i + 1 + # do the blank/comment match to try to mark more lines + # (help the reader find stuff that hasn't been covered) + if lineno in lines_hit: + outfile.write("%5d: " % lines_hit[lineno]) + n_hits += 1 + n_lines += 1 + elif rx_blank.match(line): + outfile.write(" ") + else: + # lines preceded by no marks weren't hit + # Highlight them if so indicated, unless the line contains + # #pragma: NO COVER + if lineno in lnotab and not PRAGMA_NOCOVER in lines[i]: + outfile.write(">>>>>> ") + n_lines += 1 + else: + outfile.write(" ") + outfile.write(lines[i].expandtabs(8)) + outfile.close() + + return n_hits, n_lines + +def find_lines_from_code(code, strs): + """Return dict where keys are lines in the line number table.""" + linenos = {} + + for _, lineno in dis.findlinestarts(code): + if lineno not in strs: + linenos[lineno] = 1 + + return linenos + +def find_lines(code, strs): + """Return lineno dict for all code objects reachable from code.""" + # get all of the lineno information from the code of this scope level + linenos = find_lines_from_code(code, strs) + + # and check the constants for references to other code objects + for c in code.co_consts: + if inspect.iscode(c): + # find another code object, so recurse into it + linenos.update(find_lines(c, strs)) + return linenos + +def find_strings(filename): + """Return a dict of possible docstring positions. + + The dict maps line numbers to strings. There is an entry for + line that contains only a string or a part of a triple-quoted + string. + """ + d = {} + # If the first token is a string, then it's the module docstring. + # Add this special case so that the test in the loop passes. + prev_ttype = token.INDENT + f = open(filename) + for ttype, tstr, start, end, line in tokenize.generate_tokens(f.readline): + if ttype == token.STRING: + if prev_ttype == token.INDENT: + sline, scol = start + eline, ecol = end + for i in range(sline, eline + 1): + d[i] = 1 + prev_ttype = ttype + f.close() + return d + +def find_executable_linenos(filename): + """Return dict where keys are line numbers in the line number table.""" + try: + prog = open(filename, "rU").read() + except IOError, err: + print >> sys.stderr, ("Not printing coverage data for %r: %s" + % (filename, err)) + return {} + code = compile(prog, filename, "exec") + strs = find_strings(filename) + return find_lines(code, strs) + +class Trace: + def __init__(self, count=1, trace=1, countfuncs=0, countcallers=0, + ignoremods=(), ignoredirs=(), infile=None, outfile=None, + timing=False): + """ + @param count true iff it should count number of times each + line is executed + @param trace true iff it should print out each line that is + being counted + @param countfuncs true iff it should just output a list of + (filename, modulename, funcname,) for functions + that were called at least once; This overrides + `count' and `trace' + @param ignoremods a list of the names of modules to ignore + @param ignoredirs a list of the names of directories to ignore + all of the (recursive) contents of + @param infile file from which to read stored counts to be + added into the results + @param outfile file in which to write the results + @param timing true iff timing information be displayed + """ + self.infile = infile + self.outfile = outfile + self.ignore = Ignore(ignoremods, ignoredirs) + self.counts = {} # keys are (filename, linenumber) + self.blabbed = {} # for debugging + self.pathtobasename = {} # for memoizing os.path.basename + self.donothing = 0 + self.trace = trace + self._calledfuncs = {} + self._callers = {} + self._caller_cache = {} + self.start_time = None + if timing: + self.start_time = time.time() + if countcallers: + self.globaltrace = self.globaltrace_trackcallers + elif countfuncs: + self.globaltrace = self.globaltrace_countfuncs + elif trace and count: + self.globaltrace = self.globaltrace_lt + self.localtrace = self.localtrace_trace_and_count + elif trace: + self.globaltrace = self.globaltrace_lt + self.localtrace = self.localtrace_trace + elif count: + self.globaltrace = self.globaltrace_lt + self.localtrace = self.localtrace_count + else: + # Ahem -- do nothing? Okay. + self.donothing = 1 + + def run(self, cmd): + import __main__ + dict = __main__.__dict__ + self.runctx(cmd, dict, dict) + + def runctx(self, cmd, globals=None, locals=None): + if globals is None: globals = {} + if locals is None: locals = {} + if not self.donothing: + _settrace(self.globaltrace) + try: + exec cmd in globals, locals + finally: + if not self.donothing: + _unsettrace() + + def runfunc(self, func, *args, **kw): + result = None + if not self.donothing: + sys.settrace(self.globaltrace) + try: + result = func(*args, **kw) + finally: + if not self.donothing: + sys.settrace(None) + return result + + def file_module_function_of(self, frame): + code = frame.f_code + filename = code.co_filename + if filename: + modulename = modname(filename) + else: + modulename = None + + funcname = code.co_name + clsname = None + if code in self._caller_cache: + if self._caller_cache[code] is not None: + clsname = self._caller_cache[code] + else: + self._caller_cache[code] = None + ## use of gc.get_referrers() was suggested by Michael Hudson + # all functions which refer to this code object + funcs = [f for f in gc.get_referrers(code) + if inspect.isfunction(f)] + # require len(func) == 1 to avoid ambiguity caused by calls to + # new.function(): "In the face of ambiguity, refuse the + # temptation to guess." + if len(funcs) == 1: + dicts = [d for d in gc.get_referrers(funcs[0]) + if isinstance(d, dict)] + if len(dicts) == 1: + classes = [c for c in gc.get_referrers(dicts[0]) + if hasattr(c, "__bases__")] + if len(classes) == 1: + # ditto for new.classobj() + clsname = classes[0].__name__ + # cache the result - assumption is that new.* is + # not called later to disturb this relationship + # _caller_cache could be flushed if functions in + # the new module get called. + self._caller_cache[code] = clsname + if clsname is not None: + funcname = "%s.%s" % (clsname, funcname) + + return filename, modulename, funcname + + def globaltrace_trackcallers(self, frame, why, arg): + """Handler for call events. + + Adds information about who called who to the self._callers dict. + """ + if why == 'call': + # XXX Should do a better job of identifying methods + this_func = self.file_module_function_of(frame) + parent_func = self.file_module_function_of(frame.f_back) + self._callers[(parent_func, this_func)] = 1 + + def globaltrace_countfuncs(self, frame, why, arg): + """Handler for call events. + + Adds (filename, modulename, funcname) to the self._calledfuncs dict. + """ + if why == 'call': + this_func = self.file_module_function_of(frame) + self._calledfuncs[this_func] = 1 + + def globaltrace_lt(self, frame, why, arg): + """Handler for call events. + + If the code block being entered is to be ignored, returns `None', + else returns self.localtrace. + """ + if why == 'call': + code = frame.f_code + filename = frame.f_globals.get('__file__', None) + if filename: + # XXX modname() doesn't work right for packages, so + # the ignore support won't work right for packages + modulename = modname(filename) + if modulename is not None: + ignore_it = self.ignore.names(filename, modulename) + if not ignore_it: + if self.trace: + print (" --- modulename: %s, funcname: %s" + % (modulename, code.co_name)) + return self.localtrace + else: + return None + + def localtrace_trace_and_count(self, frame, why, arg): + if why == "line": + # record the file name and line number of every trace + filename = frame.f_code.co_filename + lineno = frame.f_lineno + key = filename, lineno + self.counts[key] = self.counts.get(key, 0) + 1 + + if self.start_time: + print '%.2f' % (time.time() - self.start_time), + bname = os.path.basename(filename) + print "%s(%d): %s" % (bname, lineno, + linecache.getline(filename, lineno)), + return self.localtrace + + def localtrace_trace(self, frame, why, arg): + if why == "line": + # record the file name and line number of every trace + filename = frame.f_code.co_filename + lineno = frame.f_lineno + + if self.start_time: + print '%.2f' % (time.time() - self.start_time), + bname = os.path.basename(filename) + print "%s(%d): %s" % (bname, lineno, + linecache.getline(filename, lineno)), + return self.localtrace + + def localtrace_count(self, frame, why, arg): + if why == "line": + filename = frame.f_code.co_filename + lineno = frame.f_lineno + key = filename, lineno + self.counts[key] = self.counts.get(key, 0) + 1 + return self.localtrace + + def results(self): + return CoverageResults(self.counts, infile=self.infile, + outfile=self.outfile, + calledfuncs=self._calledfuncs, + callers=self._callers) + +def _err_exit(msg): + sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) + sys.exit(1) + +def main(argv=None): + import getopt + + if argv is None: + argv = sys.argv + try: + opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:lTg", + ["help", "version", "trace", "count", + "report", "no-report", "summary", + "file=", "missing", + "ignore-module=", "ignore-dir=", + "coverdir=", "listfuncs", + "trackcalls", "timing"]) + + except getopt.error, msg: + sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) + sys.stderr.write("Try `%s --help' for more information\n" + % sys.argv[0]) + sys.exit(1) + + trace = 0 + count = 0 + report = 0 + no_report = 0 + counts_file = None + missing = 0 + ignore_modules = [] + ignore_dirs = [] + coverdir = None + summary = 0 + listfuncs = False + countcallers = False + timing = False + + for opt, val in opts: + if opt == "--help": + usage(sys.stdout) + sys.exit(0) + + if opt == "--version": + sys.stdout.write("trace 2.0\n") + sys.exit(0) + + if opt == "-T" or opt == "--trackcalls": + countcallers = True + continue + + if opt == "-l" or opt == "--listfuncs": + listfuncs = True + continue + + if opt == "-g" or opt == "--timing": + timing = True + continue + + if opt == "-t" or opt == "--trace": + trace = 1 + continue + + if opt == "-c" or opt == "--count": + count = 1 + continue + + if opt == "-r" or opt == "--report": + report = 1 + continue + + if opt == "-R" or opt == "--no-report": + no_report = 1 + continue + + if opt == "-f" or opt == "--file": + counts_file = val + continue + + if opt == "-m" or opt == "--missing": + missing = 1 + continue + + if opt == "-C" or opt == "--coverdir": + coverdir = val + continue + + if opt == "-s" or opt == "--summary": + summary = 1 + continue + + if opt == "--ignore-module": + for mod in val.split(","): + ignore_modules.append(mod.strip()) + continue + + if opt == "--ignore-dir": + for s in val.split(os.pathsep): + s = os.path.expandvars(s) + # should I also call expanduser? (after all, could use $HOME) + + s = s.replace("$prefix", + os.path.join(sys.prefix, "lib", + "python" + sys.version[:3])) + s = s.replace("$exec_prefix", + os.path.join(sys.exec_prefix, "lib", + "python" + sys.version[:3])) + s = os.path.normpath(s) + ignore_dirs.append(s) + continue + + assert 0, "Should never get here" + + if listfuncs and (count or trace): + _err_exit("cannot specify both --listfuncs and (--trace or --count)") + + if not (count or trace or report or listfuncs or countcallers): + _err_exit("must specify one of --trace, --count, --report, " + "--listfuncs, or --trackcalls") + + if report and no_report: + _err_exit("cannot specify both --report and --no-report") + + if report and not counts_file: + _err_exit("--report requires a --file") + + if no_report and len(prog_argv) == 0: + _err_exit("missing name of file to run") + + # everything is ready + if report: + results = CoverageResults(infile=counts_file, outfile=counts_file) + results.write_results(missing, summary=summary, coverdir=coverdir) + else: + sys.argv = prog_argv + progname = prog_argv[0] + sys.path[0] = os.path.split(progname)[0] + + t = Trace(count, trace, countfuncs=listfuncs, + countcallers=countcallers, ignoremods=ignore_modules, + ignoredirs=ignore_dirs, infile=counts_file, + outfile=counts_file, timing=timing) + try: + with open(progname) as fp: + code = compile(fp.read(), progname, 'exec') + # try to emulate __main__ namespace as much as possible + globs = { + '__file__': progname, + '__name__': '__main__', + '__package__': None, + '__cached__': None, + } + t.runctx(code, globs, globs) + except IOError, err: + _err_exit("Cannot run file %r because: %s" % (sys.argv[0], err)) + except SystemExit: + pass + + results = t.results() + + if not no_report: + results.write_results(missing, summary=summary, coverdir=coverdir) + +if __name__=='__main__': + main() diff --git a/src/main/resources/PythonLibs/traceback.py b/src/main/resources/PythonLibs/traceback.py new file mode 100644 index 0000000000000000000000000000000000000000..da17d3a1f8051ffb29e42babbe100a2d59dd2d3d --- /dev/null +++ b/src/main/resources/PythonLibs/traceback.py @@ -0,0 +1,319 @@ +"""Extract, format and print information about Python stack traces.""" + +import linecache +import sys +import types + +__all__ = ['extract_stack', 'extract_tb', 'format_exception', + 'format_exception_only', 'format_list', 'format_stack', + 'format_tb', 'print_exc', 'format_exc', 'print_exception', + 'print_last', 'print_stack', 'print_tb', 'tb_lineno'] + +def _print(file, str='', terminator='\n'): + file.write(str+terminator) + + +def print_list(extracted_list, file=None): + """Print the list of tuples as returned by extract_tb() or + extract_stack() as a formatted stack trace to the given file.""" + if file is None: + file = sys.stderr + for filename, lineno, name, line in extracted_list: + _print(file, + ' File "%s", line %d, in %s' % (filename,lineno,name)) + if line: + _print(file, ' %s' % line.strip()) + +def format_list(extracted_list): + """Format a list of traceback entry tuples for printing. + + Given a list of tuples as returned by extract_tb() or + extract_stack(), return a list of strings ready for printing. + Each string in the resulting list corresponds to the item with the + same index in the argument list. Each string ends in a newline; + the strings may contain internal newlines as well, for those items + whose source text line is not None. + """ + list = [] + for filename, lineno, name, line in extracted_list: + item = ' File "%s", line %d, in %s\n' % (filename,lineno,name) + if line: + item = item + ' %s\n' % line.strip() + list.append(item) + return list + + +def print_tb(tb, limit=None, file=None): + """Print up to 'limit' stack trace entries from the traceback 'tb'. + + If 'limit' is omitted or None, all entries are printed. If 'file' + is omitted or None, the output goes to sys.stderr; otherwise + 'file' should be an open file or file-like object with a write() + method. + """ + if file is None: + file = sys.stderr + if limit is None: + if hasattr(sys, 'tracebacklimit'): + limit = sys.tracebacklimit + n = 0 + while tb is not None and (limit is None or n < limit): + f = tb.tb_frame + lineno = tb.tb_lineno + co = f.f_code + filename = co.co_filename + name = co.co_name + _print(file, + ' File "%s", line %d, in %s' % (filename, lineno, name)) + linecache.checkcache(filename) + line = linecache.getline(filename, lineno, f.f_globals) + if line: _print(file, ' ' + line.strip()) + tb = tb.tb_next + n = n+1 + +def format_tb(tb, limit = None): + """A shorthand for 'format_list(extract_stack(f, limit)).""" + return format_list(extract_tb(tb, limit)) + +def extract_tb(tb, limit = None): + """Return list of up to limit pre-processed entries from traceback. + + This is useful for alternate formatting of stack traces. If + 'limit' is omitted or None, all entries are extracted. A + pre-processed stack trace entry is a quadruple (filename, line + number, function name, text) representing the information that is + usually printed for a stack trace. The text is a string with + leading and trailing whitespace stripped; if the source is not + available it is None. + """ + if limit is None: + if hasattr(sys, 'tracebacklimit'): + limit = sys.tracebacklimit + list = [] + n = 0 + while tb is not None and (limit is None or n < limit): + f = tb.tb_frame + lineno = tb.tb_lineno + co = f.f_code + filename = co.co_filename + name = co.co_name + linecache.checkcache(filename) + line = linecache.getline(filename, lineno, f.f_globals) + if line: line = line.strip() + else: line = None + list.append((filename, lineno, name, line)) + tb = tb.tb_next + n = n+1 + return list + + +def print_exception(etype, value, tb, limit=None, file=None): + """Print exception up to 'limit' stack trace entries from 'tb' to 'file'. + + This differs from print_tb() in the following ways: (1) if + traceback is not None, it prints a header "Traceback (most recent + call last):"; (2) it prints the exception type and value after the + stack trace; (3) if type is SyntaxError and value has the + appropriate format, it prints the line where the syntax error + occurred with a caret on the next line indicating the approximate + position of the error. + """ + if file is None: + file = sys.stderr + if tb: + _print(file, 'Traceback (most recent call last):') + print_tb(tb, limit, file) + lines = format_exception_only(etype, value) + for line in lines: + _print(file, line, '') + +def format_exception(etype, value, tb, limit = None): + """Format a stack trace and the exception information. + + The arguments have the same meaning as the corresponding arguments + to print_exception(). The return value is a list of strings, each + ending in a newline and some containing internal newlines. When + these lines are concatenated and printed, exactly the same text is + printed as does print_exception(). + """ + if tb: + list = ['Traceback (most recent call last):\n'] + list = list + format_tb(tb, limit) + else: + list = [] + list = list + format_exception_only(etype, value) + return list + +def format_exception_only(etype, value): + """Format the exception part of a traceback. + + The arguments are the exception type and value such as given by + sys.last_type and sys.last_value. The return value is a list of + strings, each ending in a newline. + + Normally, the list contains a single string; however, for + SyntaxError exceptions, it contains several lines that (when + printed) display detailed information about where the syntax + error occurred. + + The message indicating which exception occurred is always the last + string in the list. + + """ + + # An instance should not have a meaningful value parameter, but + # sometimes does, particularly for string exceptions, such as + # >>> raise string1, string2 # deprecated + # + # Clear these out first because issubtype(string1, SyntaxError) + # would raise another exception and mask the original problem. + if (isinstance(etype, BaseException) or + isinstance(etype, types.InstanceType) or + etype is None or type(etype) is str): + return [_format_final_exc_line(etype, value)] + + stype = etype.__name__ + + if not issubclass(etype, SyntaxError): + return [_format_final_exc_line(stype, value)] + + # It was a syntax error; show exactly where the problem was found. + lines = [] + try: + msg, (filename, lineno, offset, badline) = value.args + except Exception: + pass + else: + filename = filename or "<string>" + lines.append(' File "%s", line %d\n' % (filename, lineno)) + if badline is not None: + lines.append(' %s\n' % badline.strip()) + if offset is not None: + caretspace = badline.rstrip('\n')[:offset].lstrip() + # non-space whitespace (likes tabs) must be kept for alignment + caretspace = ((c.isspace() and c or ' ') for c in caretspace) + # only three spaces to account for offset1 == pos 0 + lines.append(' %s^\n' % ''.join(caretspace)) + value = msg + + lines.append(_format_final_exc_line(stype, value)) + return lines + +def _format_final_exc_line(etype, value): + """Return a list of a single line -- normal case for format_exception_only""" + valuestr = _some_str(value) + if value is None or not valuestr: + line = "%s\n" % etype + else: + line = "%s: %s\n" % (etype, valuestr) + return line + +def _some_str(value): + try: + return str(value) + except Exception: + pass + try: + value = unicode(value) + return value.encode("ascii", "backslashreplace") + except Exception: + pass + return '<unprintable %s object>' % type(value).__name__ + + +def print_exc(limit=None, file=None): + """Shorthand for 'print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file)'. + (In fact, it uses sys.exc_info() to retrieve the same information + in a thread-safe way.)""" + if file is None: + file = sys.stderr + try: + etype, value, tb = sys.exc_info() + print_exception(etype, value, tb, limit, file) + finally: + etype = value = tb = None + + +def format_exc(limit=None): + """Like print_exc() but return a string.""" + try: + etype, value, tb = sys.exc_info() + return ''.join(format_exception(etype, value, tb, limit)) + finally: + etype = value = tb = None + + +def print_last(limit=None, file=None): + """This is a shorthand for 'print_exception(sys.last_type, + sys.last_value, sys.last_traceback, limit, file)'.""" + if not hasattr(sys, "last_type"): + raise ValueError("no last exception") + if file is None: + file = sys.stderr + print_exception(sys.last_type, sys.last_value, sys.last_traceback, + limit, file) + + +def print_stack(f=None, limit=None, file=None): + """Print a stack trace from its invocation point. + + The optional 'f' argument can be used to specify an alternate + stack frame at which to start. The optional 'limit' and 'file' + arguments have the same meaning as for print_exception(). + """ + if f is None: + try: + raise ZeroDivisionError + except ZeroDivisionError: + f = sys.exc_info()[2].tb_frame.f_back + print_list(extract_stack(f, limit), file) + +def format_stack(f=None, limit=None): + """Shorthand for 'format_list(extract_stack(f, limit))'.""" + if f is None: + try: + raise ZeroDivisionError + except ZeroDivisionError: + f = sys.exc_info()[2].tb_frame.f_back + return format_list(extract_stack(f, limit)) + +def extract_stack(f=None, limit = None): + """Extract the raw traceback from the current stack frame. + + The return value has the same format as for extract_tb(). The + optional 'f' and 'limit' arguments have the same meaning as for + print_stack(). Each item in the list is a quadruple (filename, + line number, function name, text), and the entries are in order + from oldest to newest stack frame. + """ + if f is None: + try: + raise ZeroDivisionError + except ZeroDivisionError: + f = sys.exc_info()[2].tb_frame.f_back + if limit is None: + if hasattr(sys, 'tracebacklimit'): + limit = sys.tracebacklimit + list = [] + n = 0 + while f is not None and (limit is None or n < limit): + lineno = f.f_lineno + co = f.f_code + filename = co.co_filename + name = co.co_name + linecache.checkcache(filename) + line = linecache.getline(filename, lineno, f.f_globals) + if line: line = line.strip() + else: line = None + list.append((filename, lineno, name, line)) + f = f.f_back + n = n+1 + list.reverse() + return list + +def tb_lineno(tb): + """Calculate correct line number of traceback given in tb. + + Obsolete in 2.3. + """ + return tb.tb_lineno diff --git a/src/main/resources/PythonLibs/tty.py b/src/main/resources/PythonLibs/tty.py new file mode 100644 index 0000000000000000000000000000000000000000..a72eb6755450bb07d9bb77fb9cdc3cf2f0148534 --- /dev/null +++ b/src/main/resources/PythonLibs/tty.py @@ -0,0 +1,36 @@ +"""Terminal utilities.""" + +# Author: Steen Lumholt. + +from termios import * + +__all__ = ["setraw", "setcbreak"] + +# Indexes for termios list. +IFLAG = 0 +OFLAG = 1 +CFLAG = 2 +LFLAG = 3 +ISPEED = 4 +OSPEED = 5 +CC = 6 + +def setraw(fd, when=TCSAFLUSH): + """Put terminal into a raw mode.""" + mode = tcgetattr(fd) + mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON) + mode[OFLAG] = mode[OFLAG] & ~(OPOST) + mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB) + mode[CFLAG] = mode[CFLAG] | CS8 + mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG) + mode[CC][VMIN] = 1 + mode[CC][VTIME] = 0 + tcsetattr(fd, when, mode) + +def setcbreak(fd, when=TCSAFLUSH): + """Put terminal into a cbreak mode.""" + mode = tcgetattr(fd) + mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON) + mode[CC][VMIN] = 1 + mode[CC][VTIME] = 0 + tcsetattr(fd, when, mode) diff --git a/src/main/resources/PythonLibs/types.py b/src/main/resources/PythonLibs/types.py new file mode 100644 index 0000000000000000000000000000000000000000..5e85b43d8eede95c66160378fc79c1d52f88891e --- /dev/null +++ b/src/main/resources/PythonLibs/types.py @@ -0,0 +1,87 @@ +"""Define names for all type symbols known in the standard interpreter. + +Types that are part of optional modules (e.g. array) are not listed. +""" +import sys + +# Iterators in Python aren't a matter of type but of protocol. A large +# and changing number of builtin types implement *some* flavor of +# iterator. Don't check the type! Use hasattr to check for both +# "__iter__" and "next" attributes instead. + +NoneType = type(None) +TypeType = type +ObjectType = object + +IntType = int +LongType = long +FloatType = float +BooleanType = bool +try: + ComplexType = complex +except NameError: + pass + +StringType = str + +# StringTypes is already outdated. Instead of writing "type(x) in +# types.StringTypes", you should use "isinstance(x, basestring)". But +# we keep around for compatibility with Python 2.2. +try: + UnicodeType = unicode + StringTypes = (StringType, UnicodeType) +except NameError: + StringTypes = (StringType,) + +# XXX: no buffer in jython +#BufferType = buffer + +TupleType = tuple +ListType = list +DictType = DictionaryType = dict + +def _f(): pass +FunctionType = type(_f) +LambdaType = type(lambda: None) # Same as FunctionType +CodeType = type(_f.func_code) + +def _g(): + yield 1 +GeneratorType = type(_g()) + +class _C: + def _m(self): pass +ClassType = type(_C) +UnboundMethodType = type(_C._m) # Same as MethodType +_x = _C() +InstanceType = type(_x) +MethodType = type(_x._m) + +BuiltinFunctionType = type(len) +BuiltinMethodType = type([].append) # Same as BuiltinFunctionType + +# XXX: Jython sys is not a real module +#ModuleType = type(sys) +ModuleType = type(sys.modules[__name__]) +FileType = file +XRangeType = xrange + +try: + raise TypeError +except TypeError: + tb = sys.exc_info()[2] + TracebackType = type(tb) + FrameType = type(tb.tb_frame) + del tb + +SliceType = slice +EllipsisType = type(Ellipsis) + +DictProxyType = type(TypeType.__dict__) +NotImplementedType = type(NotImplemented) + +# For Jython, the following two types are identical +GetSetDescriptorType = type(FunctionType.func_code) +MemberDescriptorType = type(FunctionType.func_globals) + +del sys, _f, _g, _C, _x # Not for export diff --git a/src/main/resources/PythonLibs/unicodedata.py b/src/main/resources/PythonLibs/unicodedata.py new file mode 100644 index 0000000000000000000000000000000000000000..907772b4e3bd290b601181b289ac2fcef43ddf1e --- /dev/null +++ b/src/main/resources/PythonLibs/unicodedata.py @@ -0,0 +1,258 @@ +import java.lang.Character +from com.ibm.icu.text import Normalizer +from com.ibm.icu.lang import UCharacter, UProperty +from com.ibm.icu.util import VersionInfo +from com.ibm.icu.lang.UCharacter import EastAsianWidth, DecompositionType +from com.ibm.icu.lang.UCharacterEnums import ECharacterCategory, ECharacterDirection + + +__all__ = ( + "bidirectional", "category", "combining", "decimal", "decomposition", "digit", "east_asian_width", + "lookup", "mirrored", "name", "normalize", "numeric", "unidata_version") + + +_forms = { + 'NFC': Normalizer.NFC, + 'NFKC': Normalizer.NFKC, + 'NFD': Normalizer.NFD, + 'NFKD': Normalizer.NFKD +} + +Nonesuch = object() # to distinguish from None, which is a valid return value for some functions + + +def _validate_unichr(unichr): + if not(isinstance(unichr, unicode)): + raise TypeError("must be unicode, not {}".format(type(unichr).__name__)) + if len(unichr) > 1 or len(unichr) == 0: + raise TypeError("need a single Unicode character as parameter") + + +def _get_codepoint(unichr): + _validate_unichr(unichr) + return ord(unichr) + + +def name(unichr, default=Nonesuch): + # handle None + n = UCharacter.getName(_get_codepoint(unichr)) + if n is None: + if default is not Nonesuch: + return default + else: + raise ValueError("no such name") + return n + + +def lookup(name): + codepoint = UCharacter.getCharFromName(name) + if codepoint == -1: + raise KeyError("undefined character name '{}".format(name)) + return unichr(codepoint) + + +def digit(unichr, default=Nonesuch): + d = UCharacter.digit(_get_codepoint(unichr)) + if d == -1: + if default is not Nonesuch: + return default + else: + raise ValueError("not a digit") + return d + + +def decimal(unichr, default=Nonesuch): + d = UCharacter.getNumericValue(_get_codepoint(unichr)) + if d < 0 or d > 9: + if default is not Nonesuch: + return default + else: + raise ValueError("not a decimal") + return d + + +def numeric(unichr, default=Nonesuch): + n = UCharacter.getUnicodeNumericValue(_get_codepoint(unichr)) + if n == UCharacter.NO_NUMERIC_VALUE: + if default is not Nonesuch: + return default + else: + raise ValueError("not a numeric") + return n + + +_decomp = { + DecompositionType.CANONICAL: "canonical", + DecompositionType.CIRCLE: "circle", + DecompositionType.COMPAT: "compat", + DecompositionType.FINAL: "final", + DecompositionType.FONT: "font", + DecompositionType.FRACTION: "fraction", + DecompositionType.INITIAL: "initial", + DecompositionType.ISOLATED: "isolated", + DecompositionType.MEDIAL: "medial", + DecompositionType.NARROW: "narrow", + DecompositionType.NOBREAK: "nobreak", + DecompositionType.NONE: None, + DecompositionType.SMALL: "small", + DecompositionType.SQUARE: "square", + DecompositionType.SUB: "sub", + DecompositionType.SUPER: "super", + DecompositionType.VERTICAL: "vertical", + DecompositionType.WIDE: "wide" +} + +def _get_decomp_type(unichr): + if unichr == u"\u2044": # FRACTION SLASH + # special case this for CPython compatibility even though this returns as not being combining, eg, see + # http://www.fileformat.info/info/unicode/char/2044/index.htm + return "fraction" + else: + return _decomp[UCharacter.getIntPropertyValue(ord(unichr), UProperty.DECOMPOSITION_TYPE)] + +def decomposition(unichr): + _validate_unichr(unichr) + d = Normalizer.decompose(unichr, True) + decomp_type = None + if len(d) == 1: + decomp_type = _get_decomp_type(unichr) + else: + for c in d: + decomp_type = _get_decomp_type(c) + # print "Got a decomp_type %r %r %r" % (c, d, decomp_type) + if decomp_type is not None: + break + hexed = " ".join(("{0:04X}".format(ord(c)) for c in d)) + if decomp_type: + return "<{}> {}".format(decomp_type, hexed) + elif len(d) == 1: + return "" + else: + return hexed + + +# To map from ICU4J enumerations for category, bidirection, and +# east_asian_width to the underlying property values that Python uses +# from UnicodeData.txt required a manual mapping between the following +# two files: +# +# http://icu-project.org/apiref/icu4j/constant-values.html +# http://www.unicode.org/Public/6.3.0/ucd/PropertyValueAliases.txt + +_cat = { + ECharacterCategory.COMBINING_SPACING_MARK: "Mc", + ECharacterCategory.CONNECTOR_PUNCTUATION: "Pc", + ECharacterCategory.CONTROL: "Cc", + ECharacterCategory.CURRENCY_SYMBOL: "Sc", + ECharacterCategory.DASH_PUNCTUATION: "Pd", + ECharacterCategory.DECIMAL_DIGIT_NUMBER: "Nd", + ECharacterCategory.ENCLOSING_MARK: "Me", + ECharacterCategory.END_PUNCTUATION: "Pe", + ECharacterCategory.FINAL_PUNCTUATION: "Pf", + ECharacterCategory.FORMAT: "Cf", + # per http://icu-project.org/apiref/icu4j/com/ibm/icu/lang/UCharacterEnums.ECharacterCategory.html#GENERAL_OTHER_TYPES + # - no characters in [UnicodeData.txt] have this property + ECharacterCategory.GENERAL_OTHER_TYPES: "Cn Not Assigned", + ECharacterCategory.INITIAL_PUNCTUATION: "Pi", + ECharacterCategory.LETTER_NUMBER: "Nl", + ECharacterCategory.LINE_SEPARATOR: "Zl", + ECharacterCategory.LOWERCASE_LETTER: "Ll", + ECharacterCategory.MATH_SYMBOL: "Sm", + ECharacterCategory.MODIFIER_LETTER: "Lm", + ECharacterCategory.MODIFIER_SYMBOL: "Sk", + ECharacterCategory.NON_SPACING_MARK: "Mn", + ECharacterCategory.OTHER_LETTER: "Lo", + ECharacterCategory.OTHER_NUMBER: "No", + ECharacterCategory.OTHER_PUNCTUATION: "Po", + ECharacterCategory.OTHER_SYMBOL: "So", + ECharacterCategory.PARAGRAPH_SEPARATOR: "Zp", + ECharacterCategory.PRIVATE_USE: "Co", + ECharacterCategory.SPACE_SEPARATOR: "Zs", + ECharacterCategory.START_PUNCTUATION: "Ps", + ECharacterCategory.SURROGATE: "Cs", + ECharacterCategory.TITLECASE_LETTER: "Lt", + ECharacterCategory.UNASSIGNED: "Cn", + ECharacterCategory.UPPERCASE_LETTER: "Lu", +} + +def category(unichr): + return _cat[UCharacter.getType(_get_codepoint(unichr))] + + +_dir = { + ECharacterDirection.ARABIC_NUMBER: "An", + ECharacterDirection.BLOCK_SEPARATOR: "B", + ECharacterDirection.BOUNDARY_NEUTRAL: "BN", + ECharacterDirection.COMMON_NUMBER_SEPARATOR: "CS", + ECharacterDirection.DIR_NON_SPACING_MARK: "NSM", + ECharacterDirection.EUROPEAN_NUMBER: "EN", + ECharacterDirection.EUROPEAN_NUMBER_SEPARATOR: "ES", + ECharacterDirection.EUROPEAN_NUMBER_TERMINATOR: "ET", + ECharacterDirection.FIRST_STRONG_ISOLATE: "FSI", + ECharacterDirection.LEFT_TO_RIGHT: "L", + ECharacterDirection.LEFT_TO_RIGHT_EMBEDDING: "LRE", + ECharacterDirection.LEFT_TO_RIGHT_ISOLATE: "LRI", + ECharacterDirection.LEFT_TO_RIGHT_OVERRIDE: "LRO", + ECharacterDirection.OTHER_NEUTRAL: "ON", + ECharacterDirection.POP_DIRECTIONAL_FORMAT: "PDF", + ECharacterDirection.POP_DIRECTIONAL_ISOLATE: "PDI", + ECharacterDirection.RIGHT_TO_LEFT: "R", + ECharacterDirection.RIGHT_TO_LEFT_ARABIC: "AL", + ECharacterDirection.RIGHT_TO_LEFT_EMBEDDING: "RLE", + ECharacterDirection.RIGHT_TO_LEFT_ISOLATE: "RLI", + ECharacterDirection.RIGHT_TO_LEFT_OVERRIDE: "RLO", + ECharacterDirection.SEGMENT_SEPARATOR: "S", + ECharacterDirection.WHITE_SPACE_NEUTRAL: "WS" +} + +def bidirectional(unichr): + return _dir[UCharacter.getDirection(_get_codepoint(unichr))] + + +def combining(unichr): + return UCharacter.getCombiningClass(_get_codepoint(unichr)) + + +def mirrored(unichr): + return UCharacter.isMirrored(_get_codepoint(unichr)) + + +_eaw = { + # http://www.unicode.org/reports/tr11/ + EastAsianWidth.AMBIGUOUS : "A", + EastAsianWidth.COUNT : "?", # apparently not used, see above TR + EastAsianWidth.FULLWIDTH : "F", + EastAsianWidth.HALFWIDTH : "H", + EastAsianWidth.NARROW : "Na", + EastAsianWidth.NEUTRAL : "N", + EastAsianWidth.WIDE : "W" +} + +def east_asian_width(unichr): + return _eaw[UCharacter.getIntPropertyValue(_get_codepoint(unichr), UProperty.EAST_ASIAN_WIDTH)] + + +def normalize(form, unistr): + """ + Return the normal form 'form' for the Unicode string unistr. Valid + values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'. + """ + + try: + normalizer_form = _forms[form] + except KeyError: + raise ValueError('invalid normalization form') + + return Normalizer.normalize(unistr, normalizer_form) + + +def get_icu_version(): + versions = [] + for k in VersionInfo.__dict__.iterkeys(): + if k.startswith("UNICODE_"): + v = getattr(VersionInfo, k) + versions.append((v.getMajor(), v.getMinor(), v.getMilli())) + return ".".join(str(x) for x in max(versions)) + + +unidata_version = get_icu_version() diff --git a/src/main/resources/PythonLibs/unittest/__init__.py b/src/main/resources/PythonLibs/unittest/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..201a3f0d2da21b70dbcdb09286cfe9691c7bda55 --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/__init__.py @@ -0,0 +1,69 @@ +""" +Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's +Smalltalk testing framework. + +This module contains the core framework classes that form the basis of +specific test cases and suites (TestCase, TestSuite etc.), and also a +text-based utility class for running the tests and reporting the results + (TextTestRunner). + +Simple usage: + + import unittest + + class IntegerArithmenticTestCase(unittest.TestCase): + def testAdd(self): ## test method names begin 'test*' + self.assertEqual((1 + 2), 3) + self.assertEqual(0 + 1, 1) + def testMultiply(self): + self.assertEqual((0 * 10), 0) + self.assertEqual((5 * 8), 40) + + if __name__ == '__main__': + unittest.main() + +Further information is available in the bundled documentation, and from + + http://docs.python.org/library/unittest.html + +Copyright (c) 1999-2003 Steve Purcell +Copyright (c) 2003-2010 Python Software Foundation +This module is free software, and you may redistribute it and/or modify +it under the same terms as Python itself, so long as this copyright message +and disclaimer are retained in their original form. + +IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF +THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, +AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, +SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. +""" + +__all__ = ['TestResult', 'TestCase', 'TestSuite', + 'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main', + 'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless', + 'expectedFailure', 'TextTestResult', 'installHandler', + 'registerResult', 'removeResult', 'removeHandler'] + +# Expose obsolete functions for backwards compatibility +__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases']) + +__unittest = True + +from .result import TestResult +from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, + skipUnless, expectedFailure) +from .suite import BaseTestSuite, TestSuite +from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, + findTestCases) +from .main import TestProgram, main +from .runner import TextTestRunner, TextTestResult +from .signals import installHandler, registerResult, removeResult, removeHandler + +# deprecated +_TextTestResult = TextTestResult diff --git a/src/main/resources/PythonLibs/unittest/__main__.py b/src/main/resources/PythonLibs/unittest/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..7320050ae954cc3037760f8470c91fbad7301280 --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/__main__.py @@ -0,0 +1,12 @@ +"""Main entry point""" + +import sys +if sys.argv[0].endswith("__main__.py"): + sys.argv[0] = "python -m unittest" + +__unittest = True + +from .main import main, TestProgram, USAGE_AS_MAIN +TestProgram.USAGE = USAGE_AS_MAIN + +main(module=None) diff --git a/src/main/resources/PythonLibs/unittest/case.py b/src/main/resources/PythonLibs/unittest/case.py new file mode 100644 index 0000000000000000000000000000000000000000..6257936618a82e514d30fe9f1064c88be01fb5ce --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/case.py @@ -0,0 +1,1077 @@ +"""Test case implementation""" + +import collections +import sys +import functools +import difflib +import pprint +import re +import types +import warnings + +from . import result +from .util import ( + strclass, safe_repr, unorderable_list_difference, + _count_diff_all_purpose, _count_diff_hashable +) + + +__unittest = True + + +DIFF_OMITTED = ('\nDiff is %s characters long. ' + 'Set self.maxDiff to None to see it.') + +class SkipTest(Exception): + """ + Raise this exception in a test to skip it. + + Usually you can use TestResult.skip() or one of the skipping decorators + instead of raising this directly. + """ + pass + +class _ExpectedFailure(Exception): + """ + Raise this when a test is expected to fail. + + This is an implementation detail. + """ + + def __init__(self, exc_info): + super(_ExpectedFailure, self).__init__() + self.exc_info = exc_info + +class _UnexpectedSuccess(Exception): + """ + The test was supposed to fail, but it didn't! + """ + pass + +def _id(obj): + return obj + +def skip(reason): + """ + Unconditionally skip a test. + """ + def decorator(test_item): + if not isinstance(test_item, (type, types.ClassType)): + @functools.wraps(test_item) + def skip_wrapper(*args, **kwargs): + raise SkipTest(reason) + test_item = skip_wrapper + + test_item.__unittest_skip__ = True + test_item.__unittest_skip_why__ = reason + return test_item + return decorator + +def skipIf(condition, reason): + """ + Skip a test if the condition is true. + """ + if condition: + return skip(reason) + return _id + +def skipUnless(condition, reason): + """ + Skip a test unless the condition is true. + """ + if not condition: + return skip(reason) + return _id + + +def expectedFailure(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + func(*args, **kwargs) + except Exception: + raise _ExpectedFailure(sys.exc_info()) + raise _UnexpectedSuccess + return wrapper + + +class _AssertRaisesContext(object): + """A context manager used to implement TestCase.assertRaises* methods.""" + + def __init__(self, expected, test_case, expected_regexp=None): + self.expected = expected + self.failureException = test_case.failureException + self.expected_regexp = expected_regexp + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, tb): + if exc_type is None: + try: + exc_name = self.expected.__name__ + except AttributeError: + exc_name = str(self.expected) + raise self.failureException( + "{0} not raised".format(exc_name)) + if not issubclass(exc_type, self.expected): + # let unexpected exceptions pass through + return False + self.exception = exc_value # store for later retrieval + if self.expected_regexp is None: + return True + + expected_regexp = self.expected_regexp + if isinstance(expected_regexp, basestring): + expected_regexp = re.compile(expected_regexp) + if not expected_regexp.search(str(exc_value)): + raise self.failureException('"%s" does not match "%s"' % + (expected_regexp.pattern, str(exc_value))) + return True + + +class TestCase(object): + """A class whose instances are single test cases. + + By default, the test code itself should be placed in a method named + 'runTest'. + + If the fixture may be used for many test cases, create as + many test methods as are needed. When instantiating such a TestCase + subclass, specify in the constructor arguments the name of the test method + that the instance is to execute. + + Test authors should subclass TestCase for their own tests. Construction + and deconstruction of the test's environment ('fixture') can be + implemented by overriding the 'setUp' and 'tearDown' methods respectively. + + If it is necessary to override the __init__ method, the base class + __init__ method must always be called. It is important that subclasses + should not change the signature of their __init__ method, since instances + of the classes are instantiated automatically by parts of the framework + in order to be run. + """ + + # This attribute determines which exception will be raised when + # the instance's assertion methods fail; test methods raising this + # exception will be deemed to have 'failed' rather than 'errored' + + failureException = AssertionError + + # This attribute determines whether long messages (including repr of + # objects used in assert methods) will be printed on failure in *addition* + # to any explicit message passed. + + longMessage = False + + # This attribute sets the maximum length of a diff in failure messages + # by assert methods using difflib. It is looked up as an instance attribute + # so can be configured by individual tests if required. + + maxDiff = 80*8 + + # If a string is longer than _diffThreshold, use normal comparison instead + # of difflib. See #11763. + _diffThreshold = 2**16 + + # Attribute used by TestSuite for classSetUp + + _classSetupFailed = False + + def __init__(self, methodName='runTest'): + """Create an instance of the class that will use the named test + method when executed. Raises a ValueError if the instance does + not have a method with the specified name. + """ + self._testMethodName = methodName + self._resultForDoCleanups = None + try: + testMethod = getattr(self, methodName) + except AttributeError: + raise ValueError("no such test method in %s: %s" % + (self.__class__, methodName)) + self._testMethodDoc = testMethod.__doc__ + self._cleanups = [] + + # Map types to custom assertEqual functions that will compare + # instances of said type in more detail to generate a more useful + # error message. + self._type_equality_funcs = {} + self.addTypeEqualityFunc(dict, 'assertDictEqual') + self.addTypeEqualityFunc(list, 'assertListEqual') + self.addTypeEqualityFunc(tuple, 'assertTupleEqual') + self.addTypeEqualityFunc(set, 'assertSetEqual') + self.addTypeEqualityFunc(frozenset, 'assertSetEqual') + try: + self.addTypeEqualityFunc(unicode, 'assertMultiLineEqual') + except NameError: + # No unicode support in this build + pass + + def addTypeEqualityFunc(self, typeobj, function): + """Add a type specific assertEqual style function to compare a type. + + This method is for use by TestCase subclasses that need to register + their own type equality functions to provide nicer error messages. + + Args: + typeobj: The data type to call this function on when both values + are of the same type in assertEqual(). + function: The callable taking two arguments and an optional + msg= argument that raises self.failureException with a + useful error message when the two arguments are not equal. + """ + self._type_equality_funcs[typeobj] = function + + def addCleanup(self, function, *args, **kwargs): + """Add a function, with arguments, to be called when the test is + completed. Functions added are called on a LIFO basis and are + called after tearDown on test failure or success. + + Cleanup items are called even if setUp fails (unlike tearDown).""" + self._cleanups.append((function, args, kwargs)) + + def setUp(self): + "Hook method for setting up the test fixture before exercising it." + pass + + def tearDown(self): + "Hook method for deconstructing the test fixture after testing it." + pass + + @classmethod + def setUpClass(cls): + "Hook method for setting up class fixture before running tests in the class." + + @classmethod + def tearDownClass(cls): + "Hook method for deconstructing the class fixture after running all tests in the class." + + def countTestCases(self): + return 1 + + def defaultTestResult(self): + return result.TestResult() + + def shortDescription(self): + """Returns a one-line description of the test, or None if no + description has been provided. + + The default implementation of this method returns the first line of + the specified test method's docstring. + """ + doc = self._testMethodDoc + return doc and doc.split("\n")[0].strip() or None + + + def id(self): + return "%s.%s" % (strclass(self.__class__), self._testMethodName) + + def __eq__(self, other): + if type(self) is not type(other): + return NotImplemented + + return self._testMethodName == other._testMethodName + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((type(self), self._testMethodName)) + + def __str__(self): + return "%s (%s)" % (self._testMethodName, strclass(self.__class__)) + + def __repr__(self): + return "<%s testMethod=%s>" % \ + (strclass(self.__class__), self._testMethodName) + + def _addSkip(self, result, reason): + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None: + addSkip(self, reason) + else: + warnings.warn("TestResult has no addSkip method, skips not reported", + RuntimeWarning, 2) + result.addSuccess(self) + + def run(self, result=None): + orig_result = result + if result is None: + result = self.defaultTestResult() + startTestRun = getattr(result, 'startTestRun', None) + if startTestRun is not None: + startTestRun() + + self._resultForDoCleanups = result + result.startTest(self) + + testMethod = getattr(self, self._testMethodName) + if (getattr(self.__class__, "__unittest_skip__", False) or + getattr(testMethod, "__unittest_skip__", False)): + # If the class or method was skipped. + try: + skip_why = (getattr(self.__class__, '__unittest_skip_why__', '') + or getattr(testMethod, '__unittest_skip_why__', '')) + self._addSkip(result, skip_why) + finally: + result.stopTest(self) + return + try: + success = False + try: + self.setUp() + except SkipTest as e: + self._addSkip(result, str(e)) + except KeyboardInterrupt: + raise + except: + result.addError(self, sys.exc_info()) + else: + try: + testMethod() + except KeyboardInterrupt: + raise + except self.failureException: + result.addFailure(self, sys.exc_info()) + except _ExpectedFailure as e: + addExpectedFailure = getattr(result, 'addExpectedFailure', None) + if addExpectedFailure is not None: + addExpectedFailure(self, e.exc_info) + else: + warnings.warn("TestResult has no addExpectedFailure method, reporting as passes", + RuntimeWarning) + result.addSuccess(self) + except _UnexpectedSuccess: + addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None) + if addUnexpectedSuccess is not None: + addUnexpectedSuccess(self) + else: + warnings.warn("TestResult has no addUnexpectedSuccess method, reporting as failures", + RuntimeWarning) + result.addFailure(self, sys.exc_info()) + except SkipTest as e: + self._addSkip(result, str(e)) + except: + result.addError(self, sys.exc_info()) + else: + success = True + + try: + self.tearDown() + except KeyboardInterrupt: + raise + except: + result.addError(self, sys.exc_info()) + success = False + + cleanUpSuccess = self.doCleanups() + success = success and cleanUpSuccess + if success: + result.addSuccess(self) + finally: + result.stopTest(self) + if orig_result is None: + stopTestRun = getattr(result, 'stopTestRun', None) + if stopTestRun is not None: + stopTestRun() + + def doCleanups(self): + """Execute all cleanup functions. Normally called for you after + tearDown.""" + result = self._resultForDoCleanups + ok = True + while self._cleanups: + function, args, kwargs = self._cleanups.pop(-1) + try: + function(*args, **kwargs) + except KeyboardInterrupt: + raise + except: + ok = False + result.addError(self, sys.exc_info()) + return ok + + def __call__(self, *args, **kwds): + return self.run(*args, **kwds) + + def debug(self): + """Run the test without collecting errors in a TestResult""" + self.setUp() + getattr(self, self._testMethodName)() + self.tearDown() + while self._cleanups: + function, args, kwargs = self._cleanups.pop(-1) + function(*args, **kwargs) + + def skipTest(self, reason): + """Skip this test.""" + raise SkipTest(reason) + + def fail(self, msg=None): + """Fail immediately, with the given message.""" + raise self.failureException(msg) + + def assertFalse(self, expr, msg=None): + """Check that the expression is false.""" + if expr: + msg = self._formatMessage(msg, "%s is not false" % safe_repr(expr)) + raise self.failureException(msg) + + def assertTrue(self, expr, msg=None): + """Check that the expression is true.""" + if not expr: + msg = self._formatMessage(msg, "%s is not true" % safe_repr(expr)) + raise self.failureException(msg) + + def _formatMessage(self, msg, standardMsg): + """Honour the longMessage attribute when generating failure messages. + If longMessage is False this means: + * Use only an explicit message if it is provided + * Otherwise use the standard message for the assert + + If longMessage is True: + * Use the standard message + * If an explicit message is provided, plus ' : ' and the explicit message + """ + if not self.longMessage: + return msg or standardMsg + if msg is None: + return standardMsg + try: + # don't switch to '{}' formatting in Python 2.X + # it changes the way unicode input is handled + return '%s : %s' % (standardMsg, msg) + except UnicodeDecodeError: + return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) + + + def assertRaises(self, excClass, callableObj=None, *args, **kwargs): + """Fail unless an exception of class excClass is raised + by callableObj when invoked with arguments args and keyword + arguments kwargs. If a different type of exception is + raised, it will not be caught, and the test case will be + deemed to have suffered an error, exactly as for an + unexpected exception. + + If called with callableObj omitted or None, will return a + context object used like this:: + + with self.assertRaises(SomeException): + do_something() + + The context manager keeps a reference to the exception as + the 'exception' attribute. This allows you to inspect the + exception after the assertion:: + + with self.assertRaises(SomeException) as cm: + do_something() + the_exception = cm.exception + self.assertEqual(the_exception.error_code, 3) + """ + context = _AssertRaisesContext(excClass, self) + if callableObj is None: + return context + with context: + callableObj(*args, **kwargs) + + def _getAssertEqualityFunc(self, first, second): + """Get a detailed comparison function for the types of the two args. + + Returns: A callable accepting (first, second, msg=None) that will + raise a failure exception if first != second with a useful human + readable error message for those types. + """ + # + # NOTE(gregory.p.smith): I considered isinstance(first, type(second)) + # and vice versa. I opted for the conservative approach in case + # subclasses are not intended to be compared in detail to their super + # class instances using a type equality func. This means testing + # subtypes won't automagically use the detailed comparison. Callers + # should use their type specific assertSpamEqual method to compare + # subclasses if the detailed comparison is desired and appropriate. + # See the discussion in http://bugs.python.org/issue2578. + # + if type(first) is type(second): + asserter = self._type_equality_funcs.get(type(first)) + if asserter is not None: + if isinstance(asserter, basestring): + asserter = getattr(self, asserter) + return asserter + + return self._baseAssertEqual + + def _baseAssertEqual(self, first, second, msg=None): + """The default assertEqual implementation, not type specific.""" + if not first == second: + standardMsg = '%s != %s' % (safe_repr(first), safe_repr(second)) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) + + def assertEqual(self, first, second, msg=None): + """Fail if the two objects are unequal as determined by the '==' + operator. + """ + assertion_func = self._getAssertEqualityFunc(first, second) + assertion_func(first, second, msg=msg) + + def assertNotEqual(self, first, second, msg=None): + """Fail if the two objects are equal as determined by the '!=' + operator. + """ + if not first != second: + msg = self._formatMessage(msg, '%s == %s' % (safe_repr(first), + safe_repr(second))) + raise self.failureException(msg) + + + def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None): + """Fail if the two objects are unequal as determined by their + difference rounded to the given number of decimal places + (default 7) and comparing to zero, or by comparing that the + between the two objects is more than the given delta. + + Note that decimal places (from zero) are usually not the same + as significant digits (measured from the most signficant digit). + + If the two objects compare equal then they will automatically + compare almost equal. + """ + if first == second: + # shortcut + return + if delta is not None and places is not None: + raise TypeError("specify delta or places not both") + + if delta is not None: + if abs(first - second) <= delta: + return + + standardMsg = '%s != %s within %s delta' % (safe_repr(first), + safe_repr(second), + safe_repr(delta)) + else: + if places is None: + places = 7 + + if round(abs(second-first), places) == 0: + return + + standardMsg = '%s != %s within %r places' % (safe_repr(first), + safe_repr(second), + places) + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) + + def assertNotAlmostEqual(self, first, second, places=None, msg=None, delta=None): + """Fail if the two objects are equal as determined by their + difference rounded to the given number of decimal places + (default 7) and comparing to zero, or by comparing that the + between the two objects is less than the given delta. + + Note that decimal places (from zero) are usually not the same + as significant digits (measured from the most signficant digit). + + Objects that are equal automatically fail. + """ + if delta is not None and places is not None: + raise TypeError("specify delta or places not both") + if delta is not None: + if not (first == second) and abs(first - second) > delta: + return + standardMsg = '%s == %s within %s delta' % (safe_repr(first), + safe_repr(second), + safe_repr(delta)) + else: + if places is None: + places = 7 + if not (first == second) and round(abs(second-first), places) != 0: + return + standardMsg = '%s == %s within %r places' % (safe_repr(first), + safe_repr(second), + places) + + msg = self._formatMessage(msg, standardMsg) + raise self.failureException(msg) + + # Synonyms for assertion methods + + # The plurals are undocumented. Keep them that way to discourage use. + # Do not add more. Do not remove. + # Going through a deprecation cycle on these would annoy many people. + assertEquals = assertEqual + assertNotEquals = assertNotEqual + assertAlmostEquals = assertAlmostEqual + assertNotAlmostEquals = assertNotAlmostEqual + assert_ = assertTrue + + # These fail* assertion method names are pending deprecation and will + # be a DeprecationWarning in 3.2; http://bugs.python.org/issue2578 + def _deprecate(original_func): + def deprecated_func(*args, **kwargs): + warnings.warn( + 'Please use {0} instead.'.format(original_func.__name__), + PendingDeprecationWarning, 2) + return original_func(*args, **kwargs) + return deprecated_func + + failUnlessEqual = _deprecate(assertEqual) + failIfEqual = _deprecate(assertNotEqual) + failUnlessAlmostEqual = _deprecate(assertAlmostEqual) + failIfAlmostEqual = _deprecate(assertNotAlmostEqual) + failUnless = _deprecate(assertTrue) + failUnlessRaises = _deprecate(assertRaises) + failIf = _deprecate(assertFalse) + + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): + """An equality assertion for ordered sequences (like lists and tuples). + + For the purposes of this function, a valid ordered sequence type is one + which can be indexed, has a length, and has an equality operator. + + Args: + seq1: The first sequence to compare. + seq2: The second sequence to compare. + seq_type: The expected datatype of the sequences, or None if no + datatype should be enforced. + msg: Optional message to use on failure instead of a list of + differences. + """ + if seq_type is not None: + seq_type_name = seq_type.__name__ + if not isinstance(seq1, seq_type): + raise self.failureException('First sequence is not a %s: %s' + % (seq_type_name, safe_repr(seq1))) + if not isinstance(seq2, seq_type): + raise self.failureException('Second sequence is not a %s: %s' + % (seq_type_name, safe_repr(seq2))) + else: + seq_type_name = "sequence" + + differing = None + try: + len1 = len(seq1) + except (TypeError, NotImplementedError): + differing = 'First %s has no length. Non-sequence?' % ( + seq_type_name) + + if differing is None: + try: + len2 = len(seq2) + except (TypeError, NotImplementedError): + differing = 'Second %s has no length. Non-sequence?' % ( + seq_type_name) + + if differing is None: + if seq1 == seq2: + return + + seq1_repr = safe_repr(seq1) + seq2_repr = safe_repr(seq2) + if len(seq1_repr) > 30: + seq1_repr = seq1_repr[:30] + '...' + if len(seq2_repr) > 30: + seq2_repr = seq2_repr[:30] + '...' + elements = (seq_type_name.capitalize(), seq1_repr, seq2_repr) + differing = '%ss differ: %s != %s\n' % elements + + for i in xrange(min(len1, len2)): + try: + item1 = seq1[i] + except (TypeError, IndexError, NotImplementedError): + differing += ('\nUnable to index element %d of first %s\n' % + (i, seq_type_name)) + break + + try: + item2 = seq2[i] + except (TypeError, IndexError, NotImplementedError): + differing += ('\nUnable to index element %d of second %s\n' % + (i, seq_type_name)) + break + + if item1 != item2: + differing += ('\nFirst differing element %d:\n%s\n%s\n' % + (i, item1, item2)) + break + else: + if (len1 == len2 and seq_type is None and + type(seq1) != type(seq2)): + # The sequences are the same, but have differing types. + return + + if len1 > len2: + differing += ('\nFirst %s contains %d additional ' + 'elements.\n' % (seq_type_name, len1 - len2)) + try: + differing += ('First extra element %d:\n%s\n' % + (len2, seq1[len2])) + except (TypeError, IndexError, NotImplementedError): + differing += ('Unable to index element %d ' + 'of first %s\n' % (len2, seq_type_name)) + elif len1 < len2: + differing += ('\nSecond %s contains %d additional ' + 'elements.\n' % (seq_type_name, len2 - len1)) + try: + differing += ('First extra element %d:\n%s\n' % + (len1, seq2[len1])) + except (TypeError, IndexError, NotImplementedError): + differing += ('Unable to index element %d ' + 'of second %s\n' % (len1, seq_type_name)) + standardMsg = differing + diffMsg = '\n' + '\n'.join( + difflib.ndiff(pprint.pformat(seq1).splitlines(), + pprint.pformat(seq2).splitlines())) + standardMsg = self._truncateMessage(standardMsg, diffMsg) + msg = self._formatMessage(msg, standardMsg) + self.fail(msg) + + def _truncateMessage(self, message, diff): + max_diff = self.maxDiff + if max_diff is None or len(diff) <= max_diff: + return message + diff + return message + (DIFF_OMITTED % len(diff)) + + def assertListEqual(self, list1, list2, msg=None): + """A list-specific equality assertion. + + Args: + list1: The first list to compare. + list2: The second list to compare. + msg: Optional message to use on failure instead of a list of + differences. + + """ + self.assertSequenceEqual(list1, list2, msg, seq_type=list) + + def assertTupleEqual(self, tuple1, tuple2, msg=None): + """A tuple-specific equality assertion. + + Args: + tuple1: The first tuple to compare. + tuple2: The second tuple to compare. + msg: Optional message to use on failure instead of a list of + differences. + """ + self.assertSequenceEqual(tuple1, tuple2, msg, seq_type=tuple) + + def assertSetEqual(self, set1, set2, msg=None): + """A set-specific equality assertion. + + Args: + set1: The first set to compare. + set2: The second set to compare. + msg: Optional message to use on failure instead of a list of + differences. + + assertSetEqual uses ducktyping to support different types of sets, and + is optimized for sets specifically (parameters must support a + difference method). + """ + try: + difference1 = set1.difference(set2) + except TypeError, e: + self.fail('invalid type when attempting set difference: %s' % e) + except AttributeError, e: + self.fail('first argument does not support set difference: %s' % e) + + try: + difference2 = set2.difference(set1) + except TypeError, e: + self.fail('invalid type when attempting set difference: %s' % e) + except AttributeError, e: + self.fail('second argument does not support set difference: %s' % e) + + if not (difference1 or difference2): + return + + lines = [] + if difference1: + lines.append('Items in the first set but not the second:') + for item in difference1: + lines.append(repr(item)) + if difference2: + lines.append('Items in the second set but not the first:') + for item in difference2: + lines.append(repr(item)) + + standardMsg = '\n'.join(lines) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIn(self, member, container, msg=None): + """Just like self.assertTrue(a in b), but with a nicer default message.""" + if member not in container: + standardMsg = '%s not found in %s' % (safe_repr(member), + safe_repr(container)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertNotIn(self, member, container, msg=None): + """Just like self.assertTrue(a not in b), but with a nicer default message.""" + if member in container: + standardMsg = '%s unexpectedly found in %s' % (safe_repr(member), + safe_repr(container)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIs(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is b), but with a nicer default message.""" + if expr1 is not expr2: + standardMsg = '%s is not %s' % (safe_repr(expr1), + safe_repr(expr2)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNot(self, expr1, expr2, msg=None): + """Just like self.assertTrue(a is not b), but with a nicer default message.""" + if expr1 is expr2: + standardMsg = 'unexpectedly identical: %s' % (safe_repr(expr1),) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertDictEqual(self, d1, d2, msg=None): + self.assertIsInstance(d1, dict, 'First argument is not a dictionary') + self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') + + if d1 != d2: + standardMsg = '%s != %s' % (safe_repr(d1, True), safe_repr(d2, True)) + diff = ('\n' + '\n'.join(difflib.ndiff( + pprint.pformat(d1).splitlines(), + pprint.pformat(d2).splitlines()))) + standardMsg = self._truncateMessage(standardMsg, diff) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertDictContainsSubset(self, expected, actual, msg=None): + """Checks whether actual is a superset of expected.""" + missing = [] + mismatched = [] + for key, value in expected.iteritems(): + if key not in actual: + missing.append(key) + elif value != actual[key]: + mismatched.append('%s, expected: %s, actual: %s' % + (safe_repr(key), safe_repr(value), + safe_repr(actual[key]))) + + if not (missing or mismatched): + return + + standardMsg = '' + if missing: + standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in + missing) + if mismatched: + if standardMsg: + standardMsg += '; ' + standardMsg += 'Mismatched values: %s' % ','.join(mismatched) + + self.fail(self._formatMessage(msg, standardMsg)) + + def assertItemsEqual(self, expected_seq, actual_seq, msg=None): + """An unordered sequence specific comparison. It asserts that + actual_seq and expected_seq have the same element counts. + Equivalent to:: + + self.assertEqual(Counter(iter(actual_seq)), + Counter(iter(expected_seq))) + + Asserts that each element has the same count in both sequences. + Example: + - [0, 1, 1] and [1, 0, 1] compare equal. + - [0, 0, 1] and [0, 1] compare unequal. + """ + first_seq, second_seq = list(expected_seq), list(actual_seq) + with warnings.catch_warnings(): + if sys.py3kwarning: + # Silence Py3k warning raised during the sorting + for _msg in ["(code|dict|type) inequality comparisons", + "builtin_function_or_method order comparisons", + "comparing unequal types"]: + warnings.filterwarnings("ignore", _msg, DeprecationWarning) + try: + first = collections.Counter(first_seq) + second = collections.Counter(second_seq) + except TypeError: + # Handle case with unhashable elements + differences = _count_diff_all_purpose(first_seq, second_seq) + else: + if first == second: + return + differences = _count_diff_hashable(first_seq, second_seq) + + if differences: + standardMsg = 'Element counts were not equal:\n' + lines = ['First has %d, Second has %d: %r' % diff for diff in differences] + diffMsg = '\n'.join(lines) + standardMsg = self._truncateMessage(standardMsg, diffMsg) + msg = self._formatMessage(msg, standardMsg) + self.fail(msg) + + def assertMultiLineEqual(self, first, second, msg=None): + """Assert that two multi-line strings are equal.""" + self.assertIsInstance(first, basestring, + 'First argument is not a string') + self.assertIsInstance(second, basestring, + 'Second argument is not a string') + + if first != second: + # don't use difflib if the strings are too long + if (len(first) > self._diffThreshold or + len(second) > self._diffThreshold): + self._baseAssertEqual(first, second, msg) + firstlines = first.splitlines(True) + secondlines = second.splitlines(True) + if len(firstlines) == 1 and first.strip('\r\n') == first: + firstlines = [first + '\n'] + secondlines = [second + '\n'] + standardMsg = '%s != %s' % (safe_repr(first, True), + safe_repr(second, True)) + diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) + standardMsg = self._truncateMessage(standardMsg, diff) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertLess(self, a, b, msg=None): + """Just like self.assertTrue(a < b), but with a nicer default message.""" + if not a < b: + standardMsg = '%s not less than %s' % (safe_repr(a), safe_repr(b)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertLessEqual(self, a, b, msg=None): + """Just like self.assertTrue(a <= b), but with a nicer default message.""" + if not a <= b: + standardMsg = '%s not less than or equal to %s' % (safe_repr(a), safe_repr(b)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertGreater(self, a, b, msg=None): + """Just like self.assertTrue(a > b), but with a nicer default message.""" + if not a > b: + standardMsg = '%s not greater than %s' % (safe_repr(a), safe_repr(b)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertGreaterEqual(self, a, b, msg=None): + """Just like self.assertTrue(a >= b), but with a nicer default message.""" + if not a >= b: + standardMsg = '%s not greater than or equal to %s' % (safe_repr(a), safe_repr(b)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNone(self, obj, msg=None): + """Same as self.assertTrue(obj is None), with a nicer default message.""" + if obj is not None: + standardMsg = '%s is not None' % (safe_repr(obj),) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNotNone(self, obj, msg=None): + """Included for symmetry with assertIsNone.""" + if obj is None: + standardMsg = 'unexpectedly None' + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsInstance(self, obj, cls, msg=None): + """Same as self.assertTrue(isinstance(obj, cls)), with a nicer + default message.""" + if not isinstance(obj, cls): + standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertNotIsInstance(self, obj, cls, msg=None): + """Included for symmetry with assertIsInstance.""" + if isinstance(obj, cls): + standardMsg = '%s is an instance of %r' % (safe_repr(obj), cls) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertRaisesRegexp(self, expected_exception, expected_regexp, + callable_obj=None, *args, **kwargs): + """Asserts that the message in a raised exception matches a regexp. + + Args: + expected_exception: Exception class expected to be raised. + expected_regexp: Regexp (re pattern object or string) expected + to be found in error message. + callable_obj: Function to be called. + args: Extra args. + kwargs: Extra kwargs. + """ + context = _AssertRaisesContext(expected_exception, self, expected_regexp) + if callable_obj is None: + return context + with context: + callable_obj(*args, **kwargs) + + def assertRegexpMatches(self, text, expected_regexp, msg=None): + """Fail the test unless the text matches the regular expression.""" + if isinstance(expected_regexp, basestring): + expected_regexp = re.compile(expected_regexp) + if not expected_regexp.search(text): + msg = msg or "Regexp didn't match" + msg = '%s: %r not found in %r' % (msg, expected_regexp.pattern, text) + raise self.failureException(msg) + + def assertNotRegexpMatches(self, text, unexpected_regexp, msg=None): + """Fail the test if the text matches the regular expression.""" + if isinstance(unexpected_regexp, basestring): + unexpected_regexp = re.compile(unexpected_regexp) + match = unexpected_regexp.search(text) + if match: + msg = msg or "Regexp matched" + msg = '%s: %r matches %r in %r' % (msg, + text[match.start():match.end()], + unexpected_regexp.pattern, + text) + raise self.failureException(msg) + + +class FunctionTestCase(TestCase): + """A test case that wraps a test function. + + This is useful for slipping pre-existing test functions into the + unittest framework. Optionally, set-up and tidy-up functions can be + supplied. As with TestCase, the tidy-up ('tearDown') function will + always be called if the set-up ('setUp') function ran successfully. + """ + + def __init__(self, testFunc, setUp=None, tearDown=None, description=None): + super(FunctionTestCase, self).__init__() + self._setUpFunc = setUp + self._tearDownFunc = tearDown + self._testFunc = testFunc + self._description = description + + def setUp(self): + if self._setUpFunc is not None: + self._setUpFunc() + + def tearDown(self): + if self._tearDownFunc is not None: + self._tearDownFunc() + + def runTest(self): + self._testFunc() + + def id(self): + return self._testFunc.__name__ + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + + return self._setUpFunc == other._setUpFunc and \ + self._tearDownFunc == other._tearDownFunc and \ + self._testFunc == other._testFunc and \ + self._description == other._description + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash((type(self), self._setUpFunc, self._tearDownFunc, + self._testFunc, self._description)) + + def __str__(self): + return "%s (%s)" % (strclass(self.__class__), + self._testFunc.__name__) + + def __repr__(self): + return "<%s tec=%s>" % (strclass(self.__class__), + self._testFunc) + + def shortDescription(self): + if self._description is not None: + return self._description + doc = self._testFunc.__doc__ + return doc and doc.split("\n")[0].strip() or None diff --git a/src/main/resources/PythonLibs/unittest/loader.py b/src/main/resources/PythonLibs/unittest/loader.py new file mode 100644 index 0000000000000000000000000000000000000000..1288d2d2118552453c38da3bb360202e7229cbdb --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/loader.py @@ -0,0 +1,316 @@ +"""Loading unittests.""" + +import os +import re +import sys +import traceback +import types + +from functools import cmp_to_key as _CmpToKey +from fnmatch import fnmatch + +from . import case, suite + +__unittest = True + +# what about .pyc or .pyo (etc) +# we would need to avoid loading the same tests multiple times +# from '.py', '.pyc' *and* '.pyo' +VALID_MODULE_NAME = re.compile(r'[_a-z]\w*\.py$', re.IGNORECASE) + + +def _make_failed_import_test(name, suiteClass): + message = 'Failed to import test module: %s\n%s' % (name, traceback.format_exc()) + return _make_failed_test('ModuleImportFailure', name, ImportError(message), + suiteClass) + +def _make_failed_load_tests(name, exception, suiteClass): + return _make_failed_test('LoadTestsFailure', name, exception, suiteClass) + +def _make_failed_test(classname, methodname, exception, suiteClass): + def testFailure(self): + raise exception + attrs = {methodname: testFailure} + TestClass = type(classname, (case.TestCase,), attrs) + return suiteClass((TestClass(methodname),)) + + +class TestLoader(object): + """ + This class is responsible for loading tests according to various criteria + and returning them wrapped in a TestSuite + """ + testMethodPrefix = 'test' + sortTestMethodsUsing = cmp + suiteClass = suite.TestSuite + _top_level_dir = None + + def loadTestsFromTestCase(self, testCaseClass): + """Return a suite of all tests cases contained in testCaseClass""" + if issubclass(testCaseClass, suite.TestSuite): + raise TypeError("Test cases should not be derived from TestSuite." \ + " Maybe you meant to derive from TestCase?") + testCaseNames = self.getTestCaseNames(testCaseClass) + if not testCaseNames and hasattr(testCaseClass, 'runTest'): + testCaseNames = ['runTest'] + loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) + return loaded_suite + + def loadTestsFromModule(self, module, use_load_tests=True): + """Return a suite of all tests cases contained in the given module""" + tests = [] + for name in dir(module): + obj = getattr(module, name) + if isinstance(obj, type) and issubclass(obj, case.TestCase): + tests.append(self.loadTestsFromTestCase(obj)) + + load_tests = getattr(module, 'load_tests', None) + tests = self.suiteClass(tests) + if use_load_tests and load_tests is not None: + try: + return load_tests(self, tests, None) + except Exception, e: + return _make_failed_load_tests(module.__name__, e, + self.suiteClass) + return tests + + def loadTestsFromName(self, name, module=None): + """Return a suite of all tests cases given a string specifier. + + The name may resolve either to a module, a test case class, a + test method within a test case class, or a callable object which + returns a TestCase or TestSuite instance. + + The method optionally resolves the names relative to a given module. + """ + parts = name.split('.') + if module is None: + parts_copy = parts[:] + while parts_copy: + try: + module = __import__('.'.join(parts_copy)) + break + except ImportError: + del parts_copy[-1] + if not parts_copy: + raise + parts = parts[1:] + obj = module + for part in parts: + parent, obj = obj, getattr(obj, part) + + if isinstance(obj, types.ModuleType): + return self.loadTestsFromModule(obj) + elif isinstance(obj, type) and issubclass(obj, case.TestCase): + return self.loadTestsFromTestCase(obj) + elif (isinstance(obj, types.UnboundMethodType) and + isinstance(parent, type) and + issubclass(parent, case.TestCase)): + return self.suiteClass([parent(obj.__name__)]) + elif isinstance(obj, suite.TestSuite): + return obj + elif hasattr(obj, '__call__'): + test = obj() + if isinstance(test, suite.TestSuite): + return test + elif isinstance(test, case.TestCase): + return self.suiteClass([test]) + else: + raise TypeError("calling %s returned %s, not a test" % + (obj, test)) + else: + raise TypeError("don't know how to make test from: %s" % obj) + + def loadTestsFromNames(self, names, module=None): + """Return a suite of all tests cases found using the given sequence + of string specifiers. See 'loadTestsFromName()'. + """ + suites = [self.loadTestsFromName(name, module) for name in names] + return self.suiteClass(suites) + + def getTestCaseNames(self, testCaseClass): + """Return a sorted sequence of method names found within testCaseClass + """ + def isTestMethod(attrname, testCaseClass=testCaseClass, + prefix=self.testMethodPrefix): + return attrname.startswith(prefix) and \ + hasattr(getattr(testCaseClass, attrname), '__call__') + testFnNames = filter(isTestMethod, dir(testCaseClass)) + if self.sortTestMethodsUsing: + testFnNames.sort(key=_CmpToKey(self.sortTestMethodsUsing)) + return testFnNames + + def discover(self, start_dir, pattern='test*.py', top_level_dir=None): + """Find and return all test modules from the specified start + directory, recursing into subdirectories to find them. Only test files + that match the pattern will be loaded. (Using shell style pattern + matching.) + + All test modules must be importable from the top level of the project. + If the start directory is not the top level directory then the top + level directory must be specified separately. + + If a test package name (directory with '__init__.py') matches the + pattern then the package will be checked for a 'load_tests' function. If + this exists then it will be called with loader, tests, pattern. + + If load_tests exists then discovery does *not* recurse into the package, + load_tests is responsible for loading all tests in the package. + + The pattern is deliberately not stored as a loader attribute so that + packages can continue discovery themselves. top_level_dir is stored so + load_tests does not need to pass this argument in to loader.discover(). + """ + set_implicit_top = False + if top_level_dir is None and self._top_level_dir is not None: + # make top_level_dir optional if called from load_tests in a package + top_level_dir = self._top_level_dir + elif top_level_dir is None: + set_implicit_top = True + top_level_dir = start_dir + + top_level_dir = os.path.abspath(top_level_dir) + + if not top_level_dir in sys.path: + # all test modules must be importable from the top level directory + # should we *unconditionally* put the start directory in first + # in sys.path to minimise likelihood of conflicts between installed + # modules and development versions? + sys.path.insert(0, top_level_dir) + self._top_level_dir = top_level_dir + + is_not_importable = False + if os.path.isdir(os.path.abspath(start_dir)): + start_dir = os.path.abspath(start_dir) + if start_dir != top_level_dir: + is_not_importable = not os.path.isfile(os.path.join(start_dir, '__init__.py')) + else: + # support for discovery from dotted module names + try: + __import__(start_dir) + except ImportError: + is_not_importable = True + else: + the_module = sys.modules[start_dir] + top_part = start_dir.split('.')[0] + start_dir = os.path.abspath(os.path.dirname((the_module.__file__))) + if set_implicit_top: + self._top_level_dir = self._get_directory_containing_module(top_part) + sys.path.remove(top_level_dir) + + if is_not_importable: + raise ImportError('Start directory is not importable: %r' % start_dir) + + tests = list(self._find_tests(start_dir, pattern)) + return self.suiteClass(tests) + + def _get_directory_containing_module(self, module_name): + module = sys.modules[module_name] + full_path = os.path.abspath(module.__file__) + + if os.path.basename(full_path).lower().startswith('__init__.py'): + return os.path.dirname(os.path.dirname(full_path)) + else: + # here we have been given a module rather than a package - so + # all we can do is search the *same* directory the module is in + # should an exception be raised instead + return os.path.dirname(full_path) + + def _get_name_from_path(self, path): + path = os.path.splitext(os.path.normpath(path))[0] + + _relpath = os.path.relpath(path, self._top_level_dir) + assert not os.path.isabs(_relpath), "Path must be within the project" + assert not _relpath.startswith('..'), "Path must be within the project" + + name = _relpath.replace(os.path.sep, '.') + return name + + def _get_module_from_name(self, name): + __import__(name) + return sys.modules[name] + + def _match_path(self, path, full_path, pattern): + # override this method to use alternative matching strategy + return fnmatch(path, pattern) + + def _find_tests(self, start_dir, pattern): + """Used by discovery. Yields test suites it loads.""" + paths = os.listdir(start_dir) + + for path in paths: + full_path = os.path.join(start_dir, path) + if os.path.isfile(full_path): + if not VALID_MODULE_NAME.match(path): + # valid Python identifiers only + continue + if not self._match_path(path, full_path, pattern): + continue + # if the test file matches, load it + name = self._get_name_from_path(full_path) + try: + module = self._get_module_from_name(name) + except: + yield _make_failed_import_test(name, self.suiteClass) + else: + mod_file = os.path.abspath(getattr(module, '__file__', full_path)) + realpath = os.path.splitext(mod_file)[0] + if realpath.lower().endswith('$py'): # This is needed for $py.class + realpath = realpath[:-3] + fullpath_noext = os.path.splitext(full_path)[0] + if realpath.lower() != fullpath_noext.lower(): + module_dir = os.path.dirname(realpath) + mod_name = os.path.splitext(os.path.basename(full_path))[0] + expected_dir = os.path.dirname(full_path) + msg = ("%r module incorrectly imported from %r. Expected %r. " + "Is this module globally installed?") + raise ImportError(msg % (mod_name, module_dir, expected_dir)) + yield self.loadTestsFromModule(module) + elif os.path.isdir(full_path): + if not os.path.isfile(os.path.join(full_path, '__init__.py')): + continue + + load_tests = None + tests = None + if fnmatch(path, pattern): + # only check load_tests if the package directory itself matches the filter + name = self._get_name_from_path(full_path) + package = self._get_module_from_name(name) + load_tests = getattr(package, 'load_tests', None) + tests = self.loadTestsFromModule(package, use_load_tests=False) + + if load_tests is None: + if tests is not None: + # tests loaded from package file + yield tests + # recurse into the package + for test in self._find_tests(full_path, pattern): + yield test + else: + try: + yield load_tests(self, tests, pattern) + except Exception, e: + yield _make_failed_load_tests(package.__name__, e, + self.suiteClass) + +defaultTestLoader = TestLoader() + + +def _makeLoader(prefix, sortUsing, suiteClass=None): + loader = TestLoader() + loader.sortTestMethodsUsing = sortUsing + loader.testMethodPrefix = prefix + if suiteClass: + loader.suiteClass = suiteClass + return loader + +def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp): + return _makeLoader(prefix, sortUsing).getTestCaseNames(testCaseClass) + +def makeSuite(testCaseClass, prefix='test', sortUsing=cmp, + suiteClass=suite.TestSuite): + return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromTestCase(testCaseClass) + +def findTestCases(module, prefix='test', sortUsing=cmp, + suiteClass=suite.TestSuite): + return _makeLoader(prefix, sortUsing, suiteClass).loadTestsFromModule(module) diff --git a/src/main/resources/PythonLibs/unittest/main.py b/src/main/resources/PythonLibs/unittest/main.py new file mode 100644 index 0000000000000000000000000000000000000000..b25367992de8ac7e004c906d9b6a104f83dffb80 --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/main.py @@ -0,0 +1,236 @@ +"""Unittest main program""" + +import sys +import os +import types + +from . import loader, runner +from .signals import installHandler + +__unittest = True + +FAILFAST = " -f, --failfast Stop on first failure\n" +CATCHBREAK = " -c, --catch Catch control-C and display results\n" +BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n" + +USAGE_AS_MAIN = """\ +Usage: %(progName)s [options] [tests] + +Options: + -h, --help Show this message + -v, --verbose Verbose output + -q, --quiet Minimal output +%(failfast)s%(catchbreak)s%(buffer)s +Examples: + %(progName)s test_module - run tests from test_module + %(progName)s module.TestClass - run tests from module.TestClass + %(progName)s module.Class.test_method - run specified test method + +[tests] can be a list of any number of test modules, classes and test +methods. + +Alternative Usage: %(progName)s discover [options] + +Options: + -v, --verbose Verbose output +%(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default) + -p pattern Pattern to match test files ('test*.py' default) + -t directory Top level directory of project (default to + start directory) + +For test discovery all test modules must be importable from the top +level directory of the project. +""" + +USAGE_FROM_MODULE = """\ +Usage: %(progName)s [options] [test] [...] + +Options: + -h, --help Show this message + -v, --verbose Verbose output + -q, --quiet Minimal output +%(failfast)s%(catchbreak)s%(buffer)s +Examples: + %(progName)s - run default set of tests + %(progName)s MyTestSuite - run suite 'MyTestSuite' + %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething + %(progName)s MyTestCase - run all 'test*' test methods + in MyTestCase +""" + + + +class TestProgram(object): + """A command-line program that runs a set of tests; this is primarily + for making test modules conveniently executable. + """ + USAGE = USAGE_FROM_MODULE + + # defaults for testing + failfast = catchbreak = buffer = progName = None + + def __init__(self, module='__main__', defaultTest=None, argv=None, + testRunner=None, testLoader=loader.defaultTestLoader, + exit=True, verbosity=1, failfast=None, catchbreak=None, + buffer=None): + if isinstance(module, basestring): + self.module = __import__(module) + for part in module.split('.')[1:]: + self.module = getattr(self.module, part) + else: + self.module = module + if argv is None: + argv = sys.argv + + self.exit = exit + self.failfast = failfast + self.catchbreak = catchbreak + self.verbosity = verbosity + self.buffer = buffer + self.defaultTest = defaultTest + self.testRunner = testRunner + self.testLoader = testLoader + self.progName = os.path.basename(argv[0]) + self.parseArgs(argv) + self.runTests() + + def usageExit(self, msg=None): + if msg: + print msg + usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '', + 'buffer': ''} + if self.failfast != False: + usage['failfast'] = FAILFAST + if self.catchbreak != False: + usage['catchbreak'] = CATCHBREAK + if self.buffer != False: + usage['buffer'] = BUFFEROUTPUT + print self.USAGE % usage + sys.exit(2) + + def parseArgs(self, argv): + if len(argv) > 1 and argv[1].lower() == 'discover': + self._do_discovery(argv[2:]) + return + + import getopt + long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer'] + try: + options, args = getopt.getopt(argv[1:], 'hHvqfcb', long_opts) + for opt, value in options: + if opt in ('-h','-H','--help'): + self.usageExit() + if opt in ('-q','--quiet'): + self.verbosity = 0 + if opt in ('-v','--verbose'): + self.verbosity = 2 + if opt in ('-f','--failfast'): + if self.failfast is None: + self.failfast = True + # Should this raise an exception if -f is not valid? + if opt in ('-c','--catch'): + if self.catchbreak is None: + self.catchbreak = True + # Should this raise an exception if -c is not valid? + if opt in ('-b','--buffer'): + if self.buffer is None: + self.buffer = True + # Should this raise an exception if -b is not valid? + if len(args) == 0 and self.defaultTest is None: + # createTests will load tests from self.module + self.testNames = None + elif len(args) > 0: + self.testNames = args + if __name__ == '__main__': + # to support python -m unittest ... + self.module = None + else: + self.testNames = (self.defaultTest,) + self.createTests() + except getopt.error, msg: + self.usageExit(msg) + + def createTests(self): + if self.testNames is None: + self.test = self.testLoader.loadTestsFromModule(self.module) + else: + self.test = self.testLoader.loadTestsFromNames(self.testNames, + self.module) + + def _do_discovery(self, argv, Loader=None): + if Loader is None: + Loader = lambda: self.testLoader + + # handle command line args for test discovery + self.progName = '%s discover' % self.progName + import optparse + parser = optparse.OptionParser() + parser.prog = self.progName + parser.add_option('-v', '--verbose', dest='verbose', default=False, + help='Verbose output', action='store_true') + if self.failfast != False: + parser.add_option('-f', '--failfast', dest='failfast', default=False, + help='Stop on first fail or error', + action='store_true') + if self.catchbreak != False: + parser.add_option('-c', '--catch', dest='catchbreak', default=False, + help='Catch ctrl-C and display results so far', + action='store_true') + if self.buffer != False: + parser.add_option('-b', '--buffer', dest='buffer', default=False, + help='Buffer stdout and stderr during tests', + action='store_true') + parser.add_option('-s', '--start-directory', dest='start', default='.', + help="Directory to start discovery ('.' default)") + parser.add_option('-p', '--pattern', dest='pattern', default='test*.py', + help="Pattern to match tests ('test*.py' default)") + parser.add_option('-t', '--top-level-directory', dest='top', default=None, + help='Top level directory of project (defaults to start directory)') + + options, args = parser.parse_args(argv) + if len(args) > 3: + self.usageExit() + + for name, value in zip(('start', 'pattern', 'top'), args): + setattr(options, name, value) + + # only set options from the parsing here + # if they weren't set explicitly in the constructor + if self.failfast is None: + self.failfast = options.failfast + if self.catchbreak is None: + self.catchbreak = options.catchbreak + if self.buffer is None: + self.buffer = options.buffer + + if options.verbose: + self.verbosity = 2 + + start_dir = options.start + pattern = options.pattern + top_level_dir = options.top + + loader = Loader() + self.test = loader.discover(start_dir, pattern, top_level_dir) + + def runTests(self): + if self.catchbreak: + installHandler() + if self.testRunner is None: + self.testRunner = runner.TextTestRunner + if isinstance(self.testRunner, (type, types.ClassType)): + try: + testRunner = self.testRunner(verbosity=self.verbosity, + failfast=self.failfast, + buffer=self.buffer) + except TypeError: + # didn't accept the verbosity, buffer or failfast arguments + testRunner = self.testRunner() + else: + # it is assumed to be a TestRunner instance + testRunner = self.testRunner + self.result = testRunner.run(self.test) + if self.exit: + sys.exit(not self.result.wasSuccessful()) + +main = TestProgram diff --git a/src/main/resources/PythonLibs/unittest/result.py b/src/main/resources/PythonLibs/unittest/result.py new file mode 100644 index 0000000000000000000000000000000000000000..2cc17d71c853541cfc491cf8b60181e587d92fee --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/result.py @@ -0,0 +1,193 @@ +"""Test result object""" + +import os +import sys +import traceback + +from StringIO import StringIO + +from . import util +from functools import wraps + +__unittest = True + +def failfast(method): + @wraps(method) + def inner(self, *args, **kw): + if getattr(self, 'failfast', False): + self.stop() + return method(self, *args, **kw) + return inner + +STDOUT_LINE = '\nStdout:\n%s' +STDERR_LINE = '\nStderr:\n%s' + + +class TestResult(object): + """Holder for test result information. + + Test results are automatically managed by the TestCase and TestSuite + classes, and do not need to be explicitly manipulated by writers of tests. + + Each instance holds the total number of tests run, and collections of + failures and errors that occurred among those test runs. The collections + contain tuples of (testcase, exceptioninfo), where exceptioninfo is the + formatted traceback of the error that occurred. + """ + _previousTestClass = None + _testRunEntered = False + _moduleSetUpFailed = False + def __init__(self, stream=None, descriptions=None, verbosity=None): + self.failfast = False + self.failures = [] + self.errors = [] + self.testsRun = 0 + self.skipped = [] + self.expectedFailures = [] + self.unexpectedSuccesses = [] + self.shouldStop = False + self.buffer = False + self._stdout_buffer = None + self._stderr_buffer = None + self._original_stdout = sys.stdout + self._original_stderr = sys.stderr + self._mirrorOutput = False + + def printErrors(self): + "Called by TestRunner after test run" + + def startTest(self, test): + "Called when the given test is about to be run" + self.testsRun += 1 + self._mirrorOutput = False + self._setupStdout() + + def _setupStdout(self): + if self.buffer: + if self._stderr_buffer is None: + self._stderr_buffer = StringIO() + self._stdout_buffer = StringIO() + sys.stdout = self._stdout_buffer + sys.stderr = self._stderr_buffer + + def startTestRun(self): + """Called once before any tests are executed. + + See startTest for a method called before each test. + """ + + def stopTest(self, test): + """Called when the given test has been run""" + self._restoreStdout() + self._mirrorOutput = False + + def _restoreStdout(self): + if self.buffer: + if self._mirrorOutput: + output = sys.stdout.getvalue() + error = sys.stderr.getvalue() + if output: + if not output.endswith('\n'): + output += '\n' + self._original_stdout.write(STDOUT_LINE % output) + if error: + if not error.endswith('\n'): + error += '\n' + self._original_stderr.write(STDERR_LINE % error) + + sys.stdout = self._original_stdout + sys.stderr = self._original_stderr + self._stdout_buffer.seek(0) + self._stdout_buffer.truncate() + self._stderr_buffer.seek(0) + self._stderr_buffer.truncate() + + def stopTestRun(self): + """Called once after all tests are executed. + + See stopTest for a method called after each test. + """ + + @failfast + def addError(self, test, err): + """Called when an error has occurred. 'err' is a tuple of values as + returned by sys.exc_info(). + """ + self.errors.append((test, self._exc_info_to_string(err, test))) + self._mirrorOutput = True + + @failfast + def addFailure(self, test, err): + """Called when an error has occurred. 'err' is a tuple of values as + returned by sys.exc_info().""" + self.failures.append((test, self._exc_info_to_string(err, test))) + self._mirrorOutput = True + + def addSuccess(self, test): + "Called when a test has completed successfully" + pass + + def addSkip(self, test, reason): + """Called when a test is skipped.""" + self.skipped.append((test, reason)) + + def addExpectedFailure(self, test, err): + """Called when an expected failure/error occured.""" + self.expectedFailures.append( + (test, self._exc_info_to_string(err, test))) + + @failfast + def addUnexpectedSuccess(self, test): + """Called when a test was expected to fail, but succeed.""" + self.unexpectedSuccesses.append(test) + + def wasSuccessful(self): + "Tells whether or not this result was a success" + return len(self.failures) == len(self.errors) == 0 + + def stop(self): + "Indicates that the tests should be aborted" + self.shouldStop = True + + def _exc_info_to_string(self, err, test): + """Converts a sys.exc_info()-style tuple of values into a string.""" + exctype, value, tb = err + # Skip test runner traceback levels + while tb and self._is_relevant_tb_level(tb): + tb = tb.tb_next + + if exctype is test.failureException: + # Skip assert*() traceback levels + length = self._count_relevant_tb_levels(tb) + msgLines = traceback.format_exception(exctype, value, tb, length) + else: + msgLines = traceback.format_exception(exctype, value, tb) + + if self.buffer: + output = sys.stdout.getvalue() + error = sys.stderr.getvalue() + if output: + if not output.endswith('\n'): + output += '\n' + msgLines.append(STDOUT_LINE % output) + if error: + if not error.endswith('\n'): + error += '\n' + msgLines.append(STDERR_LINE % error) + return ''.join(msgLines) + + + def _is_relevant_tb_level(self, tb): + return '__unittest' in tb.tb_frame.f_globals + + def _count_relevant_tb_levels(self, tb): + length = 0 + while tb and not self._is_relevant_tb_level(tb): + length += 1 + tb = tb.tb_next + return length + + def __repr__(self): + return ("<%s run=%i errors=%i failures=%i>" % + (util.strclass(self.__class__), self.testsRun, len(self.errors), + len(self.failures))) diff --git a/src/main/resources/PythonLibs/unittest/runner.py b/src/main/resources/PythonLibs/unittest/runner.py new file mode 100644 index 0000000000000000000000000000000000000000..7632fe9823ce51242cda0f17f885b149183ffc81 --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/runner.py @@ -0,0 +1,196 @@ +"""Running tests""" + +import sys +import time + +from . import result +from .signals import registerResult + +__unittest = True + + +class _WritelnDecorator(object): + """Used to decorate file-like objects with a handy 'writeln' method""" + def __init__(self,stream): + self.stream = stream + + def __getattr__(self, attr): + if attr in ('stream', '__getstate__'): + raise AttributeError(attr) + return getattr(self.stream,attr) + + def writeln(self, arg=None): + if arg: + self.write(arg) + self.write('\n') # text-mode streams translate to \r\n if needed + + +class TextTestResult(result.TestResult): + """A test result class that can print formatted text results to a stream. + + Used by TextTestRunner. + """ + separator1 = '=' * 70 + separator2 = '-' * 70 + + def __init__(self, stream, descriptions, verbosity): + super(TextTestResult, self).__init__(stream, descriptions, verbosity) + self.stream = stream + self.showAll = verbosity > 1 + self.dots = verbosity == 1 + self.descriptions = descriptions + + def getDescription(self, test): + doc_first_line = test.shortDescription() + if self.descriptions and doc_first_line: + return '\n'.join((str(test), doc_first_line)) + else: + return str(test) + + def startTest(self, test): + super(TextTestResult, self).startTest(test) + if self.showAll: + self.stream.write(self.getDescription(test)) + self.stream.write(" ... ") + self.stream.flush() + + def addSuccess(self, test): + super(TextTestResult, self).addSuccess(test) + if self.showAll: + self.stream.writeln("ok") + elif self.dots: + self.stream.write('.') + self.stream.flush() + + def addError(self, test, err): + super(TextTestResult, self).addError(test, err) + if self.showAll: + self.stream.writeln("ERROR") + elif self.dots: + self.stream.write('E') + self.stream.flush() + + def addFailure(self, test, err): + super(TextTestResult, self).addFailure(test, err) + if self.showAll: + self.stream.writeln("FAIL") + elif self.dots: + self.stream.write('F') + self.stream.flush() + + def addSkip(self, test, reason): + super(TextTestResult, self).addSkip(test, reason) + if self.showAll: + self.stream.writeln("skipped {0!r}".format(reason)) + elif self.dots: + self.stream.write("s") + self.stream.flush() + + def addExpectedFailure(self, test, err): + super(TextTestResult, self).addExpectedFailure(test, err) + if self.showAll: + self.stream.writeln("expected failure") + elif self.dots: + self.stream.write("x") + self.stream.flush() + + def addUnexpectedSuccess(self, test): + super(TextTestResult, self).addUnexpectedSuccess(test) + if self.showAll: + self.stream.writeln("unexpected success") + elif self.dots: + self.stream.write("u") + self.stream.flush() + + def printErrors(self): + if self.dots or self.showAll: + self.stream.writeln() + self.printErrorList('ERROR', self.errors) + self.printErrorList('FAIL', self.failures) + + def printErrorList(self, flavour, errors): + for test, err in errors: + self.stream.writeln(self.separator1) + self.stream.writeln("%s: %s" % (flavour,self.getDescription(test))) + self.stream.writeln(self.separator2) + self.stream.writeln("%s" % err) + + +class TextTestRunner(object): + """A test runner class that displays results in textual form. + + It prints out the names of tests as they are run, errors as they + occur, and a summary of the results at the end of the test run. + """ + resultclass = TextTestResult + + def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, + failfast=False, buffer=False, resultclass=None): + self.stream = _WritelnDecorator(stream) + self.descriptions = descriptions + self.verbosity = verbosity + self.failfast = failfast + self.buffer = buffer + if resultclass is not None: + self.resultclass = resultclass + + def _makeResult(self): + return self.resultclass(self.stream, self.descriptions, self.verbosity) + + def run(self, test): + "Run the given test case or test suite." + result = self._makeResult() + registerResult(result) + result.failfast = self.failfast + result.buffer = self.buffer + startTime = time.time() + startTestRun = getattr(result, 'startTestRun', None) + if startTestRun is not None: + startTestRun() + try: + test(result) + finally: + stopTestRun = getattr(result, 'stopTestRun', None) + if stopTestRun is not None: + stopTestRun() + stopTime = time.time() + timeTaken = stopTime - startTime + result.printErrors() + if hasattr(result, 'separator2'): + self.stream.writeln(result.separator2) + run = result.testsRun + self.stream.writeln("Ran %d test%s in %.3fs" % + (run, run != 1 and "s" or "", timeTaken)) + self.stream.writeln() + + expectedFails = unexpectedSuccesses = skipped = 0 + try: + results = map(len, (result.expectedFailures, + result.unexpectedSuccesses, + result.skipped)) + except AttributeError: + pass + else: + expectedFails, unexpectedSuccesses, skipped = results + + infos = [] + if not result.wasSuccessful(): + self.stream.write("FAILED") + failed, errored = map(len, (result.failures, result.errors)) + if failed: + infos.append("failures=%d" % failed) + if errored: + infos.append("errors=%d" % errored) + else: + self.stream.write("OK") + if skipped: + infos.append("skipped=%d" % skipped) + if expectedFails: + infos.append("expected failures=%d" % expectedFails) + if unexpectedSuccesses: + infos.append("unexpected successes=%d" % unexpectedSuccesses) + if infos: + self.stream.writeln(" (%s)" % (", ".join(infos),)) + else: + self.stream.write("\n") + return result diff --git a/src/main/resources/PythonLibs/unittest/signals.py b/src/main/resources/PythonLibs/unittest/signals.py new file mode 100644 index 0000000000000000000000000000000000000000..e6a5fc524397121e170bd5a888957374b91ba946 --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/signals.py @@ -0,0 +1,71 @@ +import signal +import weakref + +from functools import wraps + +__unittest = True + + +class _InterruptHandler(object): + def __init__(self, default_handler): + self.called = False + self.original_handler = default_handler + if isinstance(default_handler, int): + if default_handler == signal.SIG_DFL: + # Pretend it's signal.default_int_handler instead. + default_handler = signal.default_int_handler + elif default_handler == signal.SIG_IGN: + # Not quite the same thing as SIG_IGN, but the closest we + # can make it: do nothing. + def default_handler(unused_signum, unused_frame): + pass + else: + raise TypeError("expected SIGINT signal handler to be " + "signal.SIG_IGN, signal.SIG_DFL, or a " + "callable object") + self.default_handler = default_handler + + def __call__(self, signum, frame): + installed_handler = signal.getsignal(signal.SIGINT) + if installed_handler is not self: + # if we aren't the installed handler, then delegate immediately + # to the default handler + self.default_handler(signum, frame) + + if self.called: + self.default_handler(signum, frame) + self.called = True + for result in _results.keys(): + result.stop() + +_results = weakref.WeakKeyDictionary() +def registerResult(result): + _results[result] = 1 + +def removeResult(result): + return bool(_results.pop(result, None)) + +_interrupt_handler = None +def installHandler(): + global _interrupt_handler + if _interrupt_handler is None: + default_handler = signal.getsignal(signal.SIGINT) + _interrupt_handler = _InterruptHandler(default_handler) + signal.signal(signal.SIGINT, _interrupt_handler) + + +def removeHandler(method=None): + if method is not None: + @wraps(method) + def inner(*args, **kwargs): + initial = signal.getsignal(signal.SIGINT) + removeHandler() + try: + return method(*args, **kwargs) + finally: + signal.signal(signal.SIGINT, initial) + return inner + + global _interrupt_handler + if _interrupt_handler is not None: + signal.signal(signal.SIGINT, _interrupt_handler.original_handler) diff --git a/src/main/resources/PythonLibs/unittest/suite.py b/src/main/resources/PythonLibs/unittest/suite.py new file mode 100644 index 0000000000000000000000000000000000000000..633af5cb08552b3a2c4ed4326658d653b04f9718 --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/suite.py @@ -0,0 +1,303 @@ +"""TestSuite""" + +import sys + +from . import case +from . import util + +__unittest = True + + +def _call_if_exists(parent, attr): + func = getattr(parent, attr, lambda: None) + func() + + +class BaseTestSuite(object): + """A simple test suite that doesn't provide class or module shared fixtures. + """ + def __init__(self, tests=()): + self._tests = [] + self.addTests(tests) + + def __repr__(self): + return "<%s tests=%s>" % (util.strclass(self.__class__), list(self)) + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return list(self) == list(other) + + def __ne__(self, other): + return not self == other + + # Can't guarantee hash invariant, so flag as unhashable + __hash__ = None + + def __iter__(self): + return iter(self._tests) + + def countTestCases(self): + cases = 0 + for test in self: + cases += test.countTestCases() + return cases + + def addTest(self, test): + # sanity checks + if not hasattr(test, '__call__'): + raise TypeError("{} is not callable".format(repr(test))) + if isinstance(test, type) and issubclass(test, + (case.TestCase, TestSuite)): + raise TypeError("TestCases and TestSuites must be instantiated " + "before passing them to addTest()") + self._tests.append(test) + + def addTests(self, tests): + if isinstance(tests, basestring): + raise TypeError("tests must be an iterable of tests, not a string") + for test in tests: + self.addTest(test) + + def run(self, result): + for test in self: + if result.shouldStop: + break + test(result) + return result + + def __call__(self, *args, **kwds): + return self.run(*args, **kwds) + + def debug(self): + """Run the tests without collecting errors in a TestResult""" + for test in self: + test.debug() + + +class TestSuite(BaseTestSuite): + """A test suite is a composite test consisting of a number of TestCases. + + For use, create an instance of TestSuite, then add test case instances. + When all tests have been added, the suite can be passed to a test + runner, such as TextTestRunner. It will run the individual test cases + in the order in which they were added, aggregating the results. When + subclassing, do not forget to call the base class constructor. + """ + + def run(self, result, debug=False): + topLevel = False + if getattr(result, '_testRunEntered', False) is False: + result._testRunEntered = topLevel = True + + for test in self: + if result.shouldStop: + break + + if _isnotsuite(test): + self._tearDownPreviousClass(test, result) + self._handleModuleFixture(test, result) + self._handleClassSetUp(test, result) + result._previousTestClass = test.__class__ + + if (getattr(test.__class__, '_classSetupFailed', False) or + getattr(result, '_moduleSetUpFailed', False)): + continue + + if not debug: + test(result) + else: + test.debug() + + if topLevel: + self._tearDownPreviousClass(None, result) + self._handleModuleTearDown(result) + result._testRunEntered = False + return result + + def debug(self): + """Run the tests without collecting errors in a TestResult""" + debug = _DebugResult() + self.run(debug, True) + + ################################ + + def _handleClassSetUp(self, test, result): + previousClass = getattr(result, '_previousTestClass', None) + currentClass = test.__class__ + if currentClass == previousClass: + return + if result._moduleSetUpFailed: + return + if getattr(currentClass, "__unittest_skip__", False): + return + + try: + currentClass._classSetupFailed = False + except TypeError: + # test may actually be a function + # so its class will be a builtin-type + pass + + setUpClass = getattr(currentClass, 'setUpClass', None) + if setUpClass is not None: + _call_if_exists(result, '_setupStdout') + try: + setUpClass() + except Exception as e: + if isinstance(result, _DebugResult): + raise + currentClass._classSetupFailed = True + className = util.strclass(currentClass) + errorName = 'setUpClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) + finally: + _call_if_exists(result, '_restoreStdout') + + def _get_previous_module(self, result): + previousModule = None + previousClass = getattr(result, '_previousTestClass', None) + if previousClass is not None: + previousModule = previousClass.__module__ + return previousModule + + + def _handleModuleFixture(self, test, result): + previousModule = self._get_previous_module(result) + currentModule = test.__class__.__module__ + if currentModule == previousModule: + return + + self._handleModuleTearDown(result) + + result._moduleSetUpFailed = False + try: + module = sys.modules[currentModule] + except KeyError: + return + setUpModule = getattr(module, 'setUpModule', None) + if setUpModule is not None: + _call_if_exists(result, '_setupStdout') + try: + setUpModule() + except Exception, e: + if isinstance(result, _DebugResult): + raise + result._moduleSetUpFailed = True + errorName = 'setUpModule (%s)' % currentModule + self._addClassOrModuleLevelException(result, e, errorName) + finally: + _call_if_exists(result, '_restoreStdout') + + def _addClassOrModuleLevelException(self, result, exception, errorName): + error = _ErrorHolder(errorName) + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None and isinstance(exception, case.SkipTest): + addSkip(error, str(exception)) + else: + result.addError(error, sys.exc_info()) + + def _handleModuleTearDown(self, result): + previousModule = self._get_previous_module(result) + if previousModule is None: + return + if result._moduleSetUpFailed: + return + + try: + module = sys.modules[previousModule] + except KeyError: + return + + tearDownModule = getattr(module, 'tearDownModule', None) + if tearDownModule is not None: + _call_if_exists(result, '_setupStdout') + try: + tearDownModule() + except Exception as e: + if isinstance(result, _DebugResult): + raise + errorName = 'tearDownModule (%s)' % previousModule + self._addClassOrModuleLevelException(result, e, errorName) + finally: + _call_if_exists(result, '_restoreStdout') + + def _tearDownPreviousClass(self, test, result): + previousClass = getattr(result, '_previousTestClass', None) + currentClass = test.__class__ + if currentClass == previousClass: + return + if getattr(previousClass, '_classSetupFailed', False): + return + if getattr(result, '_moduleSetUpFailed', False): + return + if getattr(previousClass, "__unittest_skip__", False): + return + + tearDownClass = getattr(previousClass, 'tearDownClass', None) + if tearDownClass is not None: + _call_if_exists(result, '_setupStdout') + try: + tearDownClass() + except Exception, e: + if isinstance(result, _DebugResult): + raise + className = util.strclass(previousClass) + errorName = 'tearDownClass (%s)' % className + self._addClassOrModuleLevelException(result, e, errorName) + finally: + _call_if_exists(result, '_restoreStdout') + + +class _ErrorHolder(object): + """ + Placeholder for a TestCase inside a result. As far as a TestResult + is concerned, this looks exactly like a unit test. Used to insert + arbitrary errors into a test suite run. + """ + # Inspired by the ErrorHolder from Twisted: + # http://twistedmatrix.com/trac/browser/trunk/twisted/trial/runner.py + + # attribute used by TestResult._exc_info_to_string + failureException = None + + def __init__(self, description): + self.description = description + + def id(self): + return self.description + + def shortDescription(self): + return None + + def __repr__(self): + return "<ErrorHolder description=%r>" % (self.description,) + + def __str__(self): + return self.id() + + def run(self, result): + # could call result.addError(...) - but this test-like object + # shouldn't be run anyway + pass + + def __call__(self, result): + return self.run(result) + + def countTestCases(self): + return 0 + +def _isnotsuite(test): + "A crude way to tell apart testcases and suites with duck-typing" + try: + iter(test) + except TypeError: + return True + return False + + +class _DebugResult(object): + "Used by the TestSuite to hold previous class when running in debug." + _previousTestClass = None + _moduleSetUpFailed = False + shouldStop = False diff --git a/src/main/resources/PythonLibs/unittest/util.py b/src/main/resources/PythonLibs/unittest/util.py new file mode 100644 index 0000000000000000000000000000000000000000..220a024e9038bdfe662b3bd8ea2e2fae9641ca72 --- /dev/null +++ b/src/main/resources/PythonLibs/unittest/util.py @@ -0,0 +1,156 @@ +"""Various utility functions.""" +from collections import namedtuple, OrderedDict + + +__unittest = True + +_MAX_LENGTH = 80 +def safe_repr(obj, short=False): + try: + result = repr(obj) + except Exception: + result = object.__repr__(obj) + if not short or len(result) < _MAX_LENGTH: + return result + return result[:_MAX_LENGTH] + ' [truncated]...' + + +def strclass(cls): + return "%s.%s" % (cls.__module__, cls.__name__) + +def sorted_list_difference(expected, actual): + """Finds elements in only one or the other of two, sorted input lists. + + Returns a two-element tuple of lists. The first list contains those + elements in the "expected" list but not in the "actual" list, and the + second contains those elements in the "actual" list but not in the + "expected" list. Duplicate elements in either input list are ignored. + """ + i = j = 0 + missing = [] + unexpected = [] + while True: + try: + e = expected[i] + a = actual[j] + if e < a: + missing.append(e) + i += 1 + while expected[i] == e: + i += 1 + elif e > a: + unexpected.append(a) + j += 1 + while actual[j] == a: + j += 1 + else: + i += 1 + try: + while expected[i] == e: + i += 1 + finally: + j += 1 + while actual[j] == a: + j += 1 + except IndexError: + missing.extend(expected[i:]) + unexpected.extend(actual[j:]) + break + return missing, unexpected + + +def unorderable_list_difference(expected, actual, ignore_duplicate=False): + """Same behavior as sorted_list_difference but + for lists of unorderable items (like dicts). + + As it does a linear search per item (remove) it + has O(n*n) performance. + """ + missing = [] + unexpected = [] + while expected: + item = expected.pop() + try: + actual.remove(item) + except ValueError: + missing.append(item) + if ignore_duplicate: + for lst in expected, actual: + try: + while True: + lst.remove(item) + except ValueError: + pass + if ignore_duplicate: + while actual: + item = actual.pop() + unexpected.append(item) + try: + while True: + actual.remove(item) + except ValueError: + pass + return missing, unexpected + + # anything left in actual is unexpected + return missing, actual + +_Mismatch = namedtuple('Mismatch', 'actual expected value') + +def _count_diff_all_purpose(actual, expected): + 'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ' + # elements need not be hashable + s, t = list(actual), list(expected) + m, n = len(s), len(t) + NULL = object() + result = [] + for i, elem in enumerate(s): + if elem is NULL: + continue + cnt_s = cnt_t = 0 + for j in range(i, m): + if s[j] == elem: + cnt_s += 1 + s[j] = NULL + for j, other_elem in enumerate(t): + if other_elem == elem: + cnt_t += 1 + t[j] = NULL + if cnt_s != cnt_t: + diff = _Mismatch(cnt_s, cnt_t, elem) + result.append(diff) + + for i, elem in enumerate(t): + if elem is NULL: + continue + cnt_t = 0 + for j in range(i, n): + if t[j] == elem: + cnt_t += 1 + t[j] = NULL + diff = _Mismatch(0, cnt_t, elem) + result.append(diff) + return result + +def _ordered_count(iterable): + 'Return dict of element counts, in the order they were first seen' + c = OrderedDict() + for elem in iterable: + c[elem] = c.get(elem, 0) + 1 + return c + +def _count_diff_hashable(actual, expected): + 'Returns list of (cnt_act, cnt_exp, elem) triples where the counts differ' + # elements must be hashable + s, t = _ordered_count(actual), _ordered_count(expected) + result = [] + for elem, cnt_s in s.items(): + cnt_t = t.get(elem, 0) + if cnt_s != cnt_t: + diff = _Mismatch(cnt_s, cnt_t, elem) + result.append(diff) + for elem, cnt_t in t.items(): + if elem not in s: + diff = _Mismatch(0, cnt_t, elem) + result.append(diff) + return result diff --git a/src/main/resources/PythonLibs/urllib.py b/src/main/resources/PythonLibs/urllib.py new file mode 100644 index 0000000000000000000000000000000000000000..55da67738358e8a051909c231f31d6d1b66d307a --- /dev/null +++ b/src/main/resources/PythonLibs/urllib.py @@ -0,0 +1,1602 @@ +"""Open an arbitrary URL. + +See the following document for more info on URLs: +"Names and Addresses, URIs, URLs, URNs, URCs", at +http://www.w3.org/pub/WWW/Addressing/Overview.html + +See also the HTTP spec (from which the error codes are derived): +"HTTP - Hypertext Transfer Protocol", at +http://www.w3.org/pub/WWW/Protocols/ + +Related standards and specs: +- RFC1808: the "relative URL" spec. (authoritative status) +- RFC1738 - the "URL standard". (authoritative status) +- RFC1630 - the "URI spec". (informational status) + +The object returned by URLopener().open(file) will differ per +protocol. All you know is that is has methods read(), readline(), +readlines(), fileno(), close() and info(). The read*(), fileno() +and close() methods work like those of open files. +The info() method returns a mimetools.Message object which can be +used to query various info about the object, if available. +(mimetools.Message objects are queried with the getheader() method.) +""" + +import string +import socket +import os +import time +import sys +import base64 + +from urlparse import urljoin as basejoin + +__all__ = ["urlopen", "URLopener", "FancyURLopener", "urlretrieve", + "urlcleanup", "quote", "quote_plus", "unquote", "unquote_plus", + "urlencode", "url2pathname", "pathname2url", "splittag", + "localhost", "thishost", "ftperrors", "basejoin", "unwrap", + "splittype", "splithost", "splituser", "splitpasswd", "splitport", + "splitnport", "splitquery", "splitattr", "splitvalue", + "getproxies"] + +__version__ = '1.17' # XXX This version is not always updated :-( + +MAXFTPCACHE = 10 # Trim the ftp cache beyond this size + +# Helper for non-unix systems +if (os._name if sys.platform.startswith('java') else os.name) == 'nt': + from nturl2path import url2pathname, pathname2url +elif os.name == 'riscos': + from rourl2path import url2pathname, pathname2url +else: + def url2pathname(pathname): + """OS-specific conversion from a relative URL of the 'file' scheme + to a file system path; not recommended for general use.""" + return unquote(pathname) + + def pathname2url(pathname): + """OS-specific conversion from a file system path to a relative URL + of the 'file' scheme; not recommended for general use.""" + return quote(pathname) + +# This really consists of two pieces: +# (1) a class which handles opening of all sorts of URLs +# (plus assorted utilities etc.) +# (2) a set of functions for parsing URLs +# XXX Should these be separated out into different modules? + + +# Shortcut for basic usage +_urlopener = None +def urlopen(url, data=None, proxies=None): + """Create a file-like object for the specified URL to read from.""" + from warnings import warnpy3k + warnpy3k("urllib.urlopen() has been removed in Python 3.0 in " + "favor of urllib2.urlopen()", stacklevel=2) + + global _urlopener + if proxies is not None: + opener = FancyURLopener(proxies=proxies) + elif not _urlopener: + opener = FancyURLopener() + _urlopener = opener + else: + opener = _urlopener + if data is None: + return opener.open(url) + else: + return opener.open(url, data) +def urlretrieve(url, filename=None, reporthook=None, data=None): + global _urlopener + if not _urlopener: + _urlopener = FancyURLopener() + return _urlopener.retrieve(url, filename, reporthook, data) +def urlcleanup(): + if _urlopener: + _urlopener.cleanup() + _safe_quoters.clear() + ftpcache.clear() + +# check for SSL +try: + import ssl +except: + _have_ssl = False +else: + _have_ssl = True + +# exception raised when downloaded size does not match content-length +class ContentTooShortError(IOError): + def __init__(self, message, content): + IOError.__init__(self, message) + self.content = content + +ftpcache = {} +class URLopener: + """Class to open URLs. + This is a class rather than just a subroutine because we may need + more than one set of global protocol-specific options. + Note -- this is a base class for those who don't want the + automatic handling of errors type 302 (relocated) and 401 + (authorization needed).""" + + __tempfiles = None + + version = "Python-urllib/%s" % __version__ + + # Constructor + def __init__(self, proxies=None, **x509): + if proxies is None: + proxies = getproxies() + assert hasattr(proxies, 'has_key'), "proxies must be a mapping" + self.proxies = proxies + self.key_file = x509.get('key_file') + self.cert_file = x509.get('cert_file') + self.addheaders = [('User-Agent', self.version)] + self.__tempfiles = [] + self.__unlink = os.unlink # See cleanup() + self.tempcache = None + # Undocumented feature: if you assign {} to tempcache, + # it is used to cache files retrieved with + # self.retrieve(). This is not enabled by default + # since it does not work for changing documents (and I + # haven't got the logic to check expiration headers + # yet). + self.ftpcache = ftpcache + # Undocumented feature: you can use a different + # ftp cache by assigning to the .ftpcache member; + # in case you want logically independent URL openers + # XXX This is not threadsafe. Bah. + + def __del__(self): + self.close() + + def close(self): + self.cleanup() + + def cleanup(self): + # This code sometimes runs when the rest of this module + # has already been deleted, so it can't use any globals + # or import anything. + if self.__tempfiles: + for file in self.__tempfiles: + try: + self.__unlink(file) + except OSError: + pass + del self.__tempfiles[:] + if self.tempcache: + self.tempcache.clear() + + def addheader(self, *args): + """Add a header to be used by the HTTP interface only + e.g. u.addheader('Accept', 'sound/basic')""" + self.addheaders.append(args) + + # External interface + def open(self, fullurl, data=None): + """Use URLopener().open(file) instead of open(file, 'r').""" + fullurl = unwrap(toBytes(fullurl)) + # percent encode url, fixing lame server errors for e.g, like space + # within url paths. + fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]|") + if self.tempcache and fullurl in self.tempcache: + filename, headers = self.tempcache[fullurl] + fp = open(filename, 'rb') + return addinfourl(fp, headers, fullurl) + urltype, url = splittype(fullurl) + if not urltype: + urltype = 'file' + if urltype in self.proxies: + proxy = self.proxies[urltype] + urltype, proxyhost = splittype(proxy) + host, selector = splithost(proxyhost) + url = (host, fullurl) # Signal special case to open_*() + else: + proxy = None + name = 'open_' + urltype + self.type = urltype + name = name.replace('-', '_') + if not hasattr(self, name): + if proxy: + return self.open_unknown_proxy(proxy, fullurl, data) + else: + return self.open_unknown(fullurl, data) + try: + if data is None: + return getattr(self, name)(url) + else: + return getattr(self, name)(url, data) + except socket.error, msg: + raise IOError, ('socket error', msg), sys.exc_info()[2] + + def open_unknown(self, fullurl, data=None): + """Overridable interface to open unknown URL type.""" + type, url = splittype(fullurl) + raise IOError, ('url error', 'unknown url type', type) + + def open_unknown_proxy(self, proxy, fullurl, data=None): + """Overridable interface to open unknown URL type.""" + type, url = splittype(fullurl) + raise IOError, ('url error', 'invalid proxy for %s' % type, proxy) + + # External interface + def retrieve(self, url, filename=None, reporthook=None, data=None): + """retrieve(url) returns (filename, headers) for a local object + or (tempfilename, headers) for a remote object.""" + url = unwrap(toBytes(url)) + if self.tempcache and url in self.tempcache: + return self.tempcache[url] + type, url1 = splittype(url) + if filename is None and (not type or type == 'file'): + try: + fp = self.open_local_file(url1) + hdrs = fp.info() + fp.close() + return url2pathname(splithost(url1)[1]), hdrs + except IOError: + pass + fp = self.open(url, data) + try: + headers = fp.info() + if filename: + tfp = open(filename, 'wb') + else: + import tempfile + garbage, path = splittype(url) + garbage, path = splithost(path or "") + path, garbage = splitquery(path or "") + path, garbage = splitattr(path or "") + suffix = os.path.splitext(path)[1] + (fd, filename) = tempfile.mkstemp(suffix) + self.__tempfiles.append(filename) + tfp = os.fdopen(fd, 'wb') + try: + result = filename, headers + if self.tempcache is not None: + self.tempcache[url] = result + bs = 1024*8 + size = -1 + read = 0 + blocknum = 0 + if "content-length" in headers: + size = int(headers["Content-Length"]) + if reporthook: + reporthook(blocknum, bs, size) + while 1: + block = fp.read(bs) + if block == "": + break + read += len(block) + tfp.write(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, bs, size) + finally: + tfp.close() + finally: + fp.close() + + # raise exception if actual size does not match content-length header + if size >= 0 and read < size: + raise ContentTooShortError("retrieval incomplete: got only %i out " + "of %i bytes" % (read, size), result) + + return result + + # Each method named open_<type> knows how to open that type of URL + + def open_http(self, url, data=None): + """Use HTTP protocol.""" + import httplib + user_passwd = None + proxy_passwd= None + if isinstance(url, str): + host, selector = splithost(url) + if host: + user_passwd, host = splituser(host) + host = unquote(host) + realhost = host + else: + host, selector = url + # check whether the proxy contains authorization information + proxy_passwd, host = splituser(host) + # now we proceed with the url we want to obtain + urltype, rest = splittype(selector) + url = rest + user_passwd = None + if urltype.lower() != 'http': + realhost = None + else: + realhost, rest = splithost(rest) + if realhost: + user_passwd, realhost = splituser(realhost) + if user_passwd: + selector = "%s://%s%s" % (urltype, realhost, rest) + if proxy_bypass(realhost): + host = realhost + + #print "proxy via http:", host, selector + if not host: raise IOError, ('http error', 'no host given') + + if proxy_passwd: + proxy_passwd = unquote(proxy_passwd) + proxy_auth = base64.b64encode(proxy_passwd).strip() + else: + proxy_auth = None + + if user_passwd: + user_passwd = unquote(user_passwd) + auth = base64.b64encode(user_passwd).strip() + else: + auth = None + h = httplib.HTTP(host) + if data is not None: + h.putrequest('POST', selector) + h.putheader('Content-Type', 'application/x-www-form-urlencoded') + h.putheader('Content-Length', '%d' % len(data)) + else: + h.putrequest('GET', selector) + if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) + if auth: h.putheader('Authorization', 'Basic %s' % auth) + if realhost: h.putheader('Host', realhost) + for args in self.addheaders: h.putheader(*args) + h.endheaders(data) + errcode, errmsg, headers = h.getreply() + fp = h.getfile() + if errcode == -1: + if fp: fp.close() + # something went wrong with the HTTP status line + raise IOError, ('http protocol error', 0, + 'got a bad status line', None) + # According to RFC 2616, "2xx" code indicates that the client's + # request was successfully received, understood, and accepted. + if (200 <= errcode < 300): + return addinfourl(fp, headers, "http:" + url, errcode) + else: + if data is None: + return self.http_error(url, fp, errcode, errmsg, headers) + else: + return self.http_error(url, fp, errcode, errmsg, headers, data) + + def http_error(self, url, fp, errcode, errmsg, headers, data=None): + """Handle http errors. + Derived class can override this, or provide specific handlers + named http_error_DDD where DDD is the 3-digit error code.""" + # First check if there's a specific handler for this error + name = 'http_error_%d' % errcode + if hasattr(self, name): + method = getattr(self, name) + if data is None: + result = method(url, fp, errcode, errmsg, headers) + else: + result = method(url, fp, errcode, errmsg, headers, data) + if result: return result + return self.http_error_default(url, fp, errcode, errmsg, headers) + + def http_error_default(self, url, fp, errcode, errmsg, headers): + """Default error handler: close the connection and raise IOError.""" + fp.close() + raise IOError, ('http error', errcode, errmsg, headers) + + if _have_ssl: + def open_https(self, url, data=None): + """Use HTTPS protocol.""" + + import httplib + user_passwd = None + proxy_passwd = None + if isinstance(url, str): + host, selector = splithost(url) + if host: + user_passwd, host = splituser(host) + host = unquote(host) + realhost = host + else: + host, selector = url + # here, we determine, whether the proxy contains authorization information + proxy_passwd, host = splituser(host) + urltype, rest = splittype(selector) + url = rest + user_passwd = None + if urltype.lower() != 'https': + realhost = None + else: + realhost, rest = splithost(rest) + if realhost: + user_passwd, realhost = splituser(realhost) + if user_passwd: + selector = "%s://%s%s" % (urltype, realhost, rest) + #print "proxy via https:", host, selector + if not host: raise IOError, ('https error', 'no host given') + if proxy_passwd: + proxy_passwd = unquote(proxy_passwd) + proxy_auth = base64.b64encode(proxy_passwd).strip() + else: + proxy_auth = None + if user_passwd: + user_passwd = unquote(user_passwd) + auth = base64.b64encode(user_passwd).strip() + else: + auth = None + h = httplib.HTTPS(host, 0, + key_file=self.key_file, + cert_file=self.cert_file) + if data is not None: + h.putrequest('POST', selector) + h.putheader('Content-Type', + 'application/x-www-form-urlencoded') + h.putheader('Content-Length', '%d' % len(data)) + else: + h.putrequest('GET', selector) + if proxy_auth: h.putheader('Proxy-Authorization', 'Basic %s' % proxy_auth) + if auth: h.putheader('Authorization', 'Basic %s' % auth) + if realhost: h.putheader('Host', realhost) + for args in self.addheaders: h.putheader(*args) + h.endheaders(data) + errcode, errmsg, headers = h.getreply() + fp = h.getfile() + if errcode == -1: + if fp: fp.close() + # something went wrong with the HTTP status line + raise IOError, ('http protocol error', 0, + 'got a bad status line', None) + # According to RFC 2616, "2xx" code indicates that the client's + # request was successfully received, understood, and accepted. + if (200 <= errcode < 300): + return addinfourl(fp, headers, "https:" + url, errcode) + else: + if data is None: + return self.http_error(url, fp, errcode, errmsg, headers) + else: + return self.http_error(url, fp, errcode, errmsg, headers, + data) + + def open_file(self, url): + """Use local file or FTP depending on form of URL.""" + if not isinstance(url, str): + raise IOError, ('file error', 'proxy support for file protocol currently not implemented') + if url[:2] == '//' and url[2:3] != '/' and url[2:12].lower() != 'localhost/': + return self.open_ftp(url) + else: + return self.open_local_file(url) + + def open_local_file(self, url): + """Use local file.""" + import mimetypes, mimetools, email.utils + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + host, file = splithost(url) + localname = url2pathname(file) + try: + stats = os.stat(localname) + except OSError, e: + raise IOError(e.errno, e.strerror, e.filename) + size = stats.st_size + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) + mtype = mimetypes.guess_type(url)[0] + headers = mimetools.Message(StringIO( + 'Content-Type: %s\nContent-Length: %d\nLast-modified: %s\n' % + (mtype or 'text/plain', size, modified))) + if not host: + urlfile = file + if file[:1] == '/': + urlfile = 'file://' + file + elif file[:2] == './': + raise ValueError("local file url may start with / or file:. Unknown url of type: %s" % url) + return addinfourl(open(localname, 'rb'), + headers, urlfile) + host, port = splitport(host) + if not port \ + and socket.gethostbyname(host) in (localhost(), thishost()): + urlfile = file + if file[:1] == '/': + urlfile = 'file://' + file + return addinfourl(open(localname, 'rb'), + headers, urlfile) + raise IOError, ('local file error', 'not on local host') + + def open_ftp(self, url): + """Use FTP protocol.""" + if not isinstance(url, str): + raise IOError, ('ftp error', 'proxy support for ftp protocol currently not implemented') + import mimetypes, mimetools + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + host, path = splithost(url) + if not host: raise IOError, ('ftp error', 'no host given') + host, port = splitport(host) + user, host = splituser(host) + if user: user, passwd = splitpasswd(user) + else: passwd = None + host = unquote(host) + user = user or '' + passwd = passwd or '' + host = socket.gethostbyname(host) + if not port: + import ftplib + port = ftplib.FTP_PORT + else: + port = int(port) + path, attrs = splitattr(path) + path = unquote(path) + dirs = path.split('/') + dirs, file = dirs[:-1], dirs[-1] + if dirs and not dirs[0]: dirs = dirs[1:] + if dirs and not dirs[0]: dirs[0] = '/' + key = user, host, port, '/'.join(dirs) + # XXX thread unsafe! + if len(self.ftpcache) > MAXFTPCACHE: + # Prune the cache, rather arbitrarily + for k in self.ftpcache.keys(): + if k != key: + v = self.ftpcache[k] + del self.ftpcache[k] + v.close() + try: + if not key in self.ftpcache: + self.ftpcache[key] = \ + ftpwrapper(user, passwd, host, port, dirs) + if not file: type = 'D' + else: type = 'I' + for attr in attrs: + attr, value = splitvalue(attr) + if attr.lower() == 'type' and \ + value in ('a', 'A', 'i', 'I', 'd', 'D'): + type = value.upper() + (fp, retrlen) = self.ftpcache[key].retrfile(file, type) + mtype = mimetypes.guess_type("ftp:" + url)[0] + headers = "" + if mtype: + headers += "Content-Type: %s\n" % mtype + if retrlen is not None and retrlen >= 0: + headers += "Content-Length: %d\n" % retrlen + headers = mimetools.Message(StringIO(headers)) + return addinfourl(fp, headers, "ftp:" + url) + except ftperrors(), msg: + raise IOError, ('ftp error', msg), sys.exc_info()[2] + + def open_data(self, url, data=None): + """Use "data" URL.""" + if not isinstance(url, str): + raise IOError, ('data error', 'proxy support for data protocol currently not implemented') + # ignore POSTed data + # + # syntax of data URLs: + # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + # mediatype := [ type "/" subtype ] *( ";" parameter ) + # data := *urlchar + # parameter := attribute "=" value + import mimetools + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + try: + [type, data] = url.split(',', 1) + except ValueError: + raise IOError, ('data error', 'bad data URL') + if not type: + type = 'text/plain;charset=US-ASCII' + semi = type.rfind(';') + if semi >= 0 and '=' not in type[semi:]: + encoding = type[semi+1:] + type = type[:semi] + else: + encoding = '' + msg = [] + msg.append('Date: %s'%time.strftime('%a, %d %b %Y %H:%M:%S GMT', + time.gmtime(time.time()))) + msg.append('Content-type: %s' % type) + if encoding == 'base64': + data = base64.decodestring(data) + else: + data = unquote(data) + msg.append('Content-Length: %d' % len(data)) + msg.append('') + msg.append(data) + msg = '\n'.join(msg) + f = StringIO(msg) + headers = mimetools.Message(f, 0) + #f.fileno = None # needed for addinfourl + return addinfourl(f, headers, url) + + +class FancyURLopener(URLopener): + """Derived class with handlers for errors we can handle (perhaps).""" + + def __init__(self, *args, **kwargs): + URLopener.__init__(self, *args, **kwargs) + self.auth_cache = {} + self.tries = 0 + self.maxtries = 10 + + def http_error_default(self, url, fp, errcode, errmsg, headers): + """Default error handling -- don't raise an exception.""" + return addinfourl(fp, headers, "http:" + url, errcode) + + def http_error_302(self, url, fp, errcode, errmsg, headers, data=None): + """Error 302 -- relocated (temporarily).""" + self.tries += 1 + if self.maxtries and self.tries >= self.maxtries: + if hasattr(self, "http_error_500"): + meth = self.http_error_500 + else: + meth = self.http_error_default + self.tries = 0 + return meth(url, fp, 500, + "Internal Server Error: Redirect Recursion", headers) + result = self.redirect_internal(url, fp, errcode, errmsg, headers, + data) + self.tries = 0 + return result + + def redirect_internal(self, url, fp, errcode, errmsg, headers, data): + if 'location' in headers: + newurl = headers['location'] + elif 'uri' in headers: + newurl = headers['uri'] + else: + return + fp.close() + # In case the server sent a relative URL, join with original: + newurl = basejoin(self.type + ":" + url, newurl) + + # For security reasons we do not allow redirects to protocols + # other than HTTP, HTTPS or FTP. + newurl_lower = newurl.lower() + if not (newurl_lower.startswith('http://') or + newurl_lower.startswith('https://') or + newurl_lower.startswith('ftp://')): + raise IOError('redirect error', errcode, + errmsg + " - Redirection to url '%s' is not allowed" % + newurl, + headers) + + return self.open(newurl) + + def http_error_301(self, url, fp, errcode, errmsg, headers, data=None): + """Error 301 -- also relocated (permanently).""" + return self.http_error_302(url, fp, errcode, errmsg, headers, data) + + def http_error_303(self, url, fp, errcode, errmsg, headers, data=None): + """Error 303 -- also relocated (essentially identical to 302).""" + return self.http_error_302(url, fp, errcode, errmsg, headers, data) + + def http_error_307(self, url, fp, errcode, errmsg, headers, data=None): + """Error 307 -- relocated, but turn POST into error.""" + if data is None: + return self.http_error_302(url, fp, errcode, errmsg, headers, data) + else: + return self.http_error_default(url, fp, errcode, errmsg, headers) + + def http_error_401(self, url, fp, errcode, errmsg, headers, data=None): + """Error 401 -- authentication required. + This function supports Basic authentication only.""" + if not 'www-authenticate' in headers: + URLopener.http_error_default(self, url, fp, + errcode, errmsg, headers) + stuff = headers['www-authenticate'] + import re + match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff) + if not match: + URLopener.http_error_default(self, url, fp, + errcode, errmsg, headers) + scheme, realm = match.groups() + if scheme.lower() != 'basic': + URLopener.http_error_default(self, url, fp, + errcode, errmsg, headers) + name = 'retry_' + self.type + '_basic_auth' + if data is None: + return getattr(self,name)(url, realm) + else: + return getattr(self,name)(url, realm, data) + + def http_error_407(self, url, fp, errcode, errmsg, headers, data=None): + """Error 407 -- proxy authentication required. + This function supports Basic authentication only.""" + if not 'proxy-authenticate' in headers: + URLopener.http_error_default(self, url, fp, + errcode, errmsg, headers) + stuff = headers['proxy-authenticate'] + import re + match = re.match('[ \t]*([^ \t]+)[ \t]+realm="([^"]*)"', stuff) + if not match: + URLopener.http_error_default(self, url, fp, + errcode, errmsg, headers) + scheme, realm = match.groups() + if scheme.lower() != 'basic': + URLopener.http_error_default(self, url, fp, + errcode, errmsg, headers) + name = 'retry_proxy_' + self.type + '_basic_auth' + if data is None: + return getattr(self,name)(url, realm) + else: + return getattr(self,name)(url, realm, data) + + def retry_proxy_http_basic_auth(self, url, realm, data=None): + host, selector = splithost(url) + newurl = 'http://' + host + selector + proxy = self.proxies['http'] + urltype, proxyhost = splittype(proxy) + proxyhost, proxyselector = splithost(proxyhost) + i = proxyhost.find('@') + 1 + proxyhost = proxyhost[i:] + user, passwd = self.get_user_passwd(proxyhost, realm, i) + if not (user or passwd): return None + proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost + self.proxies['http'] = 'http://' + proxyhost + proxyselector + if data is None: + return self.open(newurl) + else: + return self.open(newurl, data) + + def retry_proxy_https_basic_auth(self, url, realm, data=None): + host, selector = splithost(url) + newurl = 'https://' + host + selector + proxy = self.proxies['https'] + urltype, proxyhost = splittype(proxy) + proxyhost, proxyselector = splithost(proxyhost) + i = proxyhost.find('@') + 1 + proxyhost = proxyhost[i:] + user, passwd = self.get_user_passwd(proxyhost, realm, i) + if not (user or passwd): return None + proxyhost = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + proxyhost + self.proxies['https'] = 'https://' + proxyhost + proxyselector + if data is None: + return self.open(newurl) + else: + return self.open(newurl, data) + + def retry_http_basic_auth(self, url, realm, data=None): + host, selector = splithost(url) + i = host.find('@') + 1 + host = host[i:] + user, passwd = self.get_user_passwd(host, realm, i) + if not (user or passwd): return None + host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host + newurl = 'http://' + host + selector + if data is None: + return self.open(newurl) + else: + return self.open(newurl, data) + + def retry_https_basic_auth(self, url, realm, data=None): + host, selector = splithost(url) + i = host.find('@') + 1 + host = host[i:] + user, passwd = self.get_user_passwd(host, realm, i) + if not (user or passwd): return None + host = quote(user, safe='') + ':' + quote(passwd, safe='') + '@' + host + newurl = 'https://' + host + selector + if data is None: + return self.open(newurl) + else: + return self.open(newurl, data) + + def get_user_passwd(self, host, realm, clear_cache=0): + key = realm + '@' + host.lower() + if key in self.auth_cache: + if clear_cache: + del self.auth_cache[key] + else: + return self.auth_cache[key] + user, passwd = self.prompt_user_passwd(host, realm) + if user or passwd: self.auth_cache[key] = (user, passwd) + return user, passwd + + def prompt_user_passwd(self, host, realm): + """Override this in a GUI environment!""" + import getpass + try: + user = raw_input("Enter username for %s at %s: " % (realm, + host)) + passwd = getpass.getpass("Enter password for %s in %s at %s: " % + (user, realm, host)) + return user, passwd + except KeyboardInterrupt: + print + return None, None + + +# Utility functions + +_localhost = None +def localhost(): + """Return the IP address of the magic hostname 'localhost'.""" + global _localhost + if _localhost is None: + _localhost = socket.gethostbyname('localhost') + return _localhost + +_thishost = None +def thishost(): + """Return the IP address of the current host.""" + global _thishost + if _thishost is None: + _thishost = socket.gethostbyname(socket.gethostname()) + return _thishost + +_ftperrors = None +def ftperrors(): + """Return the set of errors raised by the FTP class.""" + global _ftperrors + if _ftperrors is None: + import ftplib + _ftperrors = ftplib.all_errors + return _ftperrors + +_noheaders = None +def noheaders(): + """Return an empty mimetools.Message object.""" + global _noheaders + if _noheaders is None: + import mimetools + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + _noheaders = mimetools.Message(StringIO(), 0) + _noheaders.fp.close() # Recycle file descriptor + return _noheaders + + +# Utility classes + +class ftpwrapper: + """Class used by open_ftp() for cache of open FTP connections.""" + + def __init__(self, user, passwd, host, port, dirs, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + persistent=True): + self.user = user + self.passwd = passwd + self.host = host + self.port = port + self.dirs = dirs + self.timeout = timeout + self.refcount = 0 + self.keepalive = persistent + self.init() + + def init(self): + import ftplib + self.busy = 0 + self.ftp = ftplib.FTP() + self.ftp.connect(self.host, self.port, self.timeout) + self.ftp.login(self.user, self.passwd) + for dir in self.dirs: + self.ftp.cwd(dir) + + def retrfile(self, file, type): + import ftplib + self.endtransfer() + if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1 + else: cmd = 'TYPE ' + type; isdir = 0 + try: + self.ftp.voidcmd(cmd) + except ftplib.all_errors: + self.init() + self.ftp.voidcmd(cmd) + conn = None + if file and not isdir: + # Try to retrieve as a file + try: + cmd = 'RETR ' + file + conn, retrlen = self.ftp.ntransfercmd(cmd) + except ftplib.error_perm, reason: + if str(reason)[:3] != '550': + raise IOError, ('ftp error', reason), sys.exc_info()[2] + if not conn: + # Set transfer mode to ASCII! + self.ftp.voidcmd('TYPE A') + # Try a directory listing. Verify that directory exists. + if file: + pwd = self.ftp.pwd() + try: + try: + self.ftp.cwd(file) + except ftplib.error_perm, reason: + raise IOError, ('ftp error', reason), sys.exc_info()[2] + finally: + self.ftp.cwd(pwd) + cmd = 'LIST ' + file + else: + cmd = 'LIST' + conn, retrlen = self.ftp.ntransfercmd(cmd) + self.busy = 1 + ftpobj = addclosehook(conn.makefile('rb'), self.file_close) + self.refcount += 1 + conn.close() + # Pass back both a suitably decorated object and a retrieval length + return (ftpobj, retrlen) + + def endtransfer(self): + if not self.busy: + return + self.busy = 0 + try: + self.ftp.voidresp() + except ftperrors(): + pass + + def close(self): + self.keepalive = False + if self.refcount <= 0: + self.real_close() + + def file_close(self): + self.endtransfer() + self.refcount -= 1 + if self.refcount <= 0 and not self.keepalive: + self.real_close() + + def real_close(self): + self.endtransfer() + try: + self.ftp.close() + except ftperrors(): + pass + +class addbase: + """Base class for addinfo and addclosehook.""" + + def __init__(self, fp): + self.fp = fp + self.read = self.fp.read + self.readline = self.fp.readline + if hasattr(self.fp, "readlines"): self.readlines = self.fp.readlines + if hasattr(self.fp, "fileno"): + self.fileno = self.fp.fileno + else: + self.fileno = lambda: None + if hasattr(self.fp, "__iter__"): + self.__iter__ = self.fp.__iter__ + if hasattr(self.fp, "next"): + self.next = self.fp.next + + def __repr__(self): + return '<%s at %r whose fp = %r>' % (self.__class__.__name__, + id(self), self.fp) + + def close(self): + self.read = None + self.readline = None + self.readlines = None + self.fileno = None + if self.fp: self.fp.close() + self.fp = None + +class addclosehook(addbase): + """Class to add a close hook to an open file.""" + + def __init__(self, fp, closehook, *hookargs): + addbase.__init__(self, fp) + self.closehook = closehook + self.hookargs = hookargs + + def close(self): + if self.closehook: + self.closehook(*self.hookargs) + self.closehook = None + self.hookargs = None + addbase.close(self) + +class addinfo(addbase): + """class to add an info() method to an open file.""" + + def __init__(self, fp, headers): + addbase.__init__(self, fp) + self.headers = headers + + def info(self): + return self.headers + +class addinfourl(addbase): + """class to add info() and geturl() methods to an open file.""" + + def __init__(self, fp, headers, url, code=None): + addbase.__init__(self, fp) + self.headers = headers + self.url = url + self.code = code + + def info(self): + return self.headers + + def getcode(self): + return self.code + + def geturl(self): + return self.url + + +# Utilities to parse URLs (most of these return None for missing parts): +# unwrap('<URL:type://host/path>') --> 'type://host/path' +# splittype('type:opaquestring') --> 'type', 'opaquestring' +# splithost('//host[:port]/path') --> 'host[:port]', '/path' +# splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]' +# splitpasswd('user:passwd') -> 'user', 'passwd' +# splitport('host:port') --> 'host', 'port' +# splitquery('/path?query') --> '/path', 'query' +# splittag('/path#tag') --> '/path', 'tag' +# splitattr('/path;attr1=value1;attr2=value2;...') -> +# '/path', ['attr1=value1', 'attr2=value2', ...] +# splitvalue('attr=value') --> 'attr', 'value' +# unquote('abc%20def') -> 'abc def' +# quote('abc def') -> 'abc%20def') + +try: + unicode +except NameError: + def _is_unicode(x): + return 0 +else: + def _is_unicode(x): + return isinstance(x, unicode) + +def toBytes(url): + """toBytes(u"URL") --> 'URL'.""" + # Most URL schemes require ASCII. If that changes, the conversion + # can be relaxed + if _is_unicode(url): + try: + url = url.encode("ASCII") + except UnicodeError: + raise UnicodeError("URL " + repr(url) + + " contains non-ASCII characters") + return url + +def unwrap(url): + """unwrap('<URL:type://host/path>') --> 'type://host/path'.""" + url = url.strip() + if url[:1] == '<' and url[-1:] == '>': + url = url[1:-1].strip() + if url[:4] == 'URL:': url = url[4:].strip() + return url + +_typeprog = None +def splittype(url): + """splittype('type:opaquestring') --> 'type', 'opaquestring'.""" + global _typeprog + if _typeprog is None: + import re + _typeprog = re.compile('^([^/:]+):') + + match = _typeprog.match(url) + if match: + scheme = match.group(1) + return scheme.lower(), url[len(scheme) + 1:] + return None, url + +_hostprog = None +def splithost(url): + """splithost('//host[:port]/path') --> 'host[:port]', '/path'.""" + global _hostprog + if _hostprog is None: + import re + _hostprog = re.compile('^//([^/?]*)(.*)$') + + match = _hostprog.match(url) + if match: + host_port = match.group(1) + path = match.group(2) + if path and not path.startswith('/'): + path = '/' + path + return host_port, path + return None, url + +_userprog = None +def splituser(host): + """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + global _userprog + if _userprog is None: + import re + _userprog = re.compile('^(.*)@(.*)$') + + match = _userprog.match(host) + if match: return match.group(1, 2) + return None, host + +_passwdprog = None +def splitpasswd(user): + """splitpasswd('user:passwd') -> 'user', 'passwd'.""" + global _passwdprog + if _passwdprog is None: + import re + _passwdprog = re.compile('^([^:]*):(.*)$',re.S) + + match = _passwdprog.match(user) + if match: return match.group(1, 2) + return user, None + +# splittag('/path#tag') --> '/path', 'tag' +_portprog = None +def splitport(host): + """splitport('host:port') --> 'host', 'port'.""" + global _portprog + if _portprog is None: + import re + _portprog = re.compile('^(.*):([0-9]+)$') + + match = _portprog.match(host) + if match: return match.group(1, 2) + return host, None + +_nportprog = None +def splitnport(host, defport=-1): + """Split host and port, returning numeric port. + Return given default port if no ':' found; defaults to -1. + Return numerical port if a valid number are found after ':'. + Return None if ':' but not a valid number.""" + global _nportprog + if _nportprog is None: + import re + _nportprog = re.compile('^(.*):(.*)$') + + match = _nportprog.match(host) + if match: + host, port = match.group(1, 2) + try: + if not port: raise ValueError, "no digits" + nport = int(port) + except ValueError: + nport = None + return host, nport + return host, defport + +_queryprog = None +def splitquery(url): + """splitquery('/path?query') --> '/path', 'query'.""" + global _queryprog + if _queryprog is None: + import re + _queryprog = re.compile('^(.*)\?([^?]*)$') + + match = _queryprog.match(url) + if match: return match.group(1, 2) + return url, None + +_tagprog = None +def splittag(url): + """splittag('/path#tag') --> '/path', 'tag'.""" + global _tagprog + if _tagprog is None: + import re + _tagprog = re.compile('^(.*)#([^#]*)$') + + match = _tagprog.match(url) + if match: return match.group(1, 2) + return url, None + +def splitattr(url): + """splitattr('/path;attr1=value1;attr2=value2;...') -> + '/path', ['attr1=value1', 'attr2=value2', ...].""" + words = url.split(';') + return words[0], words[1:] + +_valueprog = None +def splitvalue(attr): + """splitvalue('attr=value') --> 'attr', 'value'.""" + global _valueprog + if _valueprog is None: + import re + _valueprog = re.compile('^([^=]*)=(.*)$') + + match = _valueprog.match(attr) + if match: return match.group(1, 2) + return attr, None + +# urlparse contains a duplicate of this method to avoid a circular import. If +# you update this method, also update the copy in urlparse. This code +# duplication does not exist in Python3. + +_hexdig = '0123456789ABCDEFabcdef' +_hextochr = dict((a + b, chr(int(a + b, 16))) + for a in _hexdig for b in _hexdig) + +def unquote(s): + """unquote('abc%20def') -> 'abc def'.""" + res = s.split('%') + # fastpath + if len(res) == 1: + return s + s = res[0] + for item in res[1:]: + try: + s += _hextochr[item[:2]] + item[2:] + except KeyError: + s += '%' + item + except UnicodeDecodeError: + s += unichr(int(item[:2], 16)) + item[2:] + return s + +def unquote_plus(s): + """unquote('%7e/abc+def') -> '~/abc def'""" + s = s.replace('+', ' ') + return unquote(s) + +always_safe = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789' '_.-') +_safe_map = {} +for i, c in zip(xrange(256), str(bytearray(xrange(256)))): + _safe_map[c] = c if (i < 128 and c in always_safe) else '%{:02X}'.format(i) +_safe_quoters = {} + +def quote(s, safe='/'): + """quote('abc def') -> 'abc%20def' + + Each part of a URL, e.g. the path info, the query, etc., has a + different set of reserved characters that must be quoted. + + RFC 2396 Uniform Resource Identifiers (URI): Generic Syntax lists + the following reserved characters. + + reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + "$" | "," + + Each of these characters is reserved in some component of a URL, + but not necessarily in all of them. + + By default, the quote function is intended for quoting the path + section of a URL. Thus, it will not encode '/'. This character + is reserved, but in typical usage the quote function is being + called on a path where the existing slash characters are used as + reserved characters. + """ + # fastpath + if not s: + if s is None: + raise TypeError('None object cannot be quoted') + return s + cachekey = (safe, always_safe) + try: + (quoter, safe) = _safe_quoters[cachekey] + except KeyError: + safe_map = _safe_map.copy() + safe_map.update([(c, c) for c in safe]) + quoter = safe_map.__getitem__ + safe = always_safe + safe + _safe_quoters[cachekey] = (quoter, safe) + if not s.rstrip(safe): + return s + return ''.join(map(quoter, s)) + +def quote_plus(s, safe=''): + """Quote the query fragment of a URL; replacing ' ' with '+'""" + if ' ' in s: + s = quote(s, safe + ' ') + return s.replace(' ', '+') + return quote(s, safe) + +def urlencode(query, doseq=0): + """Encode a sequence of two-element tuples or dictionary into a URL query string. + + If any values in the query arg are sequences and doseq is true, each + sequence element is converted to a separate parameter. + + If the query arg is a sequence of two-element tuples, the order of the + parameters in the output will match the order of parameters in the + input. + """ + + if hasattr(query,"items"): + # mapping objects + query = query.items() + else: + # it's a bother at times that strings and string-like objects are + # sequences... + try: + # non-sequence items should not work with len() + # non-empty strings will fail this + if len(query) and not isinstance(query[0], tuple): + raise TypeError + # zero-length sequences of all types will get here and succeed, + # but that's a minor nit - since the original implementation + # allowed empty dicts that type of behavior probably should be + # preserved for consistency + except TypeError: + ty,va,tb = sys.exc_info() + raise TypeError, "not a valid non-string sequence or mapping object", tb + + l = [] + if not doseq: + # preserve old behavior + for k, v in query: + k = quote_plus(str(k)) + v = quote_plus(str(v)) + l.append(k + '=' + v) + else: + for k, v in query: + k = quote_plus(str(k)) + if isinstance(v, str): + v = quote_plus(v) + l.append(k + '=' + v) + elif _is_unicode(v): + # is there a reasonable way to convert to ASCII? + # encode generates a string, but "replace" or "ignore" + # lose information and "strict" can raise UnicodeError + v = quote_plus(v.encode("ASCII","replace")) + l.append(k + '=' + v) + else: + try: + # is this a sufficient test for sequence-ness? + len(v) + except TypeError: + # not a sequence + v = quote_plus(str(v)) + l.append(k + '=' + v) + else: + # loop over the sequence + for elt in v: + l.append(k + '=' + quote_plus(str(elt))) + return '&'.join(l) + +# Proxy handling +def getproxies_environment(): + """Return a dictionary of scheme -> proxy server URL mappings. + + Scan the environment for variables named <scheme>_proxy; + this seems to be the standard convention. If you need a + different way, you can pass a proxies dictionary to the + [Fancy]URLopener constructor. + + """ + proxies = {} + for name, value in os.environ.items(): + name = name.lower() + if value and name[-6:] == '_proxy': + proxies[name[:-6]] = value + return proxies + +def proxy_bypass_environment(host): + """Test if proxies should not be used for a particular host. + + Checks the environment for a variable named no_proxy, which should + be a list of DNS suffixes separated by commas, or '*' for all hosts. + """ + no_proxy = os.environ.get('no_proxy', '') or os.environ.get('NO_PROXY', '') + # '*' is special case for always bypass + if no_proxy == '*': + return 1 + # strip port off host + hostonly, port = splitport(host) + # check if the host ends with any of the DNS suffixes + no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')] + for name in no_proxy_list: + if name and (hostonly.endswith(name) or host.endswith(name)): + return 1 + # otherwise, don't bypass + return 0 + + +if sys.platform == 'darwin': + from _scproxy import _get_proxy_settings, _get_proxies + + def proxy_bypass_macosx_sysconf(host): + """ + Return True iff this host shouldn't be accessed using a proxy + + This function uses the MacOSX framework SystemConfiguration + to fetch the proxy information. + """ + import re + import socket + from fnmatch import fnmatch + + hostonly, port = splitport(host) + + def ip2num(ipAddr): + parts = ipAddr.split('.') + parts = map(int, parts) + if len(parts) != 4: + parts = (parts + [0, 0, 0, 0])[:4] + return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3] + + proxy_settings = _get_proxy_settings() + + # Check for simple host names: + if '.' not in host: + if proxy_settings['exclude_simple']: + return True + + hostIP = None + + for value in proxy_settings.get('exceptions', ()): + # Items in the list are strings like these: *.local, 169.254/16 + if not value: continue + + m = re.match(r"(\d+(?:\.\d+)*)(/\d+)?", value) + if m is not None: + if hostIP is None: + try: + hostIP = socket.gethostbyname(hostonly) + hostIP = ip2num(hostIP) + except socket.error: + continue + + base = ip2num(m.group(1)) + mask = m.group(2) + if mask is None: + mask = 8 * (m.group(1).count('.') + 1) + + else: + mask = int(mask[1:]) + mask = 32 - mask + + if (hostIP >> mask) == (base >> mask): + return True + + elif fnmatch(host, value): + return True + + return False + + def getproxies_macosx_sysconf(): + """Return a dictionary of scheme -> proxy server URL mappings. + + This function uses the MacOSX framework SystemConfiguration + to fetch the proxy information. + """ + return _get_proxies() + + def proxy_bypass(host): + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_macosx_sysconf(host) + + def getproxies(): + return getproxies_environment() or getproxies_macosx_sysconf() + +elif os.name == 'nt': + def getproxies_registry(): + """Return a dictionary of scheme -> proxy server URL mappings. + + Win32 uses the registry to store proxies. + + """ + proxies = {} + try: + import _winreg + except ImportError: + # Std module, so should be around - but you never know! + return proxies + try: + internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + proxyEnable = _winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0] + if proxyEnable: + # Returned as Unicode but problems if not converted to ASCII + proxyServer = str(_winreg.QueryValueEx(internetSettings, + 'ProxyServer')[0]) + if '=' in proxyServer: + # Per-protocol settings + for p in proxyServer.split(';'): + protocol, address = p.split('=', 1) + # See if address has a type:// prefix + import re + if not re.match('^([^/:]+)://', address): + address = '%s://%s' % (protocol, address) + proxies[protocol] = address + else: + # Use one setting for all protocols + if proxyServer[:5] == 'http:': + proxies['http'] = proxyServer + else: + proxies['http'] = 'http://%s' % proxyServer + proxies['https'] = 'https://%s' % proxyServer + proxies['ftp'] = 'ftp://%s' % proxyServer + internetSettings.Close() + except (WindowsError, ValueError, TypeError): + # Either registry key not found etc, or the value in an + # unexpected format. + # proxies already set up to be empty so nothing to do + pass + return proxies + + def getproxies(): + """Return a dictionary of scheme -> proxy server URL mappings. + + Returns settings gathered from the environment, if specified, + or the registry. + + """ + return getproxies_environment() or getproxies_registry() + + def proxy_bypass_registry(host): + try: + import _winreg + import re + except ImportError: + # Std modules, so should be around - but you never know! + return 0 + try: + internetSettings = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + proxyEnable = _winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0] + proxyOverride = str(_winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0]) + # ^^^^ Returned as Unicode but problems if not converted to ASCII + except WindowsError: + return 0 + if not proxyEnable or not proxyOverride: + return 0 + # try to make a host list from name and IP address. + rawHost, port = splitport(host) + host = [rawHost] + try: + addr = socket.gethostbyname(rawHost) + if addr != rawHost: + host.append(addr) + except socket.error: + pass + try: + fqdn = socket.getfqdn(rawHost) + if fqdn != rawHost: + host.append(fqdn) + except socket.error: + pass + # make a check value list from the registry entry: replace the + # '<local>' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '<local>': + if '.' not in rawHost: + return 1 + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + for val in host: + # print "%s <--> %s" %( test, val ) + if re.match(test, val, re.I): + return 1 + return 0 + + def proxy_bypass(host): + """Return a dictionary of scheme -> proxy server URL mappings. + + Returns settings gathered from the environment, if specified, + or the registry. + + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + +else: + # By default use environment variables + getproxies = getproxies_environment + proxy_bypass = proxy_bypass_environment + +# Test and time quote() and unquote() +def test1(): + s = '' + for i in range(256): s = s + chr(i) + s = s*4 + t0 = time.time() + qs = quote(s) + uqs = unquote(qs) + t1 = time.time() + if uqs != s: + print 'Wrong!' + print repr(s) + print repr(qs) + print repr(uqs) + print round(t1 - t0, 3), 'sec' + + +def reporthook(blocknum, blocksize, totalsize): + # Report during remote transfers + print "Block number: %d, Block size: %d, Total size: %d" % ( + blocknum, blocksize, totalsize) diff --git a/src/main/resources/PythonLibs/urllib2.py b/src/main/resources/PythonLibs/urllib2.py new file mode 100644 index 0000000000000000000000000000000000000000..aadeb7371ebc694ff6c230a38f9c6c8c9425f58c --- /dev/null +++ b/src/main/resources/PythonLibs/urllib2.py @@ -0,0 +1,1470 @@ +"""An extensible library for opening URLs using a variety of protocols + +The simplest way to use this module is to call the urlopen function, +which accepts a string containing a URL or a Request object (described +below). It opens the URL and returns the results as file-like +object; the returned object has some extra methods described below. + +The OpenerDirector manages a collection of Handler objects that do +all the actual work. Each Handler implements a particular protocol or +option. The OpenerDirector is a composite object that invokes the +Handlers needed to open the requested URL. For example, the +HTTPHandler performs HTTP GET and POST requests and deals with +non-error returns. The HTTPRedirectHandler automatically deals with +HTTP 301, 302, 303 and 307 redirect errors, and the HTTPDigestAuthHandler +deals with digest authentication. + +urlopen(url, data=None) -- Basic usage is the same as original +urllib. pass the url and optionally data to post to an HTTP URL, and +get a file-like object back. One difference is that you can also pass +a Request instance instead of URL. Raises a URLError (subclass of +IOError); for HTTP errors, raises an HTTPError, which can also be +treated as a valid response. + +build_opener -- Function that creates a new OpenerDirector instance. +Will install the default handlers. Accepts one or more Handlers as +arguments, either instances or Handler classes that it will +instantiate. If one of the argument is a subclass of the default +handler, the argument will be installed instead of the default. + +install_opener -- Installs a new opener as the default opener. + +objects of interest: + +OpenerDirector -- Sets up the User Agent as the Python-urllib client and manages +the Handler classes, while dealing with requests and responses. + +Request -- An object that encapsulates the state of a request. The +state can be as simple as the URL. It can also include extra HTTP +headers, e.g. a User-Agent. + +BaseHandler -- + +exceptions: +URLError -- A subclass of IOError, individual protocols have their own +specific subclass. + +HTTPError -- Also a valid HTTP response, so you can treat an HTTP error +as an exceptional event or valid response. + +internals: +BaseHandler and parent +_call_chain conventions + +Example usage: + +import urllib2 + +# set up authentication info +authinfo = urllib2.HTTPBasicAuthHandler() +authinfo.add_password(realm='PDQ Application', + uri='https://mahler:8092/site-updates.py', + user='klem', + passwd='geheim$parole') + +proxy_support = urllib2.ProxyHandler({"http" : "http://ahad-haam:3128"}) + +# build a new opener that adds authentication and caching FTP handlers +opener = urllib2.build_opener(proxy_support, authinfo, urllib2.CacheFTPHandler) + +# install it +urllib2.install_opener(opener) + +f = urllib2.urlopen('http://www.python.org/') + + +""" + +# XXX issues: +# If an authentication error handler that tries to perform +# authentication for some reason but fails, how should the error be +# signalled? The client needs to know the HTTP error code. But if +# the handler knows that the problem was, e.g., that it didn't know +# that hash algo that requested in the challenge, it would be good to +# pass that information along to the client, too. +# ftp errors aren't handled cleanly +# check digest against correct (i.e. non-apache) implementation + +# Possible extensions: +# complex proxies XXX not sure what exactly was meant by this +# abstract factory for opener + +import base64 +import hashlib +import httplib +import mimetools +import os +import posixpath +import random +import re +import socket +import sys +import time +import urlparse +import bisect +import warnings + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +from urllib import (unwrap, unquote, splittype, splithost, quote, + addinfourl, splitport, splittag, toBytes, + splitattr, ftpwrapper, splituser, splitpasswd, splitvalue) + +# support for FileHandler, proxies via environment variables +from urllib import localhost, url2pathname, getproxies, proxy_bypass + +# used in User-Agent header sent +__version__ = sys.version[:3] + +_opener = None +def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + global _opener + if _opener is None: + _opener = build_opener() + return _opener.open(url, data, timeout) + +def install_opener(opener): + global _opener + _opener = opener + +# do these error classes make sense? +# make sure all of the IOError stuff is overridden. we just want to be +# subtypes. + +class URLError(IOError): + # URLError is a sub-type of IOError, but it doesn't share any of + # the implementation. need to override __init__ and __str__. + # It sets self.args for compatibility with other EnvironmentError + # subclasses, but args doesn't have the typical format with errno in + # slot 0 and strerror in slot 1. This may be better than nothing. + def __init__(self, reason): + self.args = reason, + self.reason = reason + + def __str__(self): + return '<urlopen error %s>' % self.reason + +class HTTPError(URLError, addinfourl): + """Raised when HTTP error occurs, but also acts like non-error return""" + __super_init = addinfourl.__init__ + + def __init__(self, url, code, msg, hdrs, fp): + self.code = code + self.msg = msg + self.hdrs = hdrs + self.fp = fp + self.filename = url + # The addinfourl classes depend on fp being a valid file + # object. In some cases, the HTTPError may not have a valid + # file object. If this happens, the simplest workaround is to + # not initialize the base classes. + if fp is not None: + self.__super_init(fp, hdrs, url, code) + + def __str__(self): + return 'HTTP Error %s: %s' % (self.code, self.msg) + + # since URLError specifies a .reason attribute, HTTPError should also + # provide this attribute. See issue13211 fo discussion. + @property + def reason(self): + return self.msg + + def info(self): + return self.hdrs + +# copied from cookielib.py +_cut_port_re = re.compile(r":\d+$") +def request_host(request): + """Return request-host, as defined by RFC 2965. + + Variation from RFC: returned value is lowercased, for convenient + comparison. + + """ + url = request.get_full_url() + host = urlparse.urlparse(url)[1] + if host == "": + host = request.get_header("Host", "") + + # remove port, if present + host = _cut_port_re.sub("", host, 1) + return host.lower() + +class Request: + + def __init__(self, url, data=None, headers={}, + origin_req_host=None, unverifiable=False): + # unwrap('<URL:type://host/path>') --> 'type://host/path' + self.__original = unwrap(url) + self.__original, self.__fragment = splittag(self.__original) + self.type = None + # self.__r_type is what's left after doing the splittype + self.host = None + self.port = None + self._tunnel_host = None + self.data = data + self.headers = {} + for key, value in headers.items(): + self.add_header(key, value) + self.unredirected_hdrs = {} + if origin_req_host is None: + origin_req_host = request_host(self) + self.origin_req_host = origin_req_host + self.unverifiable = unverifiable + + def __getattr__(self, attr): + # XXX this is a fallback mechanism to guard against these + # methods getting called in a non-standard order. this may be + # too complicated and/or unnecessary. + # XXX should the __r_XXX attributes be public? + if attr[:12] == '_Request__r_': + name = attr[12:] + if hasattr(Request, 'get_' + name): + getattr(self, 'get_' + name)() + return getattr(self, attr) + raise AttributeError, attr + + def get_method(self): + if self.has_data(): + return "POST" + else: + return "GET" + + # XXX these helper methods are lame + + def add_data(self, data): + self.data = data + + def has_data(self): + return self.data is not None + + def get_data(self): + return self.data + + def get_full_url(self): + if self.__fragment: + return '%s#%s' % (self.__original, self.__fragment) + else: + return self.__original + + def get_type(self): + if self.type is None: + self.type, self.__r_type = splittype(self.__original) + if self.type is None: + raise ValueError, "unknown url type: %s" % self.__original + return self.type + + def get_host(self): + if self.host is None: + self.host, self.__r_host = splithost(self.__r_type) + if self.host: + self.host = unquote(self.host) + return self.host + + def get_selector(self): + return self.__r_host + + def set_proxy(self, host, type): + if self.type == 'https' and not self._tunnel_host: + self._tunnel_host = self.host + else: + self.type = type + self.__r_host = self.__original + + self.host = host + + def has_proxy(self): + return self.__r_host == self.__original + + def get_origin_req_host(self): + return self.origin_req_host + + def is_unverifiable(self): + return self.unverifiable + + def add_header(self, key, val): + # useful for something like authentication + self.headers[key.capitalize()] = val + + def add_unredirected_header(self, key, val): + # will not be added to a redirected request + self.unredirected_hdrs[key.capitalize()] = val + + def has_header(self, header_name): + return (header_name in self.headers or + header_name in self.unredirected_hdrs) + + def get_header(self, header_name, default=None): + return self.headers.get( + header_name, + self.unredirected_hdrs.get(header_name, default)) + + def header_items(self): + hdrs = self.unredirected_hdrs.copy() + hdrs.update(self.headers) + return hdrs.items() + +class OpenerDirector: + def __init__(self): + client_version = "Python-urllib/%s" % __version__ + self.addheaders = [('User-agent', client_version)] + # self.handlers is retained only for backward compatibility + self.handlers = [] + # manage the individual handlers + self.handle_open = {} + self.handle_error = {} + self.process_response = {} + self.process_request = {} + + def add_handler(self, handler): + if not hasattr(handler, "add_parent"): + raise TypeError("expected BaseHandler instance, got %r" % + type(handler)) + + added = False + for meth in dir(handler): + if meth in ["redirect_request", "do_open", "proxy_open"]: + # oops, coincidental match + continue + + i = meth.find("_") + protocol = meth[:i] + condition = meth[i+1:] + + if condition.startswith("error"): + j = condition.find("_") + i + 1 + kind = meth[j+1:] + try: + kind = int(kind) + except ValueError: + pass + lookup = self.handle_error.get(protocol, {}) + self.handle_error[protocol] = lookup + elif condition == "open": + kind = protocol + lookup = self.handle_open + elif condition == "response": + kind = protocol + lookup = self.process_response + elif condition == "request": + kind = protocol + lookup = self.process_request + else: + continue + + handlers = lookup.setdefault(kind, []) + if handlers: + bisect.insort(handlers, handler) + else: + handlers.append(handler) + added = True + + if added: + bisect.insort(self.handlers, handler) + handler.add_parent(self) + + def close(self): + # Only exists for backwards compatibility. + pass + + def _call_chain(self, chain, kind, meth_name, *args): + # Handlers raise an exception if no one else should try to handle + # the request, or return None if they can't but another handler + # could. Otherwise, they return the response. + handlers = chain.get(kind, ()) + for handler in handlers: + func = getattr(handler, meth_name) + + result = func(*args) + if result is not None: + return result + + def open(self, fullurl, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT): + # accept a URL or a Request object + if isinstance(fullurl, basestring): + req = Request(fullurl, data) + else: + req = fullurl + if data is not None: + req.add_data(data) + + req.timeout = timeout + protocol = req.get_type() + + # pre-process request + meth_name = protocol+"_request" + for processor in self.process_request.get(protocol, []): + meth = getattr(processor, meth_name) + req = meth(req) + + response = self._open(req, data) + + # post-process response + meth_name = protocol+"_response" + for processor in self.process_response.get(protocol, []): + meth = getattr(processor, meth_name) + response = meth(req, response) + + return response + + def _open(self, req, data=None): + result = self._call_chain(self.handle_open, 'default', + 'default_open', req) + if result: + return result + + protocol = req.get_type() + result = self._call_chain(self.handle_open, protocol, protocol + + '_open', req) + if result: + return result + + return self._call_chain(self.handle_open, 'unknown', + 'unknown_open', req) + + def error(self, proto, *args): + if proto in ('http', 'https'): + # XXX http[s] protocols are special-cased + dict = self.handle_error['http'] # https is not different than http + proto = args[2] # YUCK! + meth_name = 'http_error_%s' % proto + http_err = 1 + orig_args = args + else: + dict = self.handle_error + meth_name = proto + '_error' + http_err = 0 + args = (dict, proto, meth_name) + args + result = self._call_chain(*args) + if result: + return result + + if http_err: + args = (dict, 'default', 'http_error_default') + orig_args + return self._call_chain(*args) + +# XXX probably also want an abstract factory that knows when it makes +# sense to skip a superclass in favor of a subclass and when it might +# make sense to include both + +def build_opener(*handlers): + """Create an opener object from a list of handlers. + + The opener will use several default handlers, including support + for HTTP, FTP and when applicable, HTTPS. + + If any of the handlers passed as arguments are subclasses of the + default handlers, the default handlers will not be used. + """ + import types + def isclass(obj): + return isinstance(obj, (types.ClassType, type)) + + opener = OpenerDirector() + default_classes = [ProxyHandler, UnknownHandler, HTTPHandler, + HTTPDefaultErrorHandler, HTTPRedirectHandler, + FTPHandler, FileHandler, HTTPErrorProcessor] + if hasattr(httplib, 'HTTPS'): + default_classes.append(HTTPSHandler) + skip = set() + for klass in default_classes: + for check in handlers: + if isclass(check): + if issubclass(check, klass): + skip.add(klass) + elif isinstance(check, klass): + skip.add(klass) + for klass in skip: + default_classes.remove(klass) + + for klass in default_classes: + opener.add_handler(klass()) + + for h in handlers: + if isclass(h): + h = h() + opener.add_handler(h) + return opener + +class BaseHandler: + handler_order = 500 + + def add_parent(self, parent): + self.parent = parent + + def close(self): + # Only exists for backwards compatibility + pass + + def __lt__(self, other): + if not hasattr(other, "handler_order"): + # Try to preserve the old behavior of having custom classes + # inserted after default ones (works only for custom user + # classes which are not aware of handler_order). + return True + return self.handler_order < other.handler_order + + +class HTTPErrorProcessor(BaseHandler): + """Process HTTP error responses.""" + handler_order = 1000 # after all other processing + + def http_response(self, request, response): + code, msg, hdrs = response.code, response.msg, response.info() + + # According to RFC 2616, "2xx" code indicates that the client's + # request was successfully received, understood, and accepted. + if not (200 <= code < 300): + response = self.parent.error( + 'http', request, response, code, msg, hdrs) + + return response + + https_response = http_response + +class HTTPDefaultErrorHandler(BaseHandler): + def http_error_default(self, req, fp, code, msg, hdrs): + raise HTTPError(req.get_full_url(), code, msg, hdrs, fp) + +class HTTPRedirectHandler(BaseHandler): + # maximum number of redirections to any single URL + # this is needed because of the state that cookies introduce + max_repeats = 4 + # maximum total number of redirections (regardless of URL) before + # assuming we're in a loop + max_redirections = 10 + + def redirect_request(self, req, fp, code, msg, headers, newurl): + """Return a Request or None in response to a redirect. + + This is called by the http_error_30x methods when a + redirection response is received. If a redirection should + take place, return a new Request to allow http_error_30x to + perform the redirect. Otherwise, raise HTTPError if no-one + else should try to handle this url. Return None if you can't + but another Handler might. + """ + m = req.get_method() + if (code in (301, 302, 303, 307) and m in ("GET", "HEAD") + or code in (301, 302, 303) and m == "POST"): + # Strictly (according to RFC 2616), 301 or 302 in response + # to a POST MUST NOT cause a redirection without confirmation + # from the user (of urllib2, in this case). In practice, + # essentially all clients do redirect in this case, so we + # do the same. + # be conciliant with URIs containing a space + newurl = newurl.replace(' ', '%20') + newheaders = dict((k,v) for k,v in req.headers.items() + if k.lower() not in ("content-length", "content-type") + ) + return Request(newurl, + headers=newheaders, + origin_req_host=req.get_origin_req_host(), + unverifiable=True) + else: + raise HTTPError(req.get_full_url(), code, msg, headers, fp) + + # Implementation note: To avoid the server sending us into an + # infinite loop, the request object needs to track what URLs we + # have already seen. Do this by adding a handler-specific + # attribute to the Request object. + def http_error_302(self, req, fp, code, msg, headers): + # Some servers (incorrectly) return multiple Location headers + # (so probably same goes for URI). Use first header. + if 'location' in headers: + newurl = headers.getheaders('location')[0] + elif 'uri' in headers: + newurl = headers.getheaders('uri')[0] + else: + return + + # fix a possible malformed URL + urlparts = urlparse.urlparse(newurl) + if not urlparts.path: + urlparts = list(urlparts) + urlparts[2] = "/" + newurl = urlparse.urlunparse(urlparts) + + newurl = urlparse.urljoin(req.get_full_url(), newurl) + + # For security reasons we do not allow redirects to protocols + # other than HTTP, HTTPS or FTP. + newurl_lower = newurl.lower() + if not (newurl_lower.startswith('http://') or + newurl_lower.startswith('https://') or + newurl_lower.startswith('ftp://')): + raise HTTPError(newurl, code, + msg + " - Redirection to url '%s' is not allowed" % + newurl, + headers, fp) + + # XXX Probably want to forget about the state of the current + # request, although that might interact poorly with other + # handlers that also use handler-specific request attributes + new = self.redirect_request(req, fp, code, msg, headers, newurl) + if new is None: + return + + # loop detection + # .redirect_dict has a key url if url was previously visited. + if hasattr(req, 'redirect_dict'): + visited = new.redirect_dict = req.redirect_dict + if (visited.get(newurl, 0) >= self.max_repeats or + len(visited) >= self.max_redirections): + raise HTTPError(req.get_full_url(), code, + self.inf_msg + msg, headers, fp) + else: + visited = new.redirect_dict = req.redirect_dict = {} + visited[newurl] = visited.get(newurl, 0) + 1 + + # Don't close the fp until we are sure that we won't use it + # with HTTPError. + fp.read() + fp.close() + + return self.parent.open(new, timeout=req.timeout) + + http_error_301 = http_error_303 = http_error_307 = http_error_302 + + inf_msg = "The HTTP server returned a redirect error that would " \ + "lead to an infinite loop.\n" \ + "The last 30x error message was:\n" + + +def _parse_proxy(proxy): + """Return (scheme, user, password, host/port) given a URL or an authority. + + If a URL is supplied, it must have an authority (host:port) component. + According to RFC 3986, having an authority component means the URL must + have two slashes after the scheme: + + >>> _parse_proxy('file:/ftp.example.com/') + Traceback (most recent call last): + ValueError: proxy URL with no authority: 'file:/ftp.example.com/' + + The first three items of the returned tuple may be None. + + Examples of authority parsing: + + >>> _parse_proxy('proxy.example.com') + (None, None, None, 'proxy.example.com') + >>> _parse_proxy('proxy.example.com:3128') + (None, None, None, 'proxy.example.com:3128') + + The authority component may optionally include userinfo (assumed to be + username:password): + + >>> _parse_proxy('joe:password@proxy.example.com') + (None, 'joe', 'password', 'proxy.example.com') + >>> _parse_proxy('joe:password@proxy.example.com:3128') + (None, 'joe', 'password', 'proxy.example.com:3128') + + Same examples, but with URLs instead: + + >>> _parse_proxy('http://proxy.example.com/') + ('http', None, None, 'proxy.example.com') + >>> _parse_proxy('http://proxy.example.com:3128/') + ('http', None, None, 'proxy.example.com:3128') + >>> _parse_proxy('http://joe:password@proxy.example.com/') + ('http', 'joe', 'password', 'proxy.example.com') + >>> _parse_proxy('http://joe:password@proxy.example.com:3128') + ('http', 'joe', 'password', 'proxy.example.com:3128') + + Everything after the authority is ignored: + + >>> _parse_proxy('ftp://joe:password@proxy.example.com/rubbish:3128') + ('ftp', 'joe', 'password', 'proxy.example.com') + + Test for no trailing '/' case: + + >>> _parse_proxy('http://joe:password@proxy.example.com') + ('http', 'joe', 'password', 'proxy.example.com') + + """ + scheme, r_scheme = splittype(proxy) + if not r_scheme.startswith("/"): + # authority + scheme = None + authority = proxy + else: + # URL + if not r_scheme.startswith("//"): + raise ValueError("proxy URL with no authority: %r" % proxy) + # We have an authority, so for RFC 3986-compliant URLs (by ss 3. + # and 3.3.), path is empty or starts with '/' + end = r_scheme.find("/", 2) + if end == -1: + end = None + authority = r_scheme[2:end] + userinfo, hostport = splituser(authority) + if userinfo is not None: + user, password = splitpasswd(userinfo) + else: + user = password = None + return scheme, user, password, hostport + +class ProxyHandler(BaseHandler): + # Proxies must be in front + handler_order = 100 + + def __init__(self, proxies=None): + if proxies is None: + proxies = getproxies() + assert hasattr(proxies, 'has_key'), "proxies must be a mapping" + self.proxies = proxies + for type, url in proxies.items(): + setattr(self, '%s_open' % type, + lambda r, proxy=url, type=type, meth=self.proxy_open: \ + meth(r, proxy, type)) + + def proxy_open(self, req, proxy, type): + orig_type = req.get_type() + proxy_type, user, password, hostport = _parse_proxy(proxy) + + if proxy_type is None: + proxy_type = orig_type + + if req.host and proxy_bypass(req.host): + return None + + if user and password: + user_pass = '%s:%s' % (unquote(user), unquote(password)) + creds = base64.b64encode(user_pass).strip() + req.add_header('Proxy-authorization', 'Basic ' + creds) + hostport = unquote(hostport) + req.set_proxy(hostport, proxy_type) + + if orig_type == proxy_type or orig_type == 'https': + # let other handlers take care of it + return None + else: + # need to start over, because the other handlers don't + # grok the proxy's URL type + # e.g. if we have a constructor arg proxies like so: + # {'http': 'ftp://proxy.example.com'}, we may end up turning + # a request for http://acme.example.com/a into one for + # ftp://proxy.example.com/a + return self.parent.open(req, timeout=req.timeout) + +class HTTPPasswordMgr: + + def __init__(self): + self.passwd = {} + + def add_password(self, realm, uri, user, passwd): + # uri could be a single URI or a sequence + if isinstance(uri, basestring): + uri = [uri] + if not realm in self.passwd: + self.passwd[realm] = {} + for default_port in True, False: + reduced_uri = tuple( + [self.reduce_uri(u, default_port) for u in uri]) + self.passwd[realm][reduced_uri] = (user, passwd) + + def find_user_password(self, realm, authuri): + domains = self.passwd.get(realm, {}) + for default_port in True, False: + reduced_authuri = self.reduce_uri(authuri, default_port) + for uris, authinfo in domains.iteritems(): + for uri in uris: + if self.is_suburi(uri, reduced_authuri): + return authinfo + return None, None + + def reduce_uri(self, uri, default_port=True): + """Accept authority or URI and extract only the authority and path.""" + # note HTTP URLs do not have a userinfo component + parts = urlparse.urlsplit(uri) + if parts[1]: + # URI + scheme = parts[0] + authority = parts[1] + path = parts[2] or '/' + else: + # host or host:port + scheme = None + authority = uri + path = '/' + host, port = splitport(authority) + if default_port and port is None and scheme is not None: + dport = {"http": 80, + "https": 443, + }.get(scheme) + if dport is not None: + authority = "%s:%d" % (host, dport) + return authority, path + + def is_suburi(self, base, test): + """Check if test is below base in a URI tree + + Both args must be URIs in reduced form. + """ + if base == test: + return True + if base[0] != test[0]: + return False + common = posixpath.commonprefix((base[1], test[1])) + if len(common) == len(base[1]): + return True + return False + + +class HTTPPasswordMgrWithDefaultRealm(HTTPPasswordMgr): + + def find_user_password(self, realm, authuri): + user, password = HTTPPasswordMgr.find_user_password(self, realm, + authuri) + if user is not None: + return user, password + return HTTPPasswordMgr.find_user_password(self, None, authuri) + + +class AbstractBasicAuthHandler: + + # XXX this allows for multiple auth-schemes, but will stupidly pick + # the last one with a realm specified. + + # allow for double- and single-quoted realm values + # (single quotes are a violation of the RFC, but appear in the wild) + rx = re.compile('(?:.*,)*[ \t]*([^ \t]+)[ \t]+' + 'realm=(["\']?)([^"\']*)\\2', re.I) + + # XXX could pre-emptively send auth info already accepted (RFC 2617, + # end of section 2, and section 1.2 immediately after "credentials" + # production). + + def __init__(self, password_mgr=None): + if password_mgr is None: + password_mgr = HTTPPasswordMgr() + self.passwd = password_mgr + self.add_password = self.passwd.add_password + self.retried = 0 + + def reset_retry_count(self): + self.retried = 0 + + def http_error_auth_reqed(self, authreq, host, req, headers): + # host may be an authority (without userinfo) or a URL with an + # authority + # XXX could be multiple headers + authreq = headers.get(authreq, None) + + if self.retried > 5: + # retry sending the username:password 5 times before failing. + raise HTTPError(req.get_full_url(), 401, "basic auth failed", + headers, None) + else: + self.retried += 1 + + if authreq: + mo = AbstractBasicAuthHandler.rx.search(authreq) + if mo: + scheme, quote, realm = mo.groups() + if quote not in ['"', "'"]: + warnings.warn("Basic Auth Realm was unquoted", + UserWarning, 2) + if scheme.lower() == 'basic': + response = self.retry_http_basic_auth(host, req, realm) + if response and response.code != 401: + self.retried = 0 + return response + + def retry_http_basic_auth(self, host, req, realm): + user, pw = self.passwd.find_user_password(realm, host) + if pw is not None: + raw = "%s:%s" % (user, pw) + auth = 'Basic %s' % base64.b64encode(raw).strip() + if req.headers.get(self.auth_header, None) == auth: + return None + req.add_unredirected_header(self.auth_header, auth) + return self.parent.open(req, timeout=req.timeout) + else: + return None + + +class HTTPBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): + + auth_header = 'Authorization' + + def http_error_401(self, req, fp, code, msg, headers): + url = req.get_full_url() + response = self.http_error_auth_reqed('www-authenticate', + url, req, headers) + self.reset_retry_count() + return response + + +class ProxyBasicAuthHandler(AbstractBasicAuthHandler, BaseHandler): + + auth_header = 'Proxy-authorization' + + def http_error_407(self, req, fp, code, msg, headers): + # http_error_auth_reqed requires that there is no userinfo component in + # authority. Assume there isn't one, since urllib2 does not (and + # should not, RFC 3986 s. 3.2.1) support requests for URLs containing + # userinfo. + authority = req.get_host() + response = self.http_error_auth_reqed('proxy-authenticate', + authority, req, headers) + self.reset_retry_count() + return response + + +def randombytes(n): + """Return n random bytes.""" + # Use /dev/urandom if it is available. Fall back to random module + # if not. It might be worthwhile to extend this function to use + # other platform-specific mechanisms for getting random bytes. + if os.path.exists("/dev/urandom"): + f = open("/dev/urandom") + s = f.read(n) + f.close() + return s + else: + L = [chr(random.randrange(0, 256)) for i in range(n)] + return "".join(L) + +class AbstractDigestAuthHandler: + # Digest authentication is specified in RFC 2617. + + # XXX The client does not inspect the Authentication-Info header + # in a successful response. + + # XXX It should be possible to test this implementation against + # a mock server that just generates a static set of challenges. + + # XXX qop="auth-int" supports is shaky + + def __init__(self, passwd=None): + if passwd is None: + passwd = HTTPPasswordMgr() + self.passwd = passwd + self.add_password = self.passwd.add_password + self.retried = 0 + self.nonce_count = 0 + self.last_nonce = None + + def reset_retry_count(self): + self.retried = 0 + + def http_error_auth_reqed(self, auth_header, host, req, headers): + authreq = headers.get(auth_header, None) + if self.retried > 5: + # Don't fail endlessly - if we failed once, we'll probably + # fail a second time. Hm. Unless the Password Manager is + # prompting for the information. Crap. This isn't great + # but it's better than the current 'repeat until recursion + # depth exceeded' approach <wink> + raise HTTPError(req.get_full_url(), 401, "digest auth failed", + headers, None) + else: + self.retried += 1 + if authreq: + scheme = authreq.split()[0] + if scheme.lower() == 'digest': + return self.retry_http_digest_auth(req, authreq) + + def retry_http_digest_auth(self, req, auth): + token, challenge = auth.split(' ', 1) + chal = parse_keqv_list(parse_http_list(challenge)) + auth = self.get_authorization(req, chal) + if auth: + auth_val = 'Digest %s' % auth + if req.headers.get(self.auth_header, None) == auth_val: + return None + req.add_unredirected_header(self.auth_header, auth_val) + resp = self.parent.open(req, timeout=req.timeout) + return resp + + def get_cnonce(self, nonce): + # The cnonce-value is an opaque + # quoted string value provided by the client and used by both client + # and server to avoid chosen plaintext attacks, to provide mutual + # authentication, and to provide some message integrity protection. + # This isn't a fabulous effort, but it's probably Good Enough. + dig = hashlib.sha1("%s:%s:%s:%s" % (self.nonce_count, nonce, time.ctime(), + randombytes(8))).hexdigest() + return dig[:16] + + def get_authorization(self, req, chal): + try: + realm = chal['realm'] + nonce = chal['nonce'] + qop = chal.get('qop') + algorithm = chal.get('algorithm', 'MD5') + # mod_digest doesn't send an opaque, even though it isn't + # supposed to be optional + opaque = chal.get('opaque', None) + except KeyError: + return None + + H, KD = self.get_algorithm_impls(algorithm) + if H is None: + return None + + user, pw = self.passwd.find_user_password(realm, req.get_full_url()) + if user is None: + return None + + # XXX not implemented yet + if req.has_data(): + entdig = self.get_entity_digest(req.get_data(), chal) + else: + entdig = None + + A1 = "%s:%s:%s" % (user, realm, pw) + A2 = "%s:%s" % (req.get_method(), + # XXX selector: what about proxies and full urls + req.get_selector()) + if qop == 'auth': + if nonce == self.last_nonce: + self.nonce_count += 1 + else: + self.nonce_count = 1 + self.last_nonce = nonce + + ncvalue = '%08x' % self.nonce_count + cnonce = self.get_cnonce(nonce) + noncebit = "%s:%s:%s:%s:%s" % (nonce, ncvalue, cnonce, qop, H(A2)) + respdig = KD(H(A1), noncebit) + elif qop is None: + respdig = KD(H(A1), "%s:%s" % (nonce, H(A2))) + else: + # XXX handle auth-int. + raise URLError("qop '%s' is not supported." % qop) + + # XXX should the partial digests be encoded too? + + base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ + 'response="%s"' % (user, realm, nonce, req.get_selector(), + respdig) + if opaque: + base += ', opaque="%s"' % opaque + if entdig: + base += ', digest="%s"' % entdig + base += ', algorithm="%s"' % algorithm + if qop: + base += ', qop=auth, nc=%s, cnonce="%s"' % (ncvalue, cnonce) + return base + + def get_algorithm_impls(self, algorithm): + # algorithm should be case-insensitive according to RFC2617 + algorithm = algorithm.upper() + # lambdas assume digest modules are imported at the top level + if algorithm == 'MD5': + H = lambda x: hashlib.md5(x).hexdigest() + elif algorithm == 'SHA': + H = lambda x: hashlib.sha1(x).hexdigest() + # XXX MD5-sess + KD = lambda s, d: H("%s:%s" % (s, d)) + return H, KD + + def get_entity_digest(self, data, chal): + # XXX not implemented yet + return None + + +class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): + """An authentication protocol defined by RFC 2069 + + Digest authentication improves on basic authentication because it + does not transmit passwords in the clear. + """ + + auth_header = 'Authorization' + handler_order = 490 # before Basic auth + + def http_error_401(self, req, fp, code, msg, headers): + host = urlparse.urlparse(req.get_full_url())[1] + retry = self.http_error_auth_reqed('www-authenticate', + host, req, headers) + self.reset_retry_count() + return retry + + +class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): + + auth_header = 'Proxy-Authorization' + handler_order = 490 # before Basic auth + + def http_error_407(self, req, fp, code, msg, headers): + host = req.get_host() + retry = self.http_error_auth_reqed('proxy-authenticate', + host, req, headers) + self.reset_retry_count() + return retry + +class AbstractHTTPHandler(BaseHandler): + + def __init__(self, debuglevel=0): + self._debuglevel = debuglevel + + def set_http_debuglevel(self, level): + self._debuglevel = level + + def do_request_(self, request): + host = request.get_host() + if not host: + raise URLError('no host given') + + if request.has_data(): # POST + data = request.get_data() + if not request.has_header('Content-type'): + request.add_unredirected_header( + 'Content-type', + 'application/x-www-form-urlencoded') + if not request.has_header('Content-length'): + request.add_unredirected_header( + 'Content-length', '%d' % len(data)) + + sel_host = host + if request.has_proxy(): + scheme, sel = splittype(request.get_selector()) + sel_host, sel_path = splithost(sel) + + if not request.has_header('Host'): + request.add_unredirected_header('Host', sel_host) + for name, value in self.parent.addheaders: + name = name.capitalize() + if not request.has_header(name): + request.add_unredirected_header(name, value) + + return request + + def do_open(self, http_class, req): + """Return an addinfourl object for the request, using http_class. + + http_class must implement the HTTPConnection API from httplib. + The addinfourl return value is a file-like object. It also + has methods and attributes including: + - info(): return a mimetools.Message object for the headers + - geturl(): return the original request URL + - code: HTTP status code + """ + host = req.get_host() + if not host: + raise URLError('no host given') + + h = http_class(host, timeout=req.timeout) # will parse host:port + h.set_debuglevel(self._debuglevel) + + headers = dict(req.unredirected_hdrs) + headers.update(dict((k, v) for k, v in req.headers.items() + if k not in headers)) + + # We want to make an HTTP/1.1 request, but the addinfourl + # class isn't prepared to deal with a persistent connection. + # It will try to read all remaining data from the socket, + # which will block while the server waits for the next request. + # So make sure the connection gets closed after the (only) + # request. + headers["Connection"] = "close" + headers = dict( + (name.title(), val) for name, val in headers.items()) + + if req._tunnel_host: + tunnel_headers = {} + proxy_auth_hdr = "Proxy-Authorization" + if proxy_auth_hdr in headers: + tunnel_headers[proxy_auth_hdr] = headers[proxy_auth_hdr] + # Proxy-Authorization should not be sent to origin + # server. + del headers[proxy_auth_hdr] + h.set_tunnel(req._tunnel_host, headers=tunnel_headers) + + try: + h.request(req.get_method(), req.get_selector(), req.data, headers) + except socket.error, err: # XXX what error? + h.close() + raise URLError(err) + else: + try: + r = h.getresponse(buffering=True) + except TypeError: # buffering kw not supported + r = h.getresponse() + + # Pick apart the HTTPResponse object to get the addinfourl + # object initialized properly. + + # Wrap the HTTPResponse object in socket's file object adapter + # for Windows. That adapter calls recv(), so delegate recv() + # to read(). This weird wrapping allows the returned object to + # have readline() and readlines() methods. + + # XXX It might be better to extract the read buffering code + # out of socket._fileobject() and into a base class. + + r.recv = r.read + fp = socket._fileobject(r, close=True) + + resp = addinfourl(fp, r.msg, req.get_full_url()) + resp.code = r.status + resp.msg = r.reason + return resp + + +class HTTPHandler(AbstractHTTPHandler): + + def http_open(self, req): + return self.do_open(httplib.HTTPConnection, req) + + http_request = AbstractHTTPHandler.do_request_ + +if hasattr(httplib, 'HTTPS'): + class HTTPSHandler(AbstractHTTPHandler): + + def https_open(self, req): + return self.do_open(httplib.HTTPSConnection, req) + + https_request = AbstractHTTPHandler.do_request_ + +class HTTPCookieProcessor(BaseHandler): + def __init__(self, cookiejar=None): + import cookielib + if cookiejar is None: + cookiejar = cookielib.CookieJar() + self.cookiejar = cookiejar + + def http_request(self, request): + self.cookiejar.add_cookie_header(request) + return request + + def http_response(self, request, response): + self.cookiejar.extract_cookies(response, request) + return response + + https_request = http_request + https_response = http_response + +class UnknownHandler(BaseHandler): + def unknown_open(self, req): + type = req.get_type() + raise URLError('unknown url type: %s' % type) + +def parse_keqv_list(l): + """Parse list of key=value strings where keys are not duplicated.""" + parsed = {} + for elt in l: + k, v = elt.split('=', 1) + if v[0] == '"' and v[-1] == '"': + v = v[1:-1] + parsed[k] = v + return parsed + +def parse_http_list(s): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Neither commas nor quotes count if they are escaped. + Only double-quotes count, not single-quotes. + """ + res = [] + part = '' + + escape = quote = False + for cur in s: + if escape: + part += cur + escape = False + continue + if quote: + if cur == '\\': + escape = True + continue + elif cur == '"': + quote = False + part += cur + continue + + if cur == ',': + res.append(part) + part = '' + continue + + if cur == '"': + quote = True + + part += cur + + # append last part + if part: + res.append(part) + + return [part.strip() for part in res] + +def _safe_gethostbyname(host): + try: + return socket.gethostbyname(host) + except socket.gaierror: + return None + +class FileHandler(BaseHandler): + # Use local file or FTP depending on form of URL + def file_open(self, req): + url = req.get_selector() + if url[:2] == '//' and url[2:3] != '/' and (req.host and + req.host != 'localhost'): + req.type = 'ftp' + return self.parent.open(req) + else: + return self.open_local_file(req) + + # names for the localhost + names = None + def get_names(self): + if FileHandler.names is None: + try: + FileHandler.names = tuple( + socket.gethostbyname_ex('localhost')[2] + + socket.gethostbyname_ex(socket.gethostname())[2]) + except socket.gaierror: + FileHandler.names = (socket.gethostbyname('localhost'),) + return FileHandler.names + + # not entirely sure what the rules are here + def open_local_file(self, req): + import email.utils + import mimetypes + host = req.get_host() + filename = req.get_selector() + localfile = url2pathname(filename) + try: + stats = os.stat(localfile) + size = stats.st_size + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) + mtype = mimetypes.guess_type(filename)[0] + headers = mimetools.Message(StringIO( + 'Content-type: %s\nContent-length: %d\nLast-modified: %s\n' % + (mtype or 'text/plain', size, modified))) + if host: + host, port = splitport(host) + if not host or \ + (not port and _safe_gethostbyname(host) in self.get_names()): + if host: + origurl = 'file://' + host + filename + else: + origurl = 'file://' + filename + return addinfourl(open(localfile, 'rb'), headers, origurl) + except OSError, msg: + # urllib2 users shouldn't expect OSErrors coming from urlopen() + raise URLError(msg) + raise URLError('file not on local host') + +class FTPHandler(BaseHandler): + def ftp_open(self, req): + import ftplib + import mimetypes + host = req.get_host() + if not host: + raise URLError('ftp error: no host given') + host, port = splitport(host) + if port is None: + port = ftplib.FTP_PORT + else: + port = int(port) + + # username/password handling + user, host = splituser(host) + if user: + user, passwd = splitpasswd(user) + else: + passwd = None + host = unquote(host) + user = user or '' + passwd = passwd or '' + + try: + host = socket.gethostbyname(host) + except socket.error, msg: + raise URLError(msg) + path, attrs = splitattr(req.get_selector()) + dirs = path.split('/') + dirs = map(unquote, dirs) + dirs, file = dirs[:-1], dirs[-1] + if dirs and not dirs[0]: + dirs = dirs[1:] + try: + fw = self.connect_ftp(user, passwd, host, port, dirs, req.timeout) + type = file and 'I' or 'D' + for attr in attrs: + attr, value = splitvalue(attr) + if attr.lower() == 'type' and \ + value in ('a', 'A', 'i', 'I', 'd', 'D'): + type = value.upper() + fp, retrlen = fw.retrfile(file, type) + headers = "" + mtype = mimetypes.guess_type(req.get_full_url())[0] + if mtype: + headers += "Content-type: %s\n" % mtype + if retrlen is not None and retrlen >= 0: + headers += "Content-length: %d\n" % retrlen + sf = StringIO(headers) + headers = mimetools.Message(sf) + return addinfourl(fp, headers, req.get_full_url()) + except ftplib.all_errors, msg: + raise URLError, ('ftp error: %s' % msg), sys.exc_info()[2] + + def connect_ftp(self, user, passwd, host, port, dirs, timeout): + fw = ftpwrapper(user, passwd, host, port, dirs, timeout, + persistent=False) +## fw.ftp.set_debuglevel(1) + return fw + +class CacheFTPHandler(FTPHandler): + # XXX would be nice to have pluggable cache strategies + # XXX this stuff is definitely not thread safe + def __init__(self): + self.cache = {} + self.timeout = {} + self.soonest = 0 + self.delay = 60 + self.max_conns = 16 + + def setTimeout(self, t): + self.delay = t + + def setMaxConns(self, m): + self.max_conns = m + + def connect_ftp(self, user, passwd, host, port, dirs, timeout): + key = user, host, port, '/'.join(dirs), timeout + if key in self.cache: + self.timeout[key] = time.time() + self.delay + else: + self.cache[key] = ftpwrapper(user, passwd, host, port, dirs, timeout) + self.timeout[key] = time.time() + self.delay + self.check_cache() + return self.cache[key] + + def check_cache(self): + # first check for old ones + t = time.time() + if self.soonest <= t: + for k, v in self.timeout.items(): + if v < t: + self.cache[k].close() + del self.cache[k] + del self.timeout[k] + self.soonest = min(self.timeout.values()) + + # then check the size + if len(self.cache) == self.max_conns: + for k, v in self.timeout.items(): + if v == self.soonest: + del self.cache[k] + del self.timeout[k] + break + self.soonest = min(self.timeout.values()) + + def clear_cache(self): + for conn in self.cache.values(): + conn.close() + self.cache.clear() + self.timeout.clear() diff --git a/src/main/resources/PythonLibs/urlparse.py b/src/main/resources/PythonLibs/urlparse.py new file mode 100644 index 0000000000000000000000000000000000000000..f370ce3bdcc17b11e446a1e83a7df74d50c6b7cb --- /dev/null +++ b/src/main/resources/PythonLibs/urlparse.py @@ -0,0 +1,403 @@ +"""Parse (absolute and relative) URLs. + +urlparse module is based upon the following RFC specifications. + +RFC 3986 (STD66): "Uniform Resource Identifiers" by T. Berners-Lee, R. Fielding +and L. Masinter, January 2005. + +RFC 2732 : "Format for Literal IPv6 Addresses in URL's by R.Hinden, B.Carpenter +and L.Masinter, December 1999. + +RFC 2396: "Uniform Resource Identifiers (URI)": Generic Syntax by T. +Berners-Lee, R. Fielding, and L. Masinter, August 1998. + +RFC 2368: "The mailto URL scheme", by P.Hoffman , L Masinter, J. Zwinski, July 1998. + +RFC 1808: "Relative Uniform Resource Locators", by R. Fielding, UC Irvine, June +1995. + +RFC 1738: "Uniform Resource Locators (URL)" by T. Berners-Lee, L. Masinter, M. +McCahill, December 1994 + +RFC 3986 is considered the current standard and any future changes to +urlparse module should conform with it. The urlparse module is +currently not entirely compliant with this RFC due to defacto +scenarios for parsing, and for backward compatibility purposes, some +parsing quirks from older RFCs are retained. The testcases in +test_urlparse.py provides a good indicator of parsing behavior. + +""" + +__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag", + "urlsplit", "urlunsplit", "parse_qs", "parse_qsl"] + +# A classification of schemes ('' means apply by default) +uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap', + 'wais', 'file', 'https', 'shttp', 'mms', + 'prospero', 'rtsp', 'rtspu', '', 'sftp', + 'svn', 'svn+ssh'] +uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', + 'imap', 'wais', 'file', 'mms', 'https', 'shttp', + 'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', '', + 'svn', 'svn+ssh', 'sftp','nfs','git', 'git+ssh'] +uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap', + 'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips', + 'mms', '', 'sftp', 'tel'] + +# These are not actually used anymore, but should stay for backwards +# compatibility. (They are undocumented, but have a public-looking name.) +non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', + 'telnet', 'wais', 'imap', 'snews', 'sip', 'sips'] +uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'mms', + 'gopher', 'rtsp', 'rtspu', 'sip', 'sips', ''] +uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news', + 'nntp', 'wais', 'https', 'shttp', 'snews', + 'file', 'prospero', ''] + +# Characters valid in scheme names +scheme_chars = ('abcdefghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + '0123456789' + '+-.') + +MAX_CACHE_SIZE = 20 +_parse_cache = {} + +def clear_cache(): + """Clear the parse cache.""" + _parse_cache.clear() + + +class ResultMixin(object): + """Shared methods for the parsed result objects.""" + + @property + def username(self): + netloc = self.netloc + if "@" in netloc: + userinfo = netloc.rsplit("@", 1)[0] + if ":" in userinfo: + userinfo = userinfo.split(":", 1)[0] + return userinfo + return None + + @property + def password(self): + netloc = self.netloc + if "@" in netloc: + userinfo = netloc.rsplit("@", 1)[0] + if ":" in userinfo: + return userinfo.split(":", 1)[1] + return None + + @property + def hostname(self): + netloc = self.netloc.split('@')[-1] + if '[' in netloc and ']' in netloc: + return netloc.split(']')[0][1:].lower() + elif ':' in netloc: + return netloc.split(':')[0].lower() + elif netloc == '': + return None + else: + return netloc.lower() + + @property + def port(self): + netloc = self.netloc.split('@')[-1].split(']')[-1] + if ':' in netloc: + port = netloc.split(':')[1] + port = int(port, 10) + # verify legal port + if (0 <= port <= 65535): + return port + return None + +from collections import namedtuple + +class SplitResult(namedtuple('SplitResult', 'scheme netloc path query fragment'), ResultMixin): + + __slots__ = () + + def geturl(self): + return urlunsplit(self) + + +class ParseResult(namedtuple('ParseResult', 'scheme netloc path params query fragment'), ResultMixin): + + __slots__ = () + + def geturl(self): + return urlunparse(self) + + +def urlparse(url, scheme='', allow_fragments=True): + """Parse a URL into 6 components: + <scheme>://<netloc>/<path>;<params>?<query>#<fragment> + Return a 6-tuple: (scheme, netloc, path, params, query, fragment). + Note that we don't break the components up in smaller bits + (e.g. netloc is a single string) and we don't expand % escapes.""" + tuple = urlsplit(url, scheme, allow_fragments) + scheme, netloc, url, query, fragment = tuple + if scheme in uses_params and ';' in url: + url, params = _splitparams(url) + else: + params = '' + return ParseResult(scheme, netloc, url, params, query, fragment) + +def _splitparams(url): + if '/' in url: + i = url.find(';', url.rfind('/')) + if i < 0: + return url, '' + else: + i = url.find(';') + return url[:i], url[i+1:] + +def _splitnetloc(url, start=0): + delim = len(url) # position of end of domain part of url, default is end + for c in '/?#': # look for delimiters; the order is NOT important + wdelim = url.find(c, start) # find first of this delim + if wdelim >= 0: # if found + delim = min(delim, wdelim) # use earliest delim position + return url[start:delim], url[delim:] # return (domain, rest) + +def urlsplit(url, scheme='', allow_fragments=True): + """Parse a URL into 5 components: + <scheme>://<netloc>/<path>?<query>#<fragment> + Return a 5-tuple: (scheme, netloc, path, query, fragment). + Note that we don't break the components up in smaller bits + (e.g. netloc is a single string) and we don't expand % escapes.""" + allow_fragments = bool(allow_fragments) + key = url, scheme, allow_fragments, type(url), type(scheme) + cached = _parse_cache.get(key, None) + if cached: + return cached + if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth + clear_cache() + netloc = query = fragment = '' + i = url.find(':') + if i > 0: + if url[:i] == 'http': # optimize the common case + scheme = url[:i].lower() + url = url[i+1:] + if url[:2] == '//': + netloc, url = _splitnetloc(url, 2) + if (('[' in netloc and ']' not in netloc) or + (']' in netloc and '[' not in netloc)): + raise ValueError("Invalid IPv6 URL") + if allow_fragments and '#' in url: + url, fragment = url.split('#', 1) + if '?' in url: + url, query = url.split('?', 1) + v = SplitResult(scheme, netloc, url, query, fragment) + _parse_cache[key] = v + return v + for c in url[:i]: + if c not in scheme_chars: + break + else: + # make sure "url" is not actually a port number (in which case + # "scheme" is really part of the path) + rest = url[i+1:] + if not rest or any(c not in '0123456789' for c in rest): + # not a port number + scheme, url = url[:i].lower(), rest + + if url[:2] == '//': + netloc, url = _splitnetloc(url, 2) + if (('[' in netloc and ']' not in netloc) or + (']' in netloc and '[' not in netloc)): + raise ValueError("Invalid IPv6 URL") + if allow_fragments and '#' in url: + url, fragment = url.split('#', 1) + if '?' in url: + url, query = url.split('?', 1) + v = SplitResult(scheme, netloc, url, query, fragment) + _parse_cache[key] = v + return v + +def urlunparse(data): + """Put a parsed URL back together again. This may result in a + slightly different, but equivalent URL, if the URL that was parsed + originally had redundant delimiters, e.g. a ? with an empty query + (the draft states that these are equivalent).""" + scheme, netloc, url, params, query, fragment = data + if params: + url = "%s;%s" % (url, params) + return urlunsplit((scheme, netloc, url, query, fragment)) + +def urlunsplit(data): + """Combine the elements of a tuple as returned by urlsplit() into a + complete URL as a string. The data argument can be any five-item iterable. + This may result in a slightly different, but equivalent URL, if the URL that + was parsed originally had unnecessary delimiters (for example, a ? with an + empty query; the RFC states that these are equivalent).""" + scheme, netloc, url, query, fragment = data + if netloc or (scheme and scheme in uses_netloc and url[:2] != '//'): + if url and url[:1] != '/': url = '/' + url + url = '//' + (netloc or '') + url + if scheme: + url = scheme + ':' + url + if query: + url = url + '?' + query + if fragment: + url = url + '#' + fragment + return url + +def urljoin(base, url, allow_fragments=True): + """Join a base URL and a possibly relative URL to form an absolute + interpretation of the latter.""" + if not base: + return url + if not url: + return base + bscheme, bnetloc, bpath, bparams, bquery, bfragment = \ + urlparse(base, '', allow_fragments) + scheme, netloc, path, params, query, fragment = \ + urlparse(url, bscheme, allow_fragments) + if scheme != bscheme or scheme not in uses_relative: + return url + if scheme in uses_netloc: + if netloc: + return urlunparse((scheme, netloc, path, + params, query, fragment)) + netloc = bnetloc + if path[:1] == '/': + return urlunparse((scheme, netloc, path, + params, query, fragment)) + if not path and not params: + path = bpath + params = bparams + if not query: + query = bquery + return urlunparse((scheme, netloc, path, + params, query, fragment)) + segments = bpath.split('/')[:-1] + path.split('/') + # XXX The stuff below is bogus in various ways... + if segments[-1] == '.': + segments[-1] = '' + while '.' in segments: + segments.remove('.') + while 1: + i = 1 + n = len(segments) - 1 + while i < n: + if (segments[i] == '..' + and segments[i-1] not in ('', '..')): + del segments[i-1:i+1] + break + i = i+1 + else: + break + if segments == ['', '..']: + segments[-1] = '' + elif len(segments) >= 2 and segments[-1] == '..': + segments[-2:] = [''] + return urlunparse((scheme, netloc, '/'.join(segments), + params, query, fragment)) + +def urldefrag(url): + """Removes any existing fragment from URL. + + Returns a tuple of the defragmented URL and the fragment. If + the URL contained no fragments, the second element is the + empty string. + """ + if '#' in url: + s, n, p, a, q, frag = urlparse(url) + defrag = urlunparse((s, n, p, a, q, '')) + return defrag, frag + else: + return url, '' + +# unquote method for parse_qs and parse_qsl +# Cannot use directly from urllib as it would create a circular reference +# because urllib uses urlparse methods (urljoin). If you update this function, +# update it also in urllib. This code duplication does not existin in Python3. + +_hexdig = '0123456789ABCDEFabcdef' +_hextochr = dict((a+b, chr(int(a+b,16))) + for a in _hexdig for b in _hexdig) + +def unquote(s): + """unquote('abc%20def') -> 'abc def'.""" + res = s.split('%') + # fastpath + if len(res) == 1: + return s + s = res[0] + for item in res[1:]: + try: + s += _hextochr[item[:2]] + item[2:] + except KeyError: + s += '%' + item + except UnicodeDecodeError: + s += unichr(int(item[:2], 16)) + item[2:] + return s + +def parse_qs(qs, keep_blank_values=0, strict_parsing=0): + """Parse a query given as a string argument. + + Arguments: + + qs: percent-encoded query string to be parsed + + keep_blank_values: flag indicating whether blank values in + percent-encoded queries should be treated as blank strings. + A true value indicates that blanks should be retained as + blank strings. The default false value indicates that + blank values are to be ignored and treated as if they were + not included. + + strict_parsing: flag indicating what to do with parsing errors. + If false (the default), errors are silently ignored. + If true, errors raise a ValueError exception. + """ + dict = {} + for name, value in parse_qsl(qs, keep_blank_values, strict_parsing): + if name in dict: + dict[name].append(value) + else: + dict[name] = [value] + return dict + +def parse_qsl(qs, keep_blank_values=0, strict_parsing=0): + """Parse a query given as a string argument. + + Arguments: + + qs: percent-encoded query string to be parsed + + keep_blank_values: flag indicating whether blank values in + percent-encoded queries should be treated as blank strings. A + true value indicates that blanks should be retained as blank + strings. The default false value indicates that blank values + are to be ignored and treated as if they were not included. + + strict_parsing: flag indicating what to do with parsing errors. If + false (the default), errors are silently ignored. If true, + errors raise a ValueError exception. + + Returns a list, as G-d intended. + """ + pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] + r = [] + for name_value in pairs: + if not name_value and not strict_parsing: + continue + nv = name_value.split('=', 1) + if len(nv) != 2: + if strict_parsing: + raise ValueError, "bad query field: %r" % (name_value,) + # Handle case of a control-name with no equal sign + if keep_blank_values: + nv.append('') + else: + continue + if len(nv[1]) or keep_blank_values: + name = unquote(nv[0].replace('+', ' ')) + value = unquote(nv[1].replace('+', ' ')) + r.append((name, value)) + + return r diff --git a/src/main/resources/PythonLibs/user.py b/src/main/resources/PythonLibs/user.py new file mode 100644 index 0000000000000000000000000000000000000000..596f0a74628eaa144a6437fec644a2d00df4a392 --- /dev/null +++ b/src/main/resources/PythonLibs/user.py @@ -0,0 +1,48 @@ +"""Hook to allow user-specified customization code to run. + +As a policy, Python doesn't run user-specified code on startup of +Python programs (interactive sessions execute the script specified in +the PYTHONSTARTUP environment variable if it exists). + +However, some programs or sites may find it convenient to allow users +to have a standard customization file, which gets run when a program +requests it. This module implements such a mechanism. A program +that wishes to use the mechanism must execute the statement + + import user + +The user module looks for a file .pythonrc.py in the user's home +directory and if it can be opened, execfile()s it in its own global +namespace. Errors during this phase are not caught; that's up to the +program that imports the user module, if it wishes. + +The user's .pythonrc.py could conceivably test for sys.version if it +wishes to do different things depending on the Python version. + +""" +from warnings import warnpy3k +warnpy3k("the user module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +import os + +home = os.curdir # Default +if 'HOME' in os.environ: + home = os.environ['HOME'] +elif os.name == 'posix': + home = os.path.expanduser("~/") +elif os.name == 'nt': # Contributed by Jeff Bauer + if 'HOMEPATH' in os.environ: + if 'HOMEDRIVE' in os.environ: + home = os.environ['HOMEDRIVE'] + os.environ['HOMEPATH'] + else: + home = os.environ['HOMEPATH'] + +pythonrc = os.path.join(home, ".pythonrc.py") +try: + f = open(pythonrc) +except IOError: + pass +else: + f.close() + execfile(pythonrc) diff --git a/src/main/resources/PythonLibs/uu.py b/src/main/resources/PythonLibs/uu.py new file mode 100644 index 0000000000000000000000000000000000000000..d7726d8143a6468c6aa861ae6748447a0f06b167 --- /dev/null +++ b/src/main/resources/PythonLibs/uu.py @@ -0,0 +1,211 @@ +#! /usr/bin/env python + +# Copyright 1994 by Lance Ellinghouse +# Cathedral City, California Republic, United States of America. +# 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 Lance Ellinghouse +# not be used in advertising or publicity pertaining to distribution +# of the software without specific, written prior permission. +# LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM 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. +# +# Modified by Jack Jansen, CWI, July 1995: +# - Use binascii module to do the actual line-by-line conversion +# between ascii and binary. This results in a 1000-fold speedup. The C +# version is still 5 times faster, though. +# - Arguments more compliant with python standard + +"""Implementation of the UUencode and UUdecode functions. + +encode(in_file, out_file [,name, mode]) +decode(in_file [, out_file, mode]) +""" + +import binascii +import os +import sys + +__all__ = ["Error", "encode", "decode"] + +class Error(Exception): + pass + +def encode(in_file, out_file, name=None, mode=None): + """Uuencode file""" + # + # If in_file is a pathname open it and change defaults + # + + close_in_file = False + close_out_file = False + + if in_file == '-': + in_file = sys.stdin + elif isinstance(in_file, basestring): + if name is None: + name = os.path.basename(in_file) + if mode is None: + try: + mode = os.stat(in_file).st_mode + except AttributeError: + pass + in_file = open(in_file, 'rb') + close_in_file = True + # + # Open out_file if it is a pathname + # + if out_file == '-': + out_file = sys.stdout + elif isinstance(out_file, basestring): + out_file = open(out_file, 'w') + close_out_file = True + # + # Set defaults for name and mode + # + if name is None: + name = '-' + if mode is None: + mode = 0666 + # + # Write the data + # + out_file.write('begin %o %s\n' % ((mode&0777),name)) + data = in_file.read(45) + while len(data) > 0: + out_file.write(binascii.b2a_uu(data)) + data = in_file.read(45) + out_file.write(' \nend\n') + + # Jython and other implementations requires files to be explicitly + # closed if we don't want to wait for GC + if close_in_file: + in_file.close() + if close_out_file: + out_file.close() + +def decode(in_file, out_file=None, mode=None, quiet=0): + """Decode uuencoded file""" + + close_in_file = False + close_out_file = False + + # + # Open the input file, if needed. + # + if in_file == '-': + in_file = sys.stdin + elif isinstance(in_file, basestring): + close_in_file = True + in_file = open(in_file) + # + # Read until a begin is encountered or we've exhausted the file + # + while True: + hdr = in_file.readline() + if not hdr: + raise Error('No valid begin line found in input file') + if not hdr.startswith('begin'): + continue + hdrfields = hdr.split(' ', 2) + if len(hdrfields) == 3 and hdrfields[0] == 'begin': + try: + int(hdrfields[1], 8) + break + except ValueError: + pass + if out_file is None: + out_file = hdrfields[2].rstrip() + if os.path.exists(out_file): + raise Error('Cannot overwrite existing file: %s' % out_file) + if mode is None: + mode = int(hdrfields[1], 8) + # + # Open the output file + # + opened = False + if out_file == '-': + out_file = sys.stdout + elif isinstance(out_file, basestring): + close_out_file = True + fp = open(out_file, 'wb') + try: + os.path.chmod(out_file, mode) + except AttributeError: + pass + out_file = fp + opened = True + # + # Main decoding loop + # + s = in_file.readline() + while s and s.strip() != 'end': + try: + data = binascii.a2b_uu(s) + except binascii.Error, v: + # Workaround for broken uuencoders by /Fredrik Lundh + nbytes = (((ord(s[0])-32) & 63) * 4 + 5) // 3 + data = binascii.a2b_uu(s[:nbytes]) + if not quiet: + sys.stderr.write("Warning: %s\n" % v) + out_file.write(data) + s = in_file.readline() + if not s: + raise Error('Truncated input file') + if opened: + out_file.close() + + # Jython and other implementations requires files to be explicitly + # closed if we don't want to wait for GC + if close_in_file: + in_file.close() + if close_out_file: + out_file.close() + +def test(): + """uuencode/uudecode main program""" + + import optparse + parser = optparse.OptionParser(usage='usage: %prog [-d] [-t] [input [output]]') + parser.add_option('-d', '--decode', dest='decode', help='Decode (instead of encode)?', default=False, action='store_true') + parser.add_option('-t', '--text', dest='text', help='data is text, encoded format unix-compatible text?', default=False, action='store_true') + + (options, args) = parser.parse_args() + if len(args) > 2: + parser.error('incorrect number of arguments') + sys.exit(1) + + input = sys.stdin + output = sys.stdout + if len(args) > 0: + input = args[0] + if len(args) > 1: + output = args[1] + + if options.decode: + if options.text: + if isinstance(output, basestring): + output = open(output, 'w') + else: + print sys.argv[0], ': cannot do -t to stdout' + sys.exit(1) + decode(input, output) + else: + if options.text: + if isinstance(input, basestring): + input = open(input, 'r') + else: + print sys.argv[0], ': cannot do -t from stdin' + sys.exit(1) + encode(input, output) + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/uuid.py b/src/main/resources/PythonLibs/uuid.py new file mode 100644 index 0000000000000000000000000000000000000000..fdd0c5cbec08c26c2e86aaad4460a44badefb661 --- /dev/null +++ b/src/main/resources/PythonLibs/uuid.py @@ -0,0 +1,560 @@ +r"""UUID objects (universally unique identifiers) according to RFC 4122. + +This module provides immutable UUID objects (class UUID) and the functions +uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5 +UUIDs as specified in RFC 4122. + +If all you want is a unique ID, you should probably call uuid1() or uuid4(). +Note that uuid1() may compromise privacy since it creates a UUID containing +the computer's network address. uuid4() creates a random UUID. + +Typical usage: + + >>> import uuid + + # make a UUID based on the host ID and current time + >>> uuid.uuid1() + UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') + + # make a UUID using an MD5 hash of a namespace UUID and a name + >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org') + UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') + + # make a random UUID + >>> uuid.uuid4() + UUID('16fd2706-8baf-433b-82eb-8c7fada847da') + + # make a UUID using a SHA-1 hash of a namespace UUID and a name + >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org') + UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d') + + # make a UUID from a string of hex digits (braces and hyphens ignored) + >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}') + + # convert a UUID to a string of hex digits in standard form + >>> str(x) + '00010203-0405-0607-0809-0a0b0c0d0e0f' + + # get the raw 16 bytes of the UUID + >>> x.bytes + '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' + + # make a UUID from a 16-byte string + >>> uuid.UUID(bytes=x.bytes) + UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') +""" + +__author__ = 'Ka-Ping Yee <ping@zesty.ca>' + +RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [ + 'reserved for NCS compatibility', 'specified in RFC 4122', + 'reserved for Microsoft compatibility', 'reserved for future definition'] + +class UUID(object): + """Instances of the UUID class represent UUIDs as specified in RFC 4122. + UUID objects are immutable, hashable, and usable as dictionary keys. + Converting a UUID to a string with str() yields something in the form + '12345678-1234-1234-1234-123456789abc'. The UUID constructor accepts + five possible forms: a similar string of hexadecimal digits, or a tuple + of six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and + 48-bit values respectively) as an argument named 'fields', or a string + of 16 bytes (with all the integer fields in big-endian order) as an + argument named 'bytes', or a string of 16 bytes (with the first three + fields in little-endian order) as an argument named 'bytes_le', or a + single 128-bit integer as an argument named 'int'. + + UUIDs have these read-only attributes: + + bytes the UUID as a 16-byte string (containing the six + integer fields in big-endian byte order) + + bytes_le the UUID as a 16-byte string (with time_low, time_mid, + and time_hi_version in little-endian byte order) + + fields a tuple of the six integer fields of the UUID, + which are also available as six individual attributes + and two derived attributes: + + time_low the first 32 bits of the UUID + time_mid the next 16 bits of the UUID + time_hi_version the next 16 bits of the UUID + clock_seq_hi_variant the next 8 bits of the UUID + clock_seq_low the next 8 bits of the UUID + node the last 48 bits of the UUID + + time the 60-bit timestamp + clock_seq the 14-bit sequence number + + hex the UUID as a 32-character hexadecimal string + + int the UUID as a 128-bit integer + + urn the UUID as a URN as specified in RFC 4122 + + variant the UUID variant (one of the constants RESERVED_NCS, + RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE) + + version the UUID version number (1 through 5, meaningful only + when the variant is RFC_4122) + """ + + def __init__(self, hex=None, bytes=None, bytes_le=None, fields=None, + int=None, version=None): + r"""Create a UUID from either a string of 32 hexadecimal digits, + a string of 16 bytes as the 'bytes' argument, a string of 16 bytes + in little-endian order as the 'bytes_le' argument, a tuple of six + integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version, + 8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as + the 'fields' argument, or a single 128-bit integer as the 'int' + argument. When a string of hex digits is given, curly braces, + hyphens, and a URN prefix are all optional. For example, these + expressions all yield the same UUID: + + UUID('{12345678-1234-5678-1234-567812345678}') + UUID('12345678123456781234567812345678') + UUID('urn:uuid:12345678-1234-5678-1234-567812345678') + UUID(bytes='\x12\x34\x56\x78'*4) + UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' + + '\x12\x34\x56\x78\x12\x34\x56\x78') + UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)) + UUID(int=0x12345678123456781234567812345678) + + Exactly one of 'hex', 'bytes', 'bytes_le', 'fields', or 'int' must + be given. The 'version' argument is optional; if given, the resulting + UUID will have its variant and version set according to RFC 4122, + overriding the given 'hex', 'bytes', 'bytes_le', 'fields', or 'int'. + """ + + if [hex, bytes, bytes_le, fields, int].count(None) != 4: + raise TypeError('need one of hex, bytes, bytes_le, fields, or int') + if hex is not None: + hex = hex.replace('urn:', '').replace('uuid:', '') + hex = hex.strip('{}').replace('-', '') + if len(hex) != 32: + raise ValueError('badly formed hexadecimal UUID string') + int = long(hex, 16) + if bytes_le is not None: + if len(bytes_le) != 16: + raise ValueError('bytes_le is not a 16-char string') + bytes = (bytes_le[3] + bytes_le[2] + bytes_le[1] + bytes_le[0] + + bytes_le[5] + bytes_le[4] + bytes_le[7] + bytes_le[6] + + bytes_le[8:]) + if bytes is not None: + if len(bytes) != 16: + raise ValueError('bytes is not a 16-char string') + int = long(('%02x'*16) % tuple(map(ord, bytes)), 16) + if fields is not None: + if len(fields) != 6: + raise ValueError('fields is not a 6-tuple') + (time_low, time_mid, time_hi_version, + clock_seq_hi_variant, clock_seq_low, node) = fields + if not 0 <= time_low < 1<<32L: + raise ValueError('field 1 out of range (need a 32-bit value)') + if not 0 <= time_mid < 1<<16L: + raise ValueError('field 2 out of range (need a 16-bit value)') + if not 0 <= time_hi_version < 1<<16L: + raise ValueError('field 3 out of range (need a 16-bit value)') + if not 0 <= clock_seq_hi_variant < 1<<8L: + raise ValueError('field 4 out of range (need an 8-bit value)') + if not 0 <= clock_seq_low < 1<<8L: + raise ValueError('field 5 out of range (need an 8-bit value)') + if not 0 <= node < 1<<48L: + raise ValueError('field 6 out of range (need a 48-bit value)') + clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low + int = ((time_low << 96L) | (time_mid << 80L) | + (time_hi_version << 64L) | (clock_seq << 48L) | node) + if int is not None: + if not 0 <= int < 1<<128L: + raise ValueError('int is out of range (need a 128-bit value)') + if version is not None: + if not 1 <= version <= 5: + raise ValueError('illegal version number') + # Set the variant to RFC 4122. + int &= ~(0xc000 << 48L) + int |= 0x8000 << 48L + # Set the version number. + int &= ~(0xf000 << 64L) + int |= version << 76L + self.__dict__['int'] = int + + def __cmp__(self, other): + if isinstance(other, UUID): + return cmp(self.int, other.int) + return NotImplemented + + def __hash__(self): + return hash(self.int) + + def __int__(self): + return self.int + + def __repr__(self): + return 'UUID(%r)' % str(self) + + def __setattr__(self, name, value): + raise TypeError('UUID objects are immutable') + + def __str__(self): + hex = '%032x' % self.int + return '%s-%s-%s-%s-%s' % ( + hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:]) + + def get_bytes(self): + bytes = '' + for shift in range(0, 128, 8): + bytes = chr((self.int >> shift) & 0xff) + bytes + return bytes + + bytes = property(get_bytes) + + def get_bytes_le(self): + bytes = self.bytes + return (bytes[3] + bytes[2] + bytes[1] + bytes[0] + + bytes[5] + bytes[4] + bytes[7] + bytes[6] + bytes[8:]) + + bytes_le = property(get_bytes_le) + + def get_fields(self): + return (self.time_low, self.time_mid, self.time_hi_version, + self.clock_seq_hi_variant, self.clock_seq_low, self.node) + + fields = property(get_fields) + + def get_time_low(self): + return self.int >> 96L + + time_low = property(get_time_low) + + def get_time_mid(self): + return (self.int >> 80L) & 0xffff + + time_mid = property(get_time_mid) + + def get_time_hi_version(self): + return (self.int >> 64L) & 0xffff + + time_hi_version = property(get_time_hi_version) + + def get_clock_seq_hi_variant(self): + return (self.int >> 56L) & 0xff + + clock_seq_hi_variant = property(get_clock_seq_hi_variant) + + def get_clock_seq_low(self): + return (self.int >> 48L) & 0xff + + clock_seq_low = property(get_clock_seq_low) + + def get_time(self): + return (((self.time_hi_version & 0x0fffL) << 48L) | + (self.time_mid << 32L) | self.time_low) + + time = property(get_time) + + def get_clock_seq(self): + return (((self.clock_seq_hi_variant & 0x3fL) << 8L) | + self.clock_seq_low) + + clock_seq = property(get_clock_seq) + + def get_node(self): + return self.int & 0xffffffffffff + + node = property(get_node) + + def get_hex(self): + return '%032x' % self.int + + hex = property(get_hex) + + def get_urn(self): + return 'urn:uuid:' + str(self) + + urn = property(get_urn) + + def get_variant(self): + if not self.int & (0x8000 << 48L): + return RESERVED_NCS + elif not self.int & (0x4000 << 48L): + return RFC_4122 + elif not self.int & (0x2000 << 48L): + return RESERVED_MICROSOFT + else: + return RESERVED_FUTURE + + variant = property(get_variant) + + def get_version(self): + # The version bits are only meaningful for RFC 4122 UUIDs. + if self.variant == RFC_4122: + return int((self.int >> 76L) & 0xf) + + version = property(get_version) + +def _find_mac(command, args, hw_identifiers, get_index): + import os + for dir in ['', '/sbin/', '/usr/sbin']: + executable = os.path.join(dir, command) + if not os.path.exists(executable): + continue + + try: + # LC_ALL to get English output, 2>/dev/null to + # prevent output on stderr + cmd = 'LC_ALL=C %s %s 2>/dev/null' % (executable, args) + with os.popen(cmd) as pipe: + for line in pipe: + words = line.lower().split() + for i in range(len(words)): + if words[i] in hw_identifiers: + return int( + words[get_index(i)].replace(':', ''), 16) + except IOError: + continue + return None + +def _ifconfig_getnode(): + """Get the hardware address on Unix by running ifconfig.""" + + # This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes. + for args in ('', '-a', '-av'): + mac = _find_mac('ifconfig', args, ['hwaddr', 'ether'], lambda i: i+1) + if mac: + return mac + + import socket + ip_addr = socket.gethostbyname(socket.gethostname()) + + # Try getting the MAC addr from arp based on our IP address (Solaris). + mac = _find_mac('arp', '-an', [ip_addr], lambda i: -1) + if mac: + return mac + + # This might work on HP-UX. + mac = _find_mac('lanscan', '-ai', ['lan0'], lambda i: 0) + if mac: + return mac + + return None + +def _ipconfig_getnode(): + """Get the hardware address on Windows by running ipconfig.exe.""" + import os, re + dirs = ['', r'c:\windows\system32', r'c:\winnt\system32'] + try: + import ctypes + buffer = ctypes.create_string_buffer(300) + ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300) + dirs.insert(0, buffer.value.decode('mbcs')) + except: + pass + for dir in dirs: + try: + pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all') + except IOError: + continue + else: + for line in pipe: + value = line.split(':')[-1].strip().lower() + if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value): + return int(value.replace('-', ''), 16) + finally: + pipe.close() + +def _netbios_getnode(): + """Get the hardware address on Windows using NetBIOS calls. + See http://support.microsoft.com/kb/118623 for details.""" + import win32wnet, netbios + ncb = netbios.NCB() + ncb.Command = netbios.NCBENUM + ncb.Buffer = adapters = netbios.LANA_ENUM() + adapters._pack() + if win32wnet.Netbios(ncb) != 0: + return + adapters._unpack() + for i in range(adapters.length): + ncb.Reset() + ncb.Command = netbios.NCBRESET + ncb.Lana_num = ord(adapters.lana[i]) + if win32wnet.Netbios(ncb) != 0: + continue + ncb.Reset() + ncb.Command = netbios.NCBASTAT + ncb.Lana_num = ord(adapters.lana[i]) + ncb.Callname = '*'.ljust(16) + ncb.Buffer = status = netbios.ADAPTER_STATUS() + if win32wnet.Netbios(ncb) != 0: + continue + status._unpack() + bytes = map(ord, status.adapter_address) + return ((bytes[0]<<40L) + (bytes[1]<<32L) + (bytes[2]<<24L) + + (bytes[3]<<16L) + (bytes[4]<<8L) + bytes[5]) + +# Thanks to Thomas Heller for ctypes and for his help with its use here. + +# If ctypes is available, use it to find system routines for UUID generation. +_uuid_generate_random = _uuid_generate_time = _UuidCreate = None +try: + import ctypes, ctypes.util + + # The uuid_generate_* routines are provided by libuuid on at least + # Linux and FreeBSD, and provided by libc on Mac OS X. + for libname in ['uuid', 'c']: + try: + lib = ctypes.CDLL(ctypes.util.find_library(libname)) + except: + continue + if hasattr(lib, 'uuid_generate_random'): + _uuid_generate_random = lib.uuid_generate_random + if hasattr(lib, 'uuid_generate_time'): + _uuid_generate_time = lib.uuid_generate_time + + # The uuid_generate_* functions are broken on MacOS X 10.5, as noted + # in issue #8621 the function generates the same sequence of values + # in the parent process and all children created using fork (unless + # those children use exec as well). + # + # Assume that the uuid_generate functions are broken from 10.5 onward, + # the test can be adjusted when a later version is fixed. + import sys + if sys.platform == 'darwin': + import os + if int(os.uname()[2].split('.')[0]) >= 9: + _uuid_generate_random = _uuid_generate_time = None + + # On Windows prior to 2000, UuidCreate gives a UUID containing the + # hardware address. On Windows 2000 and later, UuidCreate makes a + # random UUID and UuidCreateSequential gives a UUID containing the + # hardware address. These routines are provided by the RPC runtime. + # NOTE: at least on Tim's WinXP Pro SP2 desktop box, while the last + # 6 bytes returned by UuidCreateSequential are fixed, they don't appear + # to bear any relationship to the MAC address of any network device + # on the box. + try: + lib = ctypes.windll.rpcrt4 + except: + lib = None + _UuidCreate = getattr(lib, 'UuidCreateSequential', + getattr(lib, 'UuidCreate', None)) +except: + pass + +def _unixdll_getnode(): + """Get the hardware address on Unix using ctypes.""" + _buffer = ctypes.create_string_buffer(16) + _uuid_generate_time(_buffer) + return UUID(bytes=_buffer.raw).node + +def _windll_getnode(): + """Get the hardware address on Windows using ctypes.""" + _buffer = ctypes.create_string_buffer(16) + if _UuidCreate(_buffer) == 0: + return UUID(bytes=_buffer.raw).node + +def _random_getnode(): + """Get a random node ID, with eighth bit set as suggested by RFC 4122.""" + import random + return random.randrange(0, 1<<48L) | 0x010000000000L + +_node = None + +def getnode(): + """Get the hardware address as a 48-bit positive integer. + + The first time this runs, it may launch a separate program, which could + be quite slow. If all attempts to obtain the hardware address fail, we + choose a random 48-bit number with its eighth bit set to 1 as recommended + in RFC 4122. + """ + + global _node + if _node is not None: + return _node + + import sys + if sys.platform == 'win32': + getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode] + else: + getters = [_unixdll_getnode, _ifconfig_getnode] + + for getter in getters + [_random_getnode]: + try: + _node = getter() + except: + continue + if _node is not None: + return _node + +_last_timestamp = None + +def uuid1(node=None, clock_seq=None): + """Generate a UUID from a host ID, sequence number, and the current time. + If 'node' is not given, getnode() is used to obtain the hardware + address. If 'clock_seq' is given, it is used as the sequence number; + otherwise a random 14-bit sequence number is chosen.""" + + # When the system provides a version-1 UUID generator, use it (but don't + # use UuidCreate here because its UUIDs don't conform to RFC 4122). + if _uuid_generate_time and node is clock_seq is None: + _buffer = ctypes.create_string_buffer(16) + _uuid_generate_time(_buffer) + return UUID(bytes=_buffer.raw) + + global _last_timestamp + import time + nanoseconds = int(time.time() * 1e9) + # 0x01b21dd213814000 is the number of 100-ns intervals between the + # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. + timestamp = int(nanoseconds//100) + 0x01b21dd213814000L + if _last_timestamp is not None and timestamp <= _last_timestamp: + timestamp = _last_timestamp + 1 + _last_timestamp = timestamp + if clock_seq is None: + import random + clock_seq = random.randrange(1<<14L) # instead of stable storage + time_low = timestamp & 0xffffffffL + time_mid = (timestamp >> 32L) & 0xffffL + time_hi_version = (timestamp >> 48L) & 0x0fffL + clock_seq_low = clock_seq & 0xffL + clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL + if node is None: + node = getnode() + return UUID(fields=(time_low, time_mid, time_hi_version, + clock_seq_hi_variant, clock_seq_low, node), version=1) + +def uuid3(namespace, name): + """Generate a UUID from the MD5 hash of a namespace UUID and a name.""" + from hashlib import md5 + hash = md5(namespace.bytes + name).digest() + return UUID(bytes=hash[:16], version=3) + +def uuid4(): + """Generate a random UUID.""" + + # When the system provides a version-4 UUID generator, use it. + if _uuid_generate_random: + _buffer = ctypes.create_string_buffer(16) + _uuid_generate_random(_buffer) + return UUID(bytes=_buffer.raw) + + # Otherwise, get randomness from urandom or the 'random' module. + try: + import os + return UUID(bytes=os.urandom(16), version=4) + except: + import random + bytes = [chr(random.randrange(256)) for i in range(16)] + return UUID(bytes=bytes, version=4) + +def uuid5(namespace, name): + """Generate a UUID from the SHA-1 hash of a namespace UUID and a name.""" + from hashlib import sha1 + hash = sha1(namespace.bytes + name).digest() + return UUID(bytes=hash[:16], version=5) + +# The following standard UUIDs are for use with uuid3() or uuid5(). + +NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8') +NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8') +NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8') +NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8') diff --git a/src/main/resources/PythonLibs/warnings.py b/src/main/resources/PythonLibs/warnings.py new file mode 100644 index 0000000000000000000000000000000000000000..0668e7681d88d20eb0a6df0e163187a78ade4c38 --- /dev/null +++ b/src/main/resources/PythonLibs/warnings.py @@ -0,0 +1,424 @@ +"""Python part of the warnings subsystem.""" + +# Note: function level imports should *not* be used +# in this module as it may cause import lock deadlock. +# See bug 683658. +import linecache +import sys +import types + +__all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", + "resetwarnings", "catch_warnings"] + +def warnpy3k(message, category=None, stacklevel=1): + """Issue a deprecation warning for Python 3.x related changes. + + Warnings are omitted unless Python is started with the -3 option. + """ + if sys.py3kwarning: + if category is None: + category = DeprecationWarning + warn(message, category, stacklevel+1) + +def _show_warning(message, category, filename, lineno, file=None, line=None): + """Hook to write a warning to a file; replace if you like.""" + if file is None: + file = sys.stderr + try: + file.write(formatwarning(message, category, filename, lineno, line)) + except IOError: + pass # the file (probably stderr) is invalid - this warning gets lost. +# Keep a working version around in case the deprecation of the old API is +# triggered. +showwarning = _show_warning + +def formatwarning(message, category, filename, lineno, line=None): + """Function to format a warning the standard way.""" + s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) + line = linecache.getline(filename, lineno) if line is None else line + if line: + line = line.strip() + s += " %s\n" % line + return s + +def filterwarnings(action, message="", category=Warning, module="", lineno=0, + append=0): + """Insert an entry into the list of warnings filters (at the front). + + 'action' -- one of "error", "ignore", "always", "default", "module", + or "once" + 'message' -- a regex that the warning message must match + 'category' -- a class that the warning must be a subclass of + 'module' -- a regex that the module name must match + 'lineno' -- an integer line number, 0 matches all warnings + 'append' -- if true, append to the list of filters + """ + import re + assert action in ("error", "ignore", "always", "default", "module", + "once"), "invalid action: %r" % (action,) + assert isinstance(message, basestring), "message must be a string" + assert isinstance(category, (type, types.ClassType)), \ + "category must be a class" + assert issubclass(category, Warning), "category must be a Warning subclass" + assert isinstance(module, basestring), "module must be a string" + assert isinstance(lineno, int) and lineno >= 0, \ + "lineno must be an int >= 0" + item = (action, re.compile(message, re.I), category, + re.compile(module), lineno) + if append: + filters.append(item) + else: + filters.insert(0, item) + +def simplefilter(action, category=Warning, lineno=0, append=0): + """Insert a simple entry into the list of warnings filters (at the front). + + A simple filter matches all modules and messages. + 'action' -- one of "error", "ignore", "always", "default", "module", + or "once" + 'category' -- a class that the warning must be a subclass of + 'lineno' -- an integer line number, 0 matches all warnings + 'append' -- if true, append to the list of filters + """ + assert action in ("error", "ignore", "always", "default", "module", + "once"), "invalid action: %r" % (action,) + assert isinstance(lineno, int) and lineno >= 0, \ + "lineno must be an int >= 0" + item = (action, None, category, None, lineno) + if append: + filters.append(item) + else: + filters.insert(0, item) + +def resetwarnings(): + """Clear the list of warning filters, so that no filters are active.""" + filters[:] = [] + +class _OptionError(Exception): + """Exception used by option processing helpers.""" + pass + +# Helper to process -W options passed via sys.warnoptions +def _processoptions(args): + for arg in args: + try: + _setoption(arg) + except _OptionError, msg: + print >>sys.stderr, "Invalid -W option ignored:", msg + +# Helper for _processoptions() +def _setoption(arg): + import re + parts = arg.split(':') + if len(parts) > 5: + raise _OptionError("too many fields (max 5): %r" % (arg,)) + while len(parts) < 5: + parts.append('') + action, message, category, module, lineno = [s.strip() + for s in parts] + action = _getaction(action) + message = re.escape(message) + category = _getcategory(category) + module = re.escape(module) + if module: + module = module + '$' + if lineno: + try: + lineno = int(lineno) + if lineno < 0: + raise ValueError + except (ValueError, OverflowError): + raise _OptionError("invalid lineno %r" % (lineno,)) + else: + lineno = 0 + filterwarnings(action, message, category, module, lineno) + +# Helper for _setoption() +def _getaction(action): + if not action: + return "default" + if action == "all": return "always" # Alias + for a in ('default', 'always', 'ignore', 'module', 'once', 'error'): + if a.startswith(action): + return a + raise _OptionError("invalid action: %r" % (action,)) + +# Helper for _setoption() +def _getcategory(category): + import re + if not category: + return Warning + if re.match("^[a-zA-Z0-9_]+$", category): + try: + cat = eval(category) + except NameError: + raise _OptionError("unknown warning category: %r" % (category,)) + else: + i = category.rfind(".") + module = category[:i] + klass = category[i+1:] + try: + m = __import__(module, None, None, [klass]) + except ImportError: + raise _OptionError("invalid module name: %r" % (module,)) + try: + cat = getattr(m, klass) + except AttributeError: + raise _OptionError("unknown warning category: %r" % (category,)) + if not issubclass(cat, Warning): + raise _OptionError("invalid warning category: %r" % (category,)) + return cat + +class SysGlobals: + '''sys.__dict__ values are reflectedfields, so we use this.''' + def __getitem__(self, key): + try: + return getattr(sys, key) + except AttributeError: + raise KeyError(key) + + def get(self, key, default=None): + if key in self: + return self[key] + return default + + def setdefault(self, key, default=None): + if key not in self: + sys.__dict__[key] = default + return self[key] + + def __contains__(self, key): + return key in sys.__dict__ + +# Code typically replaced by _warnings +def warn(message, category=None, stacklevel=1): + """Issue a warning, or maybe ignore it or raise an exception.""" + # Check if message is already a Warning object + if isinstance(message, Warning): + category = message.__class__ + # Check category argument + if category is None: + category = UserWarning + assert issubclass(category, Warning) + # Get context information + try: + caller = sys._getframe(stacklevel) + except ValueError: + globals = SysGlobals() + lineno = 1 + else: + globals = caller.f_globals + lineno = caller.f_lineno + if '__name__' in globals: + module = globals['__name__'] + else: + module = "<string>" + filename = globals.get('__file__') + if filename: + fnl = filename.lower() + if fnl.endswith((".pyc", ".pyo")): + filename = filename[:-1] + elif fnl.endswith("$py.class"): + filename = filename[:-9] + '.py' + else: + if module == "__main__": + try: + filename = sys.argv[0] + except (AttributeError, TypeError): + # embedded interpreters don't have sys.argv, see bug #839151 + filename = '__main__' + if not filename: + filename = module + registry = globals.setdefault("__warningregistry__", {}) + warn_explicit(message, category, filename, lineno, module, registry, + globals) + +def warn_explicit(message, category, filename, lineno, + module=None, registry=None, module_globals=None): + lineno = int(lineno) + if module is None: + module = filename or "<unknown>" + if module[-3:].lower() == ".py": + module = module[:-3] # XXX What about leading pathname? + if registry is None: + registry = {} + if isinstance(message, Warning): + text = str(message) + category = message.__class__ + else: + text = message + message = category(message) + key = (text, category, lineno) + # Quick test for common case + if registry.get(key): + return + # Search the filters + for item in globals().get('filters', _filters): + action, msg, cat, mod, ln = item + if ((msg is None or msg.match(text)) and + issubclass(category, cat) and + (mod is None or mod.match(module)) and + (ln == 0 or lineno == ln)): + break + else: + action = globals().get('defaultaction', default_action) + # Early exit actions + if action == "ignore": + registry[key] = 1 + return + + # Prime the linecache for formatting, in case the + # "file" is actually in a zipfile or something. + linecache.getlines(filename, module_globals) + + if action == "error": + raise message + # Other actions + if action == "once": + _onceregistry = globals().get('onceregistry', once_registry) + registry[key] = 1 + oncekey = (text, category) + if _onceregistry.get(oncekey): + return + _onceregistry[oncekey] = 1 + elif action == "always": + pass + elif action == "module": + registry[key] = 1 + altkey = (text, category, 0) + if registry.get(altkey): + return + registry[altkey] = 1 + elif action == "default": + registry[key] = 1 + else: + # Unrecognized actions are errors + raise RuntimeError( + "Unrecognized action (%r) in warnings.filters:\n %s" % + (action, item)) + # Print message and context + fn = globals().get('showwarning', _show_warning) + fn(message, category, filename, lineno) + + +class WarningMessage(object): + + """Holds the result of a single showwarning() call.""" + + _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file", + "line") + + def __init__(self, message, category, filename, lineno, file=None, + line=None): + local_values = locals() + for attr in self._WARNING_DETAILS: + setattr(self, attr, local_values[attr]) + self._category_name = category.__name__ if category else None + + def __str__(self): + return ("{message : %r, category : %r, filename : %r, lineno : %s, " + "line : %r}" % (self.message, self._category_name, + self.filename, self.lineno, self.line)) + + +class catch_warnings(object): + + """A context manager that copies and restores the warnings filter upon + exiting the context. + + The 'record' argument specifies whether warnings should be captured by a + custom implementation of warnings.showwarning() and be appended to a list + returned by the context manager. Otherwise None is returned by the context + manager. The objects appended to the list are arguments whose attributes + mirror the arguments to showwarning(). + + The 'module' argument is to specify an alternative module to the module + named 'warnings' and imported under that name. This argument is only useful + when testing the warnings module itself. + + """ + + def __init__(self, record=False, module=None): + """Specify whether to record warnings and if an alternative module + should be used other than sys.modules['warnings']. + + For compatibility with Python 3.0, please consider all arguments to be + keyword-only. + + """ + self._record = record + self._module = sys.modules['warnings'] if module is None else module + self._entered = False + + def __repr__(self): + args = [] + if self._record: + args.append("record=True") + if self._module is not sys.modules['warnings']: + args.append("module=%r" % self._module) + name = type(self).__name__ + return "%s(%s)" % (name, ", ".join(args)) + + def __enter__(self): + if self._entered: + raise RuntimeError("Cannot enter %r twice" % self) + self._entered = True + self._filters = self._module.filters + self._module.filters = self._module._filters = self._filters[:] + self._showwarning = self._module.showwarning + if self._record: + log = [] + def showwarning(*args, **kwargs): + log.append(WarningMessage(*args, **kwargs)) + self._module.showwarning = showwarning + return log + else: + return None + + def __exit__(self, *exc_info): + if not self._entered: + raise RuntimeError("Cannot exit %r without entering first" % self) + self._module.filters = self._module._filters = self._filters + self._module.showwarning = self._showwarning + + +# filters contains a sequence of filter 5-tuples +# The components of the 5-tuple are: +# - an action: error, ignore, always, default, module, or once +# - a compiled regex that must match the warning message +# - a class representing the warning category +# - a compiled regex that must match the module that is being warned +# - a line number for the line being warning, or 0 to mean any line +# If either if the compiled regexs are None, match anything. +_warnings_defaults = False +try: + from _warnings import (filters, default_action, once_registry, + warn, warn_explicit) + defaultaction = default_action + onceregistry = once_registry + _warnings_defaults = True + _filters = filters +except ImportError: + filters = _filters = [] + defaultaction = default_action = "default" + onceregistry = once_registry = {} + + +# Module initialization +_processoptions(sys.warnoptions) +if not _warnings_defaults: + silence = [ImportWarning, PendingDeprecationWarning] + # Don't silence DeprecationWarning if -3 or -Q was used. + if not sys.py3kwarning and not sys.flags.division_warning: + silence.append(DeprecationWarning) + for cls in silence: + simplefilter("ignore", category=cls) + bytes_warning = sys.flags.bytes_warning + if bytes_warning > 1: + bytes_action = "error" + elif bytes_warning: + bytes_action = "default" + else: + bytes_action = "ignore" + simplefilter(bytes_action, category=BytesWarning, append=1) +del _warnings_defaults diff --git a/src/main/resources/PythonLibs/weakref.py b/src/main/resources/PythonLibs/weakref.py new file mode 100644 index 0000000000000000000000000000000000000000..e905c643f3247e1c1d754f82611a29ebdcbb715a --- /dev/null +++ b/src/main/resources/PythonLibs/weakref.py @@ -0,0 +1,385 @@ +"""Weak reference support for Python. + +This module is an implementation of PEP 205: + +http://www.python.org/dev/peps/pep-0205/ +""" + +# Naming convention: Variables named "wr" are weak reference objects; +# they are called this instead of "ref" to avoid name collisions with +# the module-global ref() function imported from _weakref. + +import UserDict + +from _weakref import ( + getweakrefcount, + getweakrefs, + ref, + proxy, + CallableProxyType, + ProxyType, + ReferenceType) + +from _weakrefset import WeakSet + +from exceptions import ReferenceError + + +ProxyTypes = (ProxyType, CallableProxyType) + +__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs", + "WeakKeyDictionary", "ReferenceError", "ReferenceType", "ProxyType", + "CallableProxyType", "ProxyTypes", "WeakValueDictionary", 'WeakSet'] + + +class WeakValueDictionary(UserDict.UserDict): + """Mapping class that references values weakly. + + Entries in the dictionary will be discarded when no strong + reference to the value exists anymore + """ + # We inherit the constructor without worrying about the input + # dictionary; since it uses our .update() method, we get the right + # checks (if the other dictionary is a WeakValueDictionary, + # objects are unwrapped on the way out, and we always wrap on the + # way in). + + def __init__(self, *args, **kw): + def remove(wr, selfref=ref(self)): + self = selfref() + if self is not None: + try: + del self.data[wr.key] + except KeyError: + pass + self._remove = remove + UserDict.UserDict.__init__(self, *args, **kw) + + def __getitem__(self, key): + o = self.data[key]() + if o is None: + raise KeyError, key + else: + return o + + def __contains__(self, key): + try: + o = self.data[key]() + except KeyError: + return False + return o is not None + + def has_key(self, key): + try: + o = self.data[key]() + except KeyError: + return False + return o is not None + + def __repr__(self): + return "<WeakValueDictionary at %s>" % id(self) + + def __setitem__(self, key, value): + self.data[key] = KeyedRef(value, self._remove, key) + + def copy(self): + new = WeakValueDictionary() + for key, wr in self.data.items(): + o = wr() + if o is not None: + new[key] = o + return new + + __copy__ = copy + + def __deepcopy__(self, memo): + from copy import deepcopy + new = self.__class__() + for key, wr in self.data.items(): + o = wr() + if o is not None: + new[deepcopy(key, memo)] = o + return new + + def get(self, key, default=None): + try: + wr = self.data[key] + except KeyError: + return default + else: + o = wr() + if o is None: + # This should only happen + return default + else: + return o + + def items(self): + L = [] + for key, wr in self.data.items(): + o = wr() + if o is not None: + L.append((key, o)) + return L + + def iteritems(self): + for wr in self.data.itervalues(): + value = wr() + if value is not None: + yield wr.key, value + + def iterkeys(self): + return self.data.iterkeys() + + def __iter__(self): + return self.data.iterkeys() + + def itervaluerefs(self): + """Return an iterator that yields the weak references to the values. + + The references are not guaranteed to be 'live' at the time + they are used, so the result of calling the references needs + to be checked before being used. This can be used to avoid + creating references that will cause the garbage collector to + keep the values around longer than needed. + + """ + return self.data.itervalues() + + def itervalues(self): + for wr in self.data.itervalues(): + obj = wr() + if obj is not None: + yield obj + + def popitem(self): + while 1: + key, wr = self.data.popitem() + o = wr() + if o is not None: + return key, o + + def pop(self, key, *args): + try: + o = self.data.pop(key)() + except KeyError: + if args: + return args[0] + raise + if o is None: + raise KeyError, key + else: + return o + + def setdefault(self, key, default=None): + try: + wr = self.data[key] + except KeyError: + self.data[key] = KeyedRef(default, self._remove, key) + return default + else: + return wr() + + def update(self, dict=None, **kwargs): + d = self.data + if dict is not None: + if not hasattr(dict, "items"): + dict = type({})(dict) + for key, o in dict.items(): + d[key] = KeyedRef(o, self._remove, key) + if len(kwargs): + self.update(kwargs) + + def valuerefs(self): + """Return a list of weak references to the values. + + The references are not guaranteed to be 'live' at the time + they are used, so the result of calling the references needs + to be checked before being used. This can be used to avoid + creating references that will cause the garbage collector to + keep the values around longer than needed. + + """ + return self.data.values() + + def values(self): + L = [] + for wr in self.data.values(): + o = wr() + if o is not None: + L.append(o) + return L + + +class KeyedRef(ref): + """Specialized reference that includes a key corresponding to the value. + + This is used in the WeakValueDictionary to avoid having to create + a function object for each key stored in the mapping. A shared + callback object can use the 'key' attribute of a KeyedRef instead + of getting a reference to the key from an enclosing scope. + + """ + + __slots__ = "key", + + def __new__(type, ob, callback, key): + self = ref.__new__(type, ob, callback) + self.key = key + return self + + def __init__(self, ob, callback, key): + super(KeyedRef, self).__init__(ob, callback) + + +class WeakKeyDictionary(UserDict.UserDict): + """ Mapping class that references keys weakly. + + Entries in the dictionary will be discarded when there is no + longer a strong reference to the key. This can be used to + associate additional data with an object owned by other parts of + an application without adding attributes to those objects. This + can be especially useful with objects that override attribute + accesses. + """ + + def __init__(self, dict=None): + self.data = {} + def remove(k, selfref=ref(self)): + self = selfref() + if self is not None: + try: + del self.data[k] + except KeyError: + pass + self._remove = remove + if dict is not None: self.update(dict) + + def __delitem__(self, key): + del self.data[ref(key)] + + def __getitem__(self, key): + return self.data[ref(key)] + + def __repr__(self): + return "<WeakKeyDictionary at %s>" % id(self) + + def __setitem__(self, key, value): + self.data[ref(key, self._remove)] = value + + def copy(self): + new = WeakKeyDictionary() + for key, value in self.data.items(): + o = key() + if o is not None: + new[o] = value + return new + + __copy__ = copy + + def __deepcopy__(self, memo): + from copy import deepcopy + new = self.__class__() + for key, value in self.data.items(): + o = key() + if o is not None: + new[o] = deepcopy(value, memo) + return new + + def get(self, key, default=None): + return self.data.get(ref(key),default) + + def has_key(self, key): + try: + wr = ref(key) + except TypeError: + return 0 + return wr in self.data + + def __contains__(self, key): + try: + wr = ref(key) + except TypeError: + return 0 + return wr in self.data + + def items(self): + L = [] + for key, value in self.data.items(): + o = key() + if o is not None: + L.append((o, value)) + return L + + def iteritems(self): + for wr, value in self.data.iteritems(): + key = wr() + if key is not None: + yield key, value + + def iterkeyrefs(self): + """Return an iterator that yields the weak references to the keys. + + The references are not guaranteed to be 'live' at the time + they are used, so the result of calling the references needs + to be checked before being used. This can be used to avoid + creating references that will cause the garbage collector to + keep the keys around longer than needed. + + """ + return self.data.iterkeys() + + def iterkeys(self): + for wr in self.data.iterkeys(): + obj = wr() + if obj is not None: + yield obj + + def __iter__(self): + return self.iterkeys() + + def itervalues(self): + return self.data.itervalues() + + def keyrefs(self): + """Return a list of weak references to the keys. + + The references are not guaranteed to be 'live' at the time + they are used, so the result of calling the references needs + to be checked before being used. This can be used to avoid + creating references that will cause the garbage collector to + keep the keys around longer than needed. + + """ + return self.data.keys() + + def keys(self): + L = [] + for wr in self.data.keys(): + o = wr() + if o is not None: + L.append(o) + return L + + def popitem(self): + while 1: + key, value = self.data.popitem() + o = key() + if o is not None: + return o, value + + def pop(self, key, *args): + return self.data.pop(ref(key), *args) + + def setdefault(self, key, default=None): + return self.data.setdefault(ref(key, self._remove),default) + + def update(self, dict=None, **kwargs): + d = self.data + if dict is not None: + if not hasattr(dict, "items"): + dict = type({})(dict) + for key, value in dict.items(): + d[ref(key, self._remove)] = value + if len(kwargs): + self.update(kwargs) diff --git a/src/main/resources/PythonLibs/whichdb.py b/src/main/resources/PythonLibs/whichdb.py new file mode 100644 index 0000000000000000000000000000000000000000..9071430b154c080c1e7278032e151d8800e7abc2 --- /dev/null +++ b/src/main/resources/PythonLibs/whichdb.py @@ -0,0 +1,117 @@ +# !/usr/bin/env python +"""Guess which db package to use to open a db file.""" + +import os +import struct +import sys + +try: + import dbm + _dbmerror = dbm.error +except ImportError: + dbm = None + # just some sort of valid exception which might be raised in the + # dbm test + _dbmerror = IOError + +def whichdb(filename): + """Guess which db package to use to open a db file. + + Return values: + + - None if the database file can't be read; + - empty string if the file can be read but can't be recognized + - the module name (e.g. "dbm" or "gdbm") if recognized. + + Importing the given module may still fail, and opening the + database using that module may still fail. + """ + + # Check for dbm first -- this has a .pag and a .dir file + try: + f = open(filename + os.extsep + "pag", "rb") + f.close() + # dbm linked with gdbm on OS/2 doesn't have .dir file + if not (dbm.library == "GNU gdbm" and sys.platform == "os2emx"): + f = open(filename + os.extsep + "dir", "rb") + f.close() + return "dbm" + except IOError: + # some dbm emulations based on Berkeley DB generate a .db file + # some do not, but they should be caught by the dbhash checks + try: + f = open(filename + os.extsep + "db", "rb") + f.close() + # guarantee we can actually open the file using dbm + # kind of overkill, but since we are dealing with emulations + # it seems like a prudent step + if dbm is not None: + d = dbm.open(filename) + d.close() + return "dbm" + except (IOError, _dbmerror): + pass + + # Check for dumbdbm next -- this has a .dir and a .dat file + try: + # First check for presence of files + os.stat(filename + os.extsep + "dat") + size = os.stat(filename + os.extsep + "dir").st_size + # dumbdbm files with no keys are empty + if size == 0: + return "dumbdbm" + f = open(filename + os.extsep + "dir", "rb") + try: + if f.read(1) in ("'", '"'): + return "dumbdbm" + finally: + f.close() + except (OSError, IOError): + pass + + # See if the file exists, return None if not + try: + f = open(filename, "rb") + except IOError: + return None + + # Read the start of the file -- the magic number + s16 = f.read(16) + f.close() + s = s16[0:4] + + # Return "" if not at least 4 bytes + if len(s) != 4: + return "" + + # Convert to 4-byte int in native byte order -- return "" if impossible + try: + (magic,) = struct.unpack("=l", s) + except struct.error: + return "" + + # Check for GNU dbm + if magic in (0x13579ace, 0x13579acd, 0x13579acf): + return "gdbm" + + # Check for old Berkeley db hash file format v2 + if magic in (0x00061561, 0x61150600): + return "bsddb185" + + # Later versions of Berkeley db hash file have a 12-byte pad in + # front of the file type + try: + (magic,) = struct.unpack("=l", s16[-4:]) + except struct.error: + return "" + + # Check for BSD hash + if magic in (0x00061561, 0x61150600): + return "dbhash" + + # Unknown + return "" + +if __name__ == "__main__": + for filename in sys.argv[1:]: + print whichdb(filename) or "UNKNOWN", filename diff --git a/src/main/resources/PythonLibs/wsgiref.egg-info b/src/main/resources/PythonLibs/wsgiref.egg-info new file mode 100644 index 0000000000000000000000000000000000000000..c0b7893c349dc091b93cb24239f2249e25a7d828 --- /dev/null +++ b/src/main/resources/PythonLibs/wsgiref.egg-info @@ -0,0 +1,8 @@ +Metadata-Version: 1.0 +Name: wsgiref +Version: 0.1.2 +Summary: WSGI (PEP 333) Reference Library +Author: Phillip J. Eby +Author-email: web-sig@python.org +License: PSF or ZPL +Platform: UNKNOWN diff --git a/src/main/resources/PythonLibs/wsgiref/__init__.py b/src/main/resources/PythonLibs/wsgiref/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..46c579f8ececc0b52cdde2f74fd6159108d4b311 --- /dev/null +++ b/src/main/resources/PythonLibs/wsgiref/__init__.py @@ -0,0 +1,23 @@ +"""wsgiref -- a WSGI (PEP 333) Reference Library + +Current Contents: + +* util -- Miscellaneous useful functions and wrappers + +* headers -- Manage response headers + +* handlers -- base classes for server/gateway implementations + +* simple_server -- a simple BaseHTTPServer that supports WSGI + +* validate -- validation wrapper that sits between an app and a server + to detect errors in either + +To-Do: + +* cgi_gateway -- Run WSGI apps under CGI (pending a deployment standard) + +* cgi_wrapper -- Run CGI apps under WSGI + +* router -- a simple middleware component that handles URL traversal +""" diff --git a/src/main/resources/PythonLibs/wsgiref/handlers.py b/src/main/resources/PythonLibs/wsgiref/handlers.py new file mode 100644 index 0000000000000000000000000000000000000000..8cb57e223aa0d3c1cd77fb0b67c5aa58c257548d --- /dev/null +++ b/src/main/resources/PythonLibs/wsgiref/handlers.py @@ -0,0 +1,450 @@ +"""Base classes for server/gateway implementations""" + +from types import StringType +from util import FileWrapper, guess_scheme, is_hop_by_hop +from headers import Headers + +import sys, os, time + +__all__ = ['BaseHandler', 'SimpleHandler', 'BaseCGIHandler', 'CGIHandler'] + +try: + dict +except NameError: + def dict(items): + d = {} + for k,v in items: + d[k] = v + return d + +# Uncomment for 2.2 compatibility. +#try: +# True +# False +#except NameError: +# True = not None +# False = not True + + +# Weekday and month names for HTTP date/time formatting; always English! +_weekdayname = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] +_monthname = [None, # Dummy so we can use 1-based month numbers + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] + +def format_date_time(timestamp): + year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp) + return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( + _weekdayname[wd], day, _monthname[month], year, hh, mm, ss + ) + + +class BaseHandler: + """Manage the invocation of a WSGI application""" + + # Configuration parameters; can override per-subclass or per-instance + wsgi_version = (1,0) + wsgi_multithread = True + wsgi_multiprocess = True + wsgi_run_once = False + + origin_server = True # We are transmitting direct to client + http_version = "1.0" # Version that should be used for response + server_software = None # String name of server software, if any + + # os_environ is used to supply configuration from the OS environment: + # by default it's a copy of 'os.environ' as of import time, but you can + # override this in e.g. your __init__ method. + os_environ = dict(os.environ.items()) + + # Collaborator classes + wsgi_file_wrapper = FileWrapper # set to None to disable + headers_class = Headers # must be a Headers-like class + + # Error handling (also per-subclass or per-instance) + traceback_limit = None # Print entire traceback to self.get_stderr() + error_status = "500 Internal Server Error" + error_headers = [('Content-Type','text/plain')] + error_body = "A server error occurred. Please contact the administrator." + + # State variables (don't mess with these) + status = result = None + headers_sent = False + headers = None + bytes_sent = 0 + + def run(self, application): + """Invoke the application""" + # Note to self: don't move the close()! Asynchronous servers shouldn't + # call close() from finish_response(), so if you close() anywhere but + # the double-error branch here, you'll break asynchronous servers by + # prematurely closing. Async servers must return from 'run()' without + # closing if there might still be output to iterate over. + try: + self.setup_environ() + self.result = application(self.environ, self.start_response) + self.finish_response() + except: + try: + self.handle_error() + except: + # If we get an error handling an error, just give up already! + self.close() + raise # ...and let the actual server figure it out. + + + def setup_environ(self): + """Set up the environment for one request""" + + env = self.environ = self.os_environ.copy() + self.add_cgi_vars() + + env['wsgi.input'] = self.get_stdin() + env['wsgi.errors'] = self.get_stderr() + env['wsgi.version'] = self.wsgi_version + env['wsgi.run_once'] = self.wsgi_run_once + env['wsgi.url_scheme'] = self.get_scheme() + env['wsgi.multithread'] = self.wsgi_multithread + env['wsgi.multiprocess'] = self.wsgi_multiprocess + + if self.wsgi_file_wrapper is not None: + env['wsgi.file_wrapper'] = self.wsgi_file_wrapper + + if self.origin_server and self.server_software: + env.setdefault('SERVER_SOFTWARE',self.server_software) + + + def finish_response(self): + """Send any iterable data, then close self and the iterable + + Subclasses intended for use in asynchronous servers will + want to redefine this method, such that it sets up callbacks + in the event loop to iterate over the data, and to call + 'self.close()' once the response is finished. + """ + try: + if not self.result_is_file() or not self.sendfile(): + for data in self.result: + self.write(data) + self.finish_content() + finally: + self.close() + + + def get_scheme(self): + """Return the URL scheme being used""" + return guess_scheme(self.environ) + + + def set_content_length(self): + """Compute Content-Length or switch to chunked encoding if possible""" + try: + blocks = len(self.result) + except (TypeError,AttributeError,NotImplementedError): + pass + else: + if blocks==1: + self.headers['Content-Length'] = str(self.bytes_sent) + return + # XXX Try for chunked encoding if origin server and client is 1.1 + + + def cleanup_headers(self): + """Make any necessary header changes or defaults + + Subclasses can extend this to add other defaults. + """ + if 'Content-Length' not in self.headers: + self.set_content_length() + + def start_response(self, status, headers,exc_info=None): + """'start_response()' callable as specified by PEP 333""" + + if exc_info: + try: + if self.headers_sent: + # Re-raise original exception if headers sent + raise exc_info[0], exc_info[1], exc_info[2] + finally: + exc_info = None # avoid dangling circular ref + elif self.headers is not None: + raise AssertionError("Headers already set!") + + assert type(status) is StringType,"Status must be a string" + assert len(status)>=4,"Status must be at least 4 characters" + assert int(status[:3]),"Status message must begin w/3-digit code" + assert status[3]==" ", "Status message must have a space after code" + if __debug__: + for name,val in headers: + assert type(name) is StringType,"Header names must be strings" + assert type(val) is StringType,"Header values must be strings" + assert not is_hop_by_hop(name),"Hop-by-hop headers not allowed" + self.status = status + self.headers = self.headers_class(headers) + return self.write + + + def send_preamble(self): + """Transmit version/status/date/server, via self._write()""" + if self.origin_server: + if self.client_is_modern(): + self._write('HTTP/%s %s\r\n' % (self.http_version,self.status)) + if 'Date' not in self.headers: + self._write( + 'Date: %s\r\n' % format_date_time(time.time()) + ) + if self.server_software and 'Server' not in self.headers: + self._write('Server: %s\r\n' % self.server_software) + else: + self._write('Status: %s\r\n' % self.status) + + def write(self, data): + """'write()' callable as specified by PEP 333""" + + assert type(data) is StringType,"write() argument must be string" + + if not self.status: + raise AssertionError("write() before start_response()") + + elif not self.headers_sent: + # Before the first output, send the stored headers + self.bytes_sent = len(data) # make sure we know content-length + self.send_headers() + else: + self.bytes_sent += len(data) + + # XXX check Content-Length and truncate if too many bytes written? + self._write(data) + self._flush() + + + def sendfile(self): + """Platform-specific file transmission + + Override this method in subclasses to support platform-specific + file transmission. It is only called if the application's + return iterable ('self.result') is an instance of + 'self.wsgi_file_wrapper'. + + This method should return a true value if it was able to actually + transmit the wrapped file-like object using a platform-specific + approach. It should return a false value if normal iteration + should be used instead. An exception can be raised to indicate + that transmission was attempted, but failed. + + NOTE: this method should call 'self.send_headers()' if + 'self.headers_sent' is false and it is going to attempt direct + transmission of the file. + """ + return False # No platform-specific transmission by default + + + def finish_content(self): + """Ensure headers and content have both been sent""" + if not self.headers_sent: + # Only zero Content-Length if not set by the application (so + # that HEAD requests can be satisfied properly, see #3839) + self.headers.setdefault('Content-Length', "0") + self.send_headers() + else: + pass # XXX check if content-length was too short? + + def close(self): + """Close the iterable (if needed) and reset all instance vars + + Subclasses may want to also drop the client connection. + """ + try: + if hasattr(self.result,'close'): + self.result.close() + finally: + self.result = self.headers = self.status = self.environ = None + self.bytes_sent = 0; self.headers_sent = False + + + def send_headers(self): + """Transmit headers to the client, via self._write()""" + self.cleanup_headers() + self.headers_sent = True + if not self.origin_server or self.client_is_modern(): + self.send_preamble() + self._write(str(self.headers)) + + + def result_is_file(self): + """True if 'self.result' is an instance of 'self.wsgi_file_wrapper'""" + wrapper = self.wsgi_file_wrapper + return wrapper is not None and isinstance(self.result,wrapper) + + + def client_is_modern(self): + """True if client can accept status and headers""" + return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9' + + + def log_exception(self,exc_info): + """Log the 'exc_info' tuple in the server log + + Subclasses may override to retarget the output or change its format. + """ + try: + from traceback import print_exception + stderr = self.get_stderr() + print_exception( + exc_info[0], exc_info[1], exc_info[2], + self.traceback_limit, stderr + ) + stderr.flush() + finally: + exc_info = None + + def handle_error(self): + """Log current error, and send error output to client if possible""" + self.log_exception(sys.exc_info()) + if not self.headers_sent: + self.result = self.error_output(self.environ, self.start_response) + self.finish_response() + # XXX else: attempt advanced recovery techniques for HTML or text? + + def error_output(self, environ, start_response): + """WSGI mini-app to create error output + + By default, this just uses the 'error_status', 'error_headers', + and 'error_body' attributes to generate an output page. It can + be overridden in a subclass to dynamically generate diagnostics, + choose an appropriate message for the user's preferred language, etc. + + Note, however, that it's not recommended from a security perspective to + spit out diagnostics to any old user; ideally, you should have to do + something special to enable diagnostic output, which is why we don't + include any here! + """ + start_response(self.error_status,self.error_headers[:],sys.exc_info()) + return [self.error_body] + + + # Pure abstract methods; *must* be overridden in subclasses + + def _write(self,data): + """Override in subclass to buffer data for send to client + + It's okay if this method actually transmits the data; BaseHandler + just separates write and flush operations for greater efficiency + when the underlying system actually has such a distinction. + """ + raise NotImplementedError + + def _flush(self): + """Override in subclass to force sending of recent '_write()' calls + + It's okay if this method is a no-op (i.e., if '_write()' actually + sends the data. + """ + raise NotImplementedError + + def get_stdin(self): + """Override in subclass to return suitable 'wsgi.input'""" + raise NotImplementedError + + def get_stderr(self): + """Override in subclass to return suitable 'wsgi.errors'""" + raise NotImplementedError + + def add_cgi_vars(self): + """Override in subclass to insert CGI variables in 'self.environ'""" + raise NotImplementedError + + +class SimpleHandler(BaseHandler): + """Handler that's just initialized with streams, environment, etc. + + This handler subclass is intended for synchronous HTTP/1.0 origin servers, + and handles sending the entire response output, given the correct inputs. + + Usage:: + + handler = SimpleHandler( + inp,out,err,env, multithread=False, multiprocess=True + ) + handler.run(app)""" + + def __init__(self,stdin,stdout,stderr,environ, + multithread=True, multiprocess=False + ): + self.stdin = stdin + self.stdout = stdout + self.stderr = stderr + self.base_env = environ + self.wsgi_multithread = multithread + self.wsgi_multiprocess = multiprocess + + def get_stdin(self): + return self.stdin + + def get_stderr(self): + return self.stderr + + def add_cgi_vars(self): + self.environ.update(self.base_env) + + def _write(self,data): + self.stdout.write(data) + self._write = self.stdout.write + + def _flush(self): + self.stdout.flush() + self._flush = self.stdout.flush + + +class BaseCGIHandler(SimpleHandler): + + """CGI-like systems using input/output/error streams and environ mapping + + Usage:: + + handler = BaseCGIHandler(inp,out,err,env) + handler.run(app) + + This handler class is useful for gateway protocols like ReadyExec and + FastCGI, that have usable input/output/error streams and an environment + mapping. It's also the base class for CGIHandler, which just uses + sys.stdin, os.environ, and so on. + + The constructor also takes keyword arguments 'multithread' and + 'multiprocess' (defaulting to 'True' and 'False' respectively) to control + the configuration sent to the application. It sets 'origin_server' to + False (to enable CGI-like output), and assumes that 'wsgi.run_once' is + False. + """ + + origin_server = False + + +class CGIHandler(BaseCGIHandler): + + """CGI-based invocation via sys.stdin/stdout/stderr and os.environ + + Usage:: + + CGIHandler().run(app) + + The difference between this class and BaseCGIHandler is that it always + uses 'wsgi.run_once' of 'True', 'wsgi.multithread' of 'False', and + 'wsgi.multiprocess' of 'True'. It does not take any initialization + parameters, but always uses 'sys.stdin', 'os.environ', and friends. + + If you need to override any of these parameters, use BaseCGIHandler + instead. + """ + + wsgi_run_once = True + # Do not allow os.environ to leak between requests in Google App Engine + # and other multi-run CGI use cases. This is not easily testable. + # See http://bugs.python.org/issue7250 + os_environ = {} + + def __init__(self): + BaseCGIHandler.__init__( + self, sys.stdin, sys.stdout, sys.stderr, dict(os.environ.items()), + multithread=False, multiprocess=True + ) diff --git a/src/main/resources/PythonLibs/wsgiref/headers.py b/src/main/resources/PythonLibs/wsgiref/headers.py new file mode 100644 index 0000000000000000000000000000000000000000..6c8c60c891355d68219c1a1022589fd639504dcf --- /dev/null +++ b/src/main/resources/PythonLibs/wsgiref/headers.py @@ -0,0 +1,169 @@ +"""Manage HTTP Response Headers + +Much of this module is red-handedly pilfered from email.message in the stdlib, +so portions are Copyright (C) 2001,2002 Python Software Foundation, and were +written by Barry Warsaw. +""" + +from types import ListType, TupleType + +# Regular expression that matches `special' characters in parameters, the +# existence of which force quoting of the parameter value. +import re +tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]') + +def _formatparam(param, value=None, quote=1): + """Convenience function to format and return a key=value pair. + + This will quote the value if needed or if quote is true. + """ + if value is not None and len(value) > 0: + if quote or tspecials.search(value): + value = value.replace('\\', '\\\\').replace('"', r'\"') + return '%s="%s"' % (param, value) + else: + return '%s=%s' % (param, value) + else: + return param + + +class Headers: + + """Manage a collection of HTTP response headers""" + + def __init__(self,headers): + if type(headers) is not ListType: + raise TypeError("Headers must be a list of name/value tuples") + self._headers = headers + + def __len__(self): + """Return the total number of headers, including duplicates.""" + return len(self._headers) + + def __setitem__(self, name, val): + """Set the value of a header.""" + del self[name] + self._headers.append((name, val)) + + def __delitem__(self,name): + """Delete all occurrences of a header, if present. + + Does *not* raise an exception if the header is missing. + """ + name = name.lower() + self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name] + + def __getitem__(self,name): + """Get the first header value for 'name' + + Return None if the header is missing instead of raising an exception. + + Note that if the header appeared multiple times, the first exactly which + occurrance gets returned is undefined. Use getall() to get all + the values matching a header field name. + """ + return self.get(name) + + def has_key(self, name): + """Return true if the message contains the header.""" + return self.get(name) is not None + + __contains__ = has_key + + + def get_all(self, name): + """Return a list of all the values for the named field. + + These will be sorted in the order they appeared in the original header + list or were added to this instance, and may contain duplicates. Any + fields deleted and re-inserted are always appended to the header list. + If no fields exist with the given name, returns an empty list. + """ + name = name.lower() + return [kv[1] for kv in self._headers if kv[0].lower()==name] + + + def get(self,name,default=None): + """Get the first header value for 'name', or return 'default'""" + name = name.lower() + for k,v in self._headers: + if k.lower()==name: + return v + return default + + + def keys(self): + """Return a list of all the header field names. + + These will be sorted in the order they appeared in the original header + list, or were added to this instance, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return [k for k, v in self._headers] + + def values(self): + """Return a list of all header values. + + These will be sorted in the order they appeared in the original header + list, or were added to this instance, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return [v for k, v in self._headers] + + def items(self): + """Get all the header fields and values. + + These will be sorted in the order they were in the original header + list, or were added to this instance, and may contain duplicates. + Any fields deleted and re-inserted are always appended to the header + list. + """ + return self._headers[:] + + def __repr__(self): + return "Headers(%r)" % self._headers + + def __str__(self): + """str() returns the formatted headers, complete with end line, + suitable for direct HTTP transmission.""" + return '\r\n'.join(["%s: %s" % kv for kv in self._headers]+['','']) + + def setdefault(self,name,value): + """Return first matching header value for 'name', or 'value' + + If there is no header named 'name', add a new header with name 'name' + and value 'value'.""" + result = self.get(name) + if result is None: + self._headers.append((name,value)) + return value + else: + return result + + def add_header(self, _name, _value, **_params): + """Extended header setting. + + _name is the header field to add. keyword arguments can be used to set + additional parameters for the header field, with underscores converted + to dashes. Normally the parameter will be added as key="value" unless + value is None, in which case only the key will be added. + + Example: + + h.add_header('content-disposition', 'attachment', filename='bud.gif') + + Note that unlike the corresponding 'email.message' method, this does + *not* handle '(charset, language, value)' tuples: all values must be + strings or None. + """ + parts = [] + if _value is not None: + parts.append(_value) + for k, v in _params.items(): + if v is None: + parts.append(k.replace('_', '-')) + else: + parts.append(_formatparam(k.replace('_', '-'), v)) + self._headers.append((_name, "; ".join(parts))) diff --git a/src/main/resources/PythonLibs/wsgiref/simple_server.py b/src/main/resources/PythonLibs/wsgiref/simple_server.py new file mode 100644 index 0000000000000000000000000000000000000000..e6a385b03c74d3a63d2c34a9ab978ad9a2bf0301 --- /dev/null +++ b/src/main/resources/PythonLibs/wsgiref/simple_server.py @@ -0,0 +1,155 @@ +"""BaseHTTPServer that implements the Python WSGI protocol (PEP 333, rev 1.21) + +This is both an example of how WSGI can be implemented, and a basis for running +simple web applications on a local machine, such as might be done when testing +or debugging an application. It has not been reviewed for security issues, +however, and we strongly recommend that you use a "real" web server for +production use. + +For example usage, see the 'if __name__=="__main__"' block at the end of the +module. See also the BaseHTTPServer module docs for other API information. +""" + +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +import urllib, sys +from wsgiref.handlers import SimpleHandler + +__version__ = "0.1" +__all__ = ['WSGIServer', 'WSGIRequestHandler', 'demo_app', 'make_server'] + + +server_version = "WSGIServer/" + __version__ +sys_version = "Python/" + sys.version.split()[0] +software_version = server_version + ' ' + sys_version + + +class ServerHandler(SimpleHandler): + + server_software = software_version + + def close(self): + try: + self.request_handler.log_request( + self.status.split(' ',1)[0], self.bytes_sent + ) + finally: + SimpleHandler.close(self) + + + +class WSGIServer(HTTPServer): + + """BaseHTTPServer that implements the Python WSGI protocol""" + + application = None + + def server_bind(self): + """Override server_bind to store the server name.""" + HTTPServer.server_bind(self) + self.setup_environ() + + def setup_environ(self): + # Set up base environment + env = self.base_environ = {} + env['SERVER_NAME'] = self.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PORT'] = str(self.server_port) + env['REMOTE_HOST']='' + env['CONTENT_LENGTH']='' + env['SCRIPT_NAME'] = '' + + def get_app(self): + return self.application + + def set_app(self,application): + self.application = application + + + +class WSGIRequestHandler(BaseHTTPRequestHandler): + + server_version = "WSGIServer/" + __version__ + + def get_environ(self): + env = self.server.base_environ.copy() + env['SERVER_PROTOCOL'] = self.request_version + env['REQUEST_METHOD'] = self.command + if '?' in self.path: + path,query = self.path.split('?',1) + else: + path,query = self.path,'' + + env['PATH_INFO'] = urllib.unquote(path) + env['QUERY_STRING'] = query + + host = self.address_string() + if host != self.client_address[0]: + env['REMOTE_HOST'] = host + env['REMOTE_ADDR'] = self.client_address[0] + + if self.headers.typeheader is None: + env['CONTENT_TYPE'] = self.headers.type + else: + env['CONTENT_TYPE'] = self.headers.typeheader + + length = self.headers.getheader('content-length') + if length: + env['CONTENT_LENGTH'] = length + + for h in self.headers.headers: + k,v = h.split(':',1) + k=k.replace('-','_').upper(); v=v.strip() + if k in env: + continue # skip content length, type,etc. + if 'HTTP_'+k in env: + env['HTTP_'+k] += ','+v # comma-separate multiple headers + else: + env['HTTP_'+k] = v + return env + + def get_stderr(self): + return sys.stderr + + def handle(self): + """Handle a single HTTP request""" + + self.raw_requestline = self.rfile.readline() + if not self.parse_request(): # An error code has been sent, just exit + return + + handler = ServerHandler( + self.rfile, self.wfile, self.get_stderr(), self.get_environ() + ) + handler.request_handler = self # backpointer for logging + handler.run(self.server.get_app()) + + + +def demo_app(environ,start_response): + from StringIO import StringIO + stdout = StringIO() + print >>stdout, "Hello world!" + print >>stdout + h = environ.items(); h.sort() + for k,v in h: + print >>stdout, k,'=', repr(v) + start_response("200 OK", [('Content-Type','text/plain')]) + return [stdout.getvalue()] + + +def make_server( + host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler +): + """Create a new WSGI server listening on `host` and `port` for `app`""" + server = server_class((host, port), handler_class) + server.set_app(app) + return server + + +if __name__ == '__main__': + httpd = make_server('', 8000, demo_app) + sa = httpd.socket.getsockname() + print "Serving HTTP on", sa[0], "port", sa[1], "..." + import webbrowser + webbrowser.open('http://localhost:8000/xyz?abc') + httpd.handle_request() # serve one request, then exit diff --git a/src/main/resources/PythonLibs/wsgiref/util.py b/src/main/resources/PythonLibs/wsgiref/util.py new file mode 100644 index 0000000000000000000000000000000000000000..194b187a4dc8d6461f4ecfa8f1b438fccf7c3516 --- /dev/null +++ b/src/main/resources/PythonLibs/wsgiref/util.py @@ -0,0 +1,165 @@ +"""Miscellaneous WSGI-related Utilities""" + +import posixpath + +__all__ = [ + 'FileWrapper', 'guess_scheme', 'application_uri', 'request_uri', + 'shift_path_info', 'setup_testing_defaults', +] + + +class FileWrapper: + """Wrapper to convert file-like objects to iterables""" + + def __init__(self, filelike, blksize=8192): + self.filelike = filelike + self.blksize = blksize + if hasattr(filelike,'close'): + self.close = filelike.close + + def __getitem__(self,key): + data = self.filelike.read(self.blksize) + if data: + return data + raise IndexError + + def __iter__(self): + return self + + def next(self): + data = self.filelike.read(self.blksize) + if data: + return data + raise StopIteration + +def guess_scheme(environ): + """Return a guess for whether 'wsgi.url_scheme' should be 'http' or 'https' + """ + if environ.get("HTTPS") in ('yes','on','1'): + return 'https' + else: + return 'http' + +def application_uri(environ): + """Return the application's base URI (no PATH_INFO or QUERY_STRING)""" + url = environ['wsgi.url_scheme']+'://' + from urllib import quote + + if environ.get('HTTP_HOST'): + url += environ['HTTP_HOST'] + else: + url += environ['SERVER_NAME'] + + if environ['wsgi.url_scheme'] == 'https': + if environ['SERVER_PORT'] != '443': + url += ':' + environ['SERVER_PORT'] + else: + if environ['SERVER_PORT'] != '80': + url += ':' + environ['SERVER_PORT'] + + url += quote(environ.get('SCRIPT_NAME') or '/') + return url + +def request_uri(environ, include_query=1): + """Return the full request URI, optionally including the query string""" + url = application_uri(environ) + from urllib import quote + path_info = quote(environ.get('PATH_INFO',''),safe='/;=,') + if not environ.get('SCRIPT_NAME'): + url += path_info[1:] + else: + url += path_info + if include_query and environ.get('QUERY_STRING'): + url += '?' + environ['QUERY_STRING'] + return url + +def shift_path_info(environ): + """Shift a name from PATH_INFO to SCRIPT_NAME, returning it + + If there are no remaining path segments in PATH_INFO, return None. + Note: 'environ' is modified in-place; use a copy if you need to keep + the original PATH_INFO or SCRIPT_NAME. + + Note: when PATH_INFO is just a '/', this returns '' and appends a trailing + '/' to SCRIPT_NAME, even though empty path segments are normally ignored, + and SCRIPT_NAME doesn't normally end in a '/'. This is intentional + behavior, to ensure that an application can tell the difference between + '/x' and '/x/' when traversing to objects. + """ + path_info = environ.get('PATH_INFO','') + if not path_info: + return None + + path_parts = path_info.split('/') + path_parts[1:-1] = [p for p in path_parts[1:-1] if p and p != '.'] + name = path_parts[1] + del path_parts[1] + + script_name = environ.get('SCRIPT_NAME','') + script_name = posixpath.normpath(script_name+'/'+name) + if script_name.endswith('/'): + script_name = script_name[:-1] + if not name and not script_name.endswith('/'): + script_name += '/' + + environ['SCRIPT_NAME'] = script_name + environ['PATH_INFO'] = '/'.join(path_parts) + + # Special case: '/.' on PATH_INFO doesn't get stripped, + # because we don't strip the last element of PATH_INFO + # if there's only one path part left. Instead of fixing this + # above, we fix it here so that PATH_INFO gets normalized to + # an empty string in the environ. + if name=='.': + name = None + return name + +def setup_testing_defaults(environ): + """Update 'environ' with trivial defaults for testing purposes + + This adds various parameters required for WSGI, including HTTP_HOST, + SERVER_NAME, SERVER_PORT, REQUEST_METHOD, SCRIPT_NAME, PATH_INFO, + and all of the wsgi.* variables. It only supplies default values, + and does not replace any existing settings for these variables. + + This routine is intended to make it easier for unit tests of WSGI + servers and applications to set up dummy environments. It should *not* + be used by actual WSGI servers or applications, since the data is fake! + """ + + environ.setdefault('SERVER_NAME','127.0.0.1') + environ.setdefault('SERVER_PROTOCOL','HTTP/1.0') + + environ.setdefault('HTTP_HOST',environ['SERVER_NAME']) + environ.setdefault('REQUEST_METHOD','GET') + + if 'SCRIPT_NAME' not in environ and 'PATH_INFO' not in environ: + environ.setdefault('SCRIPT_NAME','') + environ.setdefault('PATH_INFO','/') + + environ.setdefault('wsgi.version', (1,0)) + environ.setdefault('wsgi.run_once', 0) + environ.setdefault('wsgi.multithread', 0) + environ.setdefault('wsgi.multiprocess', 0) + + from StringIO import StringIO + environ.setdefault('wsgi.input', StringIO("")) + environ.setdefault('wsgi.errors', StringIO()) + environ.setdefault('wsgi.url_scheme',guess_scheme(environ)) + + if environ['wsgi.url_scheme']=='http': + environ.setdefault('SERVER_PORT', '80') + elif environ['wsgi.url_scheme']=='https': + environ.setdefault('SERVER_PORT', '443') + + + +_hoppish = { + 'connection':1, 'keep-alive':1, 'proxy-authenticate':1, + 'proxy-authorization':1, 'te':1, 'trailers':1, 'transfer-encoding':1, + 'upgrade':1 +}.__contains__ + +def is_hop_by_hop(header_name): + """Return true if 'header_name' is an HTTP/1.1 "Hop-by-Hop" header""" + return _hoppish(header_name.lower()) diff --git a/src/main/resources/PythonLibs/wsgiref/validate.py b/src/main/resources/PythonLibs/wsgiref/validate.py new file mode 100644 index 0000000000000000000000000000000000000000..04a893d7c614a351cd1ffda5d664cde764119dd3 --- /dev/null +++ b/src/main/resources/PythonLibs/wsgiref/validate.py @@ -0,0 +1,432 @@ +# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) +# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php +# Also licenced under the Apache License, 2.0: http://opensource.org/licenses/apache2.0.php +# Licensed to PSF under a Contributor Agreement +""" +Middleware to check for obedience to the WSGI specification. + +Some of the things this checks: + +* Signature of the application and start_response (including that + keyword arguments are not used). + +* Environment checks: + + - Environment is a dictionary (and not a subclass). + + - That all the required keys are in the environment: REQUEST_METHOD, + SERVER_NAME, SERVER_PORT, wsgi.version, wsgi.input, wsgi.errors, + wsgi.multithread, wsgi.multiprocess, wsgi.run_once + + - That HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH are not in the + environment (these headers should appear as CONTENT_LENGTH and + CONTENT_TYPE). + + - Warns if QUERY_STRING is missing, as the cgi module acts + unpredictably in that case. + + - That CGI-style variables (that don't contain a .) have + (non-unicode) string values + + - That wsgi.version is a tuple + + - That wsgi.url_scheme is 'http' or 'https' (@@: is this too + restrictive?) + + - Warns if the REQUEST_METHOD is not known (@@: probably too + restrictive). + + - That SCRIPT_NAME and PATH_INFO are empty or start with / + + - That at least one of SCRIPT_NAME or PATH_INFO are set. + + - That CONTENT_LENGTH is a positive integer. + + - That SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should + be '/'). + + - That wsgi.input has the methods read, readline, readlines, and + __iter__ + + - That wsgi.errors has the methods flush, write, writelines + +* The status is a string, contains a space, starts with an integer, + and that integer is in range (> 100). + +* That the headers is a list (not a subclass, not another kind of + sequence). + +* That the items of the headers are tuples of strings. + +* That there is no 'status' header (that is used in CGI, but not in + WSGI). + +* That the headers don't contain newlines or colons, end in _ or -, or + contain characters codes below 037. + +* That Content-Type is given if there is content (CGI often has a + default content type, but WSGI does not). + +* That no Content-Type is given when there is no content (@@: is this + too restrictive?) + +* That the exc_info argument to start_response is a tuple or None. + +* That all calls to the writer are with strings, and no other methods + on the writer are accessed. + +* That wsgi.input is used properly: + + - .read() is called with zero or one argument + + - That it returns a string + + - That readline, readlines, and __iter__ return strings + + - That .close() is not called + + - No other methods are provided + +* That wsgi.errors is used properly: + + - .write() and .writelines() is called with a string + + - That .close() is not called, and no other methods are provided. + +* The response iterator: + + - That it is not a string (it should be a list of a single string; a + string will work, but perform horribly). + + - That .next() returns a string + + - That the iterator is not iterated over until start_response has + been called (that can signal either a server or application + error). + + - That .close() is called (doesn't raise exception, only prints to + sys.stderr, because we only know it isn't called when the object + is garbage collected). +""" +__all__ = ['validator'] + + +import re +import sys +from types import DictType, StringType, TupleType, ListType +import warnings + +header_re = re.compile(r'^[a-zA-Z][a-zA-Z0-9\-_]*$') +bad_header_value_re = re.compile(r'[\000-\037]') + +class WSGIWarning(Warning): + """ + Raised in response to WSGI-spec-related warnings + """ + +def assert_(cond, *args): + if not cond: + raise AssertionError(*args) + +def validator(application): + + """ + When applied between a WSGI server and a WSGI application, this + middleware will check for WSGI compliancy on a number of levels. + This middleware does not modify the request or response in any + way, but will raise an AssertionError if anything seems off + (except for a failure to close the application iterator, which + will be printed to stderr -- there's no way to raise an exception + at that point). + """ + + def lint_app(*args, **kw): + assert_(len(args) == 2, "Two arguments required") + assert_(not kw, "No keyword arguments allowed") + environ, start_response = args + + check_environ(environ) + + # We use this to check if the application returns without + # calling start_response: + start_response_started = [] + + def start_response_wrapper(*args, **kw): + assert_(len(args) == 2 or len(args) == 3, ( + "Invalid number of arguments: %s" % (args,))) + assert_(not kw, "No keyword arguments allowed") + status = args[0] + headers = args[1] + if len(args) == 3: + exc_info = args[2] + else: + exc_info = None + + check_status(status) + check_headers(headers) + check_content_type(status, headers) + check_exc_info(exc_info) + + start_response_started.append(None) + return WriteWrapper(start_response(*args)) + + environ['wsgi.input'] = InputWrapper(environ['wsgi.input']) + environ['wsgi.errors'] = ErrorWrapper(environ['wsgi.errors']) + + iterator = application(environ, start_response_wrapper) + assert_(iterator is not None and iterator != False, + "The application must return an iterator, if only an empty list") + + check_iterator(iterator) + + return IteratorWrapper(iterator, start_response_started) + + return lint_app + +class InputWrapper: + + def __init__(self, wsgi_input): + self.input = wsgi_input + + def read(self, *args): + assert_(len(args) <= 1) + v = self.input.read(*args) + assert_(type(v) is type("")) + return v + + def readline(self): + v = self.input.readline() + assert_(type(v) is type("")) + return v + + def readlines(self, *args): + assert_(len(args) <= 1) + lines = self.input.readlines(*args) + assert_(type(lines) is type([])) + for line in lines: + assert_(type(line) is type("")) + return lines + + def __iter__(self): + while 1: + line = self.readline() + if not line: + return + yield line + + def close(self): + assert_(0, "input.close() must not be called") + +class ErrorWrapper: + + def __init__(self, wsgi_errors): + self.errors = wsgi_errors + + def write(self, s): + assert_(type(s) is type("")) + self.errors.write(s) + + def flush(self): + self.errors.flush() + + def writelines(self, seq): + for line in seq: + self.write(line) + + def close(self): + assert_(0, "errors.close() must not be called") + +class WriteWrapper: + + def __init__(self, wsgi_writer): + self.writer = wsgi_writer + + def __call__(self, s): + assert_(type(s) is type("")) + self.writer(s) + +class PartialIteratorWrapper: + + def __init__(self, wsgi_iterator): + self.iterator = wsgi_iterator + + def __iter__(self): + # We want to make sure __iter__ is called + return IteratorWrapper(self.iterator, None) + +class IteratorWrapper: + + def __init__(self, wsgi_iterator, check_start_response): + self.original_iterator = wsgi_iterator + self.iterator = iter(wsgi_iterator) + self.closed = False + self.check_start_response = check_start_response + + def __iter__(self): + return self + + def next(self): + assert_(not self.closed, + "Iterator read after closed") + v = self.iterator.next() + if self.check_start_response is not None: + assert_(self.check_start_response, + "The application returns and we started iterating over its body, but start_response has not yet been called") + self.check_start_response = None + return v + + def close(self): + self.closed = True + if hasattr(self.original_iterator, 'close'): + self.original_iterator.close() + + def __del__(self): + if not self.closed: + sys.stderr.write( + "Iterator garbage collected without being closed") + assert_(self.closed, + "Iterator garbage collected without being closed") + +def check_environ(environ): + assert_(type(environ) is DictType, + "Environment is not of the right type: %r (environment: %r)" + % (type(environ), environ)) + + for key in ['REQUEST_METHOD', 'SERVER_NAME', 'SERVER_PORT', + 'wsgi.version', 'wsgi.input', 'wsgi.errors', + 'wsgi.multithread', 'wsgi.multiprocess', + 'wsgi.run_once']: + assert_(key in environ, + "Environment missing required key: %r" % (key,)) + + for key in ['HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH']: + assert_(key not in environ, + "Environment should not have the key: %s " + "(use %s instead)" % (key, key[5:])) + + if 'QUERY_STRING' not in environ: + warnings.warn( + 'QUERY_STRING is not in the WSGI environment; the cgi ' + 'module will use sys.argv when this variable is missing, ' + 'so application errors are more likely', + WSGIWarning) + + for key in environ.keys(): + if '.' in key: + # Extension, we don't care about its type + continue + assert_(type(environ[key]) is StringType, + "Environmental variable %s is not a string: %r (value: %r)" + % (key, type(environ[key]), environ[key])) + + assert_(type(environ['wsgi.version']) is TupleType, + "wsgi.version should be a tuple (%r)" % (environ['wsgi.version'],)) + assert_(environ['wsgi.url_scheme'] in ('http', 'https'), + "wsgi.url_scheme unknown: %r" % environ['wsgi.url_scheme']) + + check_input(environ['wsgi.input']) + check_errors(environ['wsgi.errors']) + + # @@: these need filling out: + if environ['REQUEST_METHOD'] not in ( + 'GET', 'HEAD', 'POST', 'OPTIONS','PUT','DELETE','TRACE'): + warnings.warn( + "Unknown REQUEST_METHOD: %r" % environ['REQUEST_METHOD'], + WSGIWarning) + + assert_(not environ.get('SCRIPT_NAME') + or environ['SCRIPT_NAME'].startswith('/'), + "SCRIPT_NAME doesn't start with /: %r" % environ['SCRIPT_NAME']) + assert_(not environ.get('PATH_INFO') + or environ['PATH_INFO'].startswith('/'), + "PATH_INFO doesn't start with /: %r" % environ['PATH_INFO']) + if environ.get('CONTENT_LENGTH'): + assert_(int(environ['CONTENT_LENGTH']) >= 0, + "Invalid CONTENT_LENGTH: %r" % environ['CONTENT_LENGTH']) + + if not environ.get('SCRIPT_NAME'): + assert_('PATH_INFO' in environ, + "One of SCRIPT_NAME or PATH_INFO are required (PATH_INFO " + "should at least be '/' if SCRIPT_NAME is empty)") + assert_(environ.get('SCRIPT_NAME') != '/', + "SCRIPT_NAME cannot be '/'; it should instead be '', and " + "PATH_INFO should be '/'") + +def check_input(wsgi_input): + for attr in ['read', 'readline', 'readlines', '__iter__']: + assert_(hasattr(wsgi_input, attr), + "wsgi.input (%r) doesn't have the attribute %s" + % (wsgi_input, attr)) + +def check_errors(wsgi_errors): + for attr in ['flush', 'write', 'writelines']: + assert_(hasattr(wsgi_errors, attr), + "wsgi.errors (%r) doesn't have the attribute %s" + % (wsgi_errors, attr)) + +def check_status(status): + assert_(type(status) is StringType, + "Status must be a string (not %r)" % status) + # Implicitly check that we can turn it into an integer: + status_code = status.split(None, 1)[0] + assert_(len(status_code) == 3, + "Status codes must be three characters: %r" % status_code) + status_int = int(status_code) + assert_(status_int >= 100, "Status code is invalid: %r" % status_int) + if len(status) < 4 or status[3] != ' ': + warnings.warn( + "The status string (%r) should be a three-digit integer " + "followed by a single space and a status explanation" + % status, WSGIWarning) + +def check_headers(headers): + assert_(type(headers) is ListType, + "Headers (%r) must be of type list: %r" + % (headers, type(headers))) + header_names = {} + for item in headers: + assert_(type(item) is TupleType, + "Individual headers (%r) must be of type tuple: %r" + % (item, type(item))) + assert_(len(item) == 2) + name, value = item + assert_(name.lower() != 'status', + "The Status header cannot be used; it conflicts with CGI " + "script, and HTTP status is not given through headers " + "(value: %r)." % value) + header_names[name.lower()] = None + assert_('\n' not in name and ':' not in name, + "Header names may not contain ':' or '\\n': %r" % name) + assert_(header_re.search(name), "Bad header name: %r" % name) + assert_(not name.endswith('-') and not name.endswith('_'), + "Names may not end in '-' or '_': %r" % name) + if bad_header_value_re.search(value): + assert_(0, "Bad header value: %r (bad char: %r)" + % (value, bad_header_value_re.search(value).group(0))) + +def check_content_type(status, headers): + code = int(status.split(None, 1)[0]) + # @@: need one more person to verify this interpretation of RFC 2616 + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + NO_MESSAGE_BODY = (204, 304) + for name, value in headers: + if name.lower() == 'content-type': + if code not in NO_MESSAGE_BODY: + return + assert_(0, ("Content-Type header found in a %s response, " + "which must not return content.") % code) + if code not in NO_MESSAGE_BODY: + assert_(0, "No Content-Type header found in headers (%s)" % headers) + +def check_exc_info(exc_info): + assert_(exc_info is None or type(exc_info) is type(()), + "exc_info (%r) is not a tuple: %r" % (exc_info, type(exc_info))) + # More exc_info checks? + +def check_iterator(iterator): + # Technically a string is legal, which is why it's a really bad + # idea, because it may cause the response to be returned + # character-by-character + assert_(not isinstance(iterator, str), + "You should not return a string as your application iterator, " + "instead return a single-item list containing that string.") diff --git a/src/main/resources/PythonLibs/xdrlib.py b/src/main/resources/PythonLibs/xdrlib.py new file mode 100644 index 0000000000000000000000000000000000000000..ef172dd37d68b50bc369221c61e7e95f6e36e51a --- /dev/null +++ b/src/main/resources/PythonLibs/xdrlib.py @@ -0,0 +1,231 @@ +"""Implements (a subset of) Sun XDR -- eXternal Data Representation. + +See: RFC 1014 + +""" + +import struct +try: + from cStringIO import StringIO as _StringIO +except ImportError: + from StringIO import StringIO as _StringIO + +__all__ = ["Error", "Packer", "Unpacker", "ConversionError"] + +# exceptions +class Error(Exception): + """Exception class for this module. Use: + + except xdrlib.Error, var: + # var has the Error instance for the exception + + Public ivars: + msg -- contains the message + + """ + def __init__(self, msg): + self.msg = msg + def __repr__(self): + return repr(self.msg) + def __str__(self): + return str(self.msg) + + +class ConversionError(Error): + pass + + + +class Packer: + """Pack various data representations into a buffer.""" + + def __init__(self): + self.reset() + + def reset(self): + self.__buf = _StringIO() + + def get_buffer(self): + return self.__buf.getvalue() + # backwards compatibility + get_buf = get_buffer + + def pack_uint(self, x): + self.__buf.write(struct.pack('>L', x)) + + def pack_int(self, x): + self.__buf.write(struct.pack('>l', x)) + + pack_enum = pack_int + + def pack_bool(self, x): + if x: self.__buf.write('\0\0\0\1') + else: self.__buf.write('\0\0\0\0') + + def pack_uhyper(self, x): + self.pack_uint(x>>32 & 0xffffffffL) + self.pack_uint(x & 0xffffffffL) + + pack_hyper = pack_uhyper + + def pack_float(self, x): + try: self.__buf.write(struct.pack('>f', x)) + except struct.error, msg: + raise ConversionError, msg + + def pack_double(self, x): + try: self.__buf.write(struct.pack('>d', x)) + except struct.error, msg: + raise ConversionError, msg + + def pack_fstring(self, n, s): + if n < 0: + raise ValueError, 'fstring size must be nonnegative' + data = s[:n] + n = ((n+3)//4)*4 + data = data + (n - len(data)) * '\0' + self.__buf.write(data) + + pack_fopaque = pack_fstring + + def pack_string(self, s): + n = len(s) + self.pack_uint(n) + self.pack_fstring(n, s) + + pack_opaque = pack_string + pack_bytes = pack_string + + def pack_list(self, list, pack_item): + for item in list: + self.pack_uint(1) + pack_item(item) + self.pack_uint(0) + + def pack_farray(self, n, list, pack_item): + if len(list) != n: + raise ValueError, 'wrong array size' + for item in list: + pack_item(item) + + def pack_array(self, list, pack_item): + n = len(list) + self.pack_uint(n) + self.pack_farray(n, list, pack_item) + + + +class Unpacker: + """Unpacks various data representations from the given buffer.""" + + def __init__(self, data): + self.reset(data) + + def reset(self, data): + self.__buf = data + self.__pos = 0 + + def get_position(self): + return self.__pos + + def set_position(self, position): + self.__pos = position + + def get_buffer(self): + return self.__buf + + def done(self): + if self.__pos < len(self.__buf): + raise Error('unextracted data remains') + + def unpack_uint(self): + i = self.__pos + self.__pos = j = i+4 + data = self.__buf[i:j] + if len(data) < 4: + raise EOFError + x = struct.unpack('>L', data)[0] + try: + return int(x) + except OverflowError: + return x + + def unpack_int(self): + i = self.__pos + self.__pos = j = i+4 + data = self.__buf[i:j] + if len(data) < 4: + raise EOFError + return struct.unpack('>l', data)[0] + + unpack_enum = unpack_int + + def unpack_bool(self): + return bool(self.unpack_int()) + + def unpack_uhyper(self): + hi = self.unpack_uint() + lo = self.unpack_uint() + return long(hi)<<32 | lo + + def unpack_hyper(self): + x = self.unpack_uhyper() + if x >= 0x8000000000000000L: + x = x - 0x10000000000000000L + return x + + def unpack_float(self): + i = self.__pos + self.__pos = j = i+4 + data = self.__buf[i:j] + if len(data) < 4: + raise EOFError + return struct.unpack('>f', data)[0] + + def unpack_double(self): + i = self.__pos + self.__pos = j = i+8 + data = self.__buf[i:j] + if len(data) < 8: + raise EOFError + return struct.unpack('>d', data)[0] + + def unpack_fstring(self, n): + if n < 0: + raise ValueError, 'fstring size must be nonnegative' + i = self.__pos + j = i + (n+3)//4*4 + if j > len(self.__buf): + raise EOFError + self.__pos = j + return self.__buf[i:i+n] + + unpack_fopaque = unpack_fstring + + def unpack_string(self): + n = self.unpack_uint() + return self.unpack_fstring(n) + + unpack_opaque = unpack_string + unpack_bytes = unpack_string + + def unpack_list(self, unpack_item): + list = [] + while 1: + x = self.unpack_uint() + if x == 0: break + if x != 1: + raise ConversionError, '0 or 1 expected, got %r' % (x,) + item = unpack_item() + list.append(item) + return list + + def unpack_farray(self, n, unpack_item): + list = [] + for i in range(n): + list.append(unpack_item()) + return list + + def unpack_array(self, unpack_item): + n = self.unpack_uint() + return self.unpack_farray(n, unpack_item) diff --git a/src/main/resources/PythonLibs/xml/FtCore.py b/src/main/resources/PythonLibs/xml/FtCore.py new file mode 100644 index 0000000000000000000000000000000000000000..d58885f44e2dacec42b9578b8b3c62baeb1ef3af --- /dev/null +++ b/src/main/resources/PythonLibs/xml/FtCore.py @@ -0,0 +1,58 @@ +""" +Contains various definitions common to modules acquired from 4Suite +""" + +__all__ = ["FtException", "get_translator"] + + +class FtException(Exception): + def __init__(self, errorCode, messages, args): + # By defining __str__, args will be available. Otherwise + # the __init__ of Exception sets it to the passed in arguments. + self.params = args + self.errorCode = errorCode + self.message = messages[errorCode] % args + Exception.__init__(self, self.message, args) + + def __str__(self): + return self.message + + +# What follows is used to provide support for I18N in the rest of the +# 4Suite-derived packages in PyXML. +# +# Each sub-package of the top-level "xml" package that contains 4Suite +# code is really a separate text domain, but they're all called +# '4Suite'. For each domain, a translation object is provided using +# message catalogs stored inside the package. The code below defines +# a get_translator() function that returns an appropriate gettext +# function to be used as _() in the sub-package named by the +# parameter. This handles all the compatibility issues related to +# Python versions (whether the gettext module can be found) and +# whether the message catalogs can actually be found. + +def _(msg): + return msg + +try: + import gettext + +except (ImportError, IOError): + def get_translator(pkg): + return _ + +else: + import os + + _cache = {} + _top = os.path.dirname(os.path.abspath(__file__)) + + def get_translator(pkg): + if not _cache.has_key(pkg): + locale_dir = os.path.join(_top, pkg.replace(".", os.sep)) + try: + f = gettext.translation('4Suite', locale_dir).gettext + except IOError: + f = _ + _cache[pkg] = f + return _cache[pkg] diff --git a/src/main/resources/PythonLibs/xml/Uri.py b/src/main/resources/PythonLibs/xml/Uri.py new file mode 100644 index 0000000000000000000000000000000000000000..730f3caa38d5ca804c75a38af61cda27603c7c64 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/Uri.py @@ -0,0 +1,380 @@ +# pylint: disable-msg=C0103 +# +# backported code from 4Suite with slight modifications, started from r1.89 of +# Ft/Lib/Uri.py, by syt@logilab.fr on 2005-02-09 +# +# part if not all of this code should probably move to urlparse (or be used +# to fix some existant functions in this module) +# +# +# Copyright 2004 Fourthought, Inc. (USA). +# Detailed license and copyright information: http://4suite.org/COPYRIGHT +# Project home, documentation, distributions: http://4suite.org/ +import os.path +import sys +import re +import urlparse, urllib, urllib2 + +def UnsplitUriRef(uriRefSeq): + """should replace urlparse.urlunsplit + + Given a sequence as would be produced by SplitUriRef(), assembles and + returns a URI reference as a string. + """ + if not isinstance(uriRefSeq, (tuple, list)): + raise TypeError("sequence expected, got %s" % type(uriRefSeq)) + (scheme, authority, path, query, fragment) = uriRefSeq + uri = '' + if scheme is not None: + uri += scheme + ':' + if authority is not None: + uri += '//' + authority + uri += path + if query is not None: + uri += '?' + query + if fragment is not None: + uri += '#' + fragment + return uri + +SPLIT_URI_REF_PATTERN = re.compile(r"^(?:(?P<scheme>[^:/?#]+):)?(?://(?P<authority>[^/?#]*))?(?P<path>[^?#]*)(?:\?(?P<query>[^#]*))?(?:#(?P<fragment>.*))?$") + +def SplitUriRef(uriref): + """should replace urlparse.urlsplit + + Given a valid URI reference as a string, returns a tuple representing the + generic URI components, as per RFC 2396 appendix B. The tuple's structure + is (scheme, authority, path, query, fragment). + + All values will be strings (possibly empty) or None if undefined. + + Note that per rfc3986, there is no distinction between a path and + an "opaque part", as there was in RFC 2396. + """ + # the pattern will match every possible string, so it's safe to + # assume there's a groupdict method to call. + g = SPLIT_URI_REF_PATTERN.match(uriref).groupdict() + scheme = g['scheme'] + authority = g['authority'] + path = g['path'] + query = g['query'] + fragment = g['fragment'] + return (scheme, authority, path, query, fragment) + + +def Absolutize(uriRef, baseUri): + """ + Resolves a URI reference to absolute form, effecting the result of RFC + 3986 section 5. The URI reference is considered to be relative to the + given base URI. + + It is the caller's responsibility to ensure that the base URI matches + the absolute-URI syntax rule of RFC 3986, and that its path component + does not contain '.' or '..' segments if the scheme is hierarchical. + Unexpected results may occur otherwise. + + This function only conducts a minimal sanity check in order to determine + if relative resolution is possible: it raises a UriException if the base + URI does not have a scheme component. While it is true that the base URI + is irrelevant if the URI reference has a scheme, an exception is raised + in order to signal that the given string does not even come close to + meeting the criteria to be usable as a base URI. + + It is the caller's responsibility to make a determination of whether the + URI reference constitutes a "same-document reference", as defined in RFC + 2396 or RFC 3986. As per the spec, dereferencing a same-document + reference "should not" involve retrieval of a new representation of the + referenced resource. Note that the two specs have different definitions + of same-document reference: RFC 2396 says it is *only* the cases where the + reference is the empty string, or "#" followed by a fragment; RFC 3986 + requires making a comparison of the base URI to the absolute form of the + reference (as is returned by the spec), minus its fragment component, + if any. + + This function is similar to urlparse.urljoin() and urllib.basejoin(). + Those functions, however, are (as of Python 2.3) outdated, buggy, and/or + designed to produce results acceptable for use with other core Python + libraries, rather than being earnest implementations of the relevant + specs. Their problems are most noticeable in their handling of + same-document references and 'file:' URIs, both being situations that + come up far too often to consider the functions reliable enough for + general use. + """ + # Reasons to avoid using urllib.basejoin() and urlparse.urljoin(): + # - Both are partial implementations of long-obsolete specs. + # - Both accept relative URLs as the base, which no spec allows. + # - urllib.basejoin() mishandles the '' and '..' references. + # - If the base URL uses a non-hierarchical or relative path, + # or if the URL scheme is unrecognized, the result is not + # always as expected (partly due to issues in RFC 1808). + # - If the authority component of a 'file' URI is empty, + # the authority component is removed altogether. If it was + # not present, an empty authority component is in the result. + # - '.' and '..' segments are not always collapsed as well as they + # should be (partly due to issues in RFC 1808). + # - Effective Python 2.4, urllib.basejoin() *is* urlparse.urljoin(), + # but urlparse.urljoin() is still based on RFC 1808. + + # This procedure is based on the pseudocode in RFC 3986 sec. 5.2. + # + # ensure base URI is absolute + if not baseUri: + raise ValueError('baseUri is required and must be a non empty string') + if not IsAbsolute(baseUri): + raise ValueError('%r is not an absolute URI' % baseUri) + # shortcut for the simplest same-document reference cases + if uriRef == '' or uriRef[0] == '#': + return baseUri.split('#')[0] + uriRef + # ensure a clean slate + tScheme = tAuth = tPath = tQuery = None + # parse the reference into its components + (rScheme, rAuth, rPath, rQuery, rFrag) = SplitUriRef(uriRef) + # if the reference is absolute, eliminate '.' and '..' path segments + # and skip to the end + if rScheme is not None: + tScheme = rScheme + tAuth = rAuth + tPath = RemoveDotSegments(rPath) + tQuery = rQuery + else: + # the base URI's scheme, and possibly more, will be inherited + (bScheme, bAuth, bPath, bQuery, bFrag) = SplitUriRef(baseUri) + # if the reference is a net-path, just eliminate '.' and '..' path + # segments; no other changes needed. + if rAuth is not None: + tAuth = rAuth + tPath = RemoveDotSegments(rPath) + tQuery = rQuery + # if it's not a net-path, we need to inherit pieces of the base URI + else: + # use base URI's path if the reference's path is empty + if not rPath: + tPath = bPath + # use the reference's query, if any, or else the base URI's, + tQuery = rQuery is not None and rQuery or bQuery + # the reference's path is not empty + else: + # just use the reference's path if it's absolute + if rPath[0] == '/': + tPath = RemoveDotSegments(rPath) + # merge the reference's relative path with the base URI's path + else: + if bAuth is not None and not bPath: + tPath = '/' + rPath + else: + tPath = bPath[:bPath.rfind('/')+1] + rPath + tPath = RemoveDotSegments(tPath) + # use the reference's query + tQuery = rQuery + # since the reference isn't a net-path, + # use the authority from the base URI + tAuth = bAuth + # inherit the scheme from the base URI + tScheme = bScheme + # always use the reference's fragment (but no need to define another var) + #tFrag = rFrag + + # now compose the target URI (RFC 3986 sec. 5.3) + return UnsplitUriRef((tScheme, tAuth, tPath, tQuery, rFrag)) + + +REG_NAME_HOST_PATTERN = re.compile(r"^(?:(?:[0-9A-Za-z\-_\.!~*'();&=+$,]|(?:%[0-9A-Fa-f]{2}))*)$") + +def MakeUrllibSafe(uriRef): + """ + Makes the given RFC 3986-conformant URI reference safe for passing + to legacy urllib functions. The result may not be a valid URI. + + As of Python 2.3.3, urllib.urlopen() does not fully support + internationalized domain names, it does not strip fragment components, + and on Windows, it expects file URIs to use '|' instead of ':' in the + path component corresponding to the drivespec. It also relies on + urllib.unquote(), which mishandles unicode arguments. This function + produces a URI reference that will work around these issues, although + the IDN workaround is limited to Python 2.3 only. May raise a + UnicodeEncodeError if the URI reference is Unicode and erroneously + contains non-ASCII characters. + """ + # IDN support requires decoding any percent-encoded octets in the + # host part (if it's a reg-name) of the authority component, and when + # doing DNS lookups, applying IDNA encoding to that string first. + # As of Python 2.3, there is an IDNA codec, and the socket and httplib + # modules accept Unicode strings and apply IDNA encoding automatically + # where necessary. However, urllib.urlopen() has not yet been updated + # to do the same; it raises an exception if you give it a Unicode + # string, and does no conversion on non-Unicode strings, meaning you + # have to give it an IDNA string yourself. We will only support it on + # Python 2.3 and up. + # + # see if host is a reg-name, as opposed to IPv4 or IPv6 addr. + if isinstance(uriRef, unicode): + try: + uriRef = uriRef.encode('us-ascii') # parts of urllib are not unicode safe + except UnicodeError: + raise ValueError("uri %r must consist of ASCII characters." % uriRef) + (scheme, auth, path, query, frag) = urlparse.urlsplit(uriRef) + if auth and auth.find('@') > -1: + userinfo, hostport = auth.split('@') + else: + userinfo = None + hostport = auth + if hostport and hostport.find(':') > -1: + host, port = hostport.split(':') + else: + host = hostport + port = None + if host and REG_NAME_HOST_PATTERN.match(host): + # percent-encoded hostnames will always fail DNS lookups + host = urllib.unquote(host) #PercentDecode(host) + # IDNA-encode if possible. + # We shouldn't do this for schemes that don't need DNS lookup, + # but are there any (that you'd be calling urlopen for)? + if sys.version_info[0:2] >= (2, 3): + if isinstance(host, str): + host = host.decode('utf-8') + host = host.encode('idna') + # reassemble the authority with the new hostname + # (percent-decoded, and possibly IDNA-encoded) + auth = '' + if userinfo: + auth += userinfo + '@' + auth += host + if port: + auth += ':' + port + + # On Windows, ensure that '|', not ':', is used in a drivespec. + if os.name == 'nt' and scheme == 'file': + path = path.replace(':', '|', 1) + + # Note that we drop fragment, if any. See RFC 3986 sec. 3.5. + uri = urlparse.urlunsplit((scheme, auth, path, query, None)) + + return uri + + + +def BaseJoin(base, uriRef): + """ + Merges a base URI reference with another URI reference, returning a + new URI reference. + + It behaves exactly the same as Absolutize(), except the arguments + are reversed, and it accepts any URI reference (even a relative URI) + as the base URI. If the base has no scheme component, it is + evaluated as if it did, and then the scheme component of the result + is removed from the result, unless the uriRef had a scheme. Thus, if + neither argument has a scheme component, the result won't have one. + + This function is named BaseJoin because it is very much like + urllib.basejoin(), but it follows the current rfc3986 algorithms + for path merging, dot segment elimination, and inheritance of query + and fragment components. + + WARNING: This function exists for 2 reasons: (1) because of a need + within the 4Suite repository to perform URI reference absolutization + using base URIs that are stored (inappropriately) as absolute paths + in the subjects of statements in the RDF model, and (2) because of + a similar need to interpret relative repo paths in a 4Suite product + setup.xml file as being relative to a path that can be set outside + the document. When these needs go away, this function probably will, + too, so it is not advisable to use it. + """ + if IsAbsolute(base): + return Absolutize(uriRef, base) + else: + dummyscheme = 'basejoin' + res = Absolutize(uriRef, '%s:%s' % (dummyscheme, base)) + if IsAbsolute(uriRef): + # scheme will be inherited from uriRef + return res + else: + # no scheme in, no scheme out + return res[len(dummyscheme)+1:] + + +def RemoveDotSegments(path): + """ + Supports Absolutize() by implementing the remove_dot_segments function + described in RFC 3986 sec. 5.2. It collapses most of the '.' and '..' + segments out of a path without eliminating empty segments. It is intended + to be used during the path merging process and may not give expected + results when used independently. Use NormalizePathSegments() or + NormalizePathSegmentsInUri() if more general normalization is desired. + + semi-private because it is not for general use. I've implemented it + using two segment stacks, as alluded to in the spec, rather than the + explicit string-walking algorithm that would be too inefficient. (mbrown) + """ + # return empty string if entire path is just "." or ".." + if path == '.' or path == '..': + return path[0:0] # preserves string type + # remove all "./" or "../" segments at the beginning + while path: + if path[:2] == './': + path = path[2:] + elif path[:3] == '../': + path = path[3:] + else: + break + # We need to keep track of whether there was a leading slash, + # because we're going to drop it in order to prevent our list of + # segments from having an ambiguous empty first item when we call + # split(). + leading_slash = 0 + if path[:1] == '/': + path = path[1:] + leading_slash = 1 + # replace a trailing "/." with just "/" + if path[-2:] == '/.': + path = path[:-1] + # convert the segments into a list and process each segment in + # order from left to right. + segments = path.split('/') + keepers = [] + segments.reverse() + while segments: + seg = segments.pop() + # '..' means drop the previous kept segment, if any. + # If none, and if the path is relative, then keep the '..'. + # If the '..' was the last segment, ensure + # that the result ends with '/'. + if seg == '..': + if keepers: + keepers.pop() + elif not leading_slash: + keepers.append(seg) + if not segments: + keepers.append('') + # ignore '.' segments and keep all others, even empty ones + elif seg != '.': + keepers.append(seg) + # reassemble the kept segments + return leading_slash * '/' + '/'.join(keepers) + + +SCHEME_PATTERN = re.compile(r'([a-zA-Z][a-zA-Z0-9+\-.]*):') +def GetScheme(uriRef): + """ + Obtains, with optimum efficiency, just the scheme from a URI reference. + Returns a string, or if no scheme could be found, returns None. + """ + # Using a regex seems to be the best option. Called 50,000 times on + # different URIs, on a 1.0-GHz PIII with FreeBSD 4.7 and Python + # 2.2.1, this method completed in 0.95s, and 0.05s if there was no + # scheme to find. By comparison, + # urllib.splittype()[0] took 1.5s always; + # Ft.Lib.Uri.SplitUriRef()[0] took 2.5s always; + # urlparse.urlparse()[0] took 3.5s always. + m = SCHEME_PATTERN.match(uriRef) + if m is None: + return None + else: + return m.group(1) + + +def IsAbsolute(identifier): + """ + Given a string believed to be a URI or URI reference, tests that it is + absolute (as per RFC 2396), not relative -- i.e., that it has a scheme. + """ + # We do it this way to avoid compiling another massive regex. + return GetScheme(identifier) is not None diff --git a/src/main/resources/PythonLibs/xml/__init__.py b/src/main/resources/PythonLibs/xml/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e6d31444431dc7138efde512f51cdccab51f996d --- /dev/null +++ b/src/main/resources/PythonLibs/xml/__init__.py @@ -0,0 +1,36 @@ +"""Core XML support for Jython. + +This package contains two sub-packages: + +dom -- The W3C Document Object Model. This supports DOM Level 1 + + Namespaces. + +sax -- The Simple API for XML, developed by XML-Dev, led by David + Megginson and ported to Python by Lars Marius Garshol. This + supports the SAX 2 API. + +""" + +__all__ = ['dom', 'sax'] + + +_MINIMUM_XMLPLUS_VERSION = (0, 8, 5) + + +try: + import _xmlplus +except ImportError: + pass +else: + try: + v = _xmlplus.version_info + except AttributeError: + # _xmlplus is too old; ignore it + pass + else: + if v >= _MINIMUM_XMLPLUS_VERSION: + import sys + _xmlplus.__path__.extend(__path__) + sys.modules[__name__] = _xmlplus + else: + del v diff --git a/src/main/resources/PythonLibs/xml/dom/MessageSource.py b/src/main/resources/PythonLibs/xml/dom/MessageSource.py new file mode 100644 index 0000000000000000000000000000000000000000..d9503ae1f6ddf7c01e35e3f83a7f203b2282e7c0 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/MessageSource.py @@ -0,0 +1,54 @@ +# DOMException +from xml.dom import INDEX_SIZE_ERR, DOMSTRING_SIZE_ERR , HIERARCHY_REQUEST_ERR +from xml.dom import WRONG_DOCUMENT_ERR, INVALID_CHARACTER_ERR, NO_DATA_ALLOWED_ERR +from xml.dom import NO_MODIFICATION_ALLOWED_ERR, NOT_FOUND_ERR, NOT_SUPPORTED_ERR +from xml.dom import INUSE_ATTRIBUTE_ERR, INVALID_STATE_ERR, SYNTAX_ERR +from xml.dom import INVALID_MODIFICATION_ERR, NAMESPACE_ERR, INVALID_ACCESS_ERR +from xml.dom import VALIDATION_ERR + +# EventException +from xml.dom import UNSPECIFIED_EVENT_TYPE_ERR + +#Range Exceptions +from xml.dom import BAD_BOUNDARYPOINTS_ERR +from xml.dom import INVALID_NODE_TYPE_ERR + +# Fourthought Exceptions +from xml.dom import XML_PARSE_ERR + +from xml.FtCore import get_translator + +_ = get_translator("dom") + + +DOMExceptionStrings = { + INDEX_SIZE_ERR: _("Index error accessing NodeList or NamedNodeMap"), + DOMSTRING_SIZE_ERR: _("DOMString exceeds maximum size"), + HIERARCHY_REQUEST_ERR: _("Node manipulation results in invalid parent/child relationship."), + WRONG_DOCUMENT_ERR: _("Node is from a different document"), + INVALID_CHARACTER_ERR: _("Invalid or illegal character"), + NO_DATA_ALLOWED_ERR: _("Node does not support data"), + NO_MODIFICATION_ALLOWED_ERR: _("Attempt to modify a read-only object"), + NOT_FOUND_ERR: _("Node does not exist in this context"), + NOT_SUPPORTED_ERR: _("Object or operation not supported"), + INUSE_ATTRIBUTE_ERR: _("Attribute already in use by an element"), + INVALID_STATE_ERR: _("Object is not, or is no longer, usable"), + SYNTAX_ERR: _("Specified string is invalid or illegal"), + INVALID_MODIFICATION_ERR: _("Attempt to modify the type of a node"), + NAMESPACE_ERR: _("Invalid or illegal namespace operation"), + INVALID_ACCESS_ERR: _("Object does not support this operation or parameter"), + VALIDATION_ERR: _("Operation would invalidate partial validity constraint"), + } + +EventExceptionStrings = { + UNSPECIFIED_EVENT_TYPE_ERR : _("Uninitialized type in Event object"), + } + +FtExceptionStrings = { + XML_PARSE_ERR : _("XML parse error at line %d, column %d: %s"), + } + +RangeExceptionStrings = { + BAD_BOUNDARYPOINTS_ERR : _("Invalid Boundary Points specified for Range"), + INVALID_NODE_TYPE_ERR : _("Invalid Container Node") + } diff --git a/src/main/resources/PythonLibs/xml/dom/NodeFilter.py b/src/main/resources/PythonLibs/xml/dom/NodeFilter.py new file mode 100644 index 0000000000000000000000000000000000000000..fc052459da4a73bfab59a0bf2ab2e30429db9955 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/NodeFilter.py @@ -0,0 +1,27 @@ +# This is the Python mapping for interface NodeFilter from +# DOM2-Traversal-Range. It contains only constants. + +class NodeFilter: + """ + This is the DOM2 NodeFilter interface. It contains only constants. + """ + FILTER_ACCEPT = 1 + FILTER_REJECT = 2 + FILTER_SKIP = 3 + + SHOW_ALL = 0xFFFFFFFFL + SHOW_ELEMENT = 0x00000001 + SHOW_ATTRIBUTE = 0x00000002 + SHOW_TEXT = 0x00000004 + SHOW_CDATA_SECTION = 0x00000008 + SHOW_ENTITY_REFERENCE = 0x00000010 + SHOW_ENTITY = 0x00000020 + SHOW_PROCESSING_INSTRUCTION = 0x00000040 + SHOW_COMMENT = 0x00000080 + SHOW_DOCUMENT = 0x00000100 + SHOW_DOCUMENT_TYPE = 0x00000200 + SHOW_DOCUMENT_FRAGMENT = 0x00000400 + SHOW_NOTATION = 0x00000800 + + def acceptNode(self, node): + raise NotImplementedError diff --git a/src/main/resources/PythonLibs/xml/dom/__init__.py b/src/main/resources/PythonLibs/xml/dom/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..3c645bfe67ed49daa9eaedd63d262eb62e35a87d --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/__init__.py @@ -0,0 +1,232 @@ +######################################################################## +# +# File Name: __init__.py +# +# +""" +WWW: http://4suite.org/4DOM e-mail: support@4suite.org + +Copyright (c) 2000 Fourthought Inc, USA. All Rights Reserved. +See http://4suite.org/COPYRIGHT for license and copyright information +""" + + +class Node: + """Class giving the nodeType and tree-position constants.""" + + # DOM implementations may use this as a base class for their own + # Node implementations. If they don't, the constants defined here + # should still be used as the canonical definitions as they match + # the values given in the W3C recommendation. Client code can + # safely refer to these values in all tests of Node.nodeType + # values. + + ELEMENT_NODE = 1 + ATTRIBUTE_NODE = 2 + TEXT_NODE = 3 + CDATA_SECTION_NODE = 4 + ENTITY_REFERENCE_NODE = 5 + ENTITY_NODE = 6 + PROCESSING_INSTRUCTION_NODE = 7 + COMMENT_NODE = 8 + DOCUMENT_NODE = 9 + DOCUMENT_TYPE_NODE = 10 + DOCUMENT_FRAGMENT_NODE = 11 + NOTATION_NODE = 12 + + # Based on DOM Level 3 (WD 9 April 2002) + + TREE_POSITION_PRECEDING = 0x01 + TREE_POSITION_FOLLOWING = 0x02 + TREE_POSITION_ANCESTOR = 0x04 + TREE_POSITION_DESCENDENT = 0x08 + TREE_POSITION_EQUIVALENT = 0x10 + TREE_POSITION_SAME_NODE = 0x20 + TREE_POSITION_DISCONNECTED = 0x00 + +class UserDataHandler: + """Class giving the operation constants for UserDataHandler.handle().""" + + # Based on DOM Level 3 (WD 9 April 2002) + + NODE_CLONED = 1 + NODE_IMPORTED = 2 + NODE_DELETED = 3 + NODE_RENAMED = 4 + +class DOMError: + """Class giving constants for error severity.""" + + # Based on DOM Level 3 (WD 9 April 2002) + + SEVERITY_WARNING = 0 + SEVERITY_ERROR = 1 + SEVERITY_FATAL_ERROR = 2 + + +# DOMException codes +INDEX_SIZE_ERR = 1 +DOMSTRING_SIZE_ERR = 2 +HIERARCHY_REQUEST_ERR = 3 +WRONG_DOCUMENT_ERR = 4 +INVALID_CHARACTER_ERR = 5 +NO_DATA_ALLOWED_ERR = 6 +NO_MODIFICATION_ALLOWED_ERR = 7 +NOT_FOUND_ERR = 8 +NOT_SUPPORTED_ERR = 9 +INUSE_ATTRIBUTE_ERR = 10 +# DOM Level 2 +INVALID_STATE_ERR = 11 +SYNTAX_ERR = 12 +INVALID_MODIFICATION_ERR = 13 +NAMESPACE_ERR = 14 +INVALID_ACCESS_ERR = 15 +# DOM Level 3 +VALIDATION_ERR = 16 + +# EventException codes +UNSPECIFIED_EVENT_TYPE_ERR = 0 + +# Fourthought specific codes +FT_EXCEPTION_BASE = 1000 +XML_PARSE_ERR = FT_EXCEPTION_BASE + 1 + +#RangeException codes +BAD_BOUNDARYPOINTS_ERR = 1 +INVALID_NODE_TYPE_ERR = 2 + + +class DOMException(Exception): + def __init__(self, code, msg=''): + self.code = code + self.msg = msg or DOMExceptionStrings[code] + + def __str__(self): + return self.msg + +class EventException(Exception): + def __init__(self, code, msg=''): + self.code = code + self.msg = msg or EventExceptionStrings[code] + return + + def __str__(self): + return self.msg + +class RangeException(Exception): + def __init__(self, code, msg): + self.code = code + self.msg = msg or RangeExceptionStrings[code] + Exception.__init__(self, self.msg) + +class FtException(Exception): + def __init__(self, code, *args): + self.code = code + self.msg = FtExceptionStrings[code] % args + return + + def __str__(self): + return self.msg + +class IndexSizeErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, INDEX_SIZE_ERR, msg) + +class DomstringSizeErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, DOMSTRING_SIZE_ERR, msg) + +# DOMStringSizeErr was accidentally introduced in rev 1.14 of this +# file, and was released as part of PyXML 0.6.4, 0.6.5, 0.6.6, 0.7, +# and 0.7.1. It has never been part of the Python DOM API, although +# it better matches the W3C recommendation. It should remain for +# compatibility, unfortunately. +# +DOMStringSizeErr = DomstringSizeErr + +class HierarchyRequestErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, HIERARCHY_REQUEST_ERR, msg) + +class WrongDocumentErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, WRONG_DOCUMENT_ERR, msg) + +class InvalidCharacterErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, INVALID_CHARACTER_ERR, msg) + +class NoDataAllowedErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, NO_DATA_ALLOWED_ERR, msg) + +class NoModificationAllowedErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, NO_MODIFICATION_ALLOWED_ERR, msg) + +class NotFoundErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, NOT_FOUND_ERR, msg) + +class NotSupportedErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, NOT_SUPPORTED_ERR, msg) + +class InuseAttributeErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, INUSE_ATTRIBUTE_ERR, msg) + +class InvalidStateErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, INVALID_STATE_ERR, msg) + +class SyntaxErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, SYNTAX_ERR, msg) + +class InvalidModificationErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, INVALID_MODIFICATION_ERR, msg) + +class NamespaceErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, NAMESPACE_ERR, msg) + +class InvalidAccessErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, INVALID_ACCESS_ERR, msg) + +class ValidationErr(DOMException): + def __init__(self, msg=''): + DOMException.__init__(self, VALIDATION_ERR, msg) + +class UnspecifiedEventTypeErr(EventException): + def __init__(self, msg=''): + EventException.__init__(self, UNSPECIFIED_EVENT_TYPE_ERR, msg) + +class XmlParseErr(FtException): + def __init__(self, msg=''): + FtException.__init__(self, XML_PARSE_ERR, msg) + +#Specific Range Exceptions +class BadBoundaryPointsErr(RangeException): + def __init__(self, msg=''): + RangeException.__init__(self, BAD_BOUNDARYPOINTS_ERR, msg) + +class InvalidNodeTypeErr(RangeException): + def __init__(self, msg=''): + RangeException.__init__(self, INVALID_NODE_TYPE_ERR, msg) + +XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace" +XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/" +XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml" +EMPTY_NAMESPACE = None +EMPTY_PREFIX = None + +import MessageSource +DOMExceptionStrings = MessageSource.__dict__['DOMExceptionStrings'] +EventExceptionStrings = MessageSource.__dict__['EventExceptionStrings'] +FtExceptionStrings = MessageSource.__dict__['FtExceptionStrings'] +RangeExceptionStrings = MessageSource.__dict__['RangeExceptionStrings'] + +from domreg import getDOMImplementation,registerDOMImplementation diff --git a/src/main/resources/PythonLibs/xml/dom/domreg.py b/src/main/resources/PythonLibs/xml/dom/domreg.py new file mode 100644 index 0000000000000000000000000000000000000000..117ca498202eaf73330c190ec65067bf2f3dfb08 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/domreg.py @@ -0,0 +1,99 @@ +"""Registration facilities for DOM. This module should not be used +directly. Instead, the functions getDOMImplementation and +registerDOMImplementation should be imported from xml.dom.""" + +from xml.dom.minicompat import * # isinstance, StringTypes + +# This is a list of well-known implementations. Well-known names +# should be published by posting to xml-sig@python.org, and are +# subsequently recorded in this file. + +well_known_implementations = { + 'minidom':'xml.dom.minidom', + '4DOM': 'xml.dom.DOMImplementation', + } + +# DOM implementations not officially registered should register +# themselves with their + +registered = {} + +def registerDOMImplementation(name, factory): + """registerDOMImplementation(name, factory) + + Register the factory function with the name. The factory function + should return an object which implements the DOMImplementation + interface. The factory function can either return the same object, + or a new one (e.g. if that implementation supports some + customization).""" + + registered[name] = factory + +def _good_enough(dom, features): + "_good_enough(dom, features) -> Return 1 if the dom offers the features" + for f,v in features: + if not dom.hasFeature(f,v): + return 0 + return 1 + +def getDOMImplementation(name = None, features = ()): + """getDOMImplementation(name = None, features = ()) -> DOM implementation. + + Return a suitable DOM implementation. The name is either + well-known, the module name of a DOM implementation, or None. If + it is not None, imports the corresponding module and returns + DOMImplementation object if the import succeeds. + + If name is not given, consider the available implementations to + find one with the required feature set. If no implementation can + be found, raise an ImportError. The features list must be a sequence + of (feature, version) pairs which are passed to hasFeature.""" + + import os + creator = None + mod = well_known_implementations.get(name) + if mod: + mod = __import__(mod, {}, {}, ['getDOMImplementation']) + return mod.getDOMImplementation() + elif name: + return registered[name]() + elif os.environ.has_key("PYTHON_DOM"): + return getDOMImplementation(name = os.environ["PYTHON_DOM"]) + + # User did not specify a name, try implementations in arbitrary + # order, returning the one that has the required features + if isinstance(features, StringTypes): + features = _parse_feature_string(features) + for creator in registered.values(): + dom = creator() + if _good_enough(dom, features): + return dom + + for creator in well_known_implementations.keys(): + try: + dom = getDOMImplementation(name = creator) + except StandardError: # typically ImportError, or AttributeError + continue + if _good_enough(dom, features): + return dom + + raise ImportError,"no suitable DOM implementation found" + +def _parse_feature_string(s): + features = [] + parts = s.split() + i = 0 + length = len(parts) + while i < length: + feature = parts[i] + if feature[0] in "0123456789": + raise ValueError, "bad feature name: " + `feature` + i = i + 1 + version = None + if i < length: + v = parts[i] + if v[0] in "0123456789": + i = i + 1 + version = v + features.append((feature, version)) + return tuple(features) diff --git a/src/main/resources/PythonLibs/xml/dom/minicompat.py b/src/main/resources/PythonLibs/xml/dom/minicompat.py new file mode 100644 index 0000000000000000000000000000000000000000..9f2f8f76271d7e37e7c003ba13b9cf85bbbdb935 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/minicompat.py @@ -0,0 +1,184 @@ +"""Python version compatibility support for minidom.""" + +# This module should only be imported using "import *". +# +# The following names are defined: +# +# isinstance -- version of the isinstance() function that accepts +# tuples as the second parameter regardless of the +# Python version +# +# NodeList -- lightest possible NodeList implementation +# +# EmptyNodeList -- lightest possible NodeList that is guarateed to +# remain empty (immutable) +# +# StringTypes -- tuple of defined string types +# +# GetattrMagic -- base class used to make _get_<attr> be magically +# invoked when available +# defproperty -- function used in conjunction with GetattrMagic; +# using these together is needed to make them work +# as efficiently as possible in both Python 2.2+ +# and older versions. For example: +# +# class MyClass(GetattrMagic): +# def _get_myattr(self): +# return something +# +# defproperty(MyClass, "myattr", +# "return some value") +# +# For Python 2.2 and newer, this will construct a +# property object on the class, which avoids +# needing to override __getattr__(). It will only +# work for read-only attributes. +# +# For older versions of Python, inheriting from +# GetattrMagic will use the traditional +# __getattr__() hackery to achieve the same effect, +# but less efficiently. +# +# defproperty() should be used for each version of +# the relevant _get_<property>() function. +# +# NewStyle -- base class to cause __slots__ to be honored in +# the new world +# +# True, False -- only for Python 2.2 and earlier + +__all__ = ["NodeList", "EmptyNodeList", "NewStyle", + "StringTypes", "defproperty", "GetattrMagic"] + +import xml.dom + +try: + unicode +except NameError: + StringTypes = type(''), +else: + StringTypes = type(''), type(unicode('')) + + +# define True and False only if not defined as built-ins +try: + True +except NameError: + True = 1 + False = 0 + __all__.extend(["True", "False"]) + + +try: + isinstance('', StringTypes) +except TypeError: + # + # Wrap isinstance() to make it compatible with the version in + # Python 2.2 and newer. + # + _isinstance = isinstance + def isinstance(obj, type_or_seq): + try: + return _isinstance(obj, type_or_seq) + except TypeError: + for t in type_or_seq: + if _isinstance(obj, t): + return 1 + return 0 + __all__.append("isinstance") + + +if list is type([]): + class NodeList(list): + __slots__ = () + + def item(self, index): + if 0 <= index < len(self): + return self[index] + + def _get_length(self): + return len(self) + + def _set_length(self, value): + raise xml.dom.NoModificationAllowedErr( + "attempt to modify read-only attribute 'length'") + + length = property(_get_length, _set_length, + doc="The number of nodes in the NodeList.") + + def __getstate__(self): + return list(self) + + def __setstate__(self, state): + self[:] = state + + class EmptyNodeList(tuple): + __slots__ = () + + def __add__(self, other): + NL = NodeList() + NL.extend(other) + return NL + + def __radd__(self, other): + NL = NodeList() + NL.extend(other) + return NL + + def item(self, index): + return None + + def _get_length(self): + return 0 + + def _set_length(self, value): + raise xml.dom.NoModificationAllowedErr( + "attempt to modify read-only attribute 'length'") + + length = property(_get_length, _set_length, + doc="The number of nodes in the NodeList.") + +else: + def NodeList(): + return [] + + def EmptyNodeList(): + return [] + + +try: + property +except NameError: + def defproperty(klass, name, doc): + # taken care of by the base __getattr__() + pass + + class GetattrMagic: + def __getattr__(self, key): + if key.startswith("_"): + raise AttributeError, key + + try: + get = getattr(self, "_get_" + key) + except AttributeError: + raise AttributeError, key + return get() + + class NewStyle: + pass + +else: + def defproperty(klass, name, doc): + get = getattr(klass, ("_get_" + name)).im_func + def set(self, value, name=name): + raise xml.dom.NoModificationAllowedErr( + "attempt to modify read-only attribute " + repr(name)) + assert not hasattr(klass, "_set_" + name), \ + "expected not to find _set_" + name + prop = property(get, set, doc=doc) + setattr(klass, name, prop) + + class GetattrMagic: + pass + + NewStyle = object diff --git a/src/main/resources/PythonLibs/xml/dom/minidom.py b/src/main/resources/PythonLibs/xml/dom/minidom.py new file mode 100644 index 0000000000000000000000000000000000000000..b7f3be9d557c3918a0bf164456a87a0d6aa20c92 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/minidom.py @@ -0,0 +1,1944 @@ +"""\ +minidom.py -- a lightweight DOM implementation. + +parse("foo.xml") + +parseString("<foo><bar/></foo>") + +Todo: +===== + * convenience methods for getting elements and text. + * more testing + * bring some of the writer and linearizer code into conformance with this + interface + * SAX 2 namespaces +""" + +import xml.dom + +from xml.dom import EMPTY_NAMESPACE, EMPTY_PREFIX, XMLNS_NAMESPACE, domreg +from xml.dom.minicompat import * +from xml.dom.xmlbuilder import DOMImplementationLS, DocumentLS + +_TupleType = type(()) + +# This is used by the ID-cache invalidation checks; the list isn't +# actually complete, since the nodes being checked will never be the +# DOCUMENT_NODE or DOCUMENT_FRAGMENT_NODE. (The node being checked is +# the node being added or removed, not the node being modified.) +# +_nodeTypes_with_children = (xml.dom.Node.ELEMENT_NODE, + xml.dom.Node.ENTITY_REFERENCE_NODE) + + +class Node(xml.dom.Node, GetattrMagic): + namespaceURI = None # this is non-null only for elements and attributes + parentNode = None + ownerDocument = None + nextSibling = None + previousSibling = None + + prefix = EMPTY_PREFIX # non-null only for NS elements and attributes + + def __nonzero__(self): + return True + + def toxml(self, encoding = None): + return self.toprettyxml("", "", encoding) + + def toprettyxml(self, indent="\t", newl="\n", encoding = None): + # indent = the indentation string to prepend, per level + # newl = the newline string to append + writer = _get_StringIO() + if encoding is not None: + import codecs + # Can't use codecs.getwriter to preserve 2.0 compatibility + writer = codecs.lookup(encoding)[3](writer) + if self.nodeType == Node.DOCUMENT_NODE: + # Can pass encoding only to document, to put it into XML header + self.writexml(writer, "", indent, newl, encoding) + else: + self.writexml(writer, "", indent, newl) + return writer.getvalue() + + def hasAttributes(self): + return False + + def hasChildNodes(self): + if self.childNodes: + return True + else: + return False + + def _get_childNodes(self): + return self.childNodes + + def _get_firstChild(self): + if self.childNodes: + return self.childNodes[0] + + def _get_lastChild(self): + if self.childNodes: + return self.childNodes[-1] + + def insertBefore(self, newChild, refChild): + if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE: + for c in tuple(newChild.childNodes): + self.insertBefore(c, refChild) + ### The DOM does not clearly specify what to return in this case + return newChild + if newChild.nodeType not in self._child_node_types: + raise xml.dom.HierarchyRequestErr( + "%s cannot be child of %s" % (repr(newChild), repr(self))) + if newChild.parentNode is not None: + newChild.parentNode.removeChild(newChild) + if refChild is None: + self.appendChild(newChild) + else: + try: + index = self.childNodes.index(refChild) + except ValueError: + raise xml.dom.NotFoundErr() + if newChild.nodeType in _nodeTypes_with_children: + _clear_id_cache(self) + self.childNodes.insert(index, newChild) + newChild.nextSibling = refChild + refChild.previousSibling = newChild + if index: + node = self.childNodes[index-1] + node.nextSibling = newChild + newChild.previousSibling = node + else: + newChild.previousSibling = None + newChild.parentNode = self + return newChild + + def appendChild(self, node): + if node.nodeType == self.DOCUMENT_FRAGMENT_NODE: + for c in tuple(node.childNodes): + self.appendChild(c) + ### The DOM does not clearly specify what to return in this case + return node + if node.nodeType not in self._child_node_types: + raise xml.dom.HierarchyRequestErr( + "%s cannot be child of %s" % (repr(node), repr(self))) + elif node.nodeType in _nodeTypes_with_children: + _clear_id_cache(self) + if node.parentNode is not None: + node.parentNode.removeChild(node) + _append_child(self, node) + node.nextSibling = None + return node + + def replaceChild(self, newChild, oldChild): + if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE: + refChild = oldChild.nextSibling + self.removeChild(oldChild) + return self.insertBefore(newChild, refChild) + if newChild.nodeType not in self._child_node_types: + raise xml.dom.HierarchyRequestErr( + "%s cannot be child of %s" % (repr(newChild), repr(self))) + if newChild.parentNode is not None: + newChild.parentNode.removeChild(newChild) + if newChild is oldChild: + return + try: + index = self.childNodes.index(oldChild) + except ValueError: + raise xml.dom.NotFoundErr() + if (newChild.nodeType in _nodeTypes_with_children + or oldChild.nodeType in _nodeTypes_with_children): + _clear_id_cache(self) + self.childNodes[index] = newChild + newChild.parentNode = self + oldChild.parentNode = None + newChild.nextSibling = oldChild.nextSibling + newChild.previousSibling = oldChild.previousSibling + oldChild.nextSibling = None + oldChild.previousSibling = None + if newChild.previousSibling: + newChild.previousSibling.nextSibling = newChild + if newChild.nextSibling: + newChild.nextSibling.previousSibling = newChild + return oldChild + + def removeChild(self, oldChild): + try: + self.childNodes.remove(oldChild) + except ValueError: + raise xml.dom.NotFoundErr() + if oldChild.nextSibling is not None: + oldChild.nextSibling.previousSibling = oldChild.previousSibling + if oldChild.previousSibling is not None: + oldChild.previousSibling.nextSibling = oldChild.nextSibling + oldChild.nextSibling = oldChild.previousSibling = None + if oldChild.nodeType in _nodeTypes_with_children: + _clear_id_cache(self) + + oldChild.parentNode = None + return oldChild + + def normalize(self): + L = [] + for child in self.childNodes: + if child.nodeType == Node.TEXT_NODE: + data = child.data + if data and L and L[-1].nodeType == child.nodeType: + # collapse text node + node = L[-1] + node.data = node.data + child.data + node.nextSibling = child.nextSibling + child.unlink() + elif data: + if L: + L[-1].nextSibling = child + child.previousSibling = L[-1] + else: + child.previousSibling = None + L.append(child) + else: + # empty text node; discard + child.unlink() + else: + if L: + L[-1].nextSibling = child + child.previousSibling = L[-1] + else: + child.previousSibling = None + L.append(child) + if child.nodeType == Node.ELEMENT_NODE: + child.normalize() + if self.childNodes: + self.childNodes[:] = L + return + + def cloneNode(self, deep): + return _clone_node(self, deep, self.ownerDocument or self) + + def isSupported(self, feature, version): + return self.ownerDocument.implementation.hasFeature(feature, version) + + def _get_localName(self): + # Overridden in Element and Attr where localName can be Non-Null + return None + + # Node interfaces from Level 3 (WD 9 April 2002) + + def isSameNode(self, other): + return self is other + + def getInterface(self, feature): + if self.isSupported(feature, None): + return self + else: + return None + + # The "user data" functions use a dictionary that is only present + # if some user data has been set, so be careful not to assume it + # exists. + + def getUserData(self, key): + try: + return self._user_data[key][0] + except (AttributeError, KeyError): + return None + + def setUserData(self, key, data, handler): + old = None + try: + d = self._user_data + except AttributeError: + d = {} + self._user_data = d + if d.has_key(key): + old = d[key][0] + if data is None: + # ignore handlers passed for None + handler = None + if old is not None: + del d[key] + else: + d[key] = (data, handler) + return old + + def _call_user_data_handler(self, operation, src, dst): + if hasattr(self, "_user_data"): + for key, (data, handler) in self._user_data.items(): + if handler is not None: + handler.handle(operation, key, data, src, dst) + + # minidom-specific API: + + def unlink(self): + self.parentNode = self.ownerDocument = None + if self.childNodes: + for child in self.childNodes: + child.unlink() + self.childNodes = NodeList() + self.previousSibling = None + self.nextSibling = None + +defproperty(Node, "firstChild", doc="First child node, or None.") +defproperty(Node, "lastChild", doc="Last child node, or None.") +defproperty(Node, "localName", doc="Namespace-local name of this node.") + + +def _append_child(self, node): + # fast path with less checks; usable by DOM builders if careful + childNodes = self.childNodes + if childNodes: + last = childNodes[-1] + node.__dict__["previousSibling"] = last + last.__dict__["nextSibling"] = node + childNodes.append(node) + node.__dict__["parentNode"] = self + +def _in_document(node): + # return True iff node is part of a document tree + while node is not None: + if node.nodeType == Node.DOCUMENT_NODE: + return True + node = node.parentNode + return False + +def _write_data(writer, data): + "Writes datachars to writer." + data = data.replace("&", "&").replace("<", "<") + data = data.replace("\"", """).replace(">", ">") + writer.write(data) + +def _get_elements_by_tagName_helper(parent, name, rc): + for node in parent.childNodes: + if node.nodeType == Node.ELEMENT_NODE and \ + (name == "*" or node.tagName == name): + rc.append(node) + _get_elements_by_tagName_helper(node, name, rc) + return rc + +def _get_elements_by_tagName_ns_helper(parent, nsURI, localName, rc): + for node in parent.childNodes: + if node.nodeType == Node.ELEMENT_NODE: + if ((localName == "*" or node.localName == localName) and + (nsURI == "*" or node.namespaceURI == nsURI)): + rc.append(node) + _get_elements_by_tagName_ns_helper(node, nsURI, localName, rc) + return rc + +class DocumentFragment(Node): + nodeType = Node.DOCUMENT_FRAGMENT_NODE + nodeName = "#document-fragment" + nodeValue = None + attributes = None + parentNode = None + _child_node_types = (Node.ELEMENT_NODE, + Node.TEXT_NODE, + Node.CDATA_SECTION_NODE, + Node.ENTITY_REFERENCE_NODE, + Node.PROCESSING_INSTRUCTION_NODE, + Node.COMMENT_NODE, + Node.NOTATION_NODE) + + def __init__(self): + self.childNodes = NodeList() + + +class Attr(Node): + nodeType = Node.ATTRIBUTE_NODE + attributes = None + ownerElement = None + specified = False + _is_id = False + + _child_node_types = (Node.TEXT_NODE, Node.ENTITY_REFERENCE_NODE) + + def __init__(self, qName, namespaceURI=EMPTY_NAMESPACE, localName=None, + prefix=None): + # skip setattr for performance + d = self.__dict__ + d["nodeName"] = d["name"] = qName + d["namespaceURI"] = namespaceURI + d["prefix"] = prefix + d['childNodes'] = NodeList() + + # Add the single child node that represents the value of the attr + self.childNodes.append(Text()) + + # nodeValue and value are set elsewhere + + def _get_localName(self): + return self.nodeName.split(":", 1)[-1] + + def _get_name(self): + return self.name + + def _get_specified(self): + return self.specified + + def __setattr__(self, name, value): + d = self.__dict__ + if name in ("value", "nodeValue"): + d["value"] = d["nodeValue"] = value + d2 = self.childNodes[0].__dict__ + d2["data"] = d2["nodeValue"] = value + if self.ownerElement is not None: + _clear_id_cache(self.ownerElement) + elif name in ("name", "nodeName"): + d["name"] = d["nodeName"] = value + if self.ownerElement is not None: + _clear_id_cache(self.ownerElement) + else: + d[name] = value + + def _set_prefix(self, prefix): + nsuri = self.namespaceURI + if prefix == "xmlns": + if nsuri and nsuri != XMLNS_NAMESPACE: + raise xml.dom.NamespaceErr( + "illegal use of 'xmlns' prefix for the wrong namespace") + d = self.__dict__ + d['prefix'] = prefix + if prefix is None: + newName = self.localName + else: + newName = "%s:%s" % (prefix, self.localName) + if self.ownerElement: + _clear_id_cache(self.ownerElement) + d['nodeName'] = d['name'] = newName + + def _set_value(self, value): + d = self.__dict__ + d['value'] = d['nodeValue'] = value + if self.ownerElement: + _clear_id_cache(self.ownerElement) + self.childNodes[0].data = value + + def unlink(self): + # This implementation does not call the base implementation + # since most of that is not needed, and the expense of the + # method call is not warranted. We duplicate the removal of + # children, but that's all we needed from the base class. + elem = self.ownerElement + if elem is not None: + del elem._attrs[self.nodeName] + del elem._attrsNS[(self.namespaceURI, self.localName)] + if self._is_id: + self._is_id = False + elem._magic_id_nodes -= 1 + self.ownerDocument._magic_id_count -= 1 + for child in self.childNodes: + child.unlink() + del self.childNodes[:] + + def _get_isId(self): + if self._is_id: + return True + doc = self.ownerDocument + elem = self.ownerElement + if doc is None or elem is None: + return False + + info = doc._get_elem_info(elem) + if info is None: + return False + if self.namespaceURI: + return info.isIdNS(self.namespaceURI, self.localName) + else: + return info.isId(self.nodeName) + + def _get_schemaType(self): + doc = self.ownerDocument + elem = self.ownerElement + if doc is None or elem is None: + return _no_type + + info = doc._get_elem_info(elem) + if info is None: + return _no_type + if self.namespaceURI: + return info.getAttributeTypeNS(self.namespaceURI, self.localName) + else: + return info.getAttributeType(self.nodeName) + +defproperty(Attr, "isId", doc="True if this attribute is an ID.") +defproperty(Attr, "localName", doc="Namespace-local name of this attribute.") +defproperty(Attr, "schemaType", doc="Schema type for this attribute.") + + +class NamedNodeMap(NewStyle, GetattrMagic): + """The attribute list is a transient interface to the underlying + dictionaries. Mutations here will change the underlying element's + dictionary. + + Ordering is imposed artificially and does not reflect the order of + attributes as found in an input document. + """ + + __slots__ = ('_attrs', '_attrsNS', '_ownerElement') + + def __init__(self, attrs, attrsNS, ownerElement): + self._attrs = attrs + self._attrsNS = attrsNS + self._ownerElement = ownerElement + + def _get_length(self): + return len(self._attrs) + + def item(self, index): + try: + return self[self._attrs.keys()[index]] + except IndexError: + return None + + def items(self): + L = [] + for node in self._attrs.values(): + L.append((node.nodeName, node.value)) + return L + + def itemsNS(self): + L = [] + for node in self._attrs.values(): + L.append(((node.namespaceURI, node.localName), node.value)) + return L + + def has_key(self, key): + if isinstance(key, StringTypes): + return self._attrs.has_key(key) + else: + return self._attrsNS.has_key(key) + + def keys(self): + return self._attrs.keys() + + def keysNS(self): + return self._attrsNS.keys() + + def values(self): + return self._attrs.values() + + def get(self, name, value=None): + return self._attrs.get(name, value) + + __len__ = _get_length + + def __cmp__(self, other): + if self._attrs is getattr(other, "_attrs", None): + return 0 + else: + return cmp(id(self), id(other)) + + def __getitem__(self, attname_or_tuple): + if isinstance(attname_or_tuple, _TupleType): + return self._attrsNS[attname_or_tuple] + else: + return self._attrs[attname_or_tuple] + + # same as set + def __setitem__(self, attname, value): + if isinstance(value, StringTypes): + try: + node = self._attrs[attname] + except KeyError: + node = Attr(attname) + node.ownerDocument = self._ownerElement.ownerDocument + self.setNamedItem(node) + node.value = value + else: + if not isinstance(value, Attr): + raise TypeError, "value must be a string or Attr object" + node = value + self.setNamedItem(node) + + def getNamedItem(self, name): + try: + return self._attrs[name] + except KeyError: + return None + + def getNamedItemNS(self, namespaceURI, localName): + try: + return self._attrsNS[(namespaceURI, localName)] + except KeyError: + return None + + def removeNamedItem(self, name): + n = self.getNamedItem(name) + if n is not None: + _clear_id_cache(self._ownerElement) + del self._attrs[n.nodeName] + del self._attrsNS[(n.namespaceURI, n.localName)] + if n.__dict__.has_key('ownerElement'): + n.__dict__['ownerElement'] = None + return n + else: + raise xml.dom.NotFoundErr() + + def removeNamedItemNS(self, namespaceURI, localName): + n = self.getNamedItemNS(namespaceURI, localName) + if n is not None: + _clear_id_cache(self._ownerElement) + del self._attrsNS[(n.namespaceURI, n.localName)] + del self._attrs[n.nodeName] + if n.__dict__.has_key('ownerElement'): + n.__dict__['ownerElement'] = None + return n + else: + raise xml.dom.NotFoundErr() + + def setNamedItem(self, node): + if not isinstance(node, Attr): + raise xml.dom.HierarchyRequestErr( + "%s cannot be child of %s" % (repr(node), repr(self))) + old = self._attrs.get(node.name) + if old: + old.unlink() + old.ownerDocument = self._ownerElement.ownerDocument + self._attrs[node.name] = node + self._attrsNS[(node.namespaceURI, node.localName)] = node + node.ownerElement = self._ownerElement + _clear_id_cache(node.ownerElement) + return old + + def setNamedItemNS(self, node): + return self.setNamedItem(node) + + def __delitem__(self, attname_or_tuple): + node = self[attname_or_tuple] + _clear_id_cache(node.ownerElement) + node.unlink() + + def __getstate__(self): + return self._attrs, self._attrsNS, self._ownerElement + + def __setstate__(self, state): + self._attrs, self._attrsNS, self._ownerElement = state + +defproperty(NamedNodeMap, "length", + doc="Number of nodes in the NamedNodeMap.") + +AttributeList = NamedNodeMap + + +class TypeInfo(NewStyle): + __slots__ = 'namespace', 'name' + + def __init__(self, namespace, name): + self.namespace = namespace + self.name = name + + def __repr__(self): + if self.namespace: + return "<TypeInfo %s (from %s)>" % (`self.name`, `self.namespace`) + else: + return "<TypeInfo %s>" % `self.name` + + def _get_name(self): + return self.name + + def _get_namespace(self): + return self.namespace + +_no_type = TypeInfo(None, None) + +class Element(Node): + nodeType = Node.ELEMENT_NODE + nodeValue = None + schemaType = _no_type + + _magic_id_nodes = 0 + + _child_node_types = (Node.ELEMENT_NODE, + Node.PROCESSING_INSTRUCTION_NODE, + Node.COMMENT_NODE, + Node.TEXT_NODE, + Node.CDATA_SECTION_NODE, + Node.ENTITY_REFERENCE_NODE) + + def __init__(self, tagName, namespaceURI=EMPTY_NAMESPACE, prefix=None, + localName=None): + self.tagName = self.nodeName = tagName + self.prefix = prefix + self.namespaceURI = namespaceURI + self.childNodes = NodeList() + + self._attrs = {} # attributes are double-indexed: + self._attrsNS = {} # tagName -> Attribute + # URI,localName -> Attribute + # in the future: consider lazy generation + # of attribute objects this is too tricky + # for now because of headaches with + # namespaces. + + def _get_localName(self): + return self.tagName.split(":", 1)[-1] + + def _get_tagName(self): + return self.tagName + + def unlink(self): + for attr in self._attrs.values(): + attr.unlink() + self._attrs = None + self._attrsNS = None + Node.unlink(self) + + def getAttribute(self, attname): + try: + return self._attrs[attname].value + except KeyError: + return "" + + def getAttributeNS(self, namespaceURI, localName): + try: + return self._attrsNS[(namespaceURI, localName)].value + except KeyError: + return "" + + def setAttribute(self, attname, value): + attr = self.getAttributeNode(attname) + if attr is None: + attr = Attr(attname) + # for performance + d = attr.__dict__ + d["value"] = d["nodeValue"] = value + d["ownerDocument"] = self.ownerDocument + self.setAttributeNode(attr) + elif value != attr.value: + d = attr.__dict__ + d["value"] = d["nodeValue"] = value + if attr.isId: + _clear_id_cache(self) + + def setAttributeNS(self, namespaceURI, qualifiedName, value): + prefix, localname = _nssplit(qualifiedName) + attr = self.getAttributeNodeNS(namespaceURI, localname) + if attr is None: + # for performance + attr = Attr(qualifiedName, namespaceURI, localname, prefix) + d = attr.__dict__ + d["prefix"] = prefix + d["nodeName"] = qualifiedName + d["value"] = d["nodeValue"] = value + d["ownerDocument"] = self.ownerDocument + self.setAttributeNode(attr) + else: + d = attr.__dict__ + if value != attr.value: + d["value"] = d["nodeValue"] = value + if attr.isId: + _clear_id_cache(self) + if attr.prefix != prefix: + d["prefix"] = prefix + d["nodeName"] = qualifiedName + + def getAttributeNode(self, attrname): + return self._attrs.get(attrname) + + def getAttributeNodeNS(self, namespaceURI, localName): + return self._attrsNS.get((namespaceURI, localName)) + + def setAttributeNode(self, attr): + if attr.ownerElement not in (None, self): + raise xml.dom.InuseAttributeErr("attribute node already owned") + old1 = self._attrs.get(attr.name, None) + if old1 is not None: + self.removeAttributeNode(old1) + old2 = self._attrsNS.get((attr.namespaceURI, attr.localName), None) + if old2 is not None and old2 is not old1: + self.removeAttributeNode(old2) + _set_attribute_node(self, attr) + + if old1 is not attr: + # It might have already been part of this node, in which case + # it doesn't represent a change, and should not be returned. + return old1 + if old2 is not attr: + return old2 + + setAttributeNodeNS = setAttributeNode + + def removeAttribute(self, name): + try: + attr = self._attrs[name] + except KeyError: + raise xml.dom.NotFoundErr() + self.removeAttributeNode(attr) + + def removeAttributeNS(self, namespaceURI, localName): + try: + attr = self._attrsNS[(namespaceURI, localName)] + except KeyError: + raise xml.dom.NotFoundErr() + self.removeAttributeNode(attr) + + def removeAttributeNode(self, node): + if node is None: + raise xml.dom.NotFoundErr() + try: + self._attrs[node.name] + except KeyError: + raise xml.dom.NotFoundErr() + _clear_id_cache(self) + node.unlink() + # Restore this since the node is still useful and otherwise + # unlinked + node.ownerDocument = self.ownerDocument + return node + + removeAttributeNodeNS = removeAttributeNode + + def hasAttribute(self, name): + return self._attrs.has_key(name) + + def hasAttributeNS(self, namespaceURI, localName): + return self._attrsNS.has_key((namespaceURI, localName)) + + def getElementsByTagName(self, name): + return _get_elements_by_tagName_helper(self, name, NodeList()) + + def getElementsByTagNameNS(self, namespaceURI, localName): + return _get_elements_by_tagName_ns_helper( + self, namespaceURI, localName, NodeList()) + + def __repr__(self): + return "<DOM Element: %s at %#x>" % (self.tagName, id(self)) + + def writexml(self, writer, indent="", addindent="", newl=""): + # indent = current indentation + # addindent = indentation to add to higher levels + # newl = newline string + writer.write(indent+"<" + self.tagName) + + attrs = self._get_attributes() + a_names = attrs.keys() + a_names.sort() + + for a_name in a_names: + writer.write(" %s=\"" % a_name) + _write_data(writer, attrs[a_name].value) + writer.write("\"") + if self.childNodes: + writer.write(">%s"%(newl)) + for node in self.childNodes: + node.writexml(writer,indent+addindent,addindent,newl) + writer.write("%s</%s>%s" % (indent,self.tagName,newl)) + else: + writer.write("/>%s"%(newl)) + + def _get_attributes(self): + return NamedNodeMap(self._attrs, self._attrsNS, self) + + def hasAttributes(self): + if self._attrs: + return True + else: + return False + + # DOM Level 3 attributes, based on the 22 Oct 2002 draft + + def setIdAttribute(self, name): + idAttr = self.getAttributeNode(name) + self.setIdAttributeNode(idAttr) + + def setIdAttributeNS(self, namespaceURI, localName): + idAttr = self.getAttributeNodeNS(namespaceURI, localName) + self.setIdAttributeNode(idAttr) + + def setIdAttributeNode(self, idAttr): + if idAttr is None or not self.isSameNode(idAttr.ownerElement): + raise xml.dom.NotFoundErr() + if _get_containing_entref(self) is not None: + raise xml.dom.NoModificationAllowedErr() + if not idAttr._is_id: + idAttr.__dict__['_is_id'] = True + self._magic_id_nodes += 1 + self.ownerDocument._magic_id_count += 1 + _clear_id_cache(self) + +defproperty(Element, "attributes", + doc="NamedNodeMap of attributes on the element.") +defproperty(Element, "localName", + doc="Namespace-local name of this element.") + + +def _set_attribute_node(element, attr): + _clear_id_cache(element) + element._attrs[attr.name] = attr + element._attrsNS[(attr.namespaceURI, attr.localName)] = attr + + # This creates a circular reference, but Element.unlink() + # breaks the cycle since the references to the attribute + # dictionaries are tossed. + attr.__dict__['ownerElement'] = element + + +class Childless: + """Mixin that makes childless-ness easy to implement and avoids + the complexity of the Node methods that deal with children. + """ + + attributes = None + childNodes = EmptyNodeList() + firstChild = None + lastChild = None + + def _get_firstChild(self): + return None + + def _get_lastChild(self): + return None + + def appendChild(self, node): + raise xml.dom.HierarchyRequestErr( + self.nodeName + " nodes cannot have children") + + def hasChildNodes(self): + return False + + def insertBefore(self, newChild, refChild): + raise xml.dom.HierarchyRequestErr( + self.nodeName + " nodes do not have children") + + def removeChild(self, oldChild): + raise xml.dom.NotFoundErr( + self.nodeName + " nodes do not have children") + + def replaceChild(self, newChild, oldChild): + raise xml.dom.HierarchyRequestErr( + self.nodeName + " nodes do not have children") + + +class ProcessingInstruction(Childless, Node): + nodeType = Node.PROCESSING_INSTRUCTION_NODE + + def __init__(self, target, data): + self.target = self.nodeName = target + self.data = self.nodeValue = data + + def _get_data(self): + return self.data + def _set_data(self, value): + d = self.__dict__ + d['data'] = d['nodeValue'] = value + + def _get_target(self): + return self.target + def _set_target(self, value): + d = self.__dict__ + d['target'] = d['nodeName'] = value + + def __setattr__(self, name, value): + if name == "data" or name == "nodeValue": + self.__dict__['data'] = self.__dict__['nodeValue'] = value + elif name == "target" or name == "nodeName": + self.__dict__['target'] = self.__dict__['nodeName'] = value + else: + self.__dict__[name] = value + + def writexml(self, writer, indent="", addindent="", newl=""): + writer.write("%s<?%s %s?>%s" % (indent,self.target, self.data, newl)) + + +class CharacterData(Childless, Node): + def _get_length(self): + return len(self.data) + __len__ = _get_length + + def _get_data(self): + return self.__dict__['data'] + def _set_data(self, data): + d = self.__dict__ + d['data'] = d['nodeValue'] = data + + _get_nodeValue = _get_data + _set_nodeValue = _set_data + + def __setattr__(self, name, value): + if name == "data" or name == "nodeValue": + self.__dict__['data'] = self.__dict__['nodeValue'] = value + else: + self.__dict__[name] = value + + def __repr__(self): + data = self.data + if len(data) > 10: + dotdotdot = "..." + else: + dotdotdot = "" + return "<DOM %s node \"%s%s\">" % ( + self.__class__.__name__, data[0:10], dotdotdot) + + def substringData(self, offset, count): + if offset < 0: + raise xml.dom.IndexSizeErr("offset cannot be negative") + if offset > len(self.data): + raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") + if count < 0: + raise xml.dom.IndexSizeErr("count cannot be negative") + return self.data[offset:offset+count] + + def appendData(self, arg): + self.data = self.data + arg + + def insertData(self, offset, arg): + if offset < 0: + raise xml.dom.IndexSizeErr("offset cannot be negative") + if offset > len(self.data): + raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") + if arg: + self.data = "%s%s%s" % ( + self.data[:offset], arg, self.data[offset:]) + + def deleteData(self, offset, count): + if offset < 0: + raise xml.dom.IndexSizeErr("offset cannot be negative") + if offset > len(self.data): + raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") + if count < 0: + raise xml.dom.IndexSizeErr("count cannot be negative") + if count: + self.data = self.data[:offset] + self.data[offset+count:] + + def replaceData(self, offset, count, arg): + if offset < 0: + raise xml.dom.IndexSizeErr("offset cannot be negative") + if offset > len(self.data): + raise xml.dom.IndexSizeErr("offset cannot be beyond end of data") + if count < 0: + raise xml.dom.IndexSizeErr("count cannot be negative") + if count: + self.data = "%s%s%s" % ( + self.data[:offset], arg, self.data[offset+count:]) + +defproperty(CharacterData, "length", doc="Length of the string data.") + + +class Text(CharacterData): + + # This class doesn't have an __init__() by design; the intent is + # to speed construction of new instances. Once an instance is + # created, the .data and .ownerDocument attributes will need to be + # initialized. Subclasses may add an __init__() and initialize + # those members there or require them to be initialized later. + + nodeType = Node.TEXT_NODE + nodeName = "#text" + attributes = None + + def splitText(self, offset): + if offset < 0 or offset > len(self.data): + raise xml.dom.IndexSizeErr("illegal offset value") + newText = self.__class__() + newText.data = self.data[offset:] + newText.ownerDocument = self.ownerDocument + next = self.nextSibling + if self.parentNode and self in self.parentNode.childNodes: + if next is None: + self.parentNode.appendChild(newText) + else: + self.parentNode.insertBefore(newText, next) + self.data = self.data[:offset] + return newText + + def writexml(self, writer, indent="", addindent="", newl=""): + _write_data(writer, "%s%s%s"%(indent, self.data, newl)) + + # DOM Level 3 (WD 9 April 2002) + + def _get_wholeText(self): + L = [self.data] + n = self.previousSibling + while n is not None: + if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + L.insert(0, n.data) + n = n.previousSibling + else: + break + n = self.nextSibling + while n is not None: + if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + L.append(n.data) + n = n.nextSibling + else: + break + return ''.join(L) + + def replaceWholeText(self, content): + # XXX This needs to be seriously changed if minidom ever + # supports EntityReference nodes. + parent = self.parentNode + n = self.previousSibling + while n is not None: + if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + next = n.previousSibling + parent.removeChild(n) + n = next + else: + break + n = self.nextSibling + if not content: + parent.removeChild(self) + while n is not None: + if n.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + next = n.nextSibling + parent.removeChild(n) + n = next + else: + break + if content: + d = self.__dict__ + d['data'] = content + d['nodeValue'] = content + return self + else: + return None + + def _get_isWhitespaceInElementContent(self): + if self.data.strip(): + return False + elem = _get_containing_element(self) + if elem is None: + return False + info = self.ownerDocument._get_elem_info(elem) + if info is None: + return False + else: + return info.isElementContent() + +defproperty(Text, "isWhitespaceInElementContent", + doc="True iff this text node contains only whitespace" + " and is in element content.") +defproperty(Text, "wholeText", + doc="The text of all logically-adjacent text nodes.") + + +def _get_containing_element(node): + c = node.parentNode + while c is not None: + if c.nodeType == Node.ELEMENT_NODE: + return c + c = c.parentNode + return None + +def _get_containing_entref(node): + c = node.parentNode + while c is not None: + if c.nodeType == Node.ENTITY_REFERENCE_NODE: + return c + c = c.parentNode + return None + + +class Comment(Childless, CharacterData): + nodeType = Node.COMMENT_NODE + nodeName = "#comment" + + def __init__(self, data): + self.data = self.nodeValue = data + + def writexml(self, writer, indent="", addindent="", newl=""): + writer.write("%s<!--%s-->%s" % (indent, self.data, newl)) + + +class CDATASection(Text): + nodeType = Node.CDATA_SECTION_NODE + nodeName = "#cdata-section" + + def writexml(self, writer, indent="", addindent="", newl=""): + if self.data.find("]]>") >= 0: + raise ValueError("']]>' not allowed in a CDATA section") + writer.write("<![CDATA[%s]]>" % self.data) + + +class ReadOnlySequentialNamedNodeMap(NewStyle, GetattrMagic): + __slots__ = '_seq', + + def __init__(self, seq=()): + # seq should be a list or tuple + self._seq = seq + + def __len__(self): + return len(self._seq) + + def _get_length(self): + return len(self._seq) + + def getNamedItem(self, name): + for n in self._seq: + if n.nodeName == name: + return n + + def getNamedItemNS(self, namespaceURI, localName): + for n in self._seq: + if n.namespaceURI == namespaceURI and n.localName == localName: + return n + + def __getitem__(self, name_or_tuple): + if isinstance(name_or_tuple, _TupleType): + node = self.getNamedItemNS(*name_or_tuple) + else: + node = self.getNamedItem(name_or_tuple) + if node is None: + raise KeyError, name_or_tuple + return node + + def item(self, index): + if index < 0: + return None + try: + return self._seq[index] + except IndexError: + return None + + def removeNamedItem(self, name): + raise xml.dom.NoModificationAllowedErr( + "NamedNodeMap instance is read-only") + + def removeNamedItemNS(self, namespaceURI, localName): + raise xml.dom.NoModificationAllowedErr( + "NamedNodeMap instance is read-only") + + def setNamedItem(self, node): + raise xml.dom.NoModificationAllowedErr( + "NamedNodeMap instance is read-only") + + def setNamedItemNS(self, node): + raise xml.dom.NoModificationAllowedErr( + "NamedNodeMap instance is read-only") + + def __getstate__(self): + return [self._seq] + + def __setstate__(self, state): + assert len(state) == 1 + self._seq = state[0] + +defproperty(ReadOnlySequentialNamedNodeMap, "length", + doc="Number of entries in the NamedNodeMap.") + + +class Identified: + """Mix-in class that supports the publicId and systemId attributes.""" + + def _identified_mixin_init(self, publicId, systemId): + self.publicId = publicId + self.systemId = systemId + + def _get_publicId(self): + return self.publicId + + def _get_systemId(self): + return self.systemId + +class DocumentType(Identified, Childless, Node): + nodeType = Node.DOCUMENT_TYPE_NODE + nodeValue = None + name = None + publicId = None + systemId = None + internalSubset = None + + def __init__(self, qualifiedName): + self.entities = ReadOnlySequentialNamedNodeMap() + self.notations = ReadOnlySequentialNamedNodeMap() + if qualifiedName: + prefix, localname = _nssplit(qualifiedName) + self.name = localname + self.nodeName = self.name + + def _get_internalSubset(self): + return self.internalSubset + + def cloneNode(self, deep): + if self.ownerDocument is None: + # it's ok + clone = DocumentType(None) + clone.name = self.name + clone.nodeName = self.name + operation = xml.dom.UserDataHandler.NODE_CLONED + if deep: + clone.entities._seq = [] + clone.notations._seq = [] + for n in self.notations._seq: + notation = Notation(n.nodeName, n.publicId, n.systemId) + clone.notations._seq.append(notation) + n._call_user_data_handler(operation, n, notation) + for e in self.entities._seq: + entity = Entity(e.nodeName, e.publicId, e.systemId, + e.notationName) + entity.actualEncoding = e.actualEncoding + entity.encoding = e.encoding + entity.version = e.version + clone.entities._seq.append(entity) + e._call_user_data_handler(operation, n, entity) + self._call_user_data_handler(operation, self, clone) + return clone + else: + return None + + def writexml(self, writer, indent="", addindent="", newl=""): + writer.write("<!DOCTYPE ") + writer.write(self.name) + if self.publicId: + writer.write("\n PUBLIC '%s'\n '%s'" + % (self.publicId, self.systemId)) + elif self.systemId: + writer.write("\n SYSTEM '%s'" % self.systemId) + if self.internalSubset is not None: + writer.write(" [") + writer.write(self.internalSubset) + writer.write("]") + writer.write(">\n") + +class Entity(Identified, Node): + attributes = None + nodeType = Node.ENTITY_NODE + nodeValue = None + + actualEncoding = None + encoding = None + version = None + + def __init__(self, name, publicId, systemId, notation): + self.nodeName = name + self.notationName = notation + self.childNodes = NodeList() + self._identified_mixin_init(publicId, systemId) + + def _get_actualEncoding(self): + return self.actualEncoding + + def _get_encoding(self): + return self.encoding + + def _get_version(self): + return self.version + + def appendChild(self, newChild): + raise xml.dom.HierarchyRequestErr( + "cannot append children to an entity node") + + def insertBefore(self, newChild, refChild): + raise xml.dom.HierarchyRequestErr( + "cannot insert children below an entity node") + + def removeChild(self, oldChild): + raise xml.dom.HierarchyRequestErr( + "cannot remove children from an entity node") + + def replaceChild(self, newChild, oldChild): + raise xml.dom.HierarchyRequestErr( + "cannot replace children of an entity node") + +class Notation(Identified, Childless, Node): + nodeType = Node.NOTATION_NODE + nodeValue = None + + def __init__(self, name, publicId, systemId): + self.nodeName = name + self._identified_mixin_init(publicId, systemId) + + +class DOMImplementation(DOMImplementationLS): + _features = [("core", "1.0"), + ("core", "2.0"), + ("core", "3.0"), + ("core", None), + ("xml", "1.0"), + ("xml", "2.0"), + ("xml", "3.0"), + ("xml", None), + ("ls-load", "3.0"), + ("ls-load", None), + ] + + def hasFeature(self, feature, version): + if version == "": + version = None + return (feature.lower(), version) in self._features + + def createDocument(self, namespaceURI, qualifiedName, doctype): + if doctype and doctype.parentNode is not None: + raise xml.dom.WrongDocumentErr( + "doctype object owned by another DOM tree") + doc = self._create_document() + + add_root_element = not (namespaceURI is None + and qualifiedName is None + and doctype is None) + + if not qualifiedName and add_root_element: + # The spec is unclear what to raise here; SyntaxErr + # would be the other obvious candidate. Since Xerces raises + # InvalidCharacterErr, and since SyntaxErr is not listed + # for createDocument, that seems to be the better choice. + # XXX: need to check for illegal characters here and in + # createElement. + + # DOM Level III clears this up when talking about the return value + # of this function. If namespaceURI, qName and DocType are + # Null the document is returned without a document element + # Otherwise if doctype or namespaceURI are not None + # Then we go back to the above problem + raise xml.dom.InvalidCharacterErr("Element with no name") + + if add_root_element: + prefix, localname = _nssplit(qualifiedName) + if prefix == "xml" \ + and namespaceURI != "http://www.w3.org/XML/1998/namespace": + raise xml.dom.NamespaceErr("illegal use of 'xml' prefix") + if prefix and not namespaceURI: + raise xml.dom.NamespaceErr( + "illegal use of prefix without namespaces") + element = doc.createElementNS(namespaceURI, qualifiedName) + if doctype: + doc.appendChild(doctype) + doc.appendChild(element) + + if doctype: + doctype.parentNode = doctype.ownerDocument = doc + + doc.doctype = doctype + doc.implementation = self + return doc + + def createDocumentType(self, qualifiedName, publicId, systemId): + doctype = DocumentType(qualifiedName) + doctype.publicId = publicId + doctype.systemId = systemId + return doctype + + # DOM Level 3 (WD 9 April 2002) + + def getInterface(self, feature): + if self.hasFeature(feature, None): + return self + else: + return None + + # internal + def _create_document(self): + return Document() + +class ElementInfo(NewStyle): + """Object that represents content-model information for an element. + + This implementation is not expected to be used in practice; DOM + builders should provide implementations which do the right thing + using information available to it. + + """ + + __slots__ = 'tagName', + + def __init__(self, name): + self.tagName = name + + def getAttributeType(self, aname): + return _no_type + + def getAttributeTypeNS(self, namespaceURI, localName): + return _no_type + + def isElementContent(self): + return False + + def isEmpty(self): + """Returns true iff this element is declared to have an EMPTY + content model.""" + return False + + def isId(self, aname): + """Returns true iff the named attribte is a DTD-style ID.""" + return False + + def isIdNS(self, namespaceURI, localName): + """Returns true iff the identified attribute is a DTD-style ID.""" + return False + + def __getstate__(self): + return self.tagName + + def __setstate__(self, state): + self.tagName = state + +def _clear_id_cache(node): + if node.nodeType == Node.DOCUMENT_NODE: + node._id_cache.clear() + node._id_search_stack = None + elif _in_document(node): + node.ownerDocument._id_cache.clear() + node.ownerDocument._id_search_stack= None + +class Document(Node, DocumentLS): + _child_node_types = (Node.ELEMENT_NODE, Node.PROCESSING_INSTRUCTION_NODE, + Node.COMMENT_NODE, Node.DOCUMENT_TYPE_NODE) + + nodeType = Node.DOCUMENT_NODE + nodeName = "#document" + nodeValue = None + attributes = None + doctype = None + parentNode = None + previousSibling = nextSibling = None + + implementation = DOMImplementation() + + # Document attributes from Level 3 (WD 9 April 2002) + + actualEncoding = None + encoding = None + standalone = None + version = None + strictErrorChecking = False + errorHandler = None + documentURI = None + + _magic_id_count = 0 + + def __init__(self): + self.childNodes = NodeList() + # mapping of (namespaceURI, localName) -> ElementInfo + # and tagName -> ElementInfo + self._elem_info = {} + self._id_cache = {} + self._id_search_stack = None + + def _get_elem_info(self, element): + if element.namespaceURI: + key = element.namespaceURI, element.localName + else: + key = element.tagName + return self._elem_info.get(key) + + def _get_actualEncoding(self): + return self.actualEncoding + + def _get_doctype(self): + return self.doctype + + def _get_documentURI(self): + return self.documentURI + + def _get_encoding(self): + return self.encoding + + def _get_errorHandler(self): + return self.errorHandler + + def _get_standalone(self): + return self.standalone + + def _get_strictErrorChecking(self): + return self.strictErrorChecking + + def _get_version(self): + return self.version + + def appendChild(self, node): + if node.nodeType not in self._child_node_types: + raise xml.dom.HierarchyRequestErr( + "%s cannot be child of %s" % (repr(node), repr(self))) + if node.parentNode is not None: + # This needs to be done before the next test since this + # may *be* the document element, in which case it should + # end up re-ordered to the end. + node.parentNode.removeChild(node) + + if node.nodeType == Node.ELEMENT_NODE \ + and self._get_documentElement(): + raise xml.dom.HierarchyRequestErr( + "two document elements disallowed") + return Node.appendChild(self, node) + + def removeChild(self, oldChild): + try: + self.childNodes.remove(oldChild) + except ValueError: + raise xml.dom.NotFoundErr() + oldChild.nextSibling = oldChild.previousSibling = None + oldChild.parentNode = None + if self.documentElement is oldChild: + self.documentElement = None + + return oldChild + + def _get_documentElement(self): + for node in self.childNodes: + if node.nodeType == Node.ELEMENT_NODE: + return node + + def unlink(self): + if self.doctype is not None: + self.doctype.unlink() + self.doctype = None + Node.unlink(self) + + def cloneNode(self, deep): + if not deep: + return None + clone = self.implementation.createDocument(None, None, None) + clone.encoding = self.encoding + clone.standalone = self.standalone + clone.version = self.version + for n in self.childNodes: + childclone = _clone_node(n, deep, clone) + assert childclone.ownerDocument.isSameNode(clone) + clone.childNodes.append(childclone) + if childclone.nodeType == Node.DOCUMENT_NODE: + assert clone.documentElement is None + elif childclone.nodeType == Node.DOCUMENT_TYPE_NODE: + assert clone.doctype is None + clone.doctype = childclone + childclone.parentNode = clone + self._call_user_data_handler(xml.dom.UserDataHandler.NODE_CLONED, + self, clone) + return clone + + def createDocumentFragment(self): + d = DocumentFragment() + d.ownerDocument = self + return d + + def createElement(self, tagName): + e = Element(tagName) + e.ownerDocument = self + return e + + def createTextNode(self, data): + if not isinstance(data, StringTypes): + raise TypeError, "node contents must be a string" + t = Text() + t.data = data + t.ownerDocument = self + return t + + def createCDATASection(self, data): + if not isinstance(data, StringTypes): + raise TypeError, "node contents must be a string" + c = CDATASection() + c.data = data + c.ownerDocument = self + return c + + def createComment(self, data): + c = Comment(data) + c.ownerDocument = self + return c + + def createProcessingInstruction(self, target, data): + p = ProcessingInstruction(target, data) + p.ownerDocument = self + return p + + def createAttribute(self, qName): + a = Attr(qName) + a.ownerDocument = self + a.value = "" + return a + + def createElementNS(self, namespaceURI, qualifiedName): + prefix, localName = _nssplit(qualifiedName) + e = Element(qualifiedName, namespaceURI, prefix) + e.ownerDocument = self + return e + + def createAttributeNS(self, namespaceURI, qualifiedName): + prefix, localName = _nssplit(qualifiedName) + a = Attr(qualifiedName, namespaceURI, localName, prefix) + a.ownerDocument = self + a.value = "" + return a + + # A couple of implementation-specific helpers to create node types + # not supported by the W3C DOM specs: + + def _create_entity(self, name, publicId, systemId, notationName): + e = Entity(name, publicId, systemId, notationName) + e.ownerDocument = self + return e + + def _create_notation(self, name, publicId, systemId): + n = Notation(name, publicId, systemId) + n.ownerDocument = self + return n + + def getElementById(self, id): + if self._id_cache.has_key(id): + return self._id_cache[id] + if not (self._elem_info or self._magic_id_count): + return None + + stack = self._id_search_stack + if stack is None: + # we never searched before, or the cache has been cleared + stack = [self.documentElement] + self._id_search_stack = stack + elif not stack: + # Previous search was completed and cache is still valid; + # no matching node. + return None + + result = None + while stack: + node = stack.pop() + # add child elements to stack for continued searching + stack.extend([child for child in node.childNodes + if child.nodeType in _nodeTypes_with_children]) + # check this node + info = self._get_elem_info(node) + if info: + # We have to process all ID attributes before + # returning in order to get all the attributes set to + # be IDs using Element.setIdAttribute*(). + for attr in node.attributes.values(): + if attr.namespaceURI: + if info.isIdNS(attr.namespaceURI, attr.localName): + self._id_cache[attr.value] = node + if attr.value == id: + result = node + elif not node._magic_id_nodes: + break + elif info.isId(attr.name): + self._id_cache[attr.value] = node + if attr.value == id: + result = node + elif not node._magic_id_nodes: + break + elif attr._is_id: + self._id_cache[attr.value] = node + if attr.value == id: + result = node + elif node._magic_id_nodes == 1: + break + elif node._magic_id_nodes: + for attr in node.attributes.values(): + if attr._is_id: + self._id_cache[attr.value] = node + if attr.value == id: + result = node + if result is not None: + break + return result + + def getElementsByTagName(self, name): + return _get_elements_by_tagName_helper(self, name, NodeList()) + + def getElementsByTagNameNS(self, namespaceURI, localName): + return _get_elements_by_tagName_ns_helper( + self, namespaceURI, localName, NodeList()) + + def isSupported(self, feature, version): + return self.implementation.hasFeature(feature, version) + + def importNode(self, node, deep): + if node.nodeType == Node.DOCUMENT_NODE: + raise xml.dom.NotSupportedErr("cannot import document nodes") + elif node.nodeType == Node.DOCUMENT_TYPE_NODE: + raise xml.dom.NotSupportedErr("cannot import document type nodes") + return _clone_node(node, deep, self) + + def writexml(self, writer, indent="", addindent="", newl="", + encoding = None): + if encoding is None: + writer.write('<?xml version="1.0" ?>\n') + else: + writer.write('<?xml version="1.0" encoding="%s"?>\n' % encoding) + for node in self.childNodes: + node.writexml(writer, indent, addindent, newl) + + # DOM Level 3 (WD 9 April 2002) + + def renameNode(self, n, namespaceURI, name): + if n.ownerDocument is not self: + raise xml.dom.WrongDocumentErr( + "cannot rename nodes from other documents;\n" + "expected %s,\nfound %s" % (self, n.ownerDocument)) + if n.nodeType not in (Node.ELEMENT_NODE, Node.ATTRIBUTE_NODE): + raise xml.dom.NotSupportedErr( + "renameNode() only applies to element and attribute nodes") + if namespaceURI != EMPTY_NAMESPACE: + if ':' in name: + prefix, localName = name.split(':', 1) + if ( prefix == "xmlns" + and namespaceURI != xml.dom.XMLNS_NAMESPACE): + raise xml.dom.NamespaceErr( + "illegal use of 'xmlns' prefix") + else: + if ( name == "xmlns" + and namespaceURI != xml.dom.XMLNS_NAMESPACE + and n.nodeType == Node.ATTRIBUTE_NODE): + raise xml.dom.NamespaceErr( + "illegal use of the 'xmlns' attribute") + prefix = None + localName = name + else: + prefix = None + localName = None + if n.nodeType == Node.ATTRIBUTE_NODE: + element = n.ownerElement + if element is not None: + is_id = n._is_id + element.removeAttributeNode(n) + else: + element = None + # avoid __setattr__ + d = n.__dict__ + d['prefix'] = prefix + d['localName'] = localName + d['namespaceURI'] = namespaceURI + d['nodeName'] = name + if n.nodeType == Node.ELEMENT_NODE: + d['tagName'] = name + else: + # attribute node + d['name'] = name + if element is not None: + element.setAttributeNode(n) + if is_id: + element.setIdAttributeNode(n) + # It's not clear from a semantic perspective whether we should + # call the user data handlers for the NODE_RENAMED event since + # we're re-using the existing node. The draft spec has been + # interpreted as meaning "no, don't call the handler unless a + # new node is created." + return n + +defproperty(Document, "documentElement", + doc="Top-level element of this document.") + + +def _clone_node(node, deep, newOwnerDocument): + """ + Clone a node and give it the new owner document. + Called by Node.cloneNode and Document.importNode + """ + if node.ownerDocument.isSameNode(newOwnerDocument): + operation = xml.dom.UserDataHandler.NODE_CLONED + else: + operation = xml.dom.UserDataHandler.NODE_IMPORTED + if node.nodeType == Node.ELEMENT_NODE: + clone = newOwnerDocument.createElementNS(node.namespaceURI, + node.nodeName) + for attr in node.attributes.values(): + clone.setAttributeNS(attr.namespaceURI, attr.nodeName, attr.value) + a = clone.getAttributeNodeNS(attr.namespaceURI, attr.localName) + a.specified = attr.specified + + if deep: + for child in node.childNodes: + c = _clone_node(child, deep, newOwnerDocument) + clone.appendChild(c) + + elif node.nodeType == Node.DOCUMENT_FRAGMENT_NODE: + clone = newOwnerDocument.createDocumentFragment() + if deep: + for child in node.childNodes: + c = _clone_node(child, deep, newOwnerDocument) + clone.appendChild(c) + + elif node.nodeType == Node.TEXT_NODE: + clone = newOwnerDocument.createTextNode(node.data) + elif node.nodeType == Node.CDATA_SECTION_NODE: + clone = newOwnerDocument.createCDATASection(node.data) + elif node.nodeType == Node.PROCESSING_INSTRUCTION_NODE: + clone = newOwnerDocument.createProcessingInstruction(node.target, + node.data) + elif node.nodeType == Node.COMMENT_NODE: + clone = newOwnerDocument.createComment(node.data) + elif node.nodeType == Node.ATTRIBUTE_NODE: + clone = newOwnerDocument.createAttributeNS(node.namespaceURI, + node.nodeName) + clone.specified = True + clone.value = node.value + elif node.nodeType == Node.DOCUMENT_TYPE_NODE: + assert node.ownerDocument is not newOwnerDocument + operation = xml.dom.UserDataHandler.NODE_IMPORTED + clone = newOwnerDocument.implementation.createDocumentType( + node.name, node.publicId, node.systemId) + clone.ownerDocument = newOwnerDocument + if deep: + clone.entities._seq = [] + clone.notations._seq = [] + for n in node.notations._seq: + notation = Notation(n.nodeName, n.publicId, n.systemId) + notation.ownerDocument = newOwnerDocument + clone.notations._seq.append(notation) + if hasattr(n, '_call_user_data_handler'): + n._call_user_data_handler(operation, n, notation) + for e in node.entities._seq: + entity = Entity(e.nodeName, e.publicId, e.systemId, + e.notationName) + entity.actualEncoding = e.actualEncoding + entity.encoding = e.encoding + entity.version = e.version + entity.ownerDocument = newOwnerDocument + clone.entities._seq.append(entity) + if hasattr(e, '_call_user_data_handler'): + e._call_user_data_handler(operation, n, entity) + else: + # Note the cloning of Document and DocumentType nodes is + # implemenetation specific. minidom handles those cases + # directly in the cloneNode() methods. + raise xml.dom.NotSupportedErr("Cannot clone node %s" % repr(node)) + + # Check for _call_user_data_handler() since this could conceivably + # used with other DOM implementations (one of the FourThought + # DOMs, perhaps?). + if hasattr(node, '_call_user_data_handler'): + node._call_user_data_handler(operation, node, clone) + return clone + + +def _nssplit(qualifiedName): + fields = qualifiedName.split(':', 1) + if len(fields) == 2: + return fields + else: + return (None, fields[0]) + + +def _get_StringIO(): + # we can't use cStringIO since it doesn't support Unicode strings + from StringIO import StringIO + return StringIO() + +def _do_pulldom_parse(func, args, kwargs): + events = apply(func, args, kwargs) + toktype, rootNode = events.getEvent() + events.expandNode(rootNode) + events.clear() + rootNode.normalize() + return rootNode + +def parse(file, parser=None, bufsize=None): + """Parse a file into a DOM by filename or file object.""" + import sys + if parser is None and bufsize is None and sys.platform[:4] != "java": + try: + from xml.dom import expatbuilder + return expatbuilder.parse(file) + except ImportError: + pass + from xml.dom import pulldom + return _do_pulldom_parse(pulldom.parse, (file,), + {'parser': parser, 'bufsize': bufsize}) + +def parseString(string, parser=None): + """Parse a file into a DOM from a string.""" + import sys + if parser is None and sys.platform[:4] != "java": + from xml.dom import expatbuilder + return expatbuilder.parseString(string) + from xml.dom import pulldom + return _do_pulldom_parse(pulldom.parseString, (string,), + {'parser': parser}) + +def getDOMImplementation(features=None): + if features: + if isinstance(features, StringTypes): + features = domreg._parse_feature_string(features) + for f, v in features: + if not Document.implementation.hasFeature(f, v): + return None + return Document.implementation diff --git a/src/main/resources/PythonLibs/xml/dom/pulldom.py b/src/main/resources/PythonLibs/xml/dom/pulldom.py new file mode 100644 index 0000000000000000000000000000000000000000..7c99fb233e73ed63595b7eb6239ba45da1bd5c0f --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/pulldom.py @@ -0,0 +1,352 @@ +import xml.sax +import xml.sax.handler +import types + +try: + _StringTypes = [types.StringType, types.UnicodeType] +except AttributeError: + _StringTypes = [types.StringType] + +START_ELEMENT = "START_ELEMENT" +END_ELEMENT = "END_ELEMENT" +COMMENT = "COMMENT" +START_DOCUMENT = "START_DOCUMENT" +END_DOCUMENT = "END_DOCUMENT" +PROCESSING_INSTRUCTION = "PROCESSING_INSTRUCTION" +IGNORABLE_WHITESPACE = "IGNORABLE_WHITESPACE" +CHARACTERS = "CHARACTERS" + +class PullDOM(xml.sax.ContentHandler): + _locator = None + document = None + + def __init__(self, documentFactory=None): + from xml.dom import XML_NAMESPACE + self.documentFactory = documentFactory + self.firstEvent = [None, None] + self.lastEvent = self.firstEvent + self.elementStack = [] + self.push = self.elementStack.append + try: + self.pop = self.elementStack.pop + except AttributeError: + # use class' pop instead + pass + self._ns_contexts = [{XML_NAMESPACE:'xml'}] # contains uri -> prefix dicts + self._current_context = self._ns_contexts[-1] + self.pending_events = [] + + def pop(self): + result = self.elementStack[-1] + del self.elementStack[-1] + return result + + def setDocumentLocator(self, locator): + self._locator = locator + + def startPrefixMapping(self, prefix, uri): + if not hasattr(self, '_xmlns_attrs'): + self._xmlns_attrs = [] + self._xmlns_attrs.append((prefix or 'xmlns', uri)) + self._ns_contexts.append(self._current_context.copy()) + self._current_context[uri] = prefix or None + + def endPrefixMapping(self, prefix): + self._current_context = self._ns_contexts.pop() + + def startElementNS(self, name, tagName , attrs): + uri, localname = name + if uri: + # When using namespaces, the reader may or may not + # provide us with the original name. If not, create + # *a* valid tagName from the current context. + if tagName is None: + prefix = self._current_context[uri] + if prefix: + tagName = prefix + ":" + localname + else: + tagName = localname + if self.document: + node = self.document.createElementNS(uri, tagName) + else: + node = self.buildDocument(uri, tagName) + else: + # When the tagname is not prefixed, it just appears as + # localname + if self.document: + node = self.document.createElement(localname) + else: + node = self.buildDocument(None, localname) + + # Retrieve xml namespace declaration attributes. + xmlns_uri = 'http://www.w3.org/2000/xmlns/' + xmlns_attrs = getattr(self, '_xmlns_attrs', None) + if xmlns_attrs is not None: + for aname, value in xmlns_attrs: + if aname == 'xmlns': + qname = aname + else: + qname = 'xmlns:' + aname + attr = self.document.createAttributeNS(xmlns_uri, qname) + attr.value = value + node.setAttributeNodeNS(attr) + self._xmlns_attrs = [] + for aname,value in attrs.items(): + a_uri, a_localname = aname + if a_uri: + prefix = self._current_context[a_uri] + if prefix: + qname = prefix + ":" + a_localname + else: + qname = a_localname + attr = self.document.createAttributeNS(a_uri, qname) + node.setAttributeNodeNS(attr) + else: + attr = self.document.createAttribute(a_localname) + node.setAttributeNode(attr) + attr.value = value + + self.lastEvent[1] = [(START_ELEMENT, node), None] + self.lastEvent = self.lastEvent[1] + self.push(node) + + def endElementNS(self, name, tagName): + self.lastEvent[1] = [(END_ELEMENT, self.pop()), None] + self.lastEvent = self.lastEvent[1] + + def startElement(self, name, attrs): + if self.document: + node = self.document.createElement(name) + else: + node = self.buildDocument(None, name) + + for aname,value in attrs.items(): + attr = self.document.createAttribute(aname) + attr.value = value + node.setAttributeNode(attr) + + self.lastEvent[1] = [(START_ELEMENT, node), None] + self.lastEvent = self.lastEvent[1] + self.push(node) + + def endElement(self, name): + self.lastEvent[1] = [(END_ELEMENT, self.pop()), None] + self.lastEvent = self.lastEvent[1] + + def comment(self, s): + if self.document: + node = self.document.createComment(s) + self.lastEvent[1] = [(COMMENT, node), None] + self.lastEvent = self.lastEvent[1] + else: + event = [(COMMENT, s), None] + self.pending_events.append(event) + + def processingInstruction(self, target, data): + if self.document: + node = self.document.createProcessingInstruction(target, data) + self.lastEvent[1] = [(PROCESSING_INSTRUCTION, node), None] + self.lastEvent = self.lastEvent[1] + else: + event = [(PROCESSING_INSTRUCTION, target, data), None] + self.pending_events.append(event) + + def ignorableWhitespace(self, chars): + node = self.document.createTextNode(chars) + self.lastEvent[1] = [(IGNORABLE_WHITESPACE, node), None] + self.lastEvent = self.lastEvent[1] + + def characters(self, chars): + node = self.document.createTextNode(chars) + self.lastEvent[1] = [(CHARACTERS, node), None] + self.lastEvent = self.lastEvent[1] + + def startDocument(self): + if self.documentFactory is None: + import xml.dom.minidom + self.documentFactory = xml.dom.minidom.Document.implementation + + def buildDocument(self, uri, tagname): + # Can't do that in startDocument, since we need the tagname + # XXX: obtain DocumentType + node = self.documentFactory.createDocument(uri, tagname, None) + self.document = node + self.lastEvent[1] = [(START_DOCUMENT, node), None] + self.lastEvent = self.lastEvent[1] + self.push(node) + # Put everything we have seen so far into the document + for e in self.pending_events: + if e[0][0] == PROCESSING_INSTRUCTION: + _,target,data = e[0] + n = self.document.createProcessingInstruction(target, data) + e[0] = (PROCESSING_INSTRUCTION, n) + elif e[0][0] == COMMENT: + n = self.document.createComment(e[0][1]) + e[0] = (COMMENT, n) + else: + raise AssertionError("Unknown pending event ",e[0][0]) + self.lastEvent[1] = e + self.lastEvent = e + self.pending_events = None + return node.firstChild + + def endDocument(self): + self.lastEvent[1] = [(END_DOCUMENT, self.document), None] + self.pop() + + def clear(self): + "clear(): Explicitly release parsing structures" + self.document = None + +class ErrorHandler: + def warning(self, exception): + print exception + def error(self, exception): + raise exception + def fatalError(self, exception): + raise exception + +class DOMEventStream: + def __init__(self, stream, parser, bufsize): + self.stream = stream + self.parser = parser + self.bufsize = bufsize + if not hasattr(self.parser, 'feed'): + self.getEvent = self._slurp + self.reset() + + def reset(self): + self.pulldom = PullDOM() + # This content handler relies on namespace support + self.parser.setFeature(xml.sax.handler.feature_namespaces, 1) + self.parser.setContentHandler(self.pulldom) + + def __getitem__(self, pos): + rc = self.getEvent() + if rc: + return rc + raise IndexError + + def next(self): + rc = self.getEvent() + if rc: + return rc + raise StopIteration + + def __iter__(self): + return self + + def expandNode(self, node): + event = self.getEvent() + parents = [node] + while event: + token, cur_node = event + if cur_node is node: + return + if token != END_ELEMENT: + parents[-1].appendChild(cur_node) + if token == START_ELEMENT: + parents.append(cur_node) + elif token == END_ELEMENT: + del parents[-1] + event = self.getEvent() + + def getEvent(self): + # use IncrementalParser interface, so we get the desired + # pull effect + if not self.pulldom.firstEvent[1]: + self.pulldom.lastEvent = self.pulldom.firstEvent + while not self.pulldom.firstEvent[1]: + buf = self.stream.read(self.bufsize) + if not buf: + self.parser.close() + return None + self.parser.feed(buf) + rc = self.pulldom.firstEvent[1][0] + self.pulldom.firstEvent[1] = self.pulldom.firstEvent[1][1] + return rc + + def _slurp(self): + """ Fallback replacement for getEvent() using the + standard SAX2 interface, which means we slurp the + SAX events into memory (no performance gain, but + we are compatible to all SAX parsers). + """ + self.parser.parse(self.stream) + self.getEvent = self._emit + return self._emit() + + def _emit(self): + """ Fallback replacement for getEvent() that emits + the events that _slurp() read previously. + """ + if self.pulldom.firstEvent[1] is None: + return None + rc = self.pulldom.firstEvent[1][0] + self.pulldom.firstEvent[1] = self.pulldom.firstEvent[1][1] + return rc + + def clear(self): + """clear(): Explicitly release parsing objects""" + self.pulldom.clear() + del self.pulldom + self.parser = None + self.stream = None + +class SAX2DOM(PullDOM): + + def startElementNS(self, name, tagName , attrs): + PullDOM.startElementNS(self, name, tagName, attrs) + curNode = self.elementStack[-1] + parentNode = self.elementStack[-2] + parentNode.appendChild(curNode) + + def startElement(self, name, attrs): + PullDOM.startElement(self, name, attrs) + curNode = self.elementStack[-1] + parentNode = self.elementStack[-2] + parentNode.appendChild(curNode) + + def processingInstruction(self, target, data): + PullDOM.processingInstruction(self, target, data) + node = self.lastEvent[0][1] + parentNode = self.elementStack[-1] + parentNode.appendChild(node) + + def ignorableWhitespace(self, chars): + PullDOM.ignorableWhitespace(self, chars) + node = self.lastEvent[0][1] + parentNode = self.elementStack[-1] + parentNode.appendChild(node) + + def characters(self, chars): + PullDOM.characters(self, chars) + node = self.lastEvent[0][1] + parentNode = self.elementStack[-1] + parentNode.appendChild(node) + + +default_bufsize = (2 ** 14) - 20 + +def parse(stream_or_string, parser=None, bufsize=None): + if bufsize is None: + bufsize = default_bufsize + if type(stream_or_string) in _StringTypes: + stream = open(stream_or_string) + else: + stream = stream_or_string + if not parser: + parser = xml.sax.make_parser() + return DOMEventStream(stream, parser, bufsize) + +def parseString(string, parser=None): + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + + bufsize = len(string) + buf = StringIO(string) + if not parser: + parser = xml.sax.make_parser() + return DOMEventStream(buf, parser, bufsize) diff --git a/src/main/resources/PythonLibs/xml/dom/xmlbuilder.py b/src/main/resources/PythonLibs/xml/dom/xmlbuilder.py new file mode 100644 index 0000000000000000000000000000000000000000..fd43c37ed3f87bf2ed49cbc13bde7a602c3034df --- /dev/null +++ b/src/main/resources/PythonLibs/xml/dom/xmlbuilder.py @@ -0,0 +1,388 @@ +"""Implementation of the DOM Level 3 'LS-Load' feature.""" + +import copy +import xml.dom + +from xml.dom.minicompat import * + +from xml.dom.NodeFilter import NodeFilter + + +__all__ = ["DOMBuilder", "DOMEntityResolver", "DOMInputSource"] + + +class Options: + """Features object that has variables set for each DOMBuilder feature. + + The DOMBuilder class uses an instance of this class to pass settings to + the ExpatBuilder class. + """ + + # Note that the DOMBuilder class in LoadSave constrains which of these + # values can be set using the DOM Level 3 LoadSave feature. + + namespaces = 1 + namespace_declarations = True + validation = False + external_parameter_entities = True + external_general_entities = True + external_dtd_subset = True + validate_if_schema = False + validate = False + datatype_normalization = False + create_entity_ref_nodes = True + entities = True + whitespace_in_element_content = True + cdata_sections = True + comments = True + charset_overrides_xml_encoding = True + infoset = False + supported_mediatypes_only = False + + errorHandler = None + filter = None + + +class DOMBuilder: + entityResolver = None + errorHandler = None + filter = None + + ACTION_REPLACE = 1 + ACTION_APPEND_AS_CHILDREN = 2 + ACTION_INSERT_AFTER = 3 + ACTION_INSERT_BEFORE = 4 + + _legal_actions = (ACTION_REPLACE, ACTION_APPEND_AS_CHILDREN, + ACTION_INSERT_AFTER, ACTION_INSERT_BEFORE) + + def __init__(self): + self._options = Options() + + def _get_entityResolver(self): + return self.entityResolver + def _set_entityResolver(self, entityResolver): + self.entityResolver = entityResolver + + def _get_errorHandler(self): + return self.errorHandler + def _set_errorHandler(self, errorHandler): + self.errorHandler = errorHandler + + def _get_filter(self): + return self.filter + def _set_filter(self, filter): + self.filter = filter + + def setFeature(self, name, state): + if self.supportsFeature(name): + state = state and 1 or 0 + try: + settings = self._settings[(_name_xform(name), state)] + except KeyError: + raise xml.dom.NotSupportedErr( + "unsupported feature: " + `name`) + else: + for name, value in settings: + setattr(self._options, name, value) + else: + raise xml.dom.NotFoundErr("unknown feature: " + repr(name)) + + def supportsFeature(self, name): + return hasattr(self._options, _name_xform(name)) + + def canSetFeature(self, name, state): + key = (_name_xform(name), state and 1 or 0) + return self._settings.has_key(key) + + # This dictionary maps from (feature,value) to a list of + # (option,value) pairs that should be set on the Options object. + # If a (feature,value) setting is not in this dictionary, it is + # not supported by the DOMBuilder. + # + _settings = { + ("namespace_declarations", 0): [ + ("namespace_declarations", 0)], + ("namespace_declarations", 1): [ + ("namespace_declarations", 1)], + ("validation", 0): [ + ("validation", 0)], + ("external_general_entities", 0): [ + ("external_general_entities", 0)], + ("external_general_entities", 1): [ + ("external_general_entities", 1)], + ("external_parameter_entities", 0): [ + ("external_parameter_entities", 0)], + ("external_parameter_entities", 1): [ + ("external_parameter_entities", 1)], + ("validate_if_schema", 0): [ + ("validate_if_schema", 0)], + ("create_entity_ref_nodes", 0): [ + ("create_entity_ref_nodes", 0)], + ("create_entity_ref_nodes", 1): [ + ("create_entity_ref_nodes", 1)], + ("entities", 0): [ + ("create_entity_ref_nodes", 0), + ("entities", 0)], + ("entities", 1): [ + ("entities", 1)], + ("whitespace_in_element_content", 0): [ + ("whitespace_in_element_content", 0)], + ("whitespace_in_element_content", 1): [ + ("whitespace_in_element_content", 1)], + ("cdata_sections", 0): [ + ("cdata_sections", 0)], + ("cdata_sections", 1): [ + ("cdata_sections", 1)], + ("comments", 0): [ + ("comments", 0)], + ("comments", 1): [ + ("comments", 1)], + ("charset_overrides_xml_encoding", 0): [ + ("charset_overrides_xml_encoding", 0)], + ("charset_overrides_xml_encoding", 1): [ + ("charset_overrides_xml_encoding", 1)], + ("infoset", 0): [], + ("infoset", 1): [ + ("namespace_declarations", 0), + ("validate_if_schema", 0), + ("create_entity_ref_nodes", 0), + ("entities", 0), + ("cdata_sections", 0), + ("datatype_normalization", 1), + ("whitespace_in_element_content", 1), + ("comments", 1), + ("charset_overrides_xml_encoding", 1)], + ("supported_mediatypes_only", 0): [ + ("supported_mediatypes_only", 0)], + ("namespaces", 0): [ + ("namespaces", 0)], + ("namespaces", 1): [ + ("namespaces", 1)], + } + + def getFeature(self, name): + xname = _name_xform(name) + try: + return getattr(self._options, xname) + except AttributeError: + if name == "infoset": + options = self._options + return (options.datatype_normalization + and options.whitespace_in_element_content + and options.comments + and options.charset_overrides_xml_encoding + and not (options.namespace_declarations + or options.validate_if_schema + or options.create_entity_ref_nodes + or options.entities + or options.cdata_sections)) + raise xml.dom.NotFoundErr("feature %s not known" % repr(name)) + + def parseURI(self, uri): + if self.entityResolver: + input = self.entityResolver.resolveEntity(None, uri) + else: + input = DOMEntityResolver().resolveEntity(None, uri) + return self.parse(input) + + def parse(self, input): + options = copy.copy(self._options) + options.filter = self.filter + options.errorHandler = self.errorHandler + fp = input.byteStream + if fp is None and options.systemId: + import urllib2 + fp = urllib2.urlopen(input.systemId) + return self._parse_bytestream(fp, options) + + def parseWithContext(self, input, cnode, action): + if action not in self._legal_actions: + raise ValueError("not a legal action") + raise NotImplementedError("Haven't written this yet...") + + def _parse_bytestream(self, stream, options): + import xml.dom.expatbuilder + builder = xml.dom.expatbuilder.makeBuilder(options) + return builder.parseFile(stream) + + +def _name_xform(name): + return name.lower().replace('-', '_') + + +class DOMEntityResolver(NewStyle): + __slots__ = '_opener', + + def resolveEntity(self, publicId, systemId): + assert systemId is not None + source = DOMInputSource() + source.publicId = publicId + source.systemId = systemId + source.byteStream = self._get_opener().open(systemId) + + # determine the encoding if the transport provided it + source.encoding = self._guess_media_encoding(source) + + # determine the base URI is we can + import posixpath, urlparse + parts = urlparse.urlparse(systemId) + scheme, netloc, path, params, query, fragment = parts + # XXX should we check the scheme here as well? + if path and not path.endswith("/"): + path = posixpath.dirname(path) + "/" + parts = scheme, netloc, path, params, query, fragment + source.baseURI = urlparse.urlunparse(parts) + + return source + + def _get_opener(self): + try: + return self._opener + except AttributeError: + self._opener = self._create_opener() + return self._opener + + def _create_opener(self): + import urllib2 + return urllib2.build_opener() + + def _guess_media_encoding(self, source): + info = source.byteStream.info() + if info.has_key("Content-Type"): + for param in info.getplist(): + if param.startswith("charset="): + return param.split("=", 1)[1].lower() + + +class DOMInputSource(NewStyle): + __slots__ = ('byteStream', 'characterStream', 'stringData', + 'encoding', 'publicId', 'systemId', 'baseURI') + + def __init__(self): + self.byteStream = None + self.characterStream = None + self.stringData = None + self.encoding = None + self.publicId = None + self.systemId = None + self.baseURI = None + + def _get_byteStream(self): + return self.byteStream + def _set_byteStream(self, byteStream): + self.byteStream = byteStream + + def _get_characterStream(self): + return self.characterStream + def _set_characterStream(self, characterStream): + self.characterStream = characterStream + + def _get_stringData(self): + return self.stringData + def _set_stringData(self, data): + self.stringData = data + + def _get_encoding(self): + return self.encoding + def _set_encoding(self, encoding): + self.encoding = encoding + + def _get_publicId(self): + return self.publicId + def _set_publicId(self, publicId): + self.publicId = publicId + + def _get_systemId(self): + return self.systemId + def _set_systemId(self, systemId): + self.systemId = systemId + + def _get_baseURI(self): + return self.baseURI + def _set_baseURI(self, uri): + self.baseURI = uri + + +class DOMBuilderFilter: + """Element filter which can be used to tailor construction of + a DOM instance. + """ + + # There's really no need for this class; concrete implementations + # should just implement the endElement() and startElement() + # methods as appropriate. Using this makes it easy to only + # implement one of them. + + FILTER_ACCEPT = 1 + FILTER_REJECT = 2 + FILTER_SKIP = 3 + FILTER_INTERRUPT = 4 + + whatToShow = NodeFilter.SHOW_ALL + + def _get_whatToShow(self): + return self.whatToShow + + def acceptNode(self, element): + return self.FILTER_ACCEPT + + def startContainer(self, element): + return self.FILTER_ACCEPT + +del NodeFilter + + +class DocumentLS: + """Mixin to create documents that conform to the load/save spec.""" + + async = False + + def _get_async(self): + return False + def _set_async(self, async): + if async: + raise xml.dom.NotSupportedErr( + "asynchronous document loading is not supported") + + def abort(self): + # What does it mean to "clear" a document? Does the + # documentElement disappear? + raise NotImplementedError( + "haven't figured out what this means yet") + + def load(self, uri): + raise NotImplementedError("haven't written this yet") + + def loadXML(self, source): + raise NotImplementedError("haven't written this yet") + + def saveXML(self, snode): + if snode is None: + snode = self + elif snode.ownerDocument is not self: + raise xml.dom.WrongDocumentErr() + return snode.toxml() + + +class DOMImplementationLS: + MODE_SYNCHRONOUS = 1 + MODE_ASYNCHRONOUS = 2 + + def createDOMBuilder(self, mode, schemaType): + if schemaType is not None: + raise xml.dom.NotSupportedErr( + "schemaType not yet supported") + if mode == self.MODE_SYNCHRONOUS: + return DOMBuilder() + if mode == self.MODE_ASYNCHRONOUS: + raise xml.dom.NotSupportedErr( + "asynchronous builders are not supported") + raise ValueError("unknown value for mode") + + def createDOMWriter(self): + raise NotImplementedError( + "the writer interface hasn't been written yet!") + + def createDOMInputSource(self): + return DOMInputSource() diff --git a/src/main/resources/PythonLibs/xml/etree/ElementInclude.py b/src/main/resources/PythonLibs/xml/etree/ElementInclude.py new file mode 100644 index 0000000000000000000000000000000000000000..84fd7548b28a0c5f51193caf28bdf045cc1ea3a7 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/etree/ElementInclude.py @@ -0,0 +1,143 @@ +# +# ElementTree +# $Id: ElementInclude.py 3375 2008-02-13 08:05:08Z fredrik $ +# +# limited xinclude support for element trees +# +# history: +# 2003-08-15 fl created +# 2003-11-14 fl fixed default loader +# +# Copyright (c) 2003-2004 by Fredrik Lundh. All rights reserved. +# +# fredrik@pythonware.com +# http://www.pythonware.com +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2008 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# 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. +# -------------------------------------------------------------------- + +# Licensed to PSF under a Contributor Agreement. +# See http://www.python.org/psf/license for licensing details. + +## +# Limited XInclude support for the ElementTree package. +## + +import copy +from . import ElementTree + +XINCLUDE = "{http://www.w3.org/2001/XInclude}" + +XINCLUDE_INCLUDE = XINCLUDE + "include" +XINCLUDE_FALLBACK = XINCLUDE + "fallback" + +## +# Fatal include error. + +class FatalIncludeError(SyntaxError): + pass + +## +# Default loader. This loader reads an included resource from disk. +# +# @param href Resource reference. +# @param parse Parse mode. Either "xml" or "text". +# @param encoding Optional text encoding. +# @return The expanded resource. If the parse mode is "xml", this +# is an ElementTree instance. If the parse mode is "text", this +# is a Unicode string. If the loader fails, it can return None +# or raise an IOError exception. +# @throws IOError If the loader fails to load the resource. + +def default_loader(href, parse, encoding=None): + file = open(href) + if parse == "xml": + data = ElementTree.parse(file).getroot() + else: + data = file.read() + if encoding: + data = data.decode(encoding) + file.close() + return data + +## +# Expand XInclude directives. +# +# @param elem Root element. +# @param loader Optional resource loader. If omitted, it defaults +# to {@link default_loader}. If given, it should be a callable +# that implements the same interface as <b>default_loader</b>. +# @throws FatalIncludeError If the function fails to include a given +# resource, or if the tree contains malformed XInclude elements. +# @throws IOError If the function fails to load a given resource. + +def include(elem, loader=None): + if loader is None: + loader = default_loader + # look for xinclude elements + i = 0 + while i < len(elem): + e = elem[i] + if e.tag == XINCLUDE_INCLUDE: + # process xinclude directive + href = e.get("href") + parse = e.get("parse", "xml") + if parse == "xml": + node = loader(href, parse) + if node is None: + raise FatalIncludeError( + "cannot load %r as %r" % (href, parse) + ) + node = copy.copy(node) + if e.tail: + node.tail = (node.tail or "") + e.tail + elem[i] = node + elif parse == "text": + text = loader(href, parse, e.get("encoding")) + if text is None: + raise FatalIncludeError( + "cannot load %r as %r" % (href, parse) + ) + if i: + node = elem[i-1] + node.tail = (node.tail or "") + text + (e.tail or "") + else: + elem.text = (elem.text or "") + text + (e.tail or "") + del elem[i] + continue + else: + raise FatalIncludeError( + "unknown parse type in xi:include tag (%r)" % parse + ) + elif e.tag == XINCLUDE_FALLBACK: + raise FatalIncludeError( + "xi:fallback tag must be child of xi:include (%r)" % e.tag + ) + else: + include(e, loader) + i = i + 1 diff --git a/src/main/resources/PythonLibs/xml/etree/ElementPath.py b/src/main/resources/PythonLibs/xml/etree/ElementPath.py new file mode 100644 index 0000000000000000000000000000000000000000..4a626d799c827d818bfdb7cdede151039f984277 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/etree/ElementPath.py @@ -0,0 +1,303 @@ +# +# ElementTree +# $Id: ElementPath.py 3375 2008-02-13 08:05:08Z fredrik $ +# +# limited xpath support for element trees +# +# history: +# 2003-05-23 fl created +# 2003-05-28 fl added support for // etc +# 2003-08-27 fl fixed parsing of periods in element names +# 2007-09-10 fl new selection engine +# 2007-09-12 fl fixed parent selector +# 2007-09-13 fl added iterfind; changed findall to return a list +# 2007-11-30 fl added namespaces support +# 2009-10-30 fl added child element value filter +# +# Copyright (c) 2003-2009 by Fredrik Lundh. All rights reserved. +# +# fredrik@pythonware.com +# http://www.pythonware.com +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2009 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# 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. +# -------------------------------------------------------------------- + +# Licensed to PSF under a Contributor Agreement. +# See http://www.python.org/psf/license for licensing details. + +## +# Implementation module for XPath support. There's usually no reason +# to import this module directly; the <b>ElementTree</b> does this for +# you, if needed. +## + +import re + +xpath_tokenizer_re = re.compile( + "(" + "'[^']*'|\"[^\"]*\"|" + "::|" + "//?|" + "\.\.|" + "\(\)|" + "[/.*:\[\]\(\)@=])|" + "((?:\{[^}]+\})?[^/\[\]\(\)@=\s]+)|" + "\s+" + ) + +def xpath_tokenizer(pattern, namespaces=None): + for token in xpath_tokenizer_re.findall(pattern): + tag = token[1] + if tag and tag[0] != "{" and ":" in tag: + try: + prefix, uri = tag.split(":", 1) + if not namespaces: + raise KeyError + yield token[0], "{%s}%s" % (namespaces[prefix], uri) + except KeyError: + raise SyntaxError("prefix %r not found in prefix map" % prefix) + else: + yield token + +def get_parent_map(context): + parent_map = context.parent_map + if parent_map is None: + context.parent_map = parent_map = {} + for p in context.root.iter(): + for e in p: + parent_map[e] = p + return parent_map + +def prepare_child(next, token): + tag = token[1] + def select(context, result): + for elem in result: + for e in elem: + if e.tag == tag: + yield e + return select + +def prepare_star(next, token): + def select(context, result): + for elem in result: + for e in elem: + yield e + return select + +def prepare_self(next, token): + def select(context, result): + for elem in result: + yield elem + return select + +def prepare_descendant(next, token): + token = next() + if token[0] == "*": + tag = "*" + elif not token[0]: + tag = token[1] + else: + raise SyntaxError("invalid descendant") + def select(context, result): + for elem in result: + for e in elem.iter(tag): + if e is not elem: + yield e + return select + +def prepare_parent(next, token): + def select(context, result): + # FIXME: raise error if .. is applied at toplevel? + parent_map = get_parent_map(context) + result_map = {} + for elem in result: + if elem in parent_map: + parent = parent_map[elem] + if parent not in result_map: + result_map[parent] = None + yield parent + return select + +def prepare_predicate(next, token): + # FIXME: replace with real parser!!! refs: + # http://effbot.org/zone/simple-iterator-parser.htm + # http://javascript.crockford.com/tdop/tdop.html + signature = [] + predicate = [] + while 1: + token = next() + if token[0] == "]": + break + if token[0] and token[0][:1] in "'\"": + token = "'", token[0][1:-1] + signature.append(token[0] or "-") + predicate.append(token[1]) + signature = "".join(signature) + # use signature to determine predicate type + if signature == "@-": + # [@attribute] predicate + key = predicate[1] + def select(context, result): + for elem in result: + if elem.get(key) is not None: + yield elem + return select + if signature == "@-='": + # [@attribute='value'] + key = predicate[1] + value = predicate[-1] + def select(context, result): + for elem in result: + if elem.get(key) == value: + yield elem + return select + if signature == "-" and not re.match("\d+$", predicate[0]): + # [tag] + tag = predicate[0] + def select(context, result): + for elem in result: + if elem.find(tag) is not None: + yield elem + return select + if signature == "-='" and not re.match("\d+$", predicate[0]): + # [tag='value'] + tag = predicate[0] + value = predicate[-1] + def select(context, result): + for elem in result: + for e in elem.findall(tag): + if "".join(e.itertext()) == value: + yield elem + break + return select + if signature == "-" or signature == "-()" or signature == "-()-": + # [index] or [last()] or [last()-index] + if signature == "-": + index = int(predicate[0]) - 1 + else: + if predicate[0] != "last": + raise SyntaxError("unsupported function") + if signature == "-()-": + try: + index = int(predicate[2]) - 1 + except ValueError: + raise SyntaxError("unsupported expression") + else: + index = -1 + def select(context, result): + parent_map = get_parent_map(context) + for elem in result: + try: + parent = parent_map[elem] + # FIXME: what if the selector is "*" ? + elems = list(parent.findall(elem.tag)) + if elems[index] is elem: + yield elem + except (IndexError, KeyError): + pass + return select + raise SyntaxError("invalid predicate") + +ops = { + "": prepare_child, + "*": prepare_star, + ".": prepare_self, + "..": prepare_parent, + "//": prepare_descendant, + "[": prepare_predicate, + } + +_cache = {} + +class _SelectorContext: + parent_map = None + def __init__(self, root): + self.root = root + +# -------------------------------------------------------------------- + +## +# Generate all matching objects. + +def iterfind(elem, path, namespaces=None): + # compile selector pattern + if path[-1:] == "/": + path = path + "*" # implicit all (FIXME: keep this?) + try: + selector = _cache[path] + except KeyError: + if len(_cache) > 100: + _cache.clear() + if path[:1] == "/": + raise SyntaxError("cannot use absolute path on element") + next = iter(xpath_tokenizer(path, namespaces)).next + token = next() + selector = [] + while 1: + try: + selector.append(ops[token[0]](next, token)) + except StopIteration: + raise SyntaxError("invalid path") + try: + token = next() + if token[0] == "/": + token = next() + except StopIteration: + break + _cache[path] = selector + # execute selector pattern + result = [elem] + context = _SelectorContext(elem) + for select in selector: + result = select(context, result) + return result + +## +# Find first matching object. + +def find(elem, path, namespaces=None): + try: + return iterfind(elem, path, namespaces).next() + except StopIteration: + return None + +## +# Find all matching objects. + +def findall(elem, path, namespaces=None): + return list(iterfind(elem, path, namespaces)) + +## +# Find text for first matching object. + +def findtext(elem, path, default=None, namespaces=None): + try: + elem = iterfind(elem, path, namespaces).next() + return elem.text or "" + except StopIteration: + return default diff --git a/src/main/resources/PythonLibs/xml/etree/ElementTree.py b/src/main/resources/PythonLibs/xml/etree/ElementTree.py new file mode 100644 index 0000000000000000000000000000000000000000..cd33cd08a6c524ff160fcf37cc0702179d8e13e9 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/etree/ElementTree.py @@ -0,0 +1,1669 @@ +# +# ElementTree +# $Id: ElementTree.py 3440 2008-07-18 14:45:01Z fredrik $ +# +# light-weight XML support for Python 2.3 and later. +# +# history (since 1.2.6): +# 2005-11-12 fl added tostringlist/fromstringlist helpers +# 2006-07-05 fl merged in selected changes from the 1.3 sandbox +# 2006-07-05 fl removed support for 2.1 and earlier +# 2007-06-21 fl added deprecation/future warnings +# 2007-08-25 fl added doctype hook, added parser version attribute etc +# 2007-08-26 fl added new serializer code (better namespace handling, etc) +# 2007-08-27 fl warn for broken /tag searches on tree level +# 2007-09-02 fl added html/text methods to serializer (experimental) +# 2007-09-05 fl added method argument to tostring/tostringlist +# 2007-09-06 fl improved error handling +# 2007-09-13 fl added itertext, iterfind; assorted cleanups +# 2007-12-15 fl added C14N hooks, copy method (experimental) +# +# Copyright (c) 1999-2008 by Fredrik Lundh. All rights reserved. +# +# fredrik@pythonware.com +# http://www.pythonware.com +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2008 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# 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. +# -------------------------------------------------------------------- + +# Licensed to PSF under a Contributor Agreement. +# See http://www.python.org/psf/license for licensing details. + +__all__ = [ + # public symbols + "Comment", + "dump", + "Element", "ElementTree", + "fromstring", "fromstringlist", + "iselement", "iterparse", + "parse", "ParseError", + "PI", "ProcessingInstruction", + "QName", + "SubElement", + "tostring", "tostringlist", + "TreeBuilder", + "VERSION", + "XML", + "XMLParser", "XMLTreeBuilder", + ] + +VERSION = "1.3.0" + +## +# The <b>Element</b> type is a flexible container object, designed to +# store hierarchical data structures in memory. The type can be +# described as a cross between a list and a dictionary. +# <p> +# Each element has a number of properties associated with it: +# <ul> +# <li>a <i>tag</i>. This is a string identifying what kind of data +# this element represents (the element type, in other words).</li> +# <li>a number of <i>attributes</i>, stored in a Python dictionary.</li> +# <li>a <i>text</i> string.</li> +# <li>an optional <i>tail</i> string.</li> +# <li>a number of <i>child elements</i>, stored in a Python sequence</li> +# </ul> +# +# To create an element instance, use the {@link #Element} constructor +# or the {@link #SubElement} factory function. +# <p> +# The {@link #ElementTree} class can be used to wrap an element +# structure, and convert it from and to XML. +## + +import sys +import re +import warnings + + +class _SimpleElementPath(object): + # emulate pre-1.2 find/findtext/findall behaviour + def find(self, element, tag, namespaces=None): + for elem in element: + if elem.tag == tag: + return elem + return None + def findtext(self, element, tag, default=None, namespaces=None): + elem = self.find(element, tag) + if elem is None: + return default + return elem.text or "" + def iterfind(self, element, tag, namespaces=None): + if tag[:3] == ".//": + for elem in element.iter(tag[3:]): + yield elem + for elem in element: + if elem.tag == tag: + yield elem + def findall(self, element, tag, namespaces=None): + return list(self.iterfind(element, tag, namespaces)) + +try: + from . import ElementPath +except ImportError: + ElementPath = _SimpleElementPath() + +## +# Parser error. This is a subclass of <b>SyntaxError</b>. +# <p> +# In addition to the exception value, an exception instance contains a +# specific exception code in the <b>code</b> attribute, and the line and +# column of the error in the <b>position</b> attribute. + +class ParseError(SyntaxError): + pass + +# -------------------------------------------------------------------- + +## +# Checks if an object appears to be a valid element object. +# +# @param An element instance. +# @return A true value if this is an element object. +# @defreturn flag + +def iselement(element): + # FIXME: not sure about this; might be a better idea to look + # for tag/attrib/text attributes + return isinstance(element, Element) or hasattr(element, "tag") + +## +# Element class. This class defines the Element interface, and +# provides a reference implementation of this interface. +# <p> +# The element name, attribute names, and attribute values can be +# either ASCII strings (ordinary Python strings containing only 7-bit +# ASCII characters) or Unicode strings. +# +# @param tag The element name. +# @param attrib An optional dictionary, containing element attributes. +# @param **extra Additional attributes, given as keyword arguments. +# @see Element +# @see SubElement +# @see Comment +# @see ProcessingInstruction + +class Element(object): + # <tag attrib>text<child/>...</tag>tail + + ## + # (Attribute) Element tag. + + tag = None + + ## + # (Attribute) Element attribute dictionary. Where possible, use + # {@link #Element.get}, + # {@link #Element.set}, + # {@link #Element.keys}, and + # {@link #Element.items} to access + # element attributes. + + attrib = None + + ## + # (Attribute) Text before first subelement. This is either a + # string or the value None. Note that if there was no text, this + # attribute may be either None or an empty string, depending on + # the parser. + + text = None + + ## + # (Attribute) Text after this element's end tag, but before the + # next sibling element's start tag. This is either a string or + # the value None. Note that if there was no text, this attribute + # may be either None or an empty string, depending on the parser. + + tail = None # text after end tag, if any + + # constructor + + def __init__(self, tag, attrib={}, **extra): + attrib = attrib.copy() + attrib.update(extra) + self.tag = tag + self.attrib = attrib + self._children = [] + + def __repr__(self): + return "<Element %s at 0x%x>" % (repr(self.tag), id(self)) + + ## + # Creates a new element object of the same type as this element. + # + # @param tag Element tag. + # @param attrib Element attributes, given as a dictionary. + # @return A new element instance. + + def makeelement(self, tag, attrib): + return self.__class__(tag, attrib) + + ## + # (Experimental) Copies the current element. This creates a + # shallow copy; subelements will be shared with the original tree. + # + # @return A new element instance. + + def copy(self): + elem = self.makeelement(self.tag, self.attrib) + elem.text = self.text + elem.tail = self.tail + elem[:] = self + return elem + + ## + # Returns the number of subelements. Note that this only counts + # full elements; to check if there's any content in an element, you + # have to check both the length and the <b>text</b> attribute. + # + # @return The number of subelements. + + def __len__(self): + return len(self._children) + + def __nonzero__(self): + warnings.warn( + "The behavior of this method will change in future versions. " + "Use specific 'len(elem)' or 'elem is not None' test instead.", + FutureWarning, stacklevel=2 + ) + return len(self._children) != 0 # emulate old behaviour, for now + + ## + # Returns the given subelement, by index. + # + # @param index What subelement to return. + # @return The given subelement. + # @exception IndexError If the given element does not exist. + + def __getitem__(self, index): + return self._children[index] + + ## + # Replaces the given subelement, by index. + # + # @param index What subelement to replace. + # @param element The new element value. + # @exception IndexError If the given element does not exist. + + def __setitem__(self, index, element): + # if isinstance(index, slice): + # for elt in element: + # assert iselement(elt) + # else: + # assert iselement(element) + self._children[index] = element + + ## + # Deletes the given subelement, by index. + # + # @param index What subelement to delete. + # @exception IndexError If the given element does not exist. + + def __delitem__(self, index): + del self._children[index] + + ## + # Adds a subelement to the end of this element. In document order, + # the new element will appear after the last existing subelement (or + # directly after the text, if it's the first subelement), but before + # the end tag for this element. + # + # @param element The element to add. + + def append(self, element): + # assert iselement(element) + self._children.append(element) + + ## + # Appends subelements from a sequence. + # + # @param elements A sequence object with zero or more elements. + # @since 1.3 + + def extend(self, elements): + # for element in elements: + # assert iselement(element) + self._children.extend(elements) + + ## + # Inserts a subelement at the given position in this element. + # + # @param index Where to insert the new subelement. + + def insert(self, index, element): + # assert iselement(element) + self._children.insert(index, element) + + ## + # Removes a matching subelement. Unlike the <b>find</b> methods, + # this method compares elements based on identity, not on tag + # value or contents. To remove subelements by other means, the + # easiest way is often to use a list comprehension to select what + # elements to keep, and use slice assignment to update the parent + # element. + # + # @param element What element to remove. + # @exception ValueError If a matching element could not be found. + + def remove(self, element): + # assert iselement(element) + self._children.remove(element) + + ## + # (Deprecated) Returns all subelements. The elements are returned + # in document order. + # + # @return A list of subelements. + # @defreturn list of Element instances + + def getchildren(self): + warnings.warn( + "This method will be removed in future versions. " + "Use 'list(elem)' or iteration over elem instead.", + DeprecationWarning, stacklevel=2 + ) + return self._children + + ## + # Finds the first matching subelement, by tag name or path. + # + # @param path What element to look for. + # @keyparam namespaces Optional namespace prefix map. + # @return The first matching element, or None if no element was found. + # @defreturn Element or None + + def find(self, path, namespaces=None): + return ElementPath.find(self, path, namespaces) + + ## + # Finds text for the first matching subelement, by tag name or path. + # + # @param path What element to look for. + # @param default What to return if the element was not found. + # @keyparam namespaces Optional namespace prefix map. + # @return The text content of the first matching element, or the + # default value no element was found. Note that if the element + # is found, but has no text content, this method returns an + # empty string. + # @defreturn string + + def findtext(self, path, default=None, namespaces=None): + return ElementPath.findtext(self, path, default, namespaces) + + ## + # Finds all matching subelements, by tag name or path. + # + # @param path What element to look for. + # @keyparam namespaces Optional namespace prefix map. + # @return A list or other sequence containing all matching elements, + # in document order. + # @defreturn list of Element instances + + def findall(self, path, namespaces=None): + return ElementPath.findall(self, path, namespaces) + + ## + # Finds all matching subelements, by tag name or path. + # + # @param path What element to look for. + # @keyparam namespaces Optional namespace prefix map. + # @return An iterator or sequence containing all matching elements, + # in document order. + # @defreturn a generated sequence of Element instances + + def iterfind(self, path, namespaces=None): + return ElementPath.iterfind(self, path, namespaces) + + ## + # Resets an element. This function removes all subelements, clears + # all attributes, and sets the <b>text</b> and <b>tail</b> attributes + # to None. + + def clear(self): + self.attrib.clear() + self._children = [] + self.text = self.tail = None + + ## + # Gets an element attribute. Equivalent to <b>attrib.get</b>, but + # some implementations may handle this a bit more efficiently. + # + # @param key What attribute to look for. + # @param default What to return if the attribute was not found. + # @return The attribute value, or the default value, if the + # attribute was not found. + # @defreturn string or None + + def get(self, key, default=None): + return self.attrib.get(key, default) + + ## + # Sets an element attribute. Equivalent to <b>attrib[key] = value</b>, + # but some implementations may handle this a bit more efficiently. + # + # @param key What attribute to set. + # @param value The attribute value. + + def set(self, key, value): + self.attrib[key] = value + + ## + # Gets a list of attribute names. The names are returned in an + # arbitrary order (just like for an ordinary Python dictionary). + # Equivalent to <b>attrib.keys()</b>. + # + # @return A list of element attribute names. + # @defreturn list of strings + + def keys(self): + return self.attrib.keys() + + ## + # Gets element attributes, as a sequence. The attributes are + # returned in an arbitrary order. Equivalent to <b>attrib.items()</b>. + # + # @return A list of (name, value) tuples for all attributes. + # @defreturn list of (string, string) tuples + + def items(self): + return self.attrib.items() + + ## + # Creates a tree iterator. The iterator loops over this element + # and all subelements, in document order, and returns all elements + # with a matching tag. + # <p> + # If the tree structure is modified during iteration, new or removed + # elements may or may not be included. To get a stable set, use the + # list() function on the iterator, and loop over the resulting list. + # + # @param tag What tags to look for (default is to return all elements). + # @return An iterator containing all the matching elements. + # @defreturn iterator + + def iter(self, tag=None): + if tag == "*": + tag = None + if tag is None or self.tag == tag: + yield self + for e in self._children: + for e in e.iter(tag): + yield e + + # compatibility + def getiterator(self, tag=None): + # Change for a DeprecationWarning in 1.4 + warnings.warn( + "This method will be removed in future versions. " + "Use 'elem.iter()' or 'list(elem.iter())' instead.", + PendingDeprecationWarning, stacklevel=2 + ) + return list(self.iter(tag)) + + ## + # Creates a text iterator. The iterator loops over this element + # and all subelements, in document order, and returns all inner + # text. + # + # @return An iterator containing all inner text. + # @defreturn iterator + + def itertext(self): + tag = self.tag + if not isinstance(tag, basestring) and tag is not None: + return + if self.text: + yield self.text + for e in self: + for s in e.itertext(): + yield s + if e.tail: + yield e.tail + +# compatibility +_Element = _ElementInterface = Element + +## +# Subelement factory. This function creates an element instance, and +# appends it to an existing element. +# <p> +# The element name, attribute names, and attribute values can be +# either 8-bit ASCII strings or Unicode strings. +# +# @param parent The parent element. +# @param tag The subelement name. +# @param attrib An optional dictionary, containing element attributes. +# @param **extra Additional attributes, given as keyword arguments. +# @return An element instance. +# @defreturn Element + +def SubElement(parent, tag, attrib={}, **extra): + attrib = attrib.copy() + attrib.update(extra) + element = parent.makeelement(tag, attrib) + parent.append(element) + return element + +## +# Comment element factory. This factory function creates a special +# element that will be serialized as an XML comment by the standard +# serializer. +# <p> +# The comment string can be either an 8-bit ASCII string or a Unicode +# string. +# +# @param text A string containing the comment string. +# @return An element instance, representing a comment. +# @defreturn Element + +def Comment(text=None): + element = Element(Comment) + element.text = text + return element + +## +# PI element factory. This factory function creates a special element +# that will be serialized as an XML processing instruction by the standard +# serializer. +# +# @param target A string containing the PI target. +# @param text A string containing the PI contents, if any. +# @return An element instance, representing a PI. +# @defreturn Element + +def ProcessingInstruction(target, text=None): + element = Element(ProcessingInstruction) + element.text = target + if text: + element.text = element.text + " " + text + return element + +PI = ProcessingInstruction + +## +# QName wrapper. This can be used to wrap a QName attribute value, in +# order to get proper namespace handling on output. +# +# @param text A string containing the QName value, in the form {uri}local, +# or, if the tag argument is given, the URI part of a QName. +# @param tag Optional tag. If given, the first argument is interpreted as +# an URI, and this argument is interpreted as a local name. +# @return An opaque object, representing the QName. + +class QName(object): + def __init__(self, text_or_uri, tag=None): + if tag: + text_or_uri = "{%s}%s" % (text_or_uri, tag) + self.text = text_or_uri + def __str__(self): + return self.text + def __hash__(self): + return hash(self.text) + def __cmp__(self, other): + if isinstance(other, QName): + return cmp(self.text, other.text) + return cmp(self.text, other) + +# -------------------------------------------------------------------- + +## +# ElementTree wrapper class. This class represents an entire element +# hierarchy, and adds some extra support for serialization to and from +# standard XML. +# +# @param element Optional root element. +# @keyparam file Optional file handle or file name. If given, the +# tree is initialized with the contents of this XML file. + +class ElementTree(object): + + def __init__(self, element=None, file=None): + # assert element is None or iselement(element) + self._root = element # first node + if file: + self.parse(file) + + ## + # Gets the root element for this tree. + # + # @return An element instance. + # @defreturn Element + + def getroot(self): + return self._root + + ## + # Replaces the root element for this tree. This discards the + # current contents of the tree, and replaces it with the given + # element. Use with care. + # + # @param element An element instance. + + def _setroot(self, element): + # assert iselement(element) + self._root = element + + ## + # Loads an external XML document into this element tree. + # + # @param source A file name or file object. If a file object is + # given, it only has to implement a <b>read(n)</b> method. + # @keyparam parser An optional parser instance. If not given, the + # standard {@link XMLParser} parser is used. + # @return The document root element. + # @defreturn Element + # @exception ParseError If the parser fails to parse the document. + + def parse(self, source, parser=None): + close_source = False + if not hasattr(source, "read"): + source = open(source, "rb") + close_source = True + try: + if not parser: + parser = XMLParser(target=TreeBuilder()) + while 1: + data = source.read(65536) + if not data: + break + parser.feed(data) + self._root = parser.close() + return self._root + finally: + if close_source: + source.close() + + ## + # Creates a tree iterator for the root element. The iterator loops + # over all elements in this tree, in document order. + # + # @param tag What tags to look for (default is to return all elements) + # @return An iterator. + # @defreturn iterator + + def iter(self, tag=None): + # assert self._root is not None + return self._root.iter(tag) + + # compatibility + def getiterator(self, tag=None): + # Change for a DeprecationWarning in 1.4 + warnings.warn( + "This method will be removed in future versions. " + "Use 'tree.iter()' or 'list(tree.iter())' instead.", + PendingDeprecationWarning, stacklevel=2 + ) + return list(self.iter(tag)) + + ## + # Finds the first toplevel element with given tag. + # Same as getroot().find(path). + # + # @param path What element to look for. + # @keyparam namespaces Optional namespace prefix map. + # @return The first matching element, or None if no element was found. + # @defreturn Element or None + + def find(self, path, namespaces=None): + # assert self._root is not None + if path[:1] == "/": + path = "." + path + warnings.warn( + "This search is broken in 1.3 and earlier, and will be " + "fixed in a future version. If you rely on the current " + "behaviour, change it to %r" % path, + FutureWarning, stacklevel=2 + ) + return self._root.find(path, namespaces) + + ## + # Finds the element text for the first toplevel element with given + # tag. Same as getroot().findtext(path). + # + # @param path What toplevel element to look for. + # @param default What to return if the element was not found. + # @keyparam namespaces Optional namespace prefix map. + # @return The text content of the first matching element, or the + # default value no element was found. Note that if the element + # is found, but has no text content, this method returns an + # empty string. + # @defreturn string + + def findtext(self, path, default=None, namespaces=None): + # assert self._root is not None + if path[:1] == "/": + path = "." + path + warnings.warn( + "This search is broken in 1.3 and earlier, and will be " + "fixed in a future version. If you rely on the current " + "behaviour, change it to %r" % path, + FutureWarning, stacklevel=2 + ) + return self._root.findtext(path, default, namespaces) + + ## + # Finds all toplevel elements with the given tag. + # Same as getroot().findall(path). + # + # @param path What element to look for. + # @keyparam namespaces Optional namespace prefix map. + # @return A list or iterator containing all matching elements, + # in document order. + # @defreturn list of Element instances + + def findall(self, path, namespaces=None): + # assert self._root is not None + if path[:1] == "/": + path = "." + path + warnings.warn( + "This search is broken in 1.3 and earlier, and will be " + "fixed in a future version. If you rely on the current " + "behaviour, change it to %r" % path, + FutureWarning, stacklevel=2 + ) + return self._root.findall(path, namespaces) + + ## + # Finds all matching subelements, by tag name or path. + # Same as getroot().iterfind(path). + # + # @param path What element to look for. + # @keyparam namespaces Optional namespace prefix map. + # @return An iterator or sequence containing all matching elements, + # in document order. + # @defreturn a generated sequence of Element instances + + def iterfind(self, path, namespaces=None): + # assert self._root is not None + if path[:1] == "/": + path = "." + path + warnings.warn( + "This search is broken in 1.3 and earlier, and will be " + "fixed in a future version. If you rely on the current " + "behaviour, change it to %r" % path, + FutureWarning, stacklevel=2 + ) + return self._root.iterfind(path, namespaces) + + ## + # Writes the element tree to a file, as XML. + # + # @def write(file, **options) + # @param file A file name, or a file object opened for writing. + # @param **options Options, given as keyword arguments. + # @keyparam encoding Optional output encoding (default is US-ASCII). + # @keyparam xml_declaration Controls if an XML declaration should + # be added to the file. Use False for never, True for always, + # None for only if not US-ASCII or UTF-8. None is default. + # @keyparam default_namespace Sets the default XML namespace (for "xmlns"). + # @keyparam method Optional output method ("xml", "html", "text" or + # "c14n"; default is "xml"). + + def write(self, file_or_filename, + # keyword arguments + encoding=None, + xml_declaration=None, + default_namespace=None, + method=None): + # assert self._root is not None + if not method: + method = "xml" + elif method not in _serialize: + # FIXME: raise an ImportError for c14n if ElementC14N is missing? + raise ValueError("unknown method %r" % method) + if hasattr(file_or_filename, "write"): + file = file_or_filename + else: + file = open(file_or_filename, "wb") + write = file.write + if not encoding: + if method == "c14n": + encoding = "utf-8" + else: + encoding = "us-ascii" + elif xml_declaration or (xml_declaration is None and + encoding not in ("utf-8", "us-ascii")): + if method == "xml": + write("<?xml version='1.0' encoding='%s'?>\n" % encoding) + if method == "text": + _serialize_text(write, self._root, encoding) + else: + qnames, namespaces = _namespaces( + self._root, encoding, default_namespace + ) + serialize = _serialize[method] + serialize(write, self._root, encoding, qnames, namespaces) + if file_or_filename is not file: + file.close() + + def write_c14n(self, file): + # lxml.etree compatibility. use output method instead + return self.write(file, method="c14n") + +# -------------------------------------------------------------------- +# serialization support + +def _namespaces(elem, encoding, default_namespace=None): + # identify namespaces used in this tree + + # maps qnames to *encoded* prefix:local names + qnames = {None: None} + + # maps uri:s to prefixes + namespaces = {} + if default_namespace: + namespaces[default_namespace] = "" + + def encode(text): + return text.encode(encoding) + + def add_qname(qname): + # calculate serialized qname representation + try: + if qname[:1] == "{": + uri, tag = qname[1:].rsplit("}", 1) + prefix = namespaces.get(uri) + if prefix is None: + prefix = _namespace_map.get(uri) + if prefix is None: + prefix = "ns%d" % len(namespaces) + if prefix != "xml": + namespaces[uri] = prefix + if prefix: + qnames[qname] = encode("%s:%s" % (prefix, tag)) + else: + qnames[qname] = encode(tag) # default element + else: + if default_namespace: + # FIXME: can this be handled in XML 1.0? + raise ValueError( + "cannot use non-qualified names with " + "default_namespace option" + ) + qnames[qname] = encode(qname) + except TypeError: + _raise_serialization_error(qname) + + # populate qname and namespaces table + try: + iterate = elem.iter + except AttributeError: + iterate = elem.getiterator # cET compatibility + for elem in iterate(): + tag = elem.tag + if isinstance(tag, QName): + if tag.text not in qnames: + add_qname(tag.text) + elif isinstance(tag, basestring): + if tag not in qnames: + add_qname(tag) + elif tag is not None and tag is not Comment and tag is not PI: + _raise_serialization_error(tag) + for key, value in elem.items(): + if isinstance(key, QName): + key = key.text + if key not in qnames: + add_qname(key) + if isinstance(value, QName) and value.text not in qnames: + add_qname(value.text) + text = elem.text + if isinstance(text, QName) and text.text not in qnames: + add_qname(text.text) + return qnames, namespaces + +def _serialize_xml(write, elem, encoding, qnames, namespaces): + tag = elem.tag + text = elem.text + if tag is Comment: + write("<!--%s-->" % _encode(text, encoding)) + elif tag is ProcessingInstruction: + write("<?%s?>" % _encode(text, encoding)) + else: + tag = qnames[tag] + if tag is None: + if text: + write(_escape_cdata(text, encoding)) + for e in elem: + _serialize_xml(write, e, encoding, qnames, None) + else: + write("<" + tag) + items = elem.items() + if items or namespaces: + if namespaces: + for v, k in sorted(namespaces.items(), + key=lambda x: x[1]): # sort on prefix + if k: + k = ":" + k + write(" xmlns%s=\"%s\"" % ( + k.encode(encoding), + _escape_attrib(v, encoding) + )) + for k, v in sorted(items): # lexical order + if isinstance(k, QName): + k = k.text + if isinstance(v, QName): + v = qnames[v.text] + else: + v = _escape_attrib(v, encoding) + write(" %s=\"%s\"" % (qnames[k], v)) + if text or len(elem): + write(">") + if text: + write(_escape_cdata(text, encoding)) + for e in elem: + _serialize_xml(write, e, encoding, qnames, None) + write("</" + tag + ">") + else: + write(" />") + if elem.tail: + write(_escape_cdata(elem.tail, encoding)) + +HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr", + "img", "input", "isindex", "link", "meta", "param") + +try: + HTML_EMPTY = set(HTML_EMPTY) +except NameError: + pass + +def _serialize_html(write, elem, encoding, qnames, namespaces): + tag = elem.tag + text = elem.text + if tag is Comment: + write("<!--%s-->" % _escape_cdata(text, encoding)) + elif tag is ProcessingInstruction: + write("<?%s?>" % _escape_cdata(text, encoding)) + else: + tag = qnames[tag] + if tag is None: + if text: + write(_escape_cdata(text, encoding)) + for e in elem: + _serialize_html(write, e, encoding, qnames, None) + else: + write("<" + tag) + items = elem.items() + if items or namespaces: + if namespaces: + for v, k in sorted(namespaces.items(), + key=lambda x: x[1]): # sort on prefix + if k: + k = ":" + k + write(" xmlns%s=\"%s\"" % ( + k.encode(encoding), + _escape_attrib(v, encoding) + )) + for k, v in sorted(items): # lexical order + if isinstance(k, QName): + k = k.text + if isinstance(v, QName): + v = qnames[v.text] + else: + v = _escape_attrib_html(v, encoding) + # FIXME: handle boolean attributes + write(" %s=\"%s\"" % (qnames[k], v)) + write(">") + tag = tag.lower() + if text: + if tag == "script" or tag == "style": + write(_encode(text, encoding)) + else: + write(_escape_cdata(text, encoding)) + for e in elem: + _serialize_html(write, e, encoding, qnames, None) + if tag not in HTML_EMPTY: + write("</" + tag + ">") + if elem.tail: + write(_escape_cdata(elem.tail, encoding)) + +def _serialize_text(write, elem, encoding): + for part in elem.itertext(): + write(part.encode(encoding)) + if elem.tail: + write(elem.tail.encode(encoding)) + +_serialize = { + "xml": _serialize_xml, + "html": _serialize_html, + "text": _serialize_text, +# this optional method is imported at the end of the module +# "c14n": _serialize_c14n, +} + +## +# Registers a namespace prefix. The registry is global, and any +# existing mapping for either the given prefix or the namespace URI +# will be removed. +# +# @param prefix Namespace prefix. +# @param uri Namespace uri. Tags and attributes in this namespace +# will be serialized with the given prefix, if at all possible. +# @exception ValueError If the prefix is reserved, or is otherwise +# invalid. + +def register_namespace(prefix, uri): + if re.match("ns\d+$", prefix): + raise ValueError("Prefix format reserved for internal use") + for k, v in _namespace_map.items(): + if k == uri or v == prefix: + del _namespace_map[k] + _namespace_map[uri] = prefix + +_namespace_map = { + # "well-known" namespace prefixes + "http://www.w3.org/XML/1998/namespace": "xml", + "http://www.w3.org/1999/xhtml": "html", + "http://www.w3.org/1999/02/22-rdf-syntax-ns#": "rdf", + "http://schemas.xmlsoap.org/wsdl/": "wsdl", + # xml schema + "http://www.w3.org/2001/XMLSchema": "xs", + "http://www.w3.org/2001/XMLSchema-instance": "xsi", + # dublin core + "http://purl.org/dc/elements/1.1/": "dc", +} + +def _raise_serialization_error(text): + raise TypeError( + "cannot serialize %r (type %s)" % (text, type(text).__name__) + ) + +def _encode(text, encoding): + try: + return text.encode(encoding, "xmlcharrefreplace") + except (TypeError, AttributeError): + _raise_serialization_error(text) + +def _escape_cdata(text, encoding): + # escape character data + try: + # it's worth avoiding do-nothing calls for strings that are + # shorter than 500 character, or so. assume that's, by far, + # the most common case in most applications. + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + return text.encode(encoding, "xmlcharrefreplace") + except (TypeError, AttributeError): + _raise_serialization_error(text) + +def _escape_attrib(text, encoding): + # escape attribute value + try: + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if "\"" in text: + text = text.replace("\"", """) + if "\n" in text: + text = text.replace("\n", " ") + return text.encode(encoding, "xmlcharrefreplace") + except (TypeError, AttributeError): + _raise_serialization_error(text) + +def _escape_attrib_html(text, encoding): + # escape attribute value + try: + if "&" in text: + text = text.replace("&", "&") + if ">" in text: + text = text.replace(">", ">") + if "\"" in text: + text = text.replace("\"", """) + return text.encode(encoding, "xmlcharrefreplace") + except (TypeError, AttributeError): + _raise_serialization_error(text) + +# -------------------------------------------------------------------- + +## +# Generates a string representation of an XML element, including all +# subelements. +# +# @param element An Element instance. +# @keyparam encoding Optional output encoding (default is US-ASCII). +# @keyparam method Optional output method ("xml", "html", "text" or +# "c14n"; default is "xml"). +# @return An encoded string containing the XML data. +# @defreturn string + +def tostring(element, encoding=None, method=None): + class dummy: + pass + data = [] + file = dummy() + file.write = data.append + ElementTree(element).write(file, encoding, method=method) + return "".join(data) + +## +# Generates a string representation of an XML element, including all +# subelements. The string is returned as a sequence of string fragments. +# +# @param element An Element instance. +# @keyparam encoding Optional output encoding (default is US-ASCII). +# @keyparam method Optional output method ("xml", "html", "text" or +# "c14n"; default is "xml"). +# @return A sequence object containing the XML data. +# @defreturn sequence +# @since 1.3 + +def tostringlist(element, encoding=None, method=None): + class dummy: + pass + data = [] + file = dummy() + file.write = data.append + ElementTree(element).write(file, encoding, method=method) + # FIXME: merge small fragments into larger parts + return data + +## +# Writes an element tree or element structure to sys.stdout. This +# function should be used for debugging only. +# <p> +# The exact output format is implementation dependent. In this +# version, it's written as an ordinary XML file. +# +# @param elem An element tree or an individual element. + +def dump(elem): + # debugging + if not isinstance(elem, ElementTree): + elem = ElementTree(elem) + elem.write(sys.stdout) + tail = elem.getroot().tail + if not tail or tail[-1] != "\n": + sys.stdout.write("\n") + +# -------------------------------------------------------------------- +# parsing + +## +# Parses an XML document into an element tree. +# +# @param source A filename or file object containing XML data. +# @param parser An optional parser instance. If not given, the +# standard {@link XMLParser} parser is used. +# @return An ElementTree instance + +def parse(source, parser=None): + tree = ElementTree() + tree.parse(source, parser) + return tree + +## +# Parses an XML document into an element tree incrementally, and reports +# what's going on to the user. +# +# @param source A filename or file object containing XML data. +# @param events A list of events to report back. If omitted, only "end" +# events are reported. +# @param parser An optional parser instance. If not given, the +# standard {@link XMLParser} parser is used. +# @return A (event, elem) iterator. + +def iterparse(source, events=None, parser=None): + close_source = False + if not hasattr(source, "read"): + source = open(source, "rb") + close_source = True + if not parser: + parser = XMLParser(target=TreeBuilder()) + return _IterParseIterator(source, events, parser, close_source) + +class _IterParseIterator(object): + + def __init__(self, source, events, parser, close_source=False): + self._file = source + self._close_file = close_source + self._events = [] + self._index = 0 + self._error = None + self.root = self._root = None + self._parser = parser + # wire up the parser for event reporting + parser = self._parser._parser + append = self._events.append + if events is None: + events = ["end"] + for event in events: + if event == "start": + try: + parser.ordered_attributes = 1 + parser.specified_attributes = 1 + def handler(tag, attrib_in, event=event, append=append, + start=self._parser._start_list): + append((event, start(tag, attrib_in))) + parser.StartElementHandler = handler + except AttributeError: + def handler(tag, attrib_in, event=event, append=append, + start=self._parser._start): + append((event, start(tag, attrib_in))) + parser.StartElementHandler = handler + elif event == "end": + def handler(tag, event=event, append=append, + end=self._parser._end): + append((event, end(tag))) + parser.EndElementHandler = handler + elif event == "start-ns": + def handler(prefix, uri, event=event, append=append): + try: + uri = (uri or "").encode("ascii") + except UnicodeError: + pass + append((event, (prefix or "", uri or ""))) + parser.StartNamespaceDeclHandler = handler + elif event == "end-ns": + def handler(prefix, event=event, append=append): + append((event, None)) + parser.EndNamespaceDeclHandler = handler + else: + raise ValueError("unknown event %r" % event) + + def next(self): + while 1: + try: + item = self._events[self._index] + self._index += 1 + return item + except IndexError: + pass + if self._error: + e = self._error + self._error = None + raise e + if self._parser is None: + self.root = self._root + if self._close_file: + self._file.close() + raise StopIteration + # load event buffer + del self._events[:] + self._index = 0 + data = self._file.read(16384) + if data: + try: + self._parser.feed(data) + except SyntaxError as exc: + self._error = exc + else: + self._root = self._parser.close() + self._parser = None + + def __iter__(self): + return self + +## +# Parses an XML document from a string constant. This function can +# be used to embed "XML literals" in Python code. +# +# @param source A string containing XML data. +# @param parser An optional parser instance. If not given, the +# standard {@link XMLParser} parser is used. +# @return An Element instance. +# @defreturn Element + +def XML(text, parser=None): + if not parser: + parser = XMLParser(target=TreeBuilder()) + parser.feed(text) + return parser.close() + +## +# Parses an XML document from a string constant, and also returns +# a dictionary which maps from element id:s to elements. +# +# @param source A string containing XML data. +# @param parser An optional parser instance. If not given, the +# standard {@link XMLParser} parser is used. +# @return A tuple containing an Element instance and a dictionary. +# @defreturn (Element, dictionary) + +def XMLID(text, parser=None): + if not parser: + parser = XMLParser(target=TreeBuilder()) + parser.feed(text) + tree = parser.close() + ids = {} + for elem in tree.iter(): + id = elem.get("id") + if id: + ids[id] = elem + return tree, ids + +## +# Parses an XML document from a string constant. Same as {@link #XML}. +# +# @def fromstring(text) +# @param source A string containing XML data. +# @return An Element instance. +# @defreturn Element + +fromstring = XML + +## +# Parses an XML document from a sequence of string fragments. +# +# @param sequence A list or other sequence containing XML data fragments. +# @param parser An optional parser instance. If not given, the +# standard {@link XMLParser} parser is used. +# @return An Element instance. +# @defreturn Element +# @since 1.3 + +def fromstringlist(sequence, parser=None): + if not parser: + parser = XMLParser(target=TreeBuilder()) + for text in sequence: + parser.feed(text) + return parser.close() + +# -------------------------------------------------------------------- + +## +# Generic element structure builder. This builder converts a sequence +# of {@link #TreeBuilder.start}, {@link #TreeBuilder.data}, and {@link +# #TreeBuilder.end} method calls to a well-formed element structure. +# <p> +# You can use this class to build an element structure using a custom XML +# parser, or a parser for some other XML-like format. +# +# @param element_factory Optional element factory. This factory +# is called to create new Element instances, as necessary. + +class TreeBuilder(object): + + def __init__(self, element_factory=None): + self._data = [] # data collector + self._elem = [] # element stack + self._last = None # last element + self._tail = None # true if we're after an end tag + if element_factory is None: + element_factory = Element + self._factory = element_factory + + ## + # Flushes the builder buffers, and returns the toplevel document + # element. + # + # @return An Element instance. + # @defreturn Element + + def close(self): + assert len(self._elem) == 0, "missing end tags" + assert self._last is not None, "missing toplevel element" + return self._last + + def _flush(self): + if self._data: + if self._last is not None: + text = "".join(self._data) + if self._tail: + assert self._last.tail is None, "internal error (tail)" + self._last.tail = text + else: + assert self._last.text is None, "internal error (text)" + self._last.text = text + self._data = [] + + ## + # Adds text to the current element. + # + # @param data A string. This should be either an 8-bit string + # containing ASCII text, or a Unicode string. + + def data(self, data): + self._data.append(data) + + ## + # Opens a new element. + # + # @param tag The element name. + # @param attrib A dictionary containing element attributes. + # @return The opened element. + # @defreturn Element + + def start(self, tag, attrs): + self._flush() + self._last = elem = self._factory(tag, attrs) + if self._elem: + self._elem[-1].append(elem) + self._elem.append(elem) + self._tail = 0 + return elem + + ## + # Closes the current element. + # + # @param tag The element name. + # @return The closed element. + # @defreturn Element + + def end(self, tag): + self._flush() + self._last = self._elem.pop() + assert self._last.tag == tag,\ + "end tag mismatch (expected %s, got %s)" % ( + self._last.tag, tag) + self._tail = 1 + return self._last + +## +# Element structure builder for XML source data, based on the +# <b>expat</b> parser. +# +# @keyparam target Target object. If omitted, the builder uses an +# instance of the standard {@link #TreeBuilder} class. +# @keyparam html Predefine HTML entities. This flag is not supported +# by the current implementation. +# @keyparam encoding Optional encoding. If given, the value overrides +# the encoding specified in the XML file. +# @see #ElementTree +# @see #TreeBuilder + +class XMLParser(object): + + def __init__(self, html=0, target=None, encoding=None): + try: + from xml.parsers import expat + except ImportError: + try: + import pyexpat as expat + except ImportError: + raise ImportError( + "No module named expat; use SimpleXMLTreeBuilder instead" + ) + parser = expat.ParserCreate(encoding, "}") + if target is None: + target = TreeBuilder() + # underscored names are provided for compatibility only + self.parser = self._parser = parser + self.target = self._target = target + self._error = expat.error + self._names = {} # name memo cache + # callbacks + parser.DefaultHandlerExpand = self._default + parser.StartElementHandler = self._start + parser.EndElementHandler = self._end + parser.CharacterDataHandler = self._data + # optional callbacks + parser.CommentHandler = self._comment + parser.ProcessingInstructionHandler = self._pi + # let expat do the buffering, if supported + try: + self._parser.buffer_text = 1 + except AttributeError: + pass + # use new-style attribute handling, if supported + try: + self._parser.ordered_attributes = 1 + self._parser.specified_attributes = 1 + parser.StartElementHandler = self._start_list + except AttributeError: + pass + self._doctype = None + self.entity = {} + try: + self.version = "Expat %d.%d.%d" % expat.version_info + except AttributeError: + pass # unknown + + def _raiseerror(self, value): + err = ParseError(value) + err.code = value.code + err.position = value.lineno, value.offset + raise err + + def _fixtext(self, text): + # convert text string to ascii, if possible + try: + return text.encode("ascii") + except UnicodeError: + return text + + def _fixname(self, key): + # expand qname, and convert name string to ascii, if possible + try: + name = self._names[key] + except KeyError: + name = key + if "}" in name: + name = "{" + name + self._names[key] = name = self._fixtext(name) + return name + + def _start(self, tag, attrib_in): + fixname = self._fixname + fixtext = self._fixtext + tag = fixname(tag) + attrib = {} + for key, value in attrib_in.items(): + attrib[fixname(key)] = fixtext(value) + return self.target.start(tag, attrib) + + def _start_list(self, tag, attrib_in): + fixname = self._fixname + fixtext = self._fixtext + tag = fixname(tag) + attrib = {} + if attrib_in: + for i in range(0, len(attrib_in), 2): + attrib[fixname(attrib_in[i])] = fixtext(attrib_in[i+1]) + return self.target.start(tag, attrib) + + def _data(self, text): + return self.target.data(self._fixtext(text)) + + def _end(self, tag): + return self.target.end(self._fixname(tag)) + + def _comment(self, data): + try: + comment = self.target.comment + except AttributeError: + pass + else: + return comment(self._fixtext(data)) + + def _pi(self, target, data): + try: + pi = self.target.pi + except AttributeError: + pass + else: + return pi(self._fixtext(target), self._fixtext(data)) + + def _default(self, text): + prefix = text[:1] + if prefix == "&": + # deal with undefined entities + try: + self.target.data(self.entity[text[1:-1]]) + except KeyError: + from xml.parsers import expat + err = expat.error( + "undefined entity %s: line %d, column %d" % + (text, self._parser.ErrorLineNumber, + self._parser.ErrorColumnNumber) + ) + err.code = 11 # XML_ERROR_UNDEFINED_ENTITY + err.lineno = self._parser.ErrorLineNumber + err.offset = self._parser.ErrorColumnNumber + raise err + elif prefix == "<" and text[:9] == "<!DOCTYPE": + self._doctype = [] # inside a doctype declaration + elif self._doctype is not None: + # parse doctype contents + if prefix == ">": + self._doctype = None + return + text = text.strip() + if not text: + return + self._doctype.append(text) + n = len(self._doctype) + if n > 2: + type = self._doctype[1] + if type == "PUBLIC" and n == 4: + name, type, pubid, system = self._doctype + elif type == "SYSTEM" and n == 3: + name, type, system = self._doctype + pubid = None + else: + return + if pubid: + pubid = pubid[1:-1] + if hasattr(self.target, "doctype"): + self.target.doctype(name, pubid, system[1:-1]) + elif self.doctype is not self._XMLParser__doctype: + # warn about deprecated call + self._XMLParser__doctype(name, pubid, system[1:-1]) + self.doctype(name, pubid, system[1:-1]) + self._doctype = None + + ## + # (Deprecated) Handles a doctype declaration. + # + # @param name Doctype name. + # @param pubid Public identifier. + # @param system System identifier. + + def doctype(self, name, pubid, system): + """This method of XMLParser is deprecated.""" + warnings.warn( + "This method of XMLParser is deprecated. Define doctype() " + "method on the TreeBuilder target.", + DeprecationWarning, + ) + + # sentinel, if doctype is redefined in a subclass + __doctype = doctype + + ## + # Feeds data to the parser. + # + # @param data Encoded data. + + def feed(self, data): + try: + self._parser.Parse(data, 0) + except self._error, v: + self._raiseerror(v) + + ## + # Finishes feeding data to the parser. + # + # @return An element structure. + # @defreturn Element + + def close(self): + try: + self._parser.Parse("", 1) # end of data + except self._error, v: + self._raiseerror(v) + tree = self.target.close() + del self.target, self._parser # get rid of circular references + return tree + +# compatibility +XMLTreeBuilder = XMLParser + +# workaround circular import. +try: + from ElementC14N import _serialize_c14n + _serialize["c14n"] = _serialize_c14n +except ImportError: + pass diff --git a/src/main/resources/PythonLibs/xml/etree/__init__.py b/src/main/resources/PythonLibs/xml/etree/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..27fd8f6d4e36029830517a8884fac7da56d25eb7 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/etree/__init__.py @@ -0,0 +1,33 @@ +# $Id: __init__.py 3375 2008-02-13 08:05:08Z fredrik $ +# elementtree package + +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2008 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# 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. +# -------------------------------------------------------------------- + +# Licensed to PSF under a Contributor Agreement. +# See http://www.python.org/psf/license for licensing details. diff --git a/src/main/resources/PythonLibs/xml/etree/cElementTree.py b/src/main/resources/PythonLibs/xml/etree/cElementTree.py new file mode 100644 index 0000000000000000000000000000000000000000..cad55e8d0227701df58d225136c6848e5b306687 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/etree/cElementTree.py @@ -0,0 +1,11 @@ +# make an exact copy of ElementTree's namespace here to support even +# private API usage +from xml.etree.ElementTree import ( + Comment, Element, ElementPath, ElementTree, PI, ParseError, + ProcessingInstruction, QName, SubElement, TreeBuilder, VERSION, XML, XMLID, + XMLParser, XMLTreeBuilder, _Element, _ElementInterface, _SimpleElementPath, + __all__, __doc__, __file__, __name__, __package__, _encode, + _escape_attrib, _escape_cdata, _namespace_map, + _raise_serialization_error, dump, fromstring, fromstringlist, + iselement, iterparse, parse, re, register_namespace, sys, tostring, + tostringlist) diff --git a/src/main/resources/PythonLibs/xml/parsers/__init__.py b/src/main/resources/PythonLibs/xml/parsers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/main/resources/PythonLibs/xml/parsers/expat.py b/src/main/resources/PythonLibs/xml/parsers/expat.py new file mode 100644 index 0000000000000000000000000000000000000000..31b432304f23a9817232938d0696d841894e3c2c --- /dev/null +++ b/src/main/resources/PythonLibs/xml/parsers/expat.py @@ -0,0 +1,606 @@ +# coding: utf-8 + +#------------------------------------------------------------------------------ +# Copyright (c) 2008 Sébastien Boisgérault +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# ----------------------------------------------------------------------------- + +__all__ = ["ExpatError", "ParserCreate", "XMLParserType", "error", "errors"] + +# Jython check +import sys +if not sys.platform.startswith('java'): + raise ImportError("this version of expat requires the jython interpreter") + +# Standard Python Library +import re +import types + +# Jython +from org.python.core import Py +from org.python.core.util import StringUtil +from jarray import array + +# Java Standard Edition +from java.io import ByteArrayInputStream +from java.lang import String, StringBuilder +from org.xml.sax import InputSource +from org.xml.sax import SAXNotRecognizedException, SAXParseException +from org.xml.sax.helpers import XMLReaderFactory +from org.xml.sax.ext import DefaultHandler2 + +# Xerces +_mangled_xerces_parser_name = "org.python.apache.xerces.parsers.SAXParser" +_xerces_parser_name = "org.apache.xerces.parsers.SAXParser" + + +# @expat args registry +_register = {} + + +def ParserCreate(encoding=None, namespace_separator=None): + return XMLParser(encoding, namespace_separator) + + +class XMLParser(object): + + def __init__(self, encoding, namespace_separator): + self.encoding = encoding + self.CurrentLineNumber = 1 + self.CurrentColumnNumber = 0 + self._NextLineNumber = 1 + self._NextColumnNumber = 0 + self.ErrorLineNumber = -1 + self.ErrorColumnNumber = -1 + self.ErrorCode = None + + if namespace_separator is None: + self.namespace_separator = namespace_separator + elif isinstance(namespace_separator, basestring): + self.namespace_separator = str(namespace_separator) + if len(self.namespace_separator) > 1: + error = ("namespace_separator must be at most one character, " + "omitted, or None") + raise ValueError(error) + else: + error = ("ParserCreate() argument 2 must be string or None, " + "not %s" % type(namespace_separator).__name__) + raise TypeError(error) + + # See http://bugs.jython.org/issue1537 + try: + self._reader = XMLReaderFactory.createXMLReader(_mangled_xerces_parser_name) + except: + self._reader = XMLReaderFactory.createXMLReader(_xerces_parser_name) + + if self.namespace_separator is None: + try: + feature = "http://xml.org/sax/features/namespaces" + self._reader.setFeature(feature, False) + except SAXNotRecognizedException: + error = ("namespace support cannot be disabled; " + "set namespace_separator to a string of length 1.") + raise ValueError(error) + + self._base = None + self._buffer_text = True + self._returns_unicode = True + + self._data = StringBuilder() + + self._handler = XMLEventHandler(self) + self._reader.setContentHandler(self._handler) + self._reader.setErrorHandler(self._handler) + self._reader.setDTDHandler(self._handler) + self._reader.setEntityResolver(self._handler) + + sax_properties = ("lexical-handler", "declaration-handler") + for name in sax_properties: + try: + name = "http://xml.org/sax/properties/" + name + self._reader.setProperty(name, self._handler) + except SAXNotRecognizedException: + error = "can't set property %r" % name + raise NotImplementedError(error) + + apache_features = (("nonvalidating/load-external-dtd", False),) + for name, value in apache_features: + try: + name = "http://apache.org/xml/features/" + name + self._reader.setFeature(name, value) + except SAXNotRecognizedException: + error = "can't set feature %r" % name + raise NotImplementedError(error) + + # experimental + #f = "http://xml.org/sax/features/external-general-entities" + f = "http://xml.org/sax/features/external-parameter-entities" + #self._reader.setFeature(f, False) + + # check + f = "http://xml.org/sax/features/use-entity-resolver2" + assert self._reader.getFeature(f) + + def GetBase(self): + return self._base + + def SetBase(self, base): + self._base = base + + def _error(self, value=None): + raise AttributeError("'XMLParser' has no such attribute") + + def _get_buffer_text(self): + return self._buffer_text + + def _set_buffer_text(self, value): + self._buffer_text = bool(value) + + def _get_returns_unicode(self): + return bool(self._returns_unicode) + + def _set_returns_unicode(self, value): + self._returns_unicode = value + + # 'ordered' and 'specified' attributes are not supported + ordered_attributes = property(_error, _error) + specified_attributes = property(_error, _error) + # any setting is allowed, but it won't make a difference + buffer_text = property(_get_buffer_text, _set_buffer_text) + # non-significant read-only values + buffer_used = property(lambda self: None) + buffer_size = property(lambda self: None) + # 'returns_unicode' attribute is properly supported + returns_unicode = property(_get_returns_unicode, _set_returns_unicode) + + def _expat_error(self, sax_error): + sax_message = sax_error.getMessage() + pattern = 'The entity ".*" was referenced, but not declared\.' + if re.match(pattern, sax_message): + expat_message = "undefined entity: line %s, column %s" % \ + (self.ErrorLineNumber, self.ErrorColumnNumber) + else: + expat_message = sax_message + error = ExpatError(expat_message) + error.lineno = self.ErrorLineNumber + error.offset = self.ErrorColumnNumber + error.code = self.ErrorCode + return error + + def Parse(self, data, isfinal=False): + # The 'data' argument should be an encoded text: a str instance that + # represents an array of bytes. If instead it is a unicode string, + # only the us-ascii range is considered safe enough to be silently + # converted. + if isinstance(data, unicode): + data = data.encode(sys.getdefaultencoding()) + + self._data.append(data) + + if isfinal: + bytes = StringUtil.toBytes(self._data.toString()) + byte_stream = ByteArrayInputStream(bytes) + source = InputSource(byte_stream) + if self.encoding is not None: + source.setEncoding(self.encoding) + try: + self._reader.parse(source) + except SAXParseException, sax_error: + # Experiments tend to show that the '_Next*' parser locations + # match more closely expat behavior than the 'Current*' or sax + # error locations. + self.ErrorLineNumber = self._NextLineNumber + self.ErrorColumnNumber = self._NextColumnNumber + self.ErrorCode = None + raise self._expat_error(sax_error) + return 1 + + def ParseFile(self, file): + # TODO: pseudo-buffering if a read without argument is not supported. + # document parse / parsefile usage. + return self.Parse(file.read(), isfinal=True) + + +XMLParserType = XMLParser + + +def _encode(arg, encoding): + if isinstance(arg, unicode): + return arg.encode(encoding) + else: + if isinstance(arg, dict): + iterator = arg.iteritems() + else: + iterator = iter(arg) + return type(arg)(_encode(_arg, encoding) for _arg in iterator) + + +def expat(callback=None, guard=True, force=False, returns=None): + def _expat(method): + name = method.__name__ + context = id(sys._getframe(1)) + key = name, context + append = _register.setdefault(key, []).append + append((method, callback, guard, force, returns)) + + def new_method(*args): + self = args[0] + parser = self.parser + self._update_location(event=name) # bug if multiple method def + for (method, callback, guard, force, returns) in _register[key]: + if guard not in (True, False): + guard = getattr(self, guard) + _callback = callback and guard and \ + getattr(parser, callback, None) + if _callback or force: + results = method(*args) + if _callback: + if not isinstance(results, tuple): + results = (results,) + if not parser.returns_unicode: + results = _encode(results, "utf-8") + _callback(*results) + return returns + + new_method.__name__ = name + #new_method.__doc__ = method.__doc__ # what to do with multiple docs ? + return new_method + return _expat + + +class XMLEventHandler(DefaultHandler2): + + def __init__(self, parser): + self.parser = parser + self._tags = {} + self.not_in_dtd = True + self._entity = {} + self._previous_event = None + + # --- Helpers ------------------------------------------------------------- + + def _intern(self, tag): + return self._tags.setdefault(tag, tag) + + def _qualify(self, local_name, qname, namespace=None): + namespace_separator = self.parser.namespace_separator + if namespace_separator is None: + return qname + if not namespace: + return local_name + else: + return namespace + namespace_separator + local_name + + def _char_slice_to_unicode(self, characters, start, length): + """Convert a char[] slice to a PyUnicode instance""" + text = Py.newUnicode(String(characters[start:start + length])) + return text + + def _expat_content_model(self, name, model_): + # TODO : implement a model parser + return (name, model_) # does not fit expat conventions + + def _update_location(self, event=None): + parser = self.parser + locator = self._locator + + # ugly hack that takes care of a xerces-specific (?) locator issue: + # locate start and end elements at the '<' instead of the first tag + # type character. + if event == "startElement" and self._previous_event == "characters": + parser._NextColumnNumber = max(parser._NextColumnNumber - 1, 0) + if event == "endElement" and self._previous_event == "characters": + parser._NextColumnNumber = max(parser._NextColumnNumber - 2, 0) + # TODO: use the same trick to report accurate error locations ? + + parser.CurrentLineNumber = parser._NextLineNumber + parser.CurrentColumnNumber = parser._NextColumnNumber + parser._NextLineNumber = locator.getLineNumber() + parser._NextColumnNumber = locator.getColumnNumber() - 1 + + self._previous_event = event + + # --- ContentHandler Interface -------------------------------------------- + + @expat("ProcessingInstructionHandler") + def processingInstruction(self, target, data): + return target, data + + @expat("StartElementHandler") + def startElement(self, namespace, local_name, qname, attributes): + tag = self._qualify(local_name, qname, namespace) + attribs = {} + length = attributes.getLength() + for index in range(length): + local_name = attributes.getLocalName(index) + qname = attributes.getQName(index) + namespace = attributes.getURI(index) + name = self._qualify(local_name, qname, namespace) + value = attributes.getValue(index) + attribs[name] = value + return self._intern(tag), attribs + + @expat("EndElementHandler") + def endElement(self, namespace, local_name, qname): + return self._intern(self._qualify(local_name, qname, namespace)) + + @expat("CharacterDataHandler") + def characters(self, characters, start, length): + return self._char_slice_to_unicode(characters, start, length) + + @expat("DefaultHandlerExpand") + def characters(self, characters, start, length): + return self._char_slice_to_unicode(characters, start, length) + + @expat("DefaultHandler") + def characters(self, characters, start, length): + # TODO: make a helper function here + if self._entity["location"] == (self.parser.CurrentLineNumber, + self.parser.CurrentColumnNumber): + return "&%s;" % self._entity["name"] + else: + return self._char_slice_to_unicode(characters, start, length) + + @expat("StartNamespaceDeclHandler") + def startPrefixMapping(self, prefix, uri): + return prefix, uri + + @expat("EndNamespaceDeclHandler") + def endPrefixMapping(self, prefix): + return prefix + + empty_source = InputSource(ByteArrayInputStream(array([], "b"))) + + @expat("ExternalEntityRefHandler", guard="not_in_dtd", + returns=empty_source) + def resolveEntity(self, name, publicId, baseURI, systemId): + context = name # wrong. see expat headers documentation. + base = self.parser.GetBase() + return context, base, systemId, publicId + + @expat("DefaultHandlerExpand", guard="not_in_dtd", + returns=empty_source) + def resolveEntity(self, name, publicId, baseURI, systemId): + return "&%s;" % name + + @expat("DefaultHandler", guard="not_in_dtd", + returns=empty_source) + def resolveEntity(self, name, publicId, baseURI, systemId): + return "&%s;" % name + + @expat(force=True, returns=empty_source) + def resolveEntity(self, name, publicId, baseURI, systemId): + pass + + def setDocumentLocator(self, locator): + self._locator = locator + + def skippedEntity(self, name): + error = ExpatError() + error.lineno = self.ErrorLineNumber = self.parser._NextLineNumber + error.offset = self.ErrorColumnNumber = self.parser._NextColumnNumber + error.code = self.ErrorCode = None + message = "undefined entity &%s;: line %s, column %s" + message = message % (name, error.lineno, error.offset) + error.__init__(message) + raise error + + # --- LexicalHandler Interface -------------------------------------------- + + @expat("CommentHandler") + def comment(self, characters, start, length): + return self._char_slice_to_unicode(characters, start, length) + + @expat("StartCdataSectionHandler") + def startCDATA(self): + return () + + @expat("EndCdataSectionHandler") + def endCDATA(self): + return () + + @expat("StartDoctypeDeclHandler", force=True) + def startDTD(self, name, publicId, systemId): + self.not_in_dtd = False + has_internal_subset = 0 # don't know this ... + return name, systemId, publicId, has_internal_subset + + @expat("EndDoctypeDeclHandler", force=True) + def endDTD(self): + self.not_in_dtd = True + + def startEntity(self, name): + self._entity = {} + self._entity["location"] = (self.parser._NextLineNumber, + self.parser._NextColumnNumber) + self._entity["name"] = name + + def endEntity(self, name): + pass + + # --- DTDHandler Interface ------------------------------------------------ + + @expat("NotationDeclHandler") + def notationDecl(self, name, publicId, systemId): + base = self.parser.GetBase() + return name, base, systemId, publicId + + @expat("UnparsedEntityDeclHandler") # deprecated + def unparsedEntityDecl(self, name, publicId, systemId, notationName): + base = self.parser.GetBase() + return name, base, systemId, publicId, notationName + + # --- DeclHandler Interface ----------------------------------------------- + + @expat("AttlistDeclHandler") + def attributeDecl(self, eName, aName, type, mode, value): + # TODO: adapt mode, required, etc. + required = False + return eName, aName, type, value, required + + @expat("ElementDeclHandler") + def elementDecl(self, name, model): + return self._expat_content_model(name, model) + + @expat("EntityDeclHandler") + def externalEntityDecl(self, name, publicId, systemId): + base = self.parser.GetBase() + value = None + is_parameter_entity = None + notation_name = None + return (name, is_parameter_entity, value, base, systemId, publicId, + notation_name) + + @expat("EntityDeclHandler") + def internalEntityDecl(self, name, value): + base = self.parser.GetBase() + is_parameter_entity = None + notation_name = None + systemId, publicId = None, None + return (name, is_parameter_entity, value, base, systemId, publicId, + notation_name) + + +def _init_model(): + global model + model = types.ModuleType("pyexpat.model") + model.__doc__ = "Constants used to interpret content model information." + quantifiers = "NONE, OPT, REP, PLUS" + for i, quantifier in enumerate(quantifiers.split(", ")): + setattr(model, "XML_CQUANT_" + quantifier, i) + types_ = "EMPTY, ANY, MIXED, NAME, CHOICE, SEQ" + for i, type_ in enumerate(types_.split(", ")): + setattr(model, "XML_CTYPE_" + type_, i+1) + +_init_model() +del _init_model + + +class ExpatError(Exception): + pass + + +error = ExpatError + + +def _init_error_strings(): + global ErrorString + error_strings = ( + None, + "out of memory", + "syntax error", + "no element found", + "not well-formed (invalid token)", + "unclosed token", + "partial character", + "mismatched tag", + "duplicate attribute", + "junk after document element", + "illegal parameter entity reference", + "undefined entity", + "recursive entity reference", + "asynchronous entity", + "reference to invalid character number", + "reference to binary entity", + "reference to external entity in attribute", + "XML or text declaration not at start of entity", + "unknown encoding", + "encoding specified in XML declaration is incorrect", + "unclosed CDATA section", + "error in processing external entity reference", + "document is not standalone", + "unexpected parser state - please send a bug report", + "entity declared in parameter entity", + "requested feature requires XML_DTD support in Expat", + "cannot change setting once parsing has begun", + "unbound prefix", + "must not undeclare prefix", + "incomplete markup in parameter entity", + "XML declaration not well-formed", + "text declaration not well-formed", + "illegal character(s) in public id", + "parser suspended", + "parser not suspended", + "parsing aborted", + "parsing finished", + "cannot suspend in external parameter entity") + def ErrorString(code): + try: + return error_strings[code] + except IndexError: + return None + +_init_error_strings() +del _init_error_strings + + +def _init_errors(): + global errors + + errors = types.ModuleType("pyexpat.errors") + errors.__doc__ = "Constants used to describe error conditions." + + error_names = """ + XML_ERROR_NONE + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + XML_ERROR_UNBOUND_PREFIX, + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE + """ + error_names = [name.strip() for name in error_names.split(',')] + for i, name in enumerate(error_names[1:]): + setattr(errors, name, ErrorString(i+1)) + +_init_errors() +del _init_errors diff --git a/src/main/resources/PythonLibs/xml/sax/__init__.py b/src/main/resources/PythonLibs/xml/sax/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0606990e031c9802c30ae857088063df3dc0ac7c --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/__init__.py @@ -0,0 +1,102 @@ +"""Simple API for XML (SAX) implementation for Python. + +This module provides an implementation of the SAX 2 interface; +information about the Java version of the interface can be found at +http://www.megginson.com/SAX/. The Python version of the interface is +documented at <...>. + +This package contains the following modules: + +handler -- Base classes and constants which define the SAX 2 API for + the 'client-side' of SAX for Python. + +saxutils -- Implementation of the convenience classes commonly used to + work with SAX. + +xmlreader -- Base classes and constants which define the SAX 2 API for + the parsers used with SAX for Python. + +drivers2 -- Contains the driver for that wraps a Java sax implementation in python + objects. +""" + +from xmlreader import InputSource +from handler import ContentHandler, ErrorHandler +from _exceptions import SAXException, SAXNotRecognizedException, \ + SAXParseException, SAXNotSupportedException, \ + SAXReaderNotAvailable + + +def parse(source, handler, errorHandler=ErrorHandler()): + parser = make_parser() + parser.setContentHandler(handler) + parser.setErrorHandler(errorHandler) + parser.parse(source) + +def parseString(string, handler, errorHandler=ErrorHandler()): + try: + from cStringIO import StringIO + except ImportError: + from StringIO import StringIO + + if errorHandler is None: + errorHandler = ErrorHandler() + parser = make_parser() + parser.setContentHandler(handler) + parser.setErrorHandler(errorHandler) + + inpsrc = InputSource() + inpsrc.setByteStream(StringIO(string)) + parser.parse(inpsrc) + +# this is the parser list used by the make_parser function if no +# alternatives are given as parameters to the function + +default_parser_list = ["xml.sax.drivers2.drv_javasax"] + +# tell modulefinder that importing sax potentially imports expatreader +_false = 0 +if _false: + import xml.sax.drivers2.drv_javasax + +import os, sys +if os.environ.has_key("PY_SAX_PARSER"): + default_parser_list = os.environ["PY_SAX_PARSER"].split(",") +del os + +_key = "python.xml.sax.parser" +if sys.platform[:4] == "java" and sys.registry.containsKey(_key): + default_parser_list = sys.registry.getProperty(_key).split(",") + + +def make_parser(parser_list = []): + """Creates and returns a SAX parser. + + Creates the first parser it is able to instantiate of the ones + given in the list created by doing parser_list + + default_parser_list. The lists must contain the names of Python + modules containing both a SAX parser and a create_parser function.""" + + for parser_name in parser_list + default_parser_list: + try: + return _create_parser(parser_name) + except ImportError,e: + import sys + if sys.modules.has_key(parser_name): + # The parser module was found, but importing it + # failed unexpectedly, pass this exception through + raise + except SAXReaderNotAvailable: + # The parser module detected that it won't work properly, + # so try the next one + pass + + raise SAXReaderNotAvailable("No parsers found", None) + +# --- Internal utility methods used by make_parser + +def _create_parser(parser_name): + drv_module = __import__(parser_name,{},{},['create_parser']) + return drv_module.create_parser() + +del sys diff --git a/src/main/resources/PythonLibs/xml/sax/_exceptions.py b/src/main/resources/PythonLibs/xml/sax/_exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..1d1cefead6ab94e8e02e7dd1e385f901629f584f --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/_exceptions.py @@ -0,0 +1,127 @@ +"""Different kinds of SAX Exceptions""" + +# ===== SAXEXCEPTION ===== + +class SAXException(Exception): + """Encapsulate an XML error or warning. This class can contain + basic error or warning information from either the XML parser or + the application: you can subclass it to provide additional + functionality, or to add localization. Note that although you will + receive a SAXException as the argument to the handlers in the + ErrorHandler interface, you are not actually required to throw + the exception; instead, you can simply read the information in + it.""" + + def __init__(self, msg, exception=None): + """Creates an exception. The message is required, but the exception + is optional.""" + self._msg = msg + self._exception = exception + Exception.__init__(self, msg) + + def getMessage(self): + "Return a message for this exception." + return self._msg + + def getException(self): + "Return the embedded exception, or None if there was none." + return self._exception + + def __str__(self): + "Create a string representation of the exception." + return self._msg + + def __getitem__(self, ix): + """Avoids weird error messages if someone does exception[ix] by + mistake, since Exception has __getitem__ defined.""" + raise AttributeError("__getitem__") + + +# ===== SAXPARSEEXCEPTION ===== + +class SAXParseException(SAXException): + """Encapsulate an XML parse error or warning. + + This exception will include information for locating the error in + the original XML document. Note that although the application will + receive a SAXParseException as the argument to the handlers in the + ErrorHandler interface, the application is not actually required + to throw the exception; instead, it can simply read the + information in it and take a different action. + + Since this exception is a subclass of SAXException, it inherits + the ability to wrap another exception.""" + + def __init__(self, msg, exception, locator): + "Creates the exception. The exception parameter is allowed to be None." + SAXException.__init__(self, msg, exception) + self._locator = locator + + # We need to cache this stuff at construction time. + # If this exception is thrown, the objects through which we must + # traverse to get this information may be deleted by the time + # it gets caught. + self._systemId = self._locator.getSystemId() + self._colnum = self._locator.getColumnNumber() + self._linenum = self._locator.getLineNumber() + + def getColumnNumber(self): + """The column number of the end of the text where the exception + occurred.""" + return self._colnum + + def getLineNumber(self): + "The line number of the end of the text where the exception occurred." + return self._linenum + + def getPublicId(self): + "Get the public identifier of the entity where the exception occurred." + return self._locator.getPublicId() + + def getSystemId(self): + "Get the system identifier of the entity where the exception occurred." + return self._systemId + + def __str__(self): + "Create a string representation of the exception." + sysid = self.getSystemId() + if sysid is None: + sysid = "<unknown>" + linenum = self.getLineNumber() + if linenum is None: + linenum = "?" + colnum = self.getColumnNumber() + if colnum is None: + colnum = "?" + return "%s:%s:%s: %s" % (sysid, linenum, colnum, self._msg) + + +# ===== SAXNOTRECOGNIZEDEXCEPTION ===== + +class SAXNotRecognizedException(SAXException): + """Exception class for an unrecognized identifier. + + An XMLReader will raise this exception when it is confronted with an + unrecognized feature or property. SAX applications and extensions may + use this class for similar purposes.""" + + +# ===== SAXNOTSUPPORTEDEXCEPTION ===== + +class SAXNotSupportedException(SAXException): + """Exception class for an unsupported operation. + + An XMLReader will raise this exception when a service it cannot + perform is requested (specifically setting a state or value). SAX + applications and extensions may use this class for similar + purposes.""" + +# ===== SAXNOTSUPPORTEDEXCEPTION ===== + +class SAXReaderNotAvailable(SAXNotSupportedException): + """Exception class for a missing driver. + + An XMLReader module (driver) should raise this exception when it + is first imported, e.g. when a support module cannot be imported. + It also may be raised during parsing, e.g. if executing an external + program is not permitted.""" diff --git a/src/main/resources/PythonLibs/xml/sax/drivers2/__init__.py b/src/main/resources/PythonLibs/xml/sax/drivers2/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..96a8f30ee0d3cab71389f7a4985c8a9f5aa1f5e0 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/drivers2/__init__.py @@ -0,0 +1 @@ +"Directory for SAX version 2 drivers." diff --git a/src/main/resources/PythonLibs/xml/sax/drivers2/drv_javasax.py b/src/main/resources/PythonLibs/xml/sax/drivers2/drv_javasax.py new file mode 100644 index 0000000000000000000000000000000000000000..ec85c6fffeb641ce092da3eac68fc05ec936b8d1 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/drivers2/drv_javasax.py @@ -0,0 +1,382 @@ +""" +SAX driver for the Java SAX parsers. Can only be used in Jython. + +$Id: drv_javasax.py,v 1.5 2003/01/26 09:08:51 loewis Exp $ +""" + +# --- Initialization + +version = "0.10" +revision = "$Revision: 1.5 $" + +import string +from xml.sax import xmlreader, saxutils +from xml.sax.handler import feature_namespaces, feature_namespace_prefixes +from xml.sax import _exceptions + +# we only work in jython +import sys +if sys.platform[:4] != "java": + raise _exceptions.SAXReaderNotAvailable("drv_javasax not available in CPython", None) +del sys + +# get the necessary Java SAX classes +try: + from org.python.core import FilelikeInputStream + from org.xml.sax.helpers import XMLReaderFactory + from org.xml import sax as javasax + from org.xml.sax.ext import LexicalHandler +except ImportError: + raise _exceptions.SAXReaderNotAvailable("SAX is not on the classpath", None) + +# get some JAXP stuff +try: + from javax.xml.parsers import SAXParserFactory, ParserConfigurationException + factory = SAXParserFactory.newInstance() + jaxp = 1 +except ImportError: + jaxp = 0 + +from java.lang import String + + +def _wrap_sax_exception(e): + return _exceptions.SAXParseException(e.message, + e.exception, + SimpleLocator(e.columnNumber, + e.lineNumber, + e.publicId, + e.systemId)) + +class JyErrorHandlerWrapper(javasax.ErrorHandler): + def __init__(self, err_handler): + self._err_handler = err_handler + + def error(self, exc): + self._err_handler.error(_wrap_sax_exception(exc)) + + def fatalError(self, exc): + self._err_handler.fatalError(_wrap_sax_exception(exc)) + + def warning(self, exc): + self._err_handler.warning(_wrap_sax_exception(exc)) + +class JyInputSourceWrapper(javasax.InputSource): + def __init__(self, source): + if isinstance(source, basestring): + javasax.InputSource.__init__(self, source) + elif hasattr(source, "read"):#file like object + f = source + javasax.InputSource.__init__(self, FilelikeInputStream(f)) + if hasattr(f, "name"): + self.setSystemId(f.name) + else:#xml.sax.xmlreader.InputSource object + #Use byte stream constructor if possible so that Xerces won't attempt to open + #the url at systemId unless it's really there + if source.getByteStream(): + javasax.InputSource.__init__(self, + FilelikeInputStream(source.getByteStream())) + else: + javasax.InputSource.__init__(self) + if source.getSystemId(): + self.setSystemId(source.getSystemId()) + self.setPublicId(source.getPublicId()) + self.setEncoding(source.getEncoding()) + +class JyEntityResolverWrapper(javasax.EntityResolver): + def __init__(self, entityResolver): + self._resolver = entityResolver + + def resolveEntity(self, pubId, sysId): + return JyInputSourceWrapper(self._resolver.resolveEntity(pubId, sysId)) + +class JyDTDHandlerWrapper(javasax.DTDHandler): + def __init__(self, dtdHandler): + self._handler = dtdHandler + + def notationDecl(self, name, publicId, systemId): + self._handler.notationDecl(name, publicId, systemId) + + def unparsedEntityDecl(self, name, publicId, systemId, notationName): + self._handler.unparsedEntityDecl(name, publicId, systemId, notationName) + +class SimpleLocator(xmlreader.Locator): + def __init__(self, colNum, lineNum, pubId, sysId): + self.colNum = colNum + self.lineNum = lineNum + self.pubId = pubId + self.sysId = sysId + + def getColumnNumber(self): + return self.colNum + + def getLineNumber(self): + return self.lineNum + + def getPublicId(self): + return self.pubId + + def getSystemId(self): + return self.sysId + +# --- JavaSAXParser +class JavaSAXParser(xmlreader.XMLReader, javasax.ContentHandler, LexicalHandler): + "SAX driver for the Java SAX parsers." + + def __init__(self, jdriver = None): + xmlreader.XMLReader.__init__(self) + self._parser = create_java_parser(jdriver) + self._parser.setFeature(feature_namespaces, 0) + self._parser.setFeature(feature_namespace_prefixes, 0) + self._parser.setContentHandler(self) + self._nsattrs = AttributesNSImpl() + self._attrs = AttributesImpl() + self.setEntityResolver(self.getEntityResolver()) + self.setErrorHandler(self.getErrorHandler()) + self.setDTDHandler(self.getDTDHandler()) + try: + self._parser.setProperty("http://xml.org/sax/properties/lexical-handler", self) + except Exception, x: + pass + + # XMLReader methods + + def parse(self, source): + "Parse an XML document from a URL or an InputSource." + self._parser.parse(JyInputSourceWrapper(source)) + + def getFeature(self, name): + return self._parser.getFeature(name) + + def setFeature(self, name, state): + self._parser.setFeature(name, state) + + def getProperty(self, name): + return self._parser.getProperty(name) + + def setProperty(self, name, value): + self._parser.setProperty(name, value) + + def setEntityResolver(self, resolver): + self._parser.entityResolver = JyEntityResolverWrapper(resolver) + xmlreader.XMLReader.setEntityResolver(self, resolver) + + def setErrorHandler(self, err_handler): + self._parser.errorHandler = JyErrorHandlerWrapper(err_handler) + xmlreader.XMLReader.setErrorHandler(self, err_handler) + + def setDTDHandler(self, dtd_handler): + self._parser.setDTDHandler(JyDTDHandlerWrapper(dtd_handler)) + xmlreader.XMLReader.setDTDHandler(self, dtd_handler) + + # ContentHandler methods + def setDocumentLocator(self, locator): + self._cont_handler.setDocumentLocator(locator) + + def startDocument(self): + self._cont_handler.startDocument() + self._namespaces = self._parser.getFeature(feature_namespaces) + + def startElement(self, uri, lname, qname, attrs): + if self._namespaces: + self._nsattrs._attrs = attrs + self._cont_handler.startElementNS((uri or None, lname), qname, + self._nsattrs) + else: + self._attrs._attrs = attrs + self._cont_handler.startElement(qname, self._attrs) + + def startPrefixMapping(self, prefix, uri): + self._cont_handler.startPrefixMapping(prefix, uri) + + def characters(self, char, start, len): + self._cont_handler.characters(unicode(String(char, start, len))) + + def ignorableWhitespace(self, char, start, len): + self._cont_handler.ignorableWhitespace(unicode(String(char, start, + len))) + + def endElement(self, uri, lname, qname): + if self._namespaces: + self._cont_handler.endElementNS((uri or None, lname), qname) + else: + self._cont_handler.endElement(qname) + + def endPrefixMapping(self, prefix): + self._cont_handler.endPrefixMapping(prefix) + + def endDocument(self): + self._cont_handler.endDocument() + + def processingInstruction(self, target, data): + self._cont_handler.processingInstruction(target, data) + + # Lexical handler methods + def comment(self, char, start, len): + try: + # Need to wrap this in a try..except in case the parser does not support lexical events + self._cont_handler.comment(unicode(String(char, start, len))) + except: + pass + + def startCDATA(self): + pass # TODO + + def endCDATA(self): + pass # TODO + + def startDTD(self, name, publicId, systemId): + pass # TODO + + def endDTD(self): + pass # TODO + + def startEntity(self, name): + pass # TODO + + def endEntity(self, name): + pass # TODO + +def _fixTuple(nsTuple, frm, to): + if isinstance(nsTuple, tuple) and len(nsTuple) == 2: + nsUri, localName = nsTuple + if nsUri == frm: + nsUri = to + return (nsUri, localName) + return nsTuple + +def _makeJavaNsTuple(nsTuple): + return _fixTuple(nsTuple, None, '') + +def _makePythonNsTuple(nsTuple): + return _fixTuple(nsTuple, '', None) + +class AttributesImpl: + + def __init__(self, attrs = None): + self._attrs = attrs + + def getLength(self): + return self._attrs.getLength() + + def getType(self, name): + return self._attrs.getType(_makeJavaNsTuple(name)) + + def getValue(self, name): + value = self._attrs.getValue(_makeJavaNsTuple(name)) + if value == None: + raise KeyError(name) + return value + + def getNames(self): + return [_makePythonNsTuple(self._attrs.getQName(index)) for index in range(len(self))] + + def getQNames(self): + return [self._attrs.getQName(index) for index in range(len(self))] + + def getValueByQName(self, qname): + idx = self._attrs.getIndex(qname) + if idx == -1: + raise KeyError, qname + return self._attrs.getValue(idx) + + def getNameByQName(self, qname): + idx = self._attrs.getIndex(qname) + if idx == -1: + raise KeyError, qname + return qname + + def getQNameByName(self, name): + idx = self._attrs.getIndex(_makeJavaNsTuple(name)) + if idx == -1: + raise KeyError, name + return name + + def __len__(self): + return self._attrs.getLength() + + def __getitem__(self, name): + return self.getValue(name) + + def keys(self): + return self.getNames() + + def copy(self): + return self.__class__(self._attrs) + + def items(self): + return [(name, self[name]) for name in self.getNames()] + + def values(self): + return map(self.getValue, self.getNames()) + + def get(self, name, alt=None): + try: + return self.getValue(name) + except KeyError: + return alt + + def has_key(self, name): + try: + self.getValue(name) + return True + except KeyError: + return False + +# --- AttributesNSImpl + +class AttributesNSImpl(AttributesImpl): + + def __init__(self, attrs=None): + AttributesImpl.__init__(self, attrs) + + def getType(self, name): + name = _makeJavaNsTuple(name) + return self._attrs.getType(name[0], name[1]) + + def getValue(self, name): + jname = _makeJavaNsTuple(name) + value = self._attrs.getValue(jname[0], jname[1]) + if value == None: + raise KeyError(name) + return value + + def getNames(self): + names = [] + for idx in range(len(self)): + names.append(_makePythonNsTuple( (self._attrs.getURI(idx), self._attrs.getLocalName(idx)) )) + return names + + def getNameByQName(self, qname): + idx = self._attrs.getIndex(qname) + if idx == -1: + raise KeyError, qname + return _makePythonNsTuple( (self._attrs.getURI(idx), self._attrs.getLocalName(idx)) ) + + def getQNameByName(self, name): + name = _makeJavaNsTuple(name) + idx = self._attrs.getIndex(name[0], name[1]) + if idx == -1: + raise KeyError, name + return self._attrs.getQName(idx) + + def getQNames(self): + return [self._attrs.getQName(idx) for idx in range(len(self))] + +# --- + +def create_java_parser(jdriver = None): + try: + if jdriver: + return XMLReaderFactory.createXMLReader(jdriver) + elif jaxp: + return factory.newSAXParser().getXMLReader() + else: + return XMLReaderFactory.createXMLReader() + except ParserConfigurationException, e: + raise _exceptions.SAXReaderNotAvailable(e.getMessage()) + except javasax.SAXException, e: + raise _exceptions.SAXReaderNotAvailable(e.getMessage()) + +def create_parser(jdriver = None): + return JavaSAXParser(jdriver) diff --git a/src/main/resources/PythonLibs/xml/sax/handler.py b/src/main/resources/PythonLibs/xml/sax/handler.py new file mode 100644 index 0000000000000000000000000000000000000000..aff66e695535fd14a91360e65e01144789fe0bc3 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/handler.py @@ -0,0 +1,345 @@ +""" +This module contains the core classes of version 2.0 of SAX for Python. +This file provides only default classes with absolutely minimum +functionality, from which drivers and applications can be subclassed. + +Many of these classes are empty and are included only as documentation +of the interfaces. + +$Id: handler.py,v 1.5 2002/02/14 08:09:36 loewis Exp $ +""" + +version = '2.0beta' + +#============================================================================ +# +# HANDLER INTERFACES +# +#============================================================================ + +# ===== ERRORHANDLER ===== + +class ErrorHandler: + """Basic interface for SAX error handlers. + + If you create an object that implements this interface, then + register the object with your XMLReader, the parser will call the + methods in your object to report all warnings and errors. There + are three levels of errors available: warnings, (possibly) + recoverable errors, and unrecoverable errors. All methods take a + SAXParseException as the only parameter.""" + + def error(self, exception): + "Handle a recoverable error." + raise exception + + def fatalError(self, exception): + "Handle a non-recoverable error." + raise exception + + def warning(self, exception): + "Handle a warning." + print exception + + +# ===== CONTENTHANDLER ===== + +class ContentHandler: + """Interface for receiving logical document content events. + + This is the main callback interface in SAX, and the one most + important to applications. The order of events in this interface + mirrors the order of the information in the document.""" + + def __init__(self): + self._locator = None + + def setDocumentLocator(self, locator): + """Called by the parser to give the application a locator for + locating the origin of document events. + + SAX parsers are strongly encouraged (though not absolutely + required) to supply a locator: if it does so, it must supply + the locator to the application by invoking this method before + invoking any of the other methods in the DocumentHandler + interface. + + The locator allows the application to determine the end + position of any document-related event, even if the parser is + not reporting an error. Typically, the application will use + this information for reporting its own errors (such as + character content that does not match an application's + business rules). The information returned by the locator is + probably not sufficient for use with a search engine. + + Note that the locator will return correct information only + during the invocation of the events in this interface. The + application should not attempt to use it at any other time.""" + self._locator = locator + + def startDocument(self): + """Receive notification of the beginning of a document. + + The SAX parser will invoke this method only once, before any + other methods in this interface or in DTDHandler (except for + setDocumentLocator).""" + + def endDocument(self): + """Receive notification of the end of a document. + + The SAX parser will invoke this method only once, and it will + be the last method invoked during the parse. The parser shall + not invoke this method until it has either abandoned parsing + (because of an unrecoverable error) or reached the end of + input.""" + + def startPrefixMapping(self, prefix, uri): + """Begin the scope of a prefix-URI Namespace mapping. + + The information from this event is not necessary for normal + Namespace processing: the SAX XML reader will automatically + replace prefixes for element and attribute names when the + http://xml.org/sax/features/namespaces feature is true (the + default). + + There are cases, however, when applications need to use + prefixes in character data or in attribute values, where they + cannot safely be expanded automatically; the + start/endPrefixMapping event supplies the information to the + application to expand prefixes in those contexts itself, if + necessary. + + Note that start/endPrefixMapping events are not guaranteed to + be properly nested relative to each-other: all + startPrefixMapping events will occur before the corresponding + startElement event, and all endPrefixMapping events will occur + after the corresponding endElement event, but their order is + not guaranteed.""" + + def endPrefixMapping(self, prefix): + """End the scope of a prefix-URI mapping. + + See startPrefixMapping for details. This event will always + occur after the corresponding endElement event, but the order + of endPrefixMapping events is not otherwise guaranteed.""" + + def startElement(self, name, attrs): + """Signals the start of an element in non-namespace mode. + + The name parameter contains the raw XML 1.0 name of the + element type as a string and the attrs parameter holds an + instance of the Attributes class containing the attributes of + the element.""" + + def endElement(self, name): + """Signals the end of an element in non-namespace mode. + + The name parameter contains the name of the element type, just + as with the startElement event.""" + + def startElementNS(self, name, qname, attrs): + """Signals the start of an element in namespace mode. + + The name parameter contains the name of the element type as a + (uri, localname) tuple, the qname parameter the raw XML 1.0 + name used in the source document, and the attrs parameter + holds an instance of the Attributes class containing the + attributes of the element. + + The uri part of the name tuple is None for elements which have + no namespace.""" + + def endElementNS(self, name, qname): + """Signals the end of an element in namespace mode. + + The name parameter contains the name of the element type, just + as with the startElementNS event.""" + + def characters(self, content): + """Receive notification of character data. + + The Parser will call this method to report each chunk of + character data. SAX parsers may return all contiguous + character data in a single chunk, or they may split it into + several chunks; however, all of the characters in any single + event must come from the same external entity so that the + Locator provides useful information.""" + + def ignorableWhitespace(self, whitespace): + """Receive notification of ignorable whitespace in element content. + + Validating Parsers must use this method to report each chunk + of ignorable whitespace (see the W3C XML 1.0 recommendation, + section 2.10): non-validating parsers may also use this method + if they are capable of parsing and using content models. + + SAX parsers may return all contiguous whitespace in a single + chunk, or they may split it into several chunks; however, all + of the characters in any single event must come from the same + external entity, so that the Locator provides useful + information. + + The application must not attempt to read from the array + outside of the specified range.""" + + def processingInstruction(self, target, data): + """Receive notification of a processing instruction. + + The Parser will invoke this method once for each processing + instruction found: note that processing instructions may occur + before or after the main document element. + + A SAX parser should never report an XML declaration (XML 1.0, + section 2.8) or a text declaration (XML 1.0, section 4.3.1) + using this method.""" + + def skippedEntity(self, name): + """Receive notification of a skipped entity. + + The Parser will invoke this method once for each entity + skipped. Non-validating processors may skip entities if they + have not seen the declarations (because, for example, the + entity was declared in an external DTD subset). All processors + may skip external entities, depending on the values of the + http://xml.org/sax/features/external-general-entities and the + http://xml.org/sax/features/external-parameter-entities + properties.""" + + +# ===== DTDHandler ===== + +class DTDHandler: + """Handle DTD events. + + This interface specifies only those DTD events required for basic + parsing (unparsed entities and attributes).""" + + def notationDecl(self, name, publicId, systemId): + "Handle a notation declaration event." + + def unparsedEntityDecl(self, name, publicId, systemId, ndata): + "Handle an unparsed entity declaration event." + + +# ===== ENTITYRESOLVER ===== + +class EntityResolver: + """Basic interface for resolving entities. If you create an object + implementing this interface, then register the object with your + Parser, the parser will call the method in your object to + resolve all external entities. Note that DefaultHandler implements + this interface with the default behaviour.""" + + def resolveEntity(self, publicId, systemId): + """Resolve the system identifier of an entity and return either + the system identifier to read from as a string, or an InputSource + to read from.""" + return systemId + + +#============================================================================ +# +# CORE FEATURES +# +#============================================================================ + +feature_namespaces = "http://xml.org/sax/features/namespaces" +# true: Perform Namespace processing (default). +# false: Optionally do not perform Namespace processing +# (implies namespace-prefixes). +# access: (parsing) read-only; (not parsing) read/write + +feature_namespace_prefixes = "http://xml.org/sax/features/namespace-prefixes" +# true: Report the original prefixed names and attributes used for Namespace +# declarations. +# false: Do not report attributes used for Namespace declarations, and +# optionally do not report original prefixed names (default). +# access: (parsing) read-only; (not parsing) read/write + +feature_string_interning = "http://xml.org/sax/features/string-interning" +# true: All element names, prefixes, attribute names, Namespace URIs, and +# local names are interned using the built-in intern function. +# false: Names are not necessarily interned, although they may be (default). +# access: (parsing) read-only; (not parsing) read/write + +feature_validation = "http://xml.org/sax/features/validation" +# true: Report all validation errors (implies external-general-entities and +# external-parameter-entities). +# false: Do not report validation errors. +# access: (parsing) read-only; (not parsing) read/write + +feature_external_ges = "http://xml.org/sax/features/external-general-entities" +# true: Include all external general (text) entities. +# false: Do not include external general entities. +# access: (parsing) read-only; (not parsing) read/write + +feature_external_pes = "http://xml.org/sax/features/external-parameter-entities" +# true: Include all external parameter entities, including the external +# DTD subset. +# false: Do not include any external parameter entities, even the external +# DTD subset. +# access: (parsing) read-only; (not parsing) read/write + +all_features = [feature_namespaces, + feature_namespace_prefixes, + feature_string_interning, + feature_validation, + feature_external_ges, + feature_external_pes] + + +#============================================================================ +# +# CORE PROPERTIES +# +#============================================================================ + +property_lexical_handler = "http://xml.org/sax/properties/lexical-handler" +# data type: xml.sax.sax2lib.LexicalHandler +# description: An optional extension handler for lexical events like comments. +# access: read/write + +property_declaration_handler = "http://xml.org/sax/properties/declaration-handler" +# data type: xml.sax.sax2lib.DeclHandler +# description: An optional extension handler for DTD-related events other +# than notations and unparsed entities. +# access: read/write + +property_dom_node = "http://xml.org/sax/properties/dom-node" +# data type: org.w3c.dom.Node +# description: When parsing, the current DOM node being visited if this is +# a DOM iterator; when not parsing, the root DOM node for +# iteration. +# access: (parsing) read-only; (not parsing) read/write + +property_xml_string = "http://xml.org/sax/properties/xml-string" +# data type: String +# description: The literal string of characters that was the source for +# the current event. +# access: read-only + +property_encoding = "http://www.python.org/sax/properties/encoding" +# data type: String +# description: The name of the encoding to assume for input data. +# access: write: set the encoding, e.g. established by a higher-level +# protocol. May change during parsing (e.g. after +# processing a META tag) +# read: return the current encoding (possibly established through +# auto-detection. +# initial value: UTF-8 +# + +property_interning_dict = "http://www.python.org/sax/properties/interning-dict" +# data type: Dictionary +# description: The dictionary used to intern common strings in the document +# access: write: Request that the parser uses a specific dictionary, to +# allow interning across different documents +# read: return the current interning dictionary, or None +# + +all_properties = [property_lexical_handler, + property_dom_node, + property_declaration_handler, + property_xml_string, + property_encoding, + property_interning_dict] diff --git a/src/main/resources/PythonLibs/xml/sax/saxlib.py b/src/main/resources/PythonLibs/xml/sax/saxlib.py new file mode 100644 index 0000000000000000000000000000000000000000..64603799d0ba1ed9f8e195043113dabd6066972b --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/saxlib.py @@ -0,0 +1,430 @@ +""" +This module contains the core classes of version 2.0 of SAX for Python. +This file provides only default classes with absolutely minimum +functionality, from which drivers and applications can be subclassed. + +Many of these classes are empty and are included only as documentation +of the interfaces. + +$Id: saxlib.py,v 1.12 2002/05/10 14:49:21 akuchling Exp $ +""" + +version = '2.0beta' + +# A number of interfaces used to live in saxlib, but are now in +# various other modules for Python 2 compatibility. If nobody uses +# them here any longer, the references can be removed + +from handler import ErrorHandler, ContentHandler, DTDHandler, EntityResolver +from xmlreader import XMLReader, InputSource, Locator, IncrementalParser +from _exceptions import * + +from handler import \ + feature_namespaces,\ + feature_namespace_prefixes,\ + feature_string_interning,\ + feature_validation,\ + feature_external_ges,\ + feature_external_pes,\ + all_features,\ + property_lexical_handler,\ + property_declaration_handler,\ + property_dom_node,\ + property_xml_string,\ + all_properties + +#============================================================================ +# +# MAIN INTERFACES +# +#============================================================================ + +# ===== XMLFILTER ===== + +class XMLFilter(XMLReader): + """Interface for a SAX2 parser filter. + + A parser filter is an XMLReader that gets its events from another + XMLReader (which may in turn also be a filter) rather than from a + primary source like a document or other non-SAX data source. + Filters can modify a stream of events before passing it on to its + handlers.""" + + def __init__(self, parent = None): + """Creates a filter instance, allowing applications to set the + parent on instantiation.""" + XMLReader.__init__(self) + self._parent = parent + + def setParent(self, parent): + """Sets the parent XMLReader of this filter. The argument may + not be None.""" + self._parent = parent + + def getParent(self): + "Returns the parent of this filter." + return self._parent + +# ===== ATTRIBUTES ===== + +class Attributes: + """Interface for a list of XML attributes. + + Contains a list of XML attributes, accessible by name.""" + + def getLength(self): + "Returns the number of attributes in the list." + raise NotImplementedError("This method must be implemented!") + + def getType(self, name): + "Returns the type of the attribute with the given name." + raise NotImplementedError("This method must be implemented!") + + def getValue(self, name): + "Returns the value of the attribute with the given name." + raise NotImplementedError("This method must be implemented!") + + def getValueByQName(self, name): + """Returns the value of the attribute with the given raw (or + qualified) name.""" + raise NotImplementedError("This method must be implemented!") + + def getNameByQName(self, name): + """Returns the namespace name of the attribute with the given + raw (or qualified) name.""" + raise NotImplementedError("This method must be implemented!") + + def getNames(self): + """Returns a list of the names of all attributes + in the list.""" + raise NotImplementedError("This method must be implemented!") + + def getQNames(self): + """Returns a list of the raw qualified names of all attributes + in the list.""" + raise NotImplementedError("This method must be implemented!") + + def __len__(self): + "Alias for getLength." + raise NotImplementedError("This method must be implemented!") + + def __getitem__(self, name): + "Alias for getValue." + raise NotImplementedError("This method must be implemented!") + + def keys(self): + "Returns a list of the attribute names in the list." + raise NotImplementedError("This method must be implemented!") + + def has_key(self, name): + "True if the attribute is in the list, false otherwise." + raise NotImplementedError("This method must be implemented!") + + def get(self, name, alternative=None): + """Return the value associated with attribute name; if it is not + available, then return the alternative.""" + raise NotImplementedError("This method must be implemented!") + + def copy(self): + "Return a copy of the Attributes object." + raise NotImplementedError("This method must be implemented!") + + def items(self): + "Return a list of (attribute_name, value) pairs." + raise NotImplementedError("This method must be implemented!") + + def values(self): + "Return a list of all attribute values." + raise NotImplementedError("This method must be implemented!") + + +#============================================================================ +# +# HANDLER INTERFACES +# +#============================================================================ + + +# ===== DECLHANDLER ===== + +class DeclHandler: + """Optional SAX2 handler for DTD declaration events. + + Note that some DTD declarations are already reported through the + DTDHandler interface. All events reported to this handler will + occur between the startDTD and endDTD events of the + LexicalHandler. + + To set the DeclHandler for an XMLReader, use the setProperty method + with the identifier http://xml.org/sax/handlers/DeclHandler.""" + + def attributeDecl(self, elem_name, attr_name, type, value_def, value): + """Report an attribute type declaration. + + Only the first declaration will be reported. The type will be + one of the strings "CDATA", "ID", "IDREF", "IDREFS", + "NMTOKEN", "NMTOKENS", "ENTITY", "ENTITIES", or "NOTATION", or + a list of names (in the case of enumerated definitions). + + elem_name is the element type name, attr_name the attribute + type name, type a string representing the attribute type, + value_def a string representing the default declaration + ('#IMPLIED', '#REQUIRED', '#FIXED' or None). value is a string + representing the attribute's default value, or None if there + is none.""" + + def elementDecl(self, elem_name, content_model): + """Report an element type declaration. + + Only the first declaration will be reported. + + content_model is the string 'EMPTY', the string 'ANY' or the content + model structure represented as tuple (separator, tokens, modifier) + where separator is the separator in the token list (that is, '|' or + ','), tokens is the list of tokens (element type names or tuples + representing parentheses) and modifier is the quantity modifier + ('*', '?' or '+').""" + + def internalEntityDecl(self, name, value): + """Report an internal entity declaration. + + Only the first declaration of an entity will be reported. + + name is the name of the entity. If it is a parameter entity, + the name will begin with '%'. value is the replacement text of + the entity.""" + + def externalEntityDecl(self, name, public_id, system_id): + """Report a parsed entity declaration. (Unparsed entities are + reported to the DTDHandler.) + + Only the first declaration for each entity will be reported. + + name is the name of the entity. If it is a parameter entity, + the name will begin with '%'. public_id and system_id are the + public and system identifiers of the entity. public_id will be + None if none were declared.""" + + + +# ===== LEXICALHANDLER ===== + +class LexicalHandler: + """Optional SAX2 handler for lexical events. + + This handler is used to obtain lexical information about an XML + document, that is, information about how the document was encoded + (as opposed to what it contains, which is reported to the + ContentHandler), such as comments and CDATA marked section + boundaries. + + To set the LexicalHandler of an XMLReader, use the setProperty + method with the property identifier + 'http://xml.org/sax/handlers/LexicalHandler'. There is no + guarantee that the XMLReader will support or recognize this + property.""" + + def comment(self, content): + """Reports a comment anywhere in the document (including the + DTD and outside the document element). + + content is a string that holds the contents of the comment.""" + + def startDTD(self, name, public_id, system_id): + """Report the start of the DTD declarations, if the document + has an associated DTD. + + A startEntity event will be reported before declaration events + from the external DTD subset are reported, and this can be + used to infer from which subset DTD declarations derive. + + name is the name of the document element type, public_id the + public identifier of the DTD (or None if none were supplied) + and system_id the system identfier of the external subset (or + None if none were supplied).""" + + def endDTD(self): + "Signals the end of DTD declarations." + + def startEntity(self, name): + """Report the beginning of an entity. + + The start and end of the document entity is not reported. The + start and end of the external DTD subset is reported with the + pseudo-name '[dtd]'. + + Skipped entities will be reported through the skippedEntity + event of the ContentHandler rather than through this event. + + name is the name of the entity. If it is a parameter entity, + the name will begin with '%'.""" + + def endEntity(self, name): + """Reports the end of an entity. name is the name of the + entity, and follows the same conventions as for + startEntity.""" + + def startCDATA(self): + """Reports the beginning of a CDATA marked section. + + The contents of the CDATA marked section will be reported + through the characters event.""" + + def endCDATA(self): + "Reports the end of a CDATA marked section." + + +#============================================================================ +# +# SAX 1.0 COMPATIBILITY CLASSES +# Note that these are all deprecated. +# +#============================================================================ + +# ===== ATTRIBUTELIST ===== + +class AttributeList: + """Interface for an attribute list. This interface provides + information about a list of attributes for an element (only + specified or defaulted attributes will be reported). Note that the + information returned by this object will be valid only during the + scope of the DocumentHandler.startElement callback, and the + attributes will not necessarily be provided in the order declared + or specified.""" + + def getLength(self): + "Return the number of attributes in list." + + def getName(self, i): + "Return the name of an attribute in the list." + + def getType(self, i): + """Return the type of an attribute in the list. (Parameter can be + either integer index or attribute name.)""" + + def getValue(self, i): + """Return the value of an attribute in the list. (Parameter can be + either integer index or attribute name.)""" + + def __len__(self): + "Alias for getLength." + + def __getitem__(self, key): + "Alias for getName (if key is an integer) and getValue (if string)." + + def keys(self): + "Returns a list of the attribute names." + + def has_key(self, key): + "True if the attribute is in the list, false otherwise." + + def get(self, key, alternative=None): + """Return the value associated with attribute name; if it is not + available, then return the alternative.""" + + def copy(self): + "Return a copy of the AttributeList." + + def items(self): + "Return a list of (attribute_name,value) pairs." + + def values(self): + "Return a list of all attribute values." + + +# ===== DOCUMENTHANDLER ===== + +class DocumentHandler: + """Handle general document events. This is the main client + interface for SAX: it contains callbacks for the most important + document events, such as the start and end of elements. You need + to create an object that implements this interface, and then + register it with the Parser. If you do not want to implement + the entire interface, you can derive a class from HandlerBase, + which implements the default functionality. You can find the + location of any document event using the Locator interface + supplied by setDocumentLocator().""" + + def characters(self, ch, start, length): + "Handle a character data event." + + def endDocument(self): + "Handle an event for the end of a document." + + def endElement(self, name): + "Handle an event for the end of an element." + + def ignorableWhitespace(self, ch, start, length): + "Handle an event for ignorable whitespace in element content." + + def processingInstruction(self, target, data): + "Handle a processing instruction event." + + def setDocumentLocator(self, locator): + "Receive an object for locating the origin of SAX document events." + + def startDocument(self): + "Handle an event for the beginning of a document." + + def startElement(self, name, atts): + "Handle an event for the beginning of an element." + + +# ===== HANDLERBASE ===== + +class HandlerBase(EntityResolver, DTDHandler, DocumentHandler,\ + ErrorHandler): + """Default base class for handlers. This class implements the + default behaviour for four SAX interfaces: EntityResolver, + DTDHandler, DocumentHandler, and ErrorHandler: rather + than implementing those full interfaces, you may simply extend + this class and override the methods that you need. Note that the + use of this class is optional (you are free to implement the + interfaces directly if you wish).""" + + +# ===== PARSER ===== + +class Parser: + """Basic interface for SAX (Simple API for XML) parsers. All SAX + parsers must implement this basic interface: it allows users to + register handlers for different types of events and to initiate a + parse from a URI, a character stream, or a byte stream. SAX + parsers should also implement a zero-argument constructor.""" + + def __init__(self): + self.doc_handler = DocumentHandler() + self.dtd_handler = DTDHandler() + self.ent_handler = EntityResolver() + self.err_handler = ErrorHandler() + + def parse(self, systemId): + "Parse an XML document from a system identifier." + + def parseFile(self, fileobj): + "Parse an XML document from a file-like object." + + def setDocumentHandler(self, handler): + "Register an object to receive basic document-related events." + self.doc_handler=handler + + def setDTDHandler(self, handler): + "Register an object to receive basic DTD-related events." + self.dtd_handler=handler + + def setEntityResolver(self, resolver): + "Register an object to resolve external entities." + self.ent_handler=resolver + + def setErrorHandler(self, handler): + "Register an object to receive error-message events." + self.err_handler=handler + + def setLocale(self, locale): + """Allow an application to set the locale for errors and warnings. + + SAX parsers are not required to provide localisation for errors + and warnings; if they cannot support the requested locale, + however, they must throw a SAX exception. Applications may + request a locale change in the middle of a parse.""" + raise SAXNotSupportedException("Locale support not implemented") diff --git a/src/main/resources/PythonLibs/xml/sax/saxutils.py b/src/main/resources/PythonLibs/xml/sax/saxutils.py new file mode 100644 index 0000000000000000000000000000000000000000..8d4ad9e90ae75ce77b98f2a6dc1f61eeea422fd5 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/saxutils.py @@ -0,0 +1,813 @@ +""" +A library of useful helper classes to the saxlib classes, for the +convenience of application and driver writers. + +$Id: saxutils.py,v 1.37 2005/04/13 14:02:08 syt Exp $ +""" +import os, urlparse, urllib2, types +import handler +import xmlreader +import sys, _exceptions, saxlib + +from xml.Uri import Absolutize, MakeUrllibSafe,IsAbsolute + +try: + _StringTypes = [types.StringType, types.UnicodeType] +except AttributeError: # 1.5 compatibility:UnicodeType not defined + _StringTypes = [types.StringType] + +def __dict_replace(s, d): + """Replace substrings of a string using a dictionary.""" + for key, value in d.items(): + s = s.replace(key, value) + return s + +def escape(data, entities={}): + """Escape &, <, and > in a string of data. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + data = data.replace("&", "&") + data = data.replace("<", "<") + data = data.replace(">", ">") + if entities: + data = __dict_replace(data, entities) + return data + +def unescape(data, entities={}): + """Unescape &, <, and > in a string of data. + + You can unescape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + data = data.replace("<", "<") + data = data.replace(">", ">") + if entities: + data = __dict_replace(data, entities) + # must do ampersand last + return data.replace("&", "&") + +def quoteattr(data, entities={}): + """Escape and quote an attribute value. + + Escape &, <, and > in a string of data, then quote it for use as + an attribute value. The \" character will be escaped as well, if + necessary. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + data = escape(data, entities) + if '"' in data: + if "'" in data: + data = '"%s"' % data.replace('"', """) + else: + data = "'%s'" % data + else: + data = '"%s"' % data + return data + +# --- DefaultHandler + +class DefaultHandler(handler.EntityResolver, handler.DTDHandler, + handler.ContentHandler, handler.ErrorHandler): + """Default base class for SAX2 event handlers. Implements empty + methods for all callback methods, which can be overridden by + application implementors. Replaces the deprecated SAX1 HandlerBase + class.""" + +# --- Location + +class Location: + """Represents a location in an XML entity. Initialized by being passed + a locator, from which it reads off the current location, which is then + stored internally.""" + + def __init__(self, locator): + self.__col = locator.getColumnNumber() + self.__line = locator.getLineNumber() + self.__pubid = locator.getPublicId() + self.__sysid = locator.getSystemId() + + def getColumnNumber(self): + return self.__col + + def getLineNumber(self): + return self.__line + + def getPublicId(self): + return self.__pubid + + def getSystemId(self): + return self.__sysid + + def __str__(self): + if self.__line is None: + line = "?" + else: + line = self.__line + if self.__col is None: + col = "?" + else: + col = self.__col + return "%s:%s:%s" % ( + self.__sysid or self.__pubid or "<unknown>", + line, col) + +# --- ErrorPrinter + +class ErrorPrinter: + "A simple class that just prints error messages to standard out." + + def __init__(self, level=0, outfile=sys.stderr): + self._level = level + self._outfile = outfile + + def warning(self, exception): + if self._level <= 0: + self._outfile.write("WARNING in %s: %s\n" % + (self.__getpos(exception), + exception.getMessage())) + + def error(self, exception): + if self._level <= 1: + self._outfile.write("ERROR in %s: %s\n" % + (self.__getpos(exception), + exception.getMessage())) + + def fatalError(self, exception): + if self._level <= 2: + self._outfile.write("FATAL ERROR in %s: %s\n" % + (self.__getpos(exception), + exception.getMessage())) + + def __getpos(self, exception): + if isinstance(exception, _exceptions.SAXParseException): + return "%s:%s:%s" % (exception.getSystemId(), + exception.getLineNumber(), + exception.getColumnNumber()) + else: + return "<unknown>" + +# --- ErrorRaiser + +class ErrorRaiser: + "A simple class that just raises the exceptions it is passed." + + def __init__(self, level = 0): + self._level = level + + def error(self, exception): + if self._level <= 1: + raise exception + + def fatalError(self, exception): + if self._level <= 2: + raise exception + + def warning(self, exception): + if self._level <= 0: + raise exception + +# --- AttributesImpl now lives in xmlreader +from xmlreader import AttributesImpl + +# --- XMLGenerator is the SAX2 ContentHandler for writing back XML +import codecs + +def _outputwrapper(stream,encoding): + writerclass = codecs.lookup(encoding)[3] + return writerclass(stream) + +if hasattr(codecs, "register_error"): + def writetext(stream, text, entities={}): + stream.errors = "xmlcharrefreplace" + stream.write(escape(text, entities)) + stream.errors = "strict" +else: + def writetext(stream, text, entities={}): + text = escape(text, entities) + try: + stream.write(text) + except UnicodeError: + for c in text: + try: + stream.write(c) + except UnicodeError: + stream.write("&#%d;" % ord(c)) + +def writeattr(stream, text): + countdouble = text.count('"') + if countdouble: + countsingle = text.count("'") + if countdouble <= countsingle: + entities = {'"': """} + quote = '"' + else: + entities = {"'": "'"} + quote = "'" + else: + entities = {} + quote = '"' + stream.write(quote) + writetext(stream, text, entities) + stream.write(quote) + + +class XMLGenerator(handler.ContentHandler): + GENERATED_PREFIX = "xml.sax.saxutils.prefix%s" + + def __init__(self, out=None, encoding="iso-8859-1"): + if out is None: + import sys + out = sys.stdout + handler.ContentHandler.__init__(self) + self._out = _outputwrapper(out,encoding) + self._ns_contexts = [{}] # contains uri -> prefix dicts + self._current_context = self._ns_contexts[-1] + self._undeclared_ns_maps = [] + self._encoding = encoding + self._generated_prefix_ctr = 0 + return + + # ContentHandler methods + + def startDocument(self): + self._out.write('<?xml version="1.0" encoding="%s"?>\n' % + self._encoding) + + def startPrefixMapping(self, prefix, uri): + self._ns_contexts.append(self._current_context.copy()) + self._current_context[uri] = prefix + self._undeclared_ns_maps.append((prefix, uri)) + + def endPrefixMapping(self, prefix): + self._current_context = self._ns_contexts[-1] + del self._ns_contexts[-1] + + def startElement(self, name, attrs): + self._out.write('<' + name) + for (name, value) in attrs.items(): + self._out.write(' %s=' % name) + writeattr(self._out, value) + self._out.write('>') + + def endElement(self, name): + self._out.write('</%s>' % name) + + def startElementNS(self, name, qname, attrs): + if name[0] is None: + name = name[1] + elif self._current_context[name[0]] is None: + # default namespace + name = name[1] + else: + name = self._current_context[name[0]] + ":" + name[1] + self._out.write('<' + name) + + for k,v in self._undeclared_ns_maps: + if k is None: + self._out.write(' xmlns="%s"' % (v or '')) + else: + self._out.write(' xmlns:%s="%s"' % (k,v)) + self._undeclared_ns_maps = [] + + for (name, value) in attrs.items(): + if name[0] is None: + name = name[1] + elif self._current_context[name[0]] is None: + # default namespace + #If an attribute has a nsuri but not a prefix, we must + #create a prefix and add a nsdecl + prefix = self.GENERATED_PREFIX % self._generated_prefix_ctr + self._generated_prefix_ctr = self._generated_prefix_ctr + 1 + name = prefix + ':' + name[1] + self._out.write(' xmlns:%s=%s' % (prefix, quoteattr(name[0]))) + self._current_context[name[0]] = prefix + else: + name = self._current_context[name[0]] + ":" + name[1] + self._out.write(' %s=' % name) + writeattr(self._out, value) + self._out.write('>') + + def endElementNS(self, name, qname): + # XXX: if qname is not None, we better use it. + # Python 2.0b2 requires us to use the recorded prefix for + # name[0], though + if name[0] is None: + qname = name[1] + elif self._current_context[name[0]] is None: + qname = name[1] + else: + qname = self._current_context[name[0]] + ":" + name[1] + self._out.write('</%s>' % qname) + + def characters(self, content): + writetext(self._out, content) + + def ignorableWhitespace(self, content): + self._out.write(content) + + def processingInstruction(self, target, data): + self._out.write('<?%s %s?>' % (target, data)) + + +class LexicalXMLGenerator(XMLGenerator, saxlib.LexicalHandler): + """A XMLGenerator that also supports the LexicalHandler interface""" + + def __init__(self, out=None, encoding="iso-8859-1"): + XMLGenerator.__init__(self, out, encoding) + self._in_cdata = 0 + + def characters(self, content): + if self._in_cdata: + self._out.write(content.replace(']]>', ']]>]]><![CDATA[')) + else: + self._out.write(escape(content)) + + # LexicalHandler methods + # (we only support the most important ones and inherit the rest) + + def startDTD(self, name, public_id, system_id): + self._out.write('<!DOCTYPE %s' % name) + if public_id: + self._out.write(' PUBLIC %s %s' % ( + quoteattr(public_id or ""), quoteattr(system_id or "") + )) + elif system_id: + self._out.write(' SYSTEM %s' % quoteattr(system_id or "")) + + def endDTD(self): + self._out.write('>') + + def comment(self, content): + self._out.write('<!--') + self._out.write(content) + self._out.write('-->') + + def startCDATA(self): + self._in_cdata = 1 + self._out.write('<![CDATA[') + + def endCDATA(self): + self._in_cdata = 0 + self._out.write(']]>') + + +# --- ContentGenerator is the SAX1 DocumentHandler for writing back XML +class ContentGenerator(XMLGenerator): + + def characters(self, str, start, end): + # In SAX1, characters receives start and end; in SAX2, it receives + # a string. For plain strings, we may want to use a buffer object. + return XMLGenerator.characters(self, str[start:start+end]) + +# --- XMLFilterImpl +class XMLFilterBase(saxlib.XMLFilter): + """This class is designed to sit between an XMLReader and the + client application's event handlers. By default, it does nothing + but pass requests up to the reader and events on to the handlers + unmodified, but subclasses can override specific methods to modify + the event stream or the configuration requests as they pass + through.""" + + # ErrorHandler methods + + def error(self, exception): + self._err_handler.error(exception) + + def fatalError(self, exception): + self._err_handler.fatalError(exception) + + def warning(self, exception): + self._err_handler.warning(exception) + + # ContentHandler methods + + def setDocumentLocator(self, locator): + self._cont_handler.setDocumentLocator(locator) + + def startDocument(self): + self._cont_handler.startDocument() + + def endDocument(self): + self._cont_handler.endDocument() + + def startPrefixMapping(self, prefix, uri): + self._cont_handler.startPrefixMapping(prefix, uri) + + def endPrefixMapping(self, prefix): + self._cont_handler.endPrefixMapping(prefix) + + def startElement(self, name, attrs): + self._cont_handler.startElement(name, attrs) + + def endElement(self, name): + self._cont_handler.endElement(name) + + def startElementNS(self, name, qname, attrs): + self._cont_handler.startElementNS(name, qname, attrs) + + def endElementNS(self, name, qname): + self._cont_handler.endElementNS(name, qname) + + def characters(self, content): + self._cont_handler.characters(content) + + def ignorableWhitespace(self, chars): + self._cont_handler.ignorableWhitespace(chars) + + def processingInstruction(self, target, data): + self._cont_handler.processingInstruction(target, data) + + def skippedEntity(self, name): + self._cont_handler.skippedEntity(name) + + # DTDHandler methods + + def notationDecl(self, name, publicId, systemId): + self._dtd_handler.notationDecl(name, publicId, systemId) + + def unparsedEntityDecl(self, name, publicId, systemId, ndata): + self._dtd_handler.unparsedEntityDecl(name, publicId, systemId, ndata) + + # EntityResolver methods + + def resolveEntity(self, publicId, systemId): + return self._ent_handler.resolveEntity(publicId, systemId) + + # XMLReader methods + + def parse(self, source): + self._parent.setContentHandler(self) + self._parent.setErrorHandler(self) + self._parent.setEntityResolver(self) + self._parent.setDTDHandler(self) + self._parent.parse(source) + + def setLocale(self, locale): + self._parent.setLocale(locale) + + def getFeature(self, name): + return self._parent.getFeature(name) + + def setFeature(self, name, state): + self._parent.setFeature(name, state) + + def getProperty(self, name): + return self._parent.getProperty(name) + + def setProperty(self, name, value): + self._parent.setProperty(name, value) + +# FIXME: remove this backward compatibility hack when not needed anymore +XMLFilterImpl = XMLFilterBase + +# --- BaseIncrementalParser + +class BaseIncrementalParser(xmlreader.IncrementalParser): + """This class implements the parse method of the XMLReader + interface using the feed, close and reset methods of the + IncrementalParser interface as a convenience to SAX 2.0 driver + writers.""" + + def parse(self, source): + source = prepare_input_source(source) + self.prepareParser(source) + + self._cont_handler.startDocument() + + # FIXME: what about char-stream? + inf = source.getByteStream() + buffer = inf.read(16384) + while buffer != "": + self.feed(buffer) + buffer = inf.read(16384) + + self.close() + self.reset() + + self._cont_handler.endDocument() + + def prepareParser(self, source): + """This method is called by the parse implementation to allow + the SAX 2.0 driver to prepare itself for parsing.""" + raise NotImplementedError("prepareParser must be overridden!") + +# --- Utility functions + +def prepare_input_source(source, base = ""): + """This function takes an InputSource and an optional base URL and + returns a fully resolved InputSource object ready for reading.""" + + if type(source) in _StringTypes: + source = xmlreader.InputSource(source) + elif hasattr(source, "read"): + f = source + source = xmlreader.InputSource() + source.setByteStream(f) + if hasattr(f, "name"): + source.setSystemId(absolute_system_id(f.name, base)) + + if source.getByteStream() is None: + sysid = absolute_system_id(source.getSystemId(), base) + source.setSystemId(sysid) + f = urllib2.urlopen(sysid) + source.setByteStream(f) + + return source + + +def absolute_system_id(sysid, base=''): + if os.path.exists(sysid): + sysid = 'file:%s' % os.path.abspath(sysid) + elif base: + sysid = Absolutize(sysid, base) + assert IsAbsolute(sysid) + return MakeUrllibSafe(sysid) + +# =========================================================================== +# +# DEPRECATED SAX 1.0 CLASSES +# +# =========================================================================== + +# --- AttributeMap + +class AttributeMap: + """An implementation of AttributeList that takes an (attr,val) hash + and uses it to implement the AttributeList interface.""" + + def __init__(self, map): + self.map=map + + def getLength(self): + return len(self.map.keys()) + + def getName(self, i): + try: + return self.map.keys()[i] + except IndexError,e: + return None + + def getType(self, i): + return "CDATA" + + def getValue(self, i): + try: + if type(i)==types.IntType: + return self.map[self.getName(i)] + else: + return self.map[i] + except KeyError,e: + return None + + def __len__(self): + return len(self.map) + + def __getitem__(self, key): + if type(key)==types.IntType: + return self.map.keys()[key] + else: + return self.map[key] + + def items(self): + return self.map.items() + + def keys(self): + return self.map.keys() + + def has_key(self,key): + return self.map.has_key(key) + + def get(self, key, alternative=None): + return self.map.get(key, alternative) + + def copy(self): + return AttributeMap(self.map.copy()) + + def values(self): + return self.map.values() + +# --- Event broadcasting object + +class EventBroadcaster: + """Takes a list of objects and forwards any method calls received + to all objects in the list. The attribute list holds the list and + can freely be modified by clients.""" + + class Event: + "Helper objects that represent event methods." + + def __init__(self,list,name): + self.list=list + self.name=name + + def __call__(self,*rest): + for obj in self.list: + apply(getattr(obj,self.name), rest) + + def __init__(self,list): + self.list=list + + def __getattr__(self,name): + return self.Event(self.list,name) + + def __repr__(self): + return "<EventBroadcaster instance at %d>" % id(self) + +# --- ESIS document handler +import saxlib +class ESISDocHandler(saxlib.HandlerBase): + "A SAX document handler that produces naive ESIS output." + + def __init__(self,writer=sys.stdout): + self.writer=writer + + def processingInstruction (self,target, remainder): + """Receive an event signalling that a processing instruction + has been found.""" + self.writer.write("?"+target+" "+remainder+"\n") + + def startElement(self,name,amap): + "Receive an event signalling the start of an element." + self.writer.write("("+name+"\n") + for a_name in amap.keys(): + self.writer.write("A"+a_name+" "+amap[a_name]+"\n") + + def endElement(self,name): + "Receive an event signalling the end of an element." + self.writer.write(")"+name+"\n") + + def characters(self,data,start_ix,length): + "Receive an event signalling that character data has been found." + self.writer.write("-"+data[start_ix:start_ix+length]+"\n") + +# --- XML canonizer + +class Canonizer(saxlib.HandlerBase): + "A SAX document handler that produces canonized XML output." + + def __init__(self,writer=sys.stdout): + self.elem_level=0 + self.writer=writer + + def processingInstruction (self,target, remainder): + if not target=="xml": + self.writer.write("<?"+target+" "+remainder+"?>") + + def startElement(self,name,amap): + self.writer.write("<"+name) + + a_names=amap.keys() + a_names.sort() + + for a_name in a_names: + self.writer.write(" "+a_name+"=\"") + self.write_data(amap[a_name]) + self.writer.write("\"") + self.writer.write(">") + self.elem_level=self.elem_level+1 + + def endElement(self,name): + self.writer.write("</"+name+">") + self.elem_level=self.elem_level-1 + + def ignorableWhitespace(self,data,start_ix,length): + self.characters(data,start_ix,length) + + def characters(self,data,start_ix,length): + if self.elem_level>0: + self.write_data(data[start_ix:start_ix+length]) + + def write_data(self,data): + "Writes datachars to writer." + data=data.replace("&","&") + data=data.replace("<","<") + data=data.replace("\"",""") + data=data.replace(">",">") + data=data.replace(chr(9),"	") + data=data.replace(chr(10)," ") + data=data.replace(chr(13)," ") + self.writer.write(data) + +# --- mllib + +class mllib: + """A re-implementation of the htmllib, sgmllib and xmllib interfaces as a + SAX DocumentHandler.""" + +# Unsupported: +# - setnomoretags +# - setliteral +# - translate_references +# - handle_xml +# - handle_doctype +# - handle_charref +# - handle_entityref +# - handle_comment +# - handle_cdata +# - tag_attributes + + def __init__(self): + self.reset() + + def reset(self): + import saxexts # only used here + self.parser=saxexts.XMLParserFactory.make_parser() + self.handler=mllib.Handler(self.parser,self) + self.handler.reset() + + def feed(self,data): + self.parser.feed(data) + + def close(self): + self.parser.close() + + def get_stack(self): + return self.handler.get_stack() + + # --- Handler methods (to be overridden) + + def handle_starttag(self,name,method,atts): + method(atts) + + def handle_endtag(self,name,method): + method() + + def handle_data(self,data): + pass + + def handle_proc(self,target,data): + pass + + def unknown_starttag(self,name,atts): + pass + + def unknown_endtag(self,name): + pass + + def syntax_error(self,message): + pass + + # --- The internal handler class + + class Handler(saxlib.DocumentHandler,saxlib.ErrorHandler): + """An internal class to handle SAX events and translate them to mllib + events.""" + + def __init__(self,driver,handler): + self.driver=driver + self.driver.setDocumentHandler(self) + self.driver.setErrorHandler(self) + self.handler=handler + self.reset() + + def get_stack(self): + return self.stack + + def reset(self): + self.stack=[] + + # --- DocumentHandler methods + + def characters(self, ch, start, length): + self.handler.handle_data(ch[start:start+length]) + + def endElement(self, name): + if hasattr(self.handler,"end_"+name): + self.handler.handle_endtag(name, + getattr(self.handler,"end_"+name)) + else: + self.handler.unknown_endtag(name) + + del self.stack[-1] + + def ignorableWhitespace(self, ch, start, length): + self.handler.handle_data(ch[start:start+length]) + + def processingInstruction(self, target, data): + self.handler.handle_proc(target,data) + + def startElement(self, name, atts): + self.stack.append(name) + + if hasattr(self.handler,"start_"+name): + self.handler.handle_starttag(name, + getattr(self.handler, + "start_"+name), + atts) + else: + self.handler.unknown_starttag(name,atts) + + # --- ErrorHandler methods + + def error(self, exception): + self.handler.syntax_error(str(exception)) + + def fatalError(self, exception): + raise RuntimeError(str(exception)) diff --git a/src/main/resources/PythonLibs/xml/sax/xmlreader.py b/src/main/resources/PythonLibs/xml/sax/xmlreader.py new file mode 100644 index 0000000000000000000000000000000000000000..f1c9d9db2ed26a6abc9b9ee307a64fbcd86d7169 --- /dev/null +++ b/src/main/resources/PythonLibs/xml/sax/xmlreader.py @@ -0,0 +1,378 @@ +"""An XML Reader is the SAX 2 name for an XML parser. XML Parsers +should be based on this code. """ + +import handler + +from _exceptions import SAXNotSupportedException, SAXNotRecognizedException + + +# ===== XMLREADER ===== + +class XMLReader: + """Interface for reading an XML document using callbacks. + + XMLReader is the interface that an XML parser's SAX2 driver must + implement. This interface allows an application to set and query + features and properties in the parser, to register event handlers + for document processing, and to initiate a document parse. + + All SAX interfaces are assumed to be synchronous: the parse + methods must not return until parsing is complete, and readers + must wait for an event-handler callback to return before reporting + the next event.""" + + def __init__(self): + self._cont_handler = handler.ContentHandler() + self._dtd_handler = handler.DTDHandler() + self._ent_handler = handler.EntityResolver() + self._err_handler = handler.ErrorHandler() + + def parse(self, source): + "Parse an XML document from a system identifier or an InputSource." + raise NotImplementedError("This method must be implemented!") + + def getContentHandler(self): + "Returns the current ContentHandler." + return self._cont_handler + + def setContentHandler(self, handler): + "Registers a new object to receive document content events." + self._cont_handler = handler + + def getDTDHandler(self): + "Returns the current DTD handler." + return self._dtd_handler + + def setDTDHandler(self, handler): + "Register an object to receive basic DTD-related events." + self._dtd_handler = handler + + def getEntityResolver(self): + "Returns the current EntityResolver." + return self._ent_handler + + def setEntityResolver(self, resolver): + "Register an object to resolve external entities." + self._ent_handler = resolver + + def getErrorHandler(self): + "Returns the current ErrorHandler." + return self._err_handler + + def setErrorHandler(self, handler): + "Register an object to receive error-message events." + self._err_handler = handler + + def setLocale(self, locale): + """Allow an application to set the locale for errors and warnings. + + SAX parsers are not required to provide localization for errors + and warnings; if they cannot support the requested locale, + however, they must throw a SAX exception. Applications may + request a locale change in the middle of a parse.""" + raise SAXNotSupportedException("Locale support not implemented") + + def getFeature(self, name): + "Looks up and returns the state of a SAX2 feature." + raise SAXNotRecognizedException("Feature '%s' not recognized" % name) + + def setFeature(self, name, state): + "Sets the state of a SAX2 feature." + raise SAXNotRecognizedException("Feature '%s' not recognized" % name) + + def getProperty(self, name): + "Looks up and returns the value of a SAX2 property." + raise SAXNotRecognizedException("Property '%s' not recognized" % name) + + def setProperty(self, name, value): + "Sets the value of a SAX2 property." + raise SAXNotRecognizedException("Property '%s' not recognized" % name) + +class IncrementalParser(XMLReader): + """This interface adds three extra methods to the XMLReader + interface that allow XML parsers to support incremental + parsing. Support for this interface is optional, since not all + underlying XML parsers support this functionality. + + When the parser is instantiated it is ready to begin accepting + data from the feed method immediately. After parsing has been + finished with a call to close the reset method must be called to + make the parser ready to accept new data, either from feed or + using the parse method. + + Note that these methods must _not_ be called during parsing, that + is, after parse has been called and before it returns. + + By default, the class also implements the parse method of the XMLReader + interface using the feed, close and reset methods of the + IncrementalParser interface as a convenience to SAX 2.0 driver + writers.""" + + def __init__(self, bufsize=2**16): + self._bufsize = bufsize + XMLReader.__init__(self) + + def parse(self, source): + import saxutils + source = saxutils.prepare_input_source(source) + + self.prepareParser(source) + file = source.getByteStream() + buffer = file.read(self._bufsize) + while buffer != "": + self.feed(buffer) + buffer = file.read(self._bufsize) + self.close() + + def feed(self, data): + """This method gives the raw XML data in the data parameter to + the parser and makes it parse the data, emitting the + corresponding events. It is allowed for XML constructs to be + split across several calls to feed. + + feed may raise SAXException.""" + raise NotImplementedError("This method must be implemented!") + + def prepareParser(self, source): + """This method is called by the parse implementation to allow + the SAX 2.0 driver to prepare itself for parsing.""" + raise NotImplementedError("prepareParser must be overridden!") + + def close(self): + """This method is called when the entire XML document has been + passed to the parser through the feed method, to notify the + parser that there are no more data. This allows the parser to + do the final checks on the document and empty the internal + data buffer. + + The parser will not be ready to parse another document until + the reset method has been called. + + close may raise SAXException.""" + raise NotImplementedError("This method must be implemented!") + + def reset(self): + """This method is called after close has been called to reset + the parser so that it is ready to parse new documents. The + results of calling parse or feed after close without calling + reset are undefined.""" + raise NotImplementedError("This method must be implemented!") + +# ===== LOCATOR ===== + +class Locator: + """Interface for associating a SAX event with a document + location. A locator object will return valid results only during + calls to DocumentHandler methods; at any other time, the + results are unpredictable.""" + + def getColumnNumber(self): + "Return the column number where the current event ends." + return -1 + + def getLineNumber(self): + "Return the line number where the current event ends." + return -1 + + def getPublicId(self): + "Return the public identifier for the current event." + return None + + def getSystemId(self): + "Return the system identifier for the current event." + return None + +# ===== INPUTSOURCE ===== + +class InputSource: + """Encapsulation of the information needed by the XMLReader to + read entities. + + This class may include information about the public identifier, + system identifier, byte stream (possibly with character encoding + information) and/or the character stream of an entity. + + Applications will create objects of this class for use in the + XMLReader.parse method and for returning from + EntityResolver.resolveEntity. + + An InputSource belongs to the application, the XMLReader is not + allowed to modify InputSource objects passed to it from the + application, although it may make copies and modify those.""" + + def __init__(self, system_id = None): + self.__system_id = system_id + self.__public_id = None + self.__encoding = None + self.__bytefile = None + self.__charfile = None + + def setPublicId(self, public_id): + "Sets the public identifier of this InputSource." + self.__public_id = public_id + + def getPublicId(self): + "Returns the public identifier of this InputSource." + return self.__public_id + + def setSystemId(self, system_id): + "Sets the system identifier of this InputSource." + self.__system_id = system_id + + def getSystemId(self): + "Returns the system identifier of this InputSource." + return self.__system_id + + def setEncoding(self, encoding): + """Sets the character encoding of this InputSource. + + The encoding must be a string acceptable for an XML encoding + declaration (see section 4.3.3 of the XML recommendation). + + The encoding attribute of the InputSource is ignored if the + InputSource also contains a character stream.""" + self.__encoding = encoding + + def getEncoding(self): + "Get the character encoding of this InputSource." + return self.__encoding + + def setByteStream(self, bytefile): + """Set the byte stream (a Python file-like object which does + not perform byte-to-character conversion) for this input + source. + + The SAX parser will ignore this if there is also a character + stream specified, but it will use a byte stream in preference + to opening a URI connection itself. + + If the application knows the character encoding of the byte + stream, it should set it with the setEncoding method.""" + self.__bytefile = bytefile + + def getByteStream(self): + """Get the byte stream for this input source. + + The getEncoding method will return the character encoding for + this byte stream, or None if unknown.""" + return self.__bytefile + + def setCharacterStream(self, charfile): + """Set the character stream for this input source. (The stream + must be a Python 2.0 Unicode-wrapped file-like that performs + conversion to Unicode strings.) + + If there is a character stream specified, the SAX parser will + ignore any byte stream and will not attempt to open a URI + connection to the system identifier.""" + self.__charfile = charfile + + def getCharacterStream(self): + "Get the character stream for this input source." + return self.__charfile + +# ===== ATTRIBUTESIMPL ===== + +class AttributesImpl: + + def __init__(self, attrs): + """Non-NS-aware implementation. + + attrs should be of the form {name : value}.""" + self._attrs = attrs + + def getLength(self): + return len(self._attrs) + + def getType(self, name): + return "CDATA" + + def getValue(self, name): + return self._attrs[name] + + def getValueByQName(self, name): + return self._attrs[name] + + def getNameByQName(self, name): + if not self._attrs.has_key(name): + raise KeyError, name + return name + + def getQNameByName(self, name): + if not self._attrs.has_key(name): + raise KeyError, name + return name + + def getNames(self): + return self._attrs.keys() + + def getQNames(self): + return self._attrs.keys() + + def __len__(self): + return len(self._attrs) + + def __getitem__(self, name): + return self._attrs[name] + + def keys(self): + return self._attrs.keys() + + def has_key(self, name): + return self._attrs.has_key(name) + + def get(self, name, alternative=None): + return self._attrs.get(name, alternative) + + def copy(self): + return self.__class__(self._attrs) + + def items(self): + return self._attrs.items() + + def values(self): + return self._attrs.values() + +# ===== ATTRIBUTESNSIMPL ===== + +class AttributesNSImpl(AttributesImpl): + + def __init__(self, attrs, qnames): + """NS-aware implementation. + + attrs should be of the form {(ns_uri, lname): value, ...}. + qnames of the form {(ns_uri, lname): qname, ...}.""" + self._attrs = attrs + self._qnames = qnames + + def getValueByQName(self, name): + for (nsname, qname) in self._qnames.items(): + if qname == name: + return self._attrs[nsname] + + raise KeyError, name + + def getNameByQName(self, name): + for (nsname, qname) in self._qnames.items(): + if qname == name: + return nsname + + raise KeyError, name + + def getQNameByName(self, name): + return self._qnames[name] + + def getQNames(self): + return self._qnames.values() + + def copy(self): + return self.__class__(self._attrs, self._qnames) + + +def _test(): + XMLReader() + IncrementalParser() + Locator() + +if __name__ == "__main__": + _test() diff --git a/src/main/resources/PythonLibs/xmllib.py b/src/main/resources/PythonLibs/xmllib.py new file mode 100644 index 0000000000000000000000000000000000000000..96ee8411e7a74a347a9b2935fc8b3760d0a7491a --- /dev/null +++ b/src/main/resources/PythonLibs/xmllib.py @@ -0,0 +1,930 @@ +"""A parser for XML, using the derived class as static DTD.""" + +# Author: Sjoerd Mullender. + +import re +import string + +import warnings +warnings.warn("The xmllib module is obsolete. Use xml.sax instead.", + DeprecationWarning, 2) +del warnings + +version = '0.3' + +class Error(RuntimeError): + pass + +# Regular expressions used for parsing + +_S = '[ \t\r\n]+' # white space +_opS = '[ \t\r\n]*' # optional white space +_Name = '[a-zA-Z_:][-a-zA-Z0-9._:]*' # valid XML name +_QStr = "(?:'[^']*'|\"[^\"]*\")" # quoted XML string +illegal = re.compile('[^\t\r\n -\176\240-\377]') # illegal chars in content +interesting = re.compile('[]&<]') + +amp = re.compile('&') +ref = re.compile('&(' + _Name + '|#[0-9]+|#x[0-9a-fA-F]+)[^-a-zA-Z0-9._:]') +entityref = re.compile('&(?P<name>' + _Name + ')[^-a-zA-Z0-9._:]') +charref = re.compile('&#(?P<char>[0-9]+[^0-9]|x[0-9a-fA-F]+[^0-9a-fA-F])') +space = re.compile(_S + '$') +newline = re.compile('\n') + +attrfind = re.compile( + _S + '(?P<name>' + _Name + ')' + '(' + _opS + '=' + _opS + + '(?P<value>'+_QStr+'|[-a-zA-Z0-9.:+*%?!\(\)_#=~]+))?') +starttagopen = re.compile('<' + _Name) +starttagend = re.compile(_opS + '(?P<slash>/?)>') +starttagmatch = re.compile('<(?P<tagname>'+_Name+')' + '(?P<attrs>(?:'+attrfind.pattern+')*)'+ + starttagend.pattern) +endtagopen = re.compile('</') +endbracket = re.compile(_opS + '>') +endbracketfind = re.compile('(?:[^>\'"]|'+_QStr+')*>') +tagfind = re.compile(_Name) +cdataopen = re.compile(r'<!\[CDATA\[') +cdataclose = re.compile(r'\]\]>') +# this matches one of the following: +# SYSTEM SystemLiteral +# PUBLIC PubidLiteral SystemLiteral +_SystemLiteral = '(?P<%s>'+_QStr+')' +_PublicLiteral = '(?P<%s>"[-\'\(\)+,./:=?;!*#@$_%% \n\ra-zA-Z0-9]*"|' \ + "'[-\(\)+,./:=?;!*#@$_%% \n\ra-zA-Z0-9]*')" +_ExternalId = '(?:SYSTEM|' \ + 'PUBLIC'+_S+_PublicLiteral%'pubid'+ \ + ')'+_S+_SystemLiteral%'syslit' +doctype = re.compile('<!DOCTYPE'+_S+'(?P<name>'+_Name+')' + '(?:'+_S+_ExternalId+')?'+_opS) +xmldecl = re.compile('<\?xml'+_S+ + 'version'+_opS+'='+_opS+'(?P<version>'+_QStr+')'+ + '(?:'+_S+'encoding'+_opS+'='+_opS+ + "(?P<encoding>'[A-Za-z][-A-Za-z0-9._]*'|" + '"[A-Za-z][-A-Za-z0-9._]*"))?' + '(?:'+_S+'standalone'+_opS+'='+_opS+ + '(?P<standalone>\'(?:yes|no)\'|"(?:yes|no)"))?'+ + _opS+'\?>') +procopen = re.compile(r'<\?(?P<proc>' + _Name + ')' + _opS) +procclose = re.compile(_opS + r'\?>') +commentopen = re.compile('<!--') +commentclose = re.compile('-->') +doubledash = re.compile('--') +attrtrans = string.maketrans(' \r\n\t', ' ') + +# definitions for XML namespaces +_NCName = '[a-zA-Z_][-a-zA-Z0-9._]*' # XML Name, minus the ":" +ncname = re.compile(_NCName + '$') +qname = re.compile('(?:(?P<prefix>' + _NCName + '):)?' # optional prefix + '(?P<local>' + _NCName + ')$') + +xmlns = re.compile('xmlns(?::(?P<ncname>'+_NCName+'))?$') + +# XML parser base class -- find tags and call handler functions. +# Usage: p = XMLParser(); p.feed(data); ...; p.close(). +# The dtd is defined by deriving a class which defines methods with +# special names to handle tags: start_foo and end_foo to handle <foo> +# and </foo>, respectively. The data between tags is passed to the +# parser by calling self.handle_data() with some data as argument (the +# data may be split up in arbitrary chunks). + +class XMLParser: + attributes = {} # default, to be overridden + elements = {} # default, to be overridden + + # parsing options, settable using keyword args in __init__ + __accept_unquoted_attributes = 0 + __accept_missing_endtag_name = 0 + __map_case = 0 + __accept_utf8 = 0 + __translate_attribute_references = 1 + + # Interface -- initialize and reset this instance + def __init__(self, **kw): + self.__fixed = 0 + if 'accept_unquoted_attributes' in kw: + self.__accept_unquoted_attributes = kw['accept_unquoted_attributes'] + if 'accept_missing_endtag_name' in kw: + self.__accept_missing_endtag_name = kw['accept_missing_endtag_name'] + if 'map_case' in kw: + self.__map_case = kw['map_case'] + if 'accept_utf8' in kw: + self.__accept_utf8 = kw['accept_utf8'] + if 'translate_attribute_references' in kw: + self.__translate_attribute_references = kw['translate_attribute_references'] + self.reset() + + def __fixelements(self): + self.__fixed = 1 + self.elements = {} + self.__fixdict(self.__dict__) + self.__fixclass(self.__class__) + + def __fixclass(self, kl): + self.__fixdict(kl.__dict__) + for k in kl.__bases__: + self.__fixclass(k) + + def __fixdict(self, dict): + for key in dict.keys(): + if key[:6] == 'start_': + tag = key[6:] + start, end = self.elements.get(tag, (None, None)) + if start is None: + self.elements[tag] = getattr(self, key), end + elif key[:4] == 'end_': + tag = key[4:] + start, end = self.elements.get(tag, (None, None)) + if end is None: + self.elements[tag] = start, getattr(self, key) + + # Interface -- reset this instance. Loses all unprocessed data + def reset(self): + self.rawdata = '' + self.stack = [] + self.nomoretags = 0 + self.literal = 0 + self.lineno = 1 + self.__at_start = 1 + self.__seen_doctype = None + self.__seen_starttag = 0 + self.__use_namespaces = 0 + self.__namespaces = {'xml':None} # xml is implicitly declared + # backward compatibility hack: if elements not overridden, + # fill it in ourselves + if self.elements is XMLParser.elements: + self.__fixelements() + + # For derived classes only -- enter literal mode (CDATA) till EOF + def setnomoretags(self): + self.nomoretags = self.literal = 1 + + # For derived classes only -- enter literal mode (CDATA) + def setliteral(self, *args): + self.literal = 1 + + # Interface -- feed some data to the parser. Call this as + # often as you want, with as little or as much text as you + # want (may include '\n'). (This just saves the text, all the + # processing is done by goahead().) + def feed(self, data): + self.rawdata = self.rawdata + data + self.goahead(0) + + # Interface -- handle the remaining data + def close(self): + self.goahead(1) + if self.__fixed: + self.__fixed = 0 + # remove self.elements so that we don't leak + del self.elements + + # Interface -- translate references + def translate_references(self, data, all = 1): + if not self.__translate_attribute_references: + return data + i = 0 + while 1: + res = amp.search(data, i) + if res is None: + return data + s = res.start(0) + res = ref.match(data, s) + if res is None: + self.syntax_error("bogus `&'") + i = s+1 + continue + i = res.end(0) + str = res.group(1) + rescan = 0 + if str[0] == '#': + if str[1] == 'x': + str = chr(int(str[2:], 16)) + else: + str = chr(int(str[1:])) + if data[i - 1] != ';': + self.syntax_error("`;' missing after char reference") + i = i-1 + elif all: + if str in self.entitydefs: + str = self.entitydefs[str] + rescan = 1 + elif data[i - 1] != ';': + self.syntax_error("bogus `&'") + i = s + 1 # just past the & + continue + else: + self.syntax_error("reference to unknown entity `&%s;'" % str) + str = '&' + str + ';' + elif data[i - 1] != ';': + self.syntax_error("bogus `&'") + i = s + 1 # just past the & + continue + + # when we get here, str contains the translated text and i points + # to the end of the string that is to be replaced + data = data[:s] + str + data[i:] + if rescan: + i = s + else: + i = s + len(str) + + # Interface - return a dictionary of all namespaces currently valid + def getnamespace(self): + nsdict = {} + for t, d, nst in self.stack: + nsdict.update(d) + return nsdict + + # Internal -- handle data as far as reasonable. May leave state + # and data to be processed by a subsequent call. If 'end' is + # true, force handling all data as if followed by EOF marker. + def goahead(self, end): + rawdata = self.rawdata + i = 0 + n = len(rawdata) + while i < n: + if i > 0: + self.__at_start = 0 + if self.nomoretags: + data = rawdata[i:n] + self.handle_data(data) + self.lineno = self.lineno + data.count('\n') + i = n + break + res = interesting.search(rawdata, i) + if res: + j = res.start(0) + else: + j = n + if i < j: + data = rawdata[i:j] + if self.__at_start and space.match(data) is None: + self.syntax_error('illegal data at start of file') + self.__at_start = 0 + if not self.stack and space.match(data) is None: + self.syntax_error('data not in content') + if not self.__accept_utf8 and illegal.search(data): + self.syntax_error('illegal character in content') + self.handle_data(data) + self.lineno = self.lineno + data.count('\n') + i = j + if i == n: break + if rawdata[i] == '<': + if starttagopen.match(rawdata, i): + if self.literal: + data = rawdata[i] + self.handle_data(data) + self.lineno = self.lineno + data.count('\n') + i = i+1 + continue + k = self.parse_starttag(i) + if k < 0: break + self.__seen_starttag = 1 + self.lineno = self.lineno + rawdata[i:k].count('\n') + i = k + continue + if endtagopen.match(rawdata, i): + k = self.parse_endtag(i) + if k < 0: break + self.lineno = self.lineno + rawdata[i:k].count('\n') + i = k + continue + if commentopen.match(rawdata, i): + if self.literal: + data = rawdata[i] + self.handle_data(data) + self.lineno = self.lineno + data.count('\n') + i = i+1 + continue + k = self.parse_comment(i) + if k < 0: break + self.lineno = self.lineno + rawdata[i:k].count('\n') + i = k + continue + if cdataopen.match(rawdata, i): + k = self.parse_cdata(i) + if k < 0: break + self.lineno = self.lineno + rawdata[i:k].count('\n') + i = k + continue + res = xmldecl.match(rawdata, i) + if res: + if not self.__at_start: + self.syntax_error("<?xml?> declaration not at start of document") + version, encoding, standalone = res.group('version', + 'encoding', + 'standalone') + if version[1:-1] != '1.0': + raise Error('only XML version 1.0 supported') + if encoding: encoding = encoding[1:-1] + if standalone: standalone = standalone[1:-1] + self.handle_xml(encoding, standalone) + i = res.end(0) + continue + res = procopen.match(rawdata, i) + if res: + k = self.parse_proc(i) + if k < 0: break + self.lineno = self.lineno + rawdata[i:k].count('\n') + i = k + continue + res = doctype.match(rawdata, i) + if res: + if self.literal: + data = rawdata[i] + self.handle_data(data) + self.lineno = self.lineno + data.count('\n') + i = i+1 + continue + if self.__seen_doctype: + self.syntax_error('multiple DOCTYPE elements') + if self.__seen_starttag: + self.syntax_error('DOCTYPE not at beginning of document') + k = self.parse_doctype(res) + if k < 0: break + self.__seen_doctype = res.group('name') + if self.__map_case: + self.__seen_doctype = self.__seen_doctype.lower() + self.lineno = self.lineno + rawdata[i:k].count('\n') + i = k + continue + elif rawdata[i] == '&': + if self.literal: + data = rawdata[i] + self.handle_data(data) + i = i+1 + continue + res = charref.match(rawdata, i) + if res is not None: + i = res.end(0) + if rawdata[i-1] != ';': + self.syntax_error("`;' missing in charref") + i = i-1 + if not self.stack: + self.syntax_error('data not in content') + self.handle_charref(res.group('char')[:-1]) + self.lineno = self.lineno + res.group(0).count('\n') + continue + res = entityref.match(rawdata, i) + if res is not None: + i = res.end(0) + if rawdata[i-1] != ';': + self.syntax_error("`;' missing in entityref") + i = i-1 + name = res.group('name') + if self.__map_case: + name = name.lower() + if name in self.entitydefs: + self.rawdata = rawdata = rawdata[:res.start(0)] + self.entitydefs[name] + rawdata[i:] + n = len(rawdata) + i = res.start(0) + else: + self.unknown_entityref(name) + self.lineno = self.lineno + res.group(0).count('\n') + continue + elif rawdata[i] == ']': + if self.literal: + data = rawdata[i] + self.handle_data(data) + i = i+1 + continue + if n-i < 3: + break + if cdataclose.match(rawdata, i): + self.syntax_error("bogus `]]>'") + self.handle_data(rawdata[i]) + i = i+1 + continue + else: + raise Error('neither < nor & ??') + # We get here only if incomplete matches but + # nothing else + break + # end while + if i > 0: + self.__at_start = 0 + if end and i < n: + data = rawdata[i] + self.syntax_error("bogus `%s'" % data) + if not self.__accept_utf8 and illegal.search(data): + self.syntax_error('illegal character in content') + self.handle_data(data) + self.lineno = self.lineno + data.count('\n') + self.rawdata = rawdata[i+1:] + return self.goahead(end) + self.rawdata = rawdata[i:] + if end: + if not self.__seen_starttag: + self.syntax_error('no elements in file') + if self.stack: + self.syntax_error('missing end tags') + while self.stack: + self.finish_endtag(self.stack[-1][0]) + + # Internal -- parse comment, return length or -1 if not terminated + def parse_comment(self, i): + rawdata = self.rawdata + if rawdata[i:i+4] != '<!--': + raise Error('unexpected call to handle_comment') + res = commentclose.search(rawdata, i+4) + if res is None: + return -1 + if doubledash.search(rawdata, i+4, res.start(0)): + self.syntax_error("`--' inside comment") + if rawdata[res.start(0)-1] == '-': + self.syntax_error('comment cannot end in three dashes') + if not self.__accept_utf8 and \ + illegal.search(rawdata, i+4, res.start(0)): + self.syntax_error('illegal character in comment') + self.handle_comment(rawdata[i+4: res.start(0)]) + return res.end(0) + + # Internal -- handle DOCTYPE tag, return length or -1 if not terminated + def parse_doctype(self, res): + rawdata = self.rawdata + n = len(rawdata) + name = res.group('name') + if self.__map_case: + name = name.lower() + pubid, syslit = res.group('pubid', 'syslit') + if pubid is not None: + pubid = pubid[1:-1] # remove quotes + pubid = ' '.join(pubid.split()) # normalize + if syslit is not None: syslit = syslit[1:-1] # remove quotes + j = k = res.end(0) + if k >= n: + return -1 + if rawdata[k] == '[': + level = 0 + k = k+1 + dq = sq = 0 + while k < n: + c = rawdata[k] + if not sq and c == '"': + dq = not dq + elif not dq and c == "'": + sq = not sq + elif sq or dq: + pass + elif level <= 0 and c == ']': + res = endbracket.match(rawdata, k+1) + if res is None: + return -1 + self.handle_doctype(name, pubid, syslit, rawdata[j+1:k]) + return res.end(0) + elif c == '<': + level = level + 1 + elif c == '>': + level = level - 1 + if level < 0: + self.syntax_error("bogus `>' in DOCTYPE") + k = k+1 + res = endbracketfind.match(rawdata, k) + if res is None: + return -1 + if endbracket.match(rawdata, k) is None: + self.syntax_error('garbage in DOCTYPE') + self.handle_doctype(name, pubid, syslit, None) + return res.end(0) + + # Internal -- handle CDATA tag, return length or -1 if not terminated + def parse_cdata(self, i): + rawdata = self.rawdata + if rawdata[i:i+9] != '<![CDATA[': + raise Error('unexpected call to parse_cdata') + res = cdataclose.search(rawdata, i+9) + if res is None: + return -1 + if not self.__accept_utf8 and \ + illegal.search(rawdata, i+9, res.start(0)): + self.syntax_error('illegal character in CDATA') + if not self.stack: + self.syntax_error('CDATA not in content') + self.handle_cdata(rawdata[i+9:res.start(0)]) + return res.end(0) + + __xml_namespace_attributes = {'ns':None, 'src':None, 'prefix':None} + # Internal -- handle a processing instruction tag + def parse_proc(self, i): + rawdata = self.rawdata + end = procclose.search(rawdata, i) + if end is None: + return -1 + j = end.start(0) + if not self.__accept_utf8 and illegal.search(rawdata, i+2, j): + self.syntax_error('illegal character in processing instruction') + res = tagfind.match(rawdata, i+2) + if res is None: + raise Error('unexpected call to parse_proc') + k = res.end(0) + name = res.group(0) + if self.__map_case: + name = name.lower() + if name == 'xml:namespace': + self.syntax_error('old-fashioned namespace declaration') + self.__use_namespaces = -1 + # namespace declaration + # this must come after the <?xml?> declaration (if any) + # and before the <!DOCTYPE> (if any). + if self.__seen_doctype or self.__seen_starttag: + self.syntax_error('xml:namespace declaration too late in document') + attrdict, namespace, k = self.parse_attributes(name, k, j) + if namespace: + self.syntax_error('namespace declaration inside namespace declaration') + for attrname in attrdict.keys(): + if not attrname in self.__xml_namespace_attributes: + self.syntax_error("unknown attribute `%s' in xml:namespace tag" % attrname) + if not 'ns' in attrdict or not 'prefix' in attrdict: + self.syntax_error('xml:namespace without required attributes') + prefix = attrdict.get('prefix') + if ncname.match(prefix) is None: + self.syntax_error('xml:namespace illegal prefix value') + return end.end(0) + if prefix in self.__namespaces: + self.syntax_error('xml:namespace prefix not unique') + self.__namespaces[prefix] = attrdict['ns'] + else: + if name.lower() == 'xml': + self.syntax_error('illegal processing instruction target name') + self.handle_proc(name, rawdata[k:j]) + return end.end(0) + + # Internal -- parse attributes between i and j + def parse_attributes(self, tag, i, j): + rawdata = self.rawdata + attrdict = {} + namespace = {} + while i < j: + res = attrfind.match(rawdata, i) + if res is None: + break + attrname, attrvalue = res.group('name', 'value') + if self.__map_case: + attrname = attrname.lower() + i = res.end(0) + if attrvalue is None: + self.syntax_error("no value specified for attribute `%s'" % attrname) + attrvalue = attrname + elif attrvalue[:1] == "'" == attrvalue[-1:] or \ + attrvalue[:1] == '"' == attrvalue[-1:]: + attrvalue = attrvalue[1:-1] + elif not self.__accept_unquoted_attributes: + self.syntax_error("attribute `%s' value not quoted" % attrname) + res = xmlns.match(attrname) + if res is not None: + # namespace declaration + ncname = res.group('ncname') + namespace[ncname or ''] = attrvalue or None + if not self.__use_namespaces: + self.__use_namespaces = len(self.stack)+1 + continue + if '<' in attrvalue: + self.syntax_error("`<' illegal in attribute value") + if attrname in attrdict: + self.syntax_error("attribute `%s' specified twice" % attrname) + attrvalue = attrvalue.translate(attrtrans) + attrdict[attrname] = self.translate_references(attrvalue) + return attrdict, namespace, i + + # Internal -- handle starttag, return length or -1 if not terminated + def parse_starttag(self, i): + rawdata = self.rawdata + # i points to start of tag + end = endbracketfind.match(rawdata, i+1) + if end is None: + return -1 + tag = starttagmatch.match(rawdata, i) + if tag is None or tag.end(0) != end.end(0): + self.syntax_error('garbage in starttag') + return end.end(0) + nstag = tagname = tag.group('tagname') + if self.__map_case: + nstag = tagname = nstag.lower() + if not self.__seen_starttag and self.__seen_doctype and \ + tagname != self.__seen_doctype: + self.syntax_error('starttag does not match DOCTYPE') + if self.__seen_starttag and not self.stack: + self.syntax_error('multiple elements on top level') + k, j = tag.span('attrs') + attrdict, nsdict, k = self.parse_attributes(tagname, k, j) + self.stack.append((tagname, nsdict, nstag)) + if self.__use_namespaces: + res = qname.match(tagname) + else: + res = None + if res is not None: + prefix, nstag = res.group('prefix', 'local') + if prefix is None: + prefix = '' + ns = None + for t, d, nst in self.stack: + if prefix in d: + ns = d[prefix] + if ns is None and prefix != '': + ns = self.__namespaces.get(prefix) + if ns is not None: + nstag = ns + ' ' + nstag + elif prefix != '': + nstag = prefix + ':' + nstag # undo split + self.stack[-1] = tagname, nsdict, nstag + # translate namespace of attributes + attrnamemap = {} # map from new name to old name (used for error reporting) + for key in attrdict.keys(): + attrnamemap[key] = key + if self.__use_namespaces: + nattrdict = {} + for key, val in attrdict.items(): + okey = key + res = qname.match(key) + if res is not None: + aprefix, key = res.group('prefix', 'local') + if self.__map_case: + key = key.lower() + if aprefix is not None: + ans = None + for t, d, nst in self.stack: + if aprefix in d: + ans = d[aprefix] + if ans is None: + ans = self.__namespaces.get(aprefix) + if ans is not None: + key = ans + ' ' + key + else: + key = aprefix + ':' + key + nattrdict[key] = val + attrnamemap[key] = okey + attrdict = nattrdict + attributes = self.attributes.get(nstag) + if attributes is not None: + for key in attrdict.keys(): + if not key in attributes: + self.syntax_error("unknown attribute `%s' in tag `%s'" % (attrnamemap[key], tagname)) + for key, val in attributes.items(): + if val is not None and not key in attrdict: + attrdict[key] = val + method = self.elements.get(nstag, (None, None))[0] + self.finish_starttag(nstag, attrdict, method) + if tag.group('slash') == '/': + self.finish_endtag(tagname) + return tag.end(0) + + # Internal -- parse endtag + def parse_endtag(self, i): + rawdata = self.rawdata + end = endbracketfind.match(rawdata, i+1) + if end is None: + return -1 + res = tagfind.match(rawdata, i+2) + if res is None: + if self.literal: + self.handle_data(rawdata[i]) + return i+1 + if not self.__accept_missing_endtag_name: + self.syntax_error('no name specified in end tag') + tag = self.stack[-1][0] + k = i+2 + else: + tag = res.group(0) + if self.__map_case: + tag = tag.lower() + if self.literal: + if not self.stack or tag != self.stack[-1][0]: + self.handle_data(rawdata[i]) + return i+1 + k = res.end(0) + if endbracket.match(rawdata, k) is None: + self.syntax_error('garbage in end tag') + self.finish_endtag(tag) + return end.end(0) + + # Internal -- finish processing of start tag + def finish_starttag(self, tagname, attrdict, method): + if method is not None: + self.handle_starttag(tagname, method, attrdict) + else: + self.unknown_starttag(tagname, attrdict) + + # Internal -- finish processing of end tag + def finish_endtag(self, tag): + self.literal = 0 + if not tag: + self.syntax_error('name-less end tag') + found = len(self.stack) - 1 + if found < 0: + self.unknown_endtag(tag) + return + else: + found = -1 + for i in range(len(self.stack)): + if tag == self.stack[i][0]: + found = i + if found == -1: + self.syntax_error('unopened end tag') + return + while len(self.stack) > found: + if found < len(self.stack) - 1: + self.syntax_error('missing close tag for %s' % self.stack[-1][2]) + nstag = self.stack[-1][2] + method = self.elements.get(nstag, (None, None))[1] + if method is not None: + self.handle_endtag(nstag, method) + else: + self.unknown_endtag(nstag) + if self.__use_namespaces == len(self.stack): + self.__use_namespaces = 0 + del self.stack[-1] + + # Overridable -- handle xml processing instruction + def handle_xml(self, encoding, standalone): + pass + + # Overridable -- handle DOCTYPE + def handle_doctype(self, tag, pubid, syslit, data): + pass + + # Overridable -- handle start tag + def handle_starttag(self, tag, method, attrs): + method(attrs) + + # Overridable -- handle end tag + def handle_endtag(self, tag, method): + method() + + # Example -- handle character reference, no need to override + def handle_charref(self, name): + try: + if name[0] == 'x': + n = int(name[1:], 16) + else: + n = int(name) + except ValueError: + self.unknown_charref(name) + return + if not 0 <= n <= 255: + self.unknown_charref(name) + return + self.handle_data(chr(n)) + + # Definition of entities -- derived classes may override + entitydefs = {'lt': '<', # must use charref + 'gt': '>', + 'amp': '&', # must use charref + 'quot': '"', + 'apos': ''', + } + + # Example -- handle data, should be overridden + def handle_data(self, data): + pass + + # Example -- handle cdata, could be overridden + def handle_cdata(self, data): + pass + + # Example -- handle comment, could be overridden + def handle_comment(self, data): + pass + + # Example -- handle processing instructions, could be overridden + def handle_proc(self, name, data): + pass + + # Example -- handle relatively harmless syntax errors, could be overridden + def syntax_error(self, message): + raise Error('Syntax error at line %d: %s' % (self.lineno, message)) + + # To be overridden -- handlers for unknown objects + def unknown_starttag(self, tag, attrs): pass + def unknown_endtag(self, tag): pass + def unknown_charref(self, ref): pass + def unknown_entityref(self, name): + self.syntax_error("reference to unknown entity `&%s;'" % name) + + +class TestXMLParser(XMLParser): + + def __init__(self, **kw): + self.testdata = "" + XMLParser.__init__(self, **kw) + + def handle_xml(self, encoding, standalone): + self.flush() + print 'xml: encoding =',encoding,'standalone =',standalone + + def handle_doctype(self, tag, pubid, syslit, data): + self.flush() + print 'DOCTYPE:',tag, repr(data) + + def handle_data(self, data): + self.testdata = self.testdata + data + if len(repr(self.testdata)) >= 70: + self.flush() + + def flush(self): + data = self.testdata + if data: + self.testdata = "" + print 'data:', repr(data) + + def handle_cdata(self, data): + self.flush() + print 'cdata:', repr(data) + + def handle_proc(self, name, data): + self.flush() + print 'processing:',name,repr(data) + + def handle_comment(self, data): + self.flush() + r = repr(data) + if len(r) > 68: + r = r[:32] + '...' + r[-32:] + print 'comment:', r + + def syntax_error(self, message): + print 'error at line %d:' % self.lineno, message + + def unknown_starttag(self, tag, attrs): + self.flush() + if not attrs: + print 'start tag: <' + tag + '>' + else: + print 'start tag: <' + tag, + for name, value in attrs.items(): + print name + '=' + '"' + value + '"', + print '>' + + def unknown_endtag(self, tag): + self.flush() + print 'end tag: </' + tag + '>' + + def unknown_entityref(self, ref): + self.flush() + print '*** unknown entity ref: &' + ref + ';' + + def unknown_charref(self, ref): + self.flush() + print '*** unknown char ref: &#' + ref + ';' + + def close(self): + XMLParser.close(self) + self.flush() + +def test(args = None): + import sys, getopt + from time import time + + if not args: + args = sys.argv[1:] + + opts, args = getopt.getopt(args, 'st') + klass = TestXMLParser + do_time = 0 + for o, a in opts: + if o == '-s': + klass = XMLParser + elif o == '-t': + do_time = 1 + + if args: + file = args[0] + else: + file = 'test.xml' + + if file == '-': + f = sys.stdin + else: + try: + f = open(file, 'r') + except IOError, msg: + print file, ":", msg + sys.exit(1) + + data = f.read() + if f is not sys.stdin: + f.close() + + x = klass() + t0 = time() + try: + if do_time: + x.feed(data) + x.close() + else: + for c in data: + x.feed(c) + x.close() + except Error, msg: + t1 = time() + print msg + if do_time: + print 'total time: %g' % (t1-t0) + sys.exit(1) + t1 = time() + if do_time: + print 'total time: %g' % (t1-t0) + + +if __name__ == '__main__': + test() diff --git a/src/main/resources/PythonLibs/xmlrpclib.py b/src/main/resources/PythonLibs/xmlrpclib.py new file mode 100644 index 0000000000000000000000000000000000000000..b93ea23b929750c43d737de3d9aca8ccc4da5062 --- /dev/null +++ b/src/main/resources/PythonLibs/xmlrpclib.py @@ -0,0 +1,1639 @@ +# +# XML-RPC CLIENT LIBRARY +# $Id$ +# +# an XML-RPC client interface for Python. +# +# the marshalling and response parser code can also be used to +# implement XML-RPC servers. +# +# Notes: +# this version is designed to work with Python 2.1 or newer. +# +# History: +# 1999-01-14 fl Created +# 1999-01-15 fl Changed dateTime to use localtime +# 1999-01-16 fl Added Binary/base64 element, default to RPC2 service +# 1999-01-19 fl Fixed array data element (from Skip Montanaro) +# 1999-01-21 fl Fixed dateTime constructor, etc. +# 1999-02-02 fl Added fault handling, handle empty sequences, etc. +# 1999-02-10 fl Fixed problem with empty responses (from Skip Montanaro) +# 1999-06-20 fl Speed improvements, pluggable parsers/transports (0.9.8) +# 2000-11-28 fl Changed boolean to check the truth value of its argument +# 2001-02-24 fl Added encoding/Unicode/SafeTransport patches +# 2001-02-26 fl Added compare support to wrappers (0.9.9/1.0b1) +# 2001-03-28 fl Make sure response tuple is a singleton +# 2001-03-29 fl Don't require empty params element (from Nicholas Riley) +# 2001-06-10 fl Folded in _xmlrpclib accelerator support (1.0b2) +# 2001-08-20 fl Base xmlrpclib.Error on built-in Exception (from Paul Prescod) +# 2001-09-03 fl Allow Transport subclass to override getparser +# 2001-09-10 fl Lazy import of urllib, cgi, xmllib (20x import speedup) +# 2001-10-01 fl Remove containers from memo cache when done with them +# 2001-10-01 fl Use faster escape method (80% dumps speedup) +# 2001-10-02 fl More dumps microtuning +# 2001-10-04 fl Make sure import expat gets a parser (from Guido van Rossum) +# 2001-10-10 sm Allow long ints to be passed as ints if they don't overflow +# 2001-10-17 sm Test for int and long overflow (allows use on 64-bit systems) +# 2001-11-12 fl Use repr() to marshal doubles (from Paul Felix) +# 2002-03-17 fl Avoid buffered read when possible (from James Rucker) +# 2002-04-07 fl Added pythondoc comments +# 2002-04-16 fl Added __str__ methods to datetime/binary wrappers +# 2002-05-15 fl Added error constants (from Andrew Kuchling) +# 2002-06-27 fl Merged with Python CVS version +# 2002-10-22 fl Added basic authentication (based on code from Phillip Eby) +# 2003-01-22 sm Add support for the bool type +# 2003-02-27 gvr Remove apply calls +# 2003-04-24 sm Use cStringIO if available +# 2003-04-25 ak Add support for nil +# 2003-06-15 gn Add support for time.struct_time +# 2003-07-12 gp Correct marshalling of Faults +# 2003-10-31 mvl Add multicall support +# 2004-08-20 mvl Bump minimum supported Python version to 2.1 +# +# Copyright (c) 1999-2002 by Secret Labs AB. +# Copyright (c) 1999-2002 by Fredrik Lundh. +# +# info@pythonware.com +# http://www.pythonware.com +# +# -------------------------------------------------------------------- +# The XML-RPC client interface is +# +# Copyright (c) 1999-2002 by Secret Labs AB +# Copyright (c) 1999-2002 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# 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. +# -------------------------------------------------------------------- + +# +# things to look into some day: + +# TODO: sort out True/False/boolean issues for Python 2.3 + +""" +An XML-RPC client interface for Python. + +The marshalling and response parser code can also be used to +implement XML-RPC servers. + +Exported exceptions: + + Error Base class for client errors + ProtocolError Indicates an HTTP protocol error + ResponseError Indicates a broken response package + Fault Indicates an XML-RPC fault package + +Exported classes: + + ServerProxy Represents a logical connection to an XML-RPC server + + MultiCall Executor of boxcared xmlrpc requests + Boolean boolean wrapper to generate a "boolean" XML-RPC value + DateTime dateTime wrapper for an ISO 8601 string or time tuple or + localtime integer value to generate a "dateTime.iso8601" + XML-RPC value + Binary binary data wrapper + + SlowParser Slow but safe standard parser (based on xmllib) + Marshaller Generate an XML-RPC params chunk from a Python data structure + Unmarshaller Unmarshal an XML-RPC response from incoming XML event message + Transport Handles an HTTP transaction to an XML-RPC server + SafeTransport Handles an HTTPS transaction to an XML-RPC server + +Exported constants: + + True + False + +Exported functions: + + boolean Convert any Python value to an XML-RPC boolean + getparser Create instance of the fastest available parser & attach + to an unmarshalling object + dumps Convert an argument tuple or a Fault instance to an XML-RPC + request (or response, if the methodresponse option is used). + loads Convert an XML-RPC packet to unmarshalled data plus a method + name (None if not present). +""" + +import re, string, time, operator + +from types import * +import socket +import errno +import httplib +try: + import gzip +except ImportError: + gzip = None #python can be built without zlib/gzip support + +# -------------------------------------------------------------------- +# Internal stuff + +try: + unicode +except NameError: + unicode = None # unicode support not available + +try: + import datetime +except ImportError: + datetime = None + +try: + _bool_is_builtin = False.__class__.__name__ == "bool" +except NameError: + _bool_is_builtin = 0 + +def _decode(data, encoding, is8bit=re.compile("[\x80-\xff]").search): + # decode non-ascii string (if possible) + if unicode and encoding and is8bit(data): + data = unicode(data, encoding) + return data + +def escape(s, replace=string.replace): + s = replace(s, "&", "&") + s = replace(s, "<", "<") + return replace(s, ">", ">",) + +if unicode: + def _stringify(string): + # convert to 7-bit ascii if possible + try: + return string.encode("ascii") + except UnicodeError: + return string +else: + def _stringify(string): + return string + +__version__ = "1.0.1" + +# xmlrpc integer limits +MAXINT = 2L**31-1 +MININT = -2L**31 + +# -------------------------------------------------------------------- +# Error constants (from Dan Libby's specification at +# http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php) + +# Ranges of errors +PARSE_ERROR = -32700 +SERVER_ERROR = -32600 +APPLICATION_ERROR = -32500 +SYSTEM_ERROR = -32400 +TRANSPORT_ERROR = -32300 + +# Specific errors +NOT_WELLFORMED_ERROR = -32700 +UNSUPPORTED_ENCODING = -32701 +INVALID_ENCODING_CHAR = -32702 +INVALID_XMLRPC = -32600 +METHOD_NOT_FOUND = -32601 +INVALID_METHOD_PARAMS = -32602 +INTERNAL_ERROR = -32603 + +# -------------------------------------------------------------------- +# Exceptions + +## +# Base class for all kinds of client-side errors. + +class Error(Exception): + """Base class for client errors.""" + def __str__(self): + return repr(self) + +## +# Indicates an HTTP-level protocol error. This is raised by the HTTP +# transport layer, if the server returns an error code other than 200 +# (OK). +# +# @param url The target URL. +# @param errcode The HTTP error code. +# @param errmsg The HTTP error message. +# @param headers The HTTP header dictionary. + +class ProtocolError(Error): + """Indicates an HTTP protocol error.""" + def __init__(self, url, errcode, errmsg, headers): + Error.__init__(self) + self.url = url + self.errcode = errcode + self.errmsg = errmsg + self.headers = headers + def __repr__(self): + return ( + "<ProtocolError for %s: %s %s>" % + (self.url, self.errcode, self.errmsg) + ) + +## +# Indicates a broken XML-RPC response package. This exception is +# raised by the unmarshalling layer, if the XML-RPC response is +# malformed. + +class ResponseError(Error): + """Indicates a broken response package.""" + pass + +## +# Indicates an XML-RPC fault response package. This exception is +# raised by the unmarshalling layer, if the XML-RPC response contains +# a fault string. This exception can also used as a class, to +# generate a fault XML-RPC message. +# +# @param faultCode The XML-RPC fault code. +# @param faultString The XML-RPC fault string. + +class Fault(Error): + """Indicates an XML-RPC fault package.""" + def __init__(self, faultCode, faultString, **extra): + Error.__init__(self) + self.faultCode = faultCode + self.faultString = faultString + def __repr__(self): + return ( + "<Fault %s: %s>" % + (self.faultCode, repr(self.faultString)) + ) + +# -------------------------------------------------------------------- +# Special values + +## +# Wrapper for XML-RPC boolean values. Use the xmlrpclib.True and +# xmlrpclib.False constants, or the xmlrpclib.boolean() function, to +# generate boolean XML-RPC values. +# +# @param value A boolean value. Any true value is interpreted as True, +# all other values are interpreted as False. + +from sys import modules +mod_dict = modules[__name__].__dict__ +if _bool_is_builtin: + boolean = Boolean = bool + # to avoid breaking code which references xmlrpclib.{True,False} + mod_dict['True'] = True + mod_dict['False'] = False +else: + class Boolean: + """Boolean-value wrapper. + + Use True or False to generate a "boolean" XML-RPC value. + """ + + def __init__(self, value = 0): + self.value = operator.truth(value) + + def encode(self, out): + out.write("<value><boolean>%d</boolean></value>\n" % self.value) + + def __cmp__(self, other): + if isinstance(other, Boolean): + other = other.value + return cmp(self.value, other) + + def __repr__(self): + if self.value: + return "<Boolean True at %x>" % id(self) + else: + return "<Boolean False at %x>" % id(self) + + def __int__(self): + return self.value + + def __nonzero__(self): + return self.value + + mod_dict['True'] = Boolean(1) + mod_dict['False'] = Boolean(0) + + ## + # Map true or false value to XML-RPC boolean values. + # + # @def boolean(value) + # @param value A boolean value. Any true value is mapped to True, + # all other values are mapped to False. + # @return xmlrpclib.True or xmlrpclib.False. + # @see Boolean + # @see True + # @see False + + def boolean(value, _truefalse=(False, True)): + """Convert any Python value to XML-RPC 'boolean'.""" + return _truefalse[operator.truth(value)] + +del modules, mod_dict + +## +# Wrapper for XML-RPC DateTime values. This converts a time value to +# the format used by XML-RPC. +# <p> +# The value can be given as a string in the format +# "yyyymmddThh:mm:ss", as a 9-item time tuple (as returned by +# time.localtime()), or an integer value (as returned by time.time()). +# The wrapper uses time.localtime() to convert an integer to a time +# tuple. +# +# @param value The time, given as an ISO 8601 string, a time +# tuple, or a integer time value. + +def _strftime(value): + if datetime: + if isinstance(value, datetime.datetime): + return "%04d%02d%02dT%02d:%02d:%02d" % ( + value.year, value.month, value.day, + value.hour, value.minute, value.second) + + if not isinstance(value, (TupleType, time.struct_time)): + if value == 0: + value = time.time() + value = time.localtime(value) + + return "%04d%02d%02dT%02d:%02d:%02d" % value[:6] + +class DateTime: + """DateTime wrapper for an ISO 8601 string or time tuple or + localtime integer value to generate 'dateTime.iso8601' XML-RPC + value. + """ + + def __init__(self, value=0): + if isinstance(value, StringType): + self.value = value + else: + self.value = _strftime(value) + + def make_comparable(self, other): + if isinstance(other, DateTime): + s = self.value + o = other.value + elif datetime and isinstance(other, datetime.datetime): + s = self.value + o = other.strftime("%Y%m%dT%H:%M:%S") + elif isinstance(other, (str, unicode)): + s = self.value + o = other + elif hasattr(other, "timetuple"): + s = self.timetuple() + o = other.timetuple() + else: + otype = (hasattr(other, "__class__") + and other.__class__.__name__ + or type(other)) + raise TypeError("Can't compare %s and %s" % + (self.__class__.__name__, otype)) + return s, o + + def __lt__(self, other): + s, o = self.make_comparable(other) + return s < o + + def __le__(self, other): + s, o = self.make_comparable(other) + return s <= o + + def __gt__(self, other): + s, o = self.make_comparable(other) + return s > o + + def __ge__(self, other): + s, o = self.make_comparable(other) + return s >= o + + def __eq__(self, other): + s, o = self.make_comparable(other) + return s == o + + def __ne__(self, other): + s, o = self.make_comparable(other) + return s != o + + def timetuple(self): + return time.strptime(self.value, "%Y%m%dT%H:%M:%S") + + def __cmp__(self, other): + s, o = self.make_comparable(other) + return cmp(s, o) + + ## + # Get date/time value. + # + # @return Date/time value, as an ISO 8601 string. + + def __str__(self): + return self.value + + def __repr__(self): + return "<DateTime %s at %x>" % (repr(self.value), id(self)) + + def decode(self, data): + data = str(data) + self.value = string.strip(data) + + def encode(self, out): + out.write("<value><dateTime.iso8601>") + out.write(self.value) + out.write("</dateTime.iso8601></value>\n") + +def _datetime(data): + # decode xml element contents into a DateTime structure. + value = DateTime() + value.decode(data) + return value + +def _datetime_type(data): + t = time.strptime(data, "%Y%m%dT%H:%M:%S") + return datetime.datetime(*tuple(t)[:6]) + +## +# Wrapper for binary data. This can be used to transport any kind +# of binary data over XML-RPC, using BASE64 encoding. +# +# @param data An 8-bit string containing arbitrary data. + +import base64 +try: + import cStringIO as StringIO +except ImportError: + import StringIO + +class Binary: + """Wrapper for binary data.""" + + def __init__(self, data=None): + self.data = data + + ## + # Get buffer contents. + # + # @return Buffer contents, as an 8-bit string. + + def __str__(self): + return self.data or "" + + def __cmp__(self, other): + if isinstance(other, Binary): + other = other.data + return cmp(self.data, other) + + def decode(self, data): + self.data = base64.decodestring(data) + + def encode(self, out): + out.write("<value><base64>\n") + base64.encode(StringIO.StringIO(self.data), out) + out.write("</base64></value>\n") + +def _binary(data): + # decode xml element contents into a Binary structure + value = Binary() + value.decode(data) + return value + +WRAPPERS = (DateTime, Binary) +if not _bool_is_builtin: + WRAPPERS = WRAPPERS + (Boolean,) + +# -------------------------------------------------------------------- +# XML parsers + +try: + # optional xmlrpclib accelerator + import _xmlrpclib + FastParser = _xmlrpclib.Parser + FastUnmarshaller = _xmlrpclib.Unmarshaller +except (AttributeError, ImportError): + FastParser = FastUnmarshaller = None + +try: + import _xmlrpclib + FastMarshaller = _xmlrpclib.Marshaller +except (AttributeError, ImportError): + FastMarshaller = None + +try: + from xml.parsers import expat + if not hasattr(expat, "ParserCreate"): + raise ImportError +except ImportError: + ExpatParser = None # expat not available +else: + class ExpatParser: + # fast expat parser for Python 2.0 and later. + def __init__(self, target): + self._parser = parser = expat.ParserCreate(None, None) + self._target = target + parser.StartElementHandler = target.start + parser.EndElementHandler = target.end + parser.CharacterDataHandler = target.data + encoding = None + if not parser.returns_unicode: + encoding = "utf-8" + target.xml(encoding, None) + + def feed(self, data): + self._parser.Parse(data, 0) + + def close(self): + self._parser.Parse("", 1) # end of data + del self._target, self._parser # get rid of circular references + +class SlowParser: + """Default XML parser (based on xmllib.XMLParser).""" + # this is the slowest parser. + def __init__(self, target): + import xmllib # lazy subclassing (!) + if xmllib.XMLParser not in SlowParser.__bases__: + SlowParser.__bases__ = (xmllib.XMLParser,) + self.handle_xml = target.xml + self.unknown_starttag = target.start + self.handle_data = target.data + self.handle_cdata = target.data + self.unknown_endtag = target.end + try: + xmllib.XMLParser.__init__(self, accept_utf8=1) + except TypeError: + xmllib.XMLParser.__init__(self) # pre-2.0 + +# -------------------------------------------------------------------- +# XML-RPC marshalling and unmarshalling code + +## +# XML-RPC marshaller. +# +# @param encoding Default encoding for 8-bit strings. The default +# value is None (interpreted as UTF-8). +# @see dumps + +class Marshaller: + """Generate an XML-RPC params chunk from a Python data structure. + + Create a Marshaller instance for each set of parameters, and use + the "dumps" method to convert your data (represented as a tuple) + to an XML-RPC params chunk. To write a fault response, pass a + Fault instance instead. You may prefer to use the "dumps" module + function for this purpose. + """ + + # by the way, if you don't understand what's going on in here, + # that's perfectly ok. + + def __init__(self, encoding=None, allow_none=0): + self.memo = {} + self.data = None + self.encoding = encoding + self.allow_none = allow_none + + dispatch = {} + + def dumps(self, values): + out = [] + write = out.append + dump = self.__dump + if isinstance(values, Fault): + # fault instance + write("<fault>\n") + dump({'faultCode': values.faultCode, + 'faultString': values.faultString}, + write) + write("</fault>\n") + else: + # parameter block + # FIXME: the xml-rpc specification allows us to leave out + # the entire <params> block if there are no parameters. + # however, changing this may break older code (including + # old versions of xmlrpclib.py), so this is better left as + # is for now. See @XMLRPC3 for more information. /F + write("<params>\n") + for v in values: + write("<param>\n") + dump(v, write) + write("</param>\n") + write("</params>\n") + result = string.join(out, "") + return result + + def __dump(self, value, write): + try: + f = self.dispatch[type(value)] + except KeyError: + # check if this object can be marshalled as a structure + try: + value.__dict__ + except: + raise TypeError, "cannot marshal %s objects" % type(value) + # check if this class is a sub-class of a basic type, + # because we don't know how to marshal these types + # (e.g. a string sub-class) + for type_ in type(value).__mro__: + if type_ in self.dispatch.keys(): + raise TypeError, "cannot marshal %s objects" % type(value) + f = self.dispatch[InstanceType] + f(self, value, write) + + def dump_nil (self, value, write): + if not self.allow_none: + raise TypeError, "cannot marshal None unless allow_none is enabled" + write("<value><nil/></value>") + dispatch[NoneType] = dump_nil + + def dump_int(self, value, write): + # in case ints are > 32 bits + if value > MAXINT or value < MININT: + raise OverflowError, "int exceeds XML-RPC limits" + write("<value><int>") + write(str(value)) + write("</int></value>\n") + dispatch[IntType] = dump_int + + if _bool_is_builtin: + def dump_bool(self, value, write): + write("<value><boolean>") + write(value and "1" or "0") + write("</boolean></value>\n") + dispatch[bool] = dump_bool + + def dump_long(self, value, write): + if value > MAXINT or value < MININT: + raise OverflowError, "long int exceeds XML-RPC limits" + write("<value><int>") + write(str(int(value))) + write("</int></value>\n") + dispatch[LongType] = dump_long + + def dump_double(self, value, write): + write("<value><double>") + write(repr(value)) + write("</double></value>\n") + dispatch[FloatType] = dump_double + + def dump_string(self, value, write, escape=escape): + write("<value><string>") + write(escape(value)) + write("</string></value>\n") + dispatch[StringType] = dump_string + + if unicode: + def dump_unicode(self, value, write, escape=escape): + value = value.encode(self.encoding) + write("<value><string>") + write(escape(value)) + write("</string></value>\n") + dispatch[UnicodeType] = dump_unicode + + def dump_array(self, value, write): + i = id(value) + if i in self.memo: + raise TypeError, "cannot marshal recursive sequences" + self.memo[i] = None + dump = self.__dump + write("<value><array><data>\n") + for v in value: + dump(v, write) + write("</data></array></value>\n") + del self.memo[i] + dispatch[TupleType] = dump_array + dispatch[ListType] = dump_array + + def dump_struct(self, value, write, escape=escape): + i = id(value) + if i in self.memo: + raise TypeError, "cannot marshal recursive dictionaries" + self.memo[i] = None + dump = self.__dump + write("<value><struct>\n") + for k, v in value.items(): + write("<member>\n") + if type(k) is not StringType: + if unicode and type(k) is UnicodeType: + k = k.encode(self.encoding) + else: + raise TypeError, "dictionary key must be string" + write("<name>%s</name>\n" % escape(k)) + dump(v, write) + write("</member>\n") + write("</struct></value>\n") + del self.memo[i] + dispatch[DictType] = dump_struct + + if datetime: + def dump_datetime(self, value, write): + write("<value><dateTime.iso8601>") + write(_strftime(value)) + write("</dateTime.iso8601></value>\n") + dispatch[datetime.datetime] = dump_datetime + + def dump_instance(self, value, write): + # check for special wrappers + if value.__class__ in WRAPPERS: + self.write = write + value.encode(self) + del self.write + else: + # store instance attributes as a struct (really?) + self.dump_struct(value.__dict__, write) + dispatch[InstanceType] = dump_instance + +## +# XML-RPC unmarshaller. +# +# @see loads + +class Unmarshaller: + """Unmarshal an XML-RPC response, based on incoming XML event + messages (start, data, end). Call close() to get the resulting + data structure. + + Note that this reader is fairly tolerant, and gladly accepts bogus + XML-RPC data without complaining (but not bogus XML). + """ + + # and again, if you don't understand what's going on in here, + # that's perfectly ok. + + def __init__(self, use_datetime=0): + self._type = None + self._stack = [] + self._marks = [] + self._data = [] + self._methodname = None + self._encoding = "utf-8" + self.append = self._stack.append + self._use_datetime = use_datetime + if use_datetime and not datetime: + raise ValueError, "the datetime module is not available" + + def close(self): + # return response tuple and target method + if self._type is None or self._marks: + raise ResponseError() + if self._type == "fault": + raise Fault(**self._stack[0]) + return tuple(self._stack) + + def getmethodname(self): + return self._methodname + + # + # event handlers + + def xml(self, encoding, standalone): + self._encoding = encoding + # FIXME: assert standalone == 1 ??? + + def start(self, tag, attrs): + # prepare to handle this element + if tag == "array" or tag == "struct": + self._marks.append(len(self._stack)) + self._data = [] + self._value = (tag == "value") + + def data(self, text): + self._data.append(text) + + def end(self, tag, join=string.join): + # call the appropriate end tag handler + try: + f = self.dispatch[tag] + except KeyError: + pass # unknown tag ? + else: + return f(self, join(self._data, "")) + + # + # accelerator support + + def end_dispatch(self, tag, data): + # dispatch data + try: + f = self.dispatch[tag] + except KeyError: + pass # unknown tag ? + else: + return f(self, data) + + # + # element decoders + + dispatch = {} + + def end_nil (self, data): + self.append(None) + self._value = 0 + dispatch["nil"] = end_nil + + def end_boolean(self, data): + if data == "0": + self.append(False) + elif data == "1": + self.append(True) + else: + raise TypeError, "bad boolean value" + self._value = 0 + dispatch["boolean"] = end_boolean + + def end_int(self, data): + self.append(int(data)) + self._value = 0 + dispatch["i4"] = end_int + dispatch["i8"] = end_int + dispatch["int"] = end_int + + def end_double(self, data): + self.append(float(data)) + self._value = 0 + dispatch["double"] = end_double + + def end_string(self, data): + if self._encoding: + data = _decode(data, self._encoding) + self.append(_stringify(data)) + self._value = 0 + dispatch["string"] = end_string + dispatch["name"] = end_string # struct keys are always strings + + def end_array(self, data): + mark = self._marks.pop() + # map arrays to Python lists + self._stack[mark:] = [self._stack[mark:]] + self._value = 0 + dispatch["array"] = end_array + + def end_struct(self, data): + mark = self._marks.pop() + # map structs to Python dictionaries + dict = {} + items = self._stack[mark:] + for i in range(0, len(items), 2): + dict[_stringify(items[i])] = items[i+1] + self._stack[mark:] = [dict] + self._value = 0 + dispatch["struct"] = end_struct + + def end_base64(self, data): + value = Binary() + value.decode(data) + self.append(value) + self._value = 0 + dispatch["base64"] = end_base64 + + def end_dateTime(self, data): + value = DateTime() + value.decode(data) + if self._use_datetime: + value = _datetime_type(data) + self.append(value) + dispatch["dateTime.iso8601"] = end_dateTime + + def end_value(self, data): + # if we stumble upon a value element with no internal + # elements, treat it as a string element + if self._value: + self.end_string(data) + dispatch["value"] = end_value + + def end_params(self, data): + self._type = "params" + dispatch["params"] = end_params + + def end_fault(self, data): + self._type = "fault" + dispatch["fault"] = end_fault + + def end_methodName(self, data): + if self._encoding: + data = _decode(data, self._encoding) + self._methodname = data + self._type = "methodName" # no params + dispatch["methodName"] = end_methodName + +## Multicall support +# + +class _MultiCallMethod: + # some lesser magic to store calls made to a MultiCall object + # for batch execution + def __init__(self, call_list, name): + self.__call_list = call_list + self.__name = name + def __getattr__(self, name): + return _MultiCallMethod(self.__call_list, "%s.%s" % (self.__name, name)) + def __call__(self, *args): + self.__call_list.append((self.__name, args)) + +class MultiCallIterator: + """Iterates over the results of a multicall. Exceptions are + raised in response to xmlrpc faults.""" + + def __init__(self, results): + self.results = results + + def __getitem__(self, i): + item = self.results[i] + if type(item) == type({}): + raise Fault(item['faultCode'], item['faultString']) + elif type(item) == type([]): + return item[0] + else: + raise ValueError,\ + "unexpected type in multicall result" + +class MultiCall: + """server -> a object used to boxcar method calls + + server should be a ServerProxy object. + + Methods can be added to the MultiCall using normal + method call syntax e.g.: + + multicall = MultiCall(server_proxy) + multicall.add(2,3) + multicall.get_address("Guido") + + To execute the multicall, call the MultiCall object e.g.: + + add_result, address = multicall() + """ + + def __init__(self, server): + self.__server = server + self.__call_list = [] + + def __repr__(self): + return "<MultiCall at %x>" % id(self) + + __str__ = __repr__ + + def __getattr__(self, name): + return _MultiCallMethod(self.__call_list, name) + + def __call__(self): + marshalled_list = [] + for name, args in self.__call_list: + marshalled_list.append({'methodName' : name, 'params' : args}) + + return MultiCallIterator(self.__server.system.multicall(marshalled_list)) + +# -------------------------------------------------------------------- +# convenience functions + +## +# Create a parser object, and connect it to an unmarshalling instance. +# This function picks the fastest available XML parser. +# +# return A (parser, unmarshaller) tuple. + +def getparser(use_datetime=0): + """getparser() -> parser, unmarshaller + + Create an instance of the fastest available parser, and attach it + to an unmarshalling object. Return both objects. + """ + if use_datetime and not datetime: + raise ValueError, "the datetime module is not available" + if FastParser and FastUnmarshaller: + if use_datetime: + mkdatetime = _datetime_type + else: + mkdatetime = _datetime + target = FastUnmarshaller(True, False, _binary, mkdatetime, Fault) + parser = FastParser(target) + else: + target = Unmarshaller(use_datetime=use_datetime) + if FastParser: + parser = FastParser(target) + elif ExpatParser: + parser = ExpatParser(target) + else: + parser = SlowParser(target) + return parser, target + +## +# Convert a Python tuple or a Fault instance to an XML-RPC packet. +# +# @def dumps(params, **options) +# @param params A tuple or Fault instance. +# @keyparam methodname If given, create a methodCall request for +# this method name. +# @keyparam methodresponse If given, create a methodResponse packet. +# If used with a tuple, the tuple must be a singleton (that is, +# it must contain exactly one element). +# @keyparam encoding The packet encoding. +# @return A string containing marshalled data. + +def dumps(params, methodname=None, methodresponse=None, encoding=None, + allow_none=0): + """data [,options] -> marshalled data + + Convert an argument tuple or a Fault instance to an XML-RPC + request (or response, if the methodresponse option is used). + + In addition to the data object, the following options can be given + as keyword arguments: + + methodname: the method name for a methodCall packet + + methodresponse: true to create a methodResponse packet. + If this option is used with a tuple, the tuple must be + a singleton (i.e. it can contain only one element). + + encoding: the packet encoding (default is UTF-8) + + All 8-bit strings in the data structure are assumed to use the + packet encoding. Unicode strings are automatically converted, + where necessary. + """ + + assert isinstance(params, TupleType) or isinstance(params, Fault),\ + "argument must be tuple or Fault instance" + + if isinstance(params, Fault): + methodresponse = 1 + elif methodresponse and isinstance(params, TupleType): + assert len(params) == 1, "response tuple must be a singleton" + + if not encoding: + encoding = "utf-8" + + if FastMarshaller: + m = FastMarshaller(encoding) + else: + m = Marshaller(encoding, allow_none) + + data = m.dumps(params) + + if encoding != "utf-8": + xmlheader = "<?xml version='1.0' encoding='%s'?>\n" % str(encoding) + else: + xmlheader = "<?xml version='1.0'?>\n" # utf-8 is default + + # standard XML-RPC wrappings + if methodname: + # a method call + if not isinstance(methodname, StringType): + methodname = methodname.encode(encoding) + data = ( + xmlheader, + "<methodCall>\n" + "<methodName>", methodname, "</methodName>\n", + data, + "</methodCall>\n" + ) + elif methodresponse: + # a method response, or a fault structure + data = ( + xmlheader, + "<methodResponse>\n", + data, + "</methodResponse>\n" + ) + else: + return data # return as is + return string.join(data, "") + +## +# Convert an XML-RPC packet to a Python object. If the XML-RPC packet +# represents a fault condition, this function raises a Fault exception. +# +# @param data An XML-RPC packet, given as an 8-bit string. +# @return A tuple containing the unpacked data, and the method name +# (None if not present). +# @see Fault + +def loads(data, use_datetime=0): + """data -> unmarshalled data, method name + + Convert an XML-RPC packet to unmarshalled data plus a method + name (None if not present). + + If the XML-RPC packet represents a fault condition, this function + raises a Fault exception. + """ + p, u = getparser(use_datetime=use_datetime) + p.feed(data) + p.close() + return u.close(), u.getmethodname() + +## +# Encode a string using the gzip content encoding such as specified by the +# Content-Encoding: gzip +# in the HTTP header, as described in RFC 1952 +# +# @param data the unencoded data +# @return the encoded data + +def gzip_encode(data): + """data -> gzip encoded data + + Encode data using the gzip content encoding as described in RFC 1952 + """ + if not gzip: + raise NotImplementedError + f = StringIO.StringIO() + gzf = gzip.GzipFile(mode="wb", fileobj=f, compresslevel=1) + gzf.write(data) + gzf.close() + encoded = f.getvalue() + f.close() + return encoded + +## +# Decode a string using the gzip content encoding such as specified by the +# Content-Encoding: gzip +# in the HTTP header, as described in RFC 1952 +# +# @param data The encoded data +# @return the unencoded data +# @raises ValueError if data is not correctly coded. + +def gzip_decode(data): + """gzip encoded data -> unencoded data + + Decode data using the gzip content encoding as described in RFC 1952 + """ + if not gzip: + raise NotImplementedError + f = StringIO.StringIO(data) + gzf = gzip.GzipFile(mode="rb", fileobj=f) + try: + decoded = gzf.read() + except IOError: + raise ValueError("invalid data") + f.close() + gzf.close() + return decoded + +## +# Return a decoded file-like object for the gzip encoding +# as described in RFC 1952. +# +# @param response A stream supporting a read() method +# @return a file-like object that the decoded data can be read() from + +class GzipDecodedResponse(gzip.GzipFile if gzip else object): + """a file-like object to decode a response encoded with the gzip + method, as described in RFC 1952. + """ + def __init__(self, response): + #response doesn't support tell() and read(), required by + #GzipFile + if not gzip: + raise NotImplementedError + self.stringio = StringIO.StringIO(response.read()) + gzip.GzipFile.__init__(self, mode="rb", fileobj=self.stringio) + + def close(self): + gzip.GzipFile.close(self) + self.stringio.close() + + +# -------------------------------------------------------------------- +# request dispatcher + +class _Method: + # some magic to bind an XML-RPC method to an RPC server. + # supports "nested" methods (e.g. examples.getStateName) + def __init__(self, send, name): + self.__send = send + self.__name = name + def __getattr__(self, name): + return _Method(self.__send, "%s.%s" % (self.__name, name)) + def __call__(self, *args): + return self.__send(self.__name, args) + +## +# Standard transport class for XML-RPC over HTTP. +# <p> +# You can create custom transports by subclassing this method, and +# overriding selected methods. + +class Transport: + """Handles an HTTP transaction to an XML-RPC server.""" + + # client identifier (may be overridden) + user_agent = "xmlrpclib.py/%s (by www.pythonware.com)" % __version__ + + #if true, we'll request gzip encoding + accept_gzip_encoding = True + + # if positive, encode request using gzip if it exceeds this threshold + # note that many server will get confused, so only use it if you know + # that they can decode such a request + encode_threshold = None #None = don't encode + + def __init__(self, use_datetime=0): + self._use_datetime = use_datetime + self._connection = (None, None) + self._extra_headers = [] + ## + # Send a complete request, and parse the response. + # Retry request if a cached connection has disconnected. + # + # @param host Target host. + # @param handler Target PRC handler. + # @param request_body XML-RPC request body. + # @param verbose Debugging flag. + # @return Parsed response. + + def request(self, host, handler, request_body, verbose=0): + #retry request once if cached connection has gone cold + for i in (0, 1): + try: + return self.single_request(host, handler, request_body, verbose) + except socket.error, e: + if i or e.errno not in (errno.ECONNRESET, errno.ECONNABORTED, errno.EPIPE): + raise + except httplib.BadStatusLine: #close after we sent request + if i: + raise + + ## + # Send a complete request, and parse the response. + # + # @param host Target host. + # @param handler Target PRC handler. + # @param request_body XML-RPC request body. + # @param verbose Debugging flag. + # @return Parsed response. + + def single_request(self, host, handler, request_body, verbose=0): + # issue XML-RPC request + + h = self.make_connection(host) + if verbose: + h.set_debuglevel(1) + + try: + self.send_request(h, handler, request_body) + self.send_host(h, host) + self.send_user_agent(h) + self.send_content(h, request_body) + + response = h.getresponse(buffering=True) + if response.status == 200: + self.verbose = verbose + return self.parse_response(response) + except Fault: + raise + except Exception: + # All unexpected errors leave connection in + # a strange state, so we clear it. + self.close() + raise + + #discard any response data and raise exception + if (response.getheader("content-length", 0)): + response.read() + raise ProtocolError( + host + handler, + response.status, response.reason, + response.msg, + ) + + ## + # Create parser. + # + # @return A 2-tuple containing a parser and a unmarshaller. + + def getparser(self): + # get parser and unmarshaller + return getparser(use_datetime=self._use_datetime) + + ## + # Get authorization info from host parameter + # Host may be a string, or a (host, x509-dict) tuple; if a string, + # it is checked for a "user:pw@host" format, and a "Basic + # Authentication" header is added if appropriate. + # + # @param host Host descriptor (URL or (URL, x509 info) tuple). + # @return A 3-tuple containing (actual host, extra headers, + # x509 info). The header and x509 fields may be None. + + def get_host_info(self, host): + + x509 = {} + if isinstance(host, TupleType): + host, x509 = host + + import urllib + auth, host = urllib.splituser(host) + + if auth: + import base64 + auth = base64.encodestring(urllib.unquote(auth)) + auth = string.join(string.split(auth), "") # get rid of whitespace + extra_headers = [ + ("Authorization", "Basic " + auth) + ] + else: + extra_headers = None + + return host, extra_headers, x509 + + ## + # Connect to server. + # + # @param host Target host. + # @return A connection handle. + + def make_connection(self, host): + #return an existing connection if possible. This allows + #HTTP/1.1 keep-alive. + if self._connection and host == self._connection[0]: + return self._connection[1] + + # create a HTTP connection object from a host descriptor + chost, self._extra_headers, x509 = self.get_host_info(host) + #store the host argument along with the connection object + self._connection = host, httplib.HTTPConnection(chost) + return self._connection[1] + + ## + # Clear any cached connection object. + # Used in the event of socket errors. + # + def close(self): + if self._connection[1]: + self._connection[1].close() + self._connection = (None, None) + + ## + # Send request header. + # + # @param connection Connection handle. + # @param handler Target RPC handler. + # @param request_body XML-RPC body. + + def send_request(self, connection, handler, request_body): + if (self.accept_gzip_encoding and gzip): + connection.putrequest("POST", handler, skip_accept_encoding=True) + connection.putheader("Accept-Encoding", "gzip") + else: + connection.putrequest("POST", handler) + + ## + # Send host name. + # + # @param connection Connection handle. + # @param host Host name. + # + # Note: This function doesn't actually add the "Host" + # header anymore, it is done as part of the connection.putrequest() in + # send_request() above. + + def send_host(self, connection, host): + extra_headers = self._extra_headers + if extra_headers: + if isinstance(extra_headers, DictType): + extra_headers = extra_headers.items() + for key, value in extra_headers: + connection.putheader(key, value) + + ## + # Send user-agent identifier. + # + # @param connection Connection handle. + + def send_user_agent(self, connection): + connection.putheader("User-Agent", self.user_agent) + + ## + # Send request body. + # + # @param connection Connection handle. + # @param request_body XML-RPC request body. + + def send_content(self, connection, request_body): + connection.putheader("Content-Type", "text/xml") + + #optionally encode the request + if (self.encode_threshold is not None and + self.encode_threshold < len(request_body) and + gzip): + connection.putheader("Content-Encoding", "gzip") + request_body = gzip_encode(request_body) + + connection.putheader("Content-Length", str(len(request_body))) + connection.endheaders(request_body) + + ## + # Parse response. + # + # @param file Stream. + # @return Response tuple and target method. + + def parse_response(self, response): + # read response data from httpresponse, and parse it + + # Check for new http response object, else it is a file object + if hasattr(response,'getheader'): + if response.getheader("Content-Encoding", "") == "gzip": + stream = GzipDecodedResponse(response) + else: + stream = response + else: + stream = response + + p, u = self.getparser() + + while 1: + data = stream.read(1024) + if not data: + break + if self.verbose: + print "body:", repr(data) + p.feed(data) + + if stream is not response: + stream.close() + p.close() + + return u.close() + +## +# Standard transport class for XML-RPC over HTTPS. + +class SafeTransport(Transport): + """Handles an HTTPS transaction to an XML-RPC server.""" + + # FIXME: mostly untested + + def make_connection(self, host): + if self._connection and host == self._connection[0]: + return self._connection[1] + # create a HTTPS connection object from a host descriptor + # host may be a string, or a (host, x509-dict) tuple + try: + HTTPS = httplib.HTTPSConnection + except AttributeError: + raise NotImplementedError( + "your version of httplib doesn't support HTTPS" + ) + else: + chost, self._extra_headers, x509 = self.get_host_info(host) + self._connection = host, HTTPS(chost, None, **(x509 or {})) + return self._connection[1] + +## +# Standard server proxy. This class establishes a virtual connection +# to an XML-RPC server. +# <p> +# This class is available as ServerProxy and Server. New code should +# use ServerProxy, to avoid confusion. +# +# @def ServerProxy(uri, **options) +# @param uri The connection point on the server. +# @keyparam transport A transport factory, compatible with the +# standard transport class. +# @keyparam encoding The default encoding used for 8-bit strings +# (default is UTF-8). +# @keyparam verbose Use a true value to enable debugging output. +# (printed to standard output). +# @see Transport + +class ServerProxy: + """uri [,options] -> a logical connection to an XML-RPC server + + uri is the connection point on the server, given as + scheme://host/target. + + The standard implementation always supports the "http" scheme. If + SSL socket support is available (Python 2.0), it also supports + "https". + + If the target part and the slash preceding it are both omitted, + "/RPC2" is assumed. + + The following options can be given as keyword arguments: + + transport: a transport factory + encoding: the request encoding (default is UTF-8) + + All 8-bit strings passed to the server proxy are assumed to use + the given encoding. + """ + + def __init__(self, uri, transport=None, encoding=None, verbose=0, + allow_none=0, use_datetime=0): + # establish a "logical" server connection + + if isinstance(uri, unicode): + uri = uri.encode('ISO-8859-1') + + # get the url + import urllib + type, uri = urllib.splittype(uri) + if type not in ("http", "https"): + raise IOError, "unsupported XML-RPC protocol" + self.__host, self.__handler = urllib.splithost(uri) + if not self.__handler: + self.__handler = "/RPC2" + + if transport is None: + if type == "https": + transport = SafeTransport(use_datetime=use_datetime) + else: + transport = Transport(use_datetime=use_datetime) + self.__transport = transport + + self.__encoding = encoding + self.__verbose = verbose + self.__allow_none = allow_none + + def __close(self): + self.__transport.close() + + def __request(self, methodname, params): + # call a method on the remote server + + request = dumps(params, methodname, encoding=self.__encoding, + allow_none=self.__allow_none) + + response = self.__transport.request( + self.__host, + self.__handler, + request, + verbose=self.__verbose + ) + + if len(response) == 1: + response = response[0] + + return response + + def __repr__(self): + return ( + "<ServerProxy for %s%s>" % + (self.__host, self.__handler) + ) + + __str__ = __repr__ + + def __getattr__(self, name): + # magic method dispatcher + return _Method(self.__request, name) + + # note: to call a remote object with an non-standard name, use + # result getattr(server, "strange-python-name")(args) + + def __call__(self, attr): + """A workaround to get special attributes on the ServerProxy + without interfering with the magic __getattr__ + """ + if attr == "close": + return self.__close + elif attr == "transport": + return self.__transport + raise AttributeError("Attribute %r not found" % (attr,)) + +# compatibility + +Server = ServerProxy + +# -------------------------------------------------------------------- +# test code + +if __name__ == "__main__": + + # simple test program (from the XML-RPC specification) + + # server = ServerProxy("http://localhost:8000") # local server + server = ServerProxy("http://time.xmlrpc.com/RPC2") + + print server + + try: + print server.currentTime.getCurrentTime() + except Error, v: + print "ERROR", v + + multi = MultiCall(server) + multi.currentTime.getCurrentTime() + multi.currentTime.getCurrentTime() + try: + for response in multi(): + print response + except Error, v: + print "ERROR", v diff --git a/src/main/resources/PythonLibs/zipfile.py b/src/main/resources/PythonLibs/zipfile.py new file mode 100644 index 0000000000000000000000000000000000000000..ca2a0bbb045bf7621358b690663df5e3eb4248ac --- /dev/null +++ b/src/main/resources/PythonLibs/zipfile.py @@ -0,0 +1,1439 @@ +""" +Read and write ZIP files. +""" +import struct, os, time, sys, shutil +import binascii, cStringIO, stat +import io +import re + +try: + import zlib # We may need its compression method + crc32 = zlib.crc32 +except ImportError: + zlib = None + crc32 = binascii.crc32 + +__all__ = ["BadZipfile", "error", "ZIP_STORED", "ZIP_DEFLATED", "is_zipfile", + "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile" ] + +is_jython = sys.platform.startswith('java') + +class BadZipfile(Exception): + pass + + +class LargeZipFile(Exception): + """ + Raised when writing a zipfile, the zipfile requires ZIP64 extensions + and those extensions are disabled. + """ + +error = BadZipfile # The exception raised by this module + +ZIP64_LIMIT = (1 << 31) - 1 +ZIP_FILECOUNT_LIMIT = 1 << 16 +ZIP_MAX_COMMENT = (1 << 16) - 1 + +# constants for Zip file compression methods +ZIP_STORED = 0 +ZIP_DEFLATED = 8 +# Other ZIP compression methods not supported + +# Below are some formats and associated data for reading/writing headers using +# the struct module. The names and structures of headers/records are those used +# in the PKWARE description of the ZIP file format: +# http://www.pkware.com/documents/casestudies/APPNOTE.TXT +# (URL valid as of January 2008) + +# The "end of central directory" structure, magic number, size, and indices +# (section V.I in the format document) +structEndArchive = "<4s4H2LH" +stringEndArchive = "PK\005\006" +sizeEndCentDir = struct.calcsize(structEndArchive) + +_ECD_SIGNATURE = 0 +_ECD_DISK_NUMBER = 1 +_ECD_DISK_START = 2 +_ECD_ENTRIES_THIS_DISK = 3 +_ECD_ENTRIES_TOTAL = 4 +_ECD_SIZE = 5 +_ECD_OFFSET = 6 +_ECD_COMMENT_SIZE = 7 +# These last two indices are not part of the structure as defined in the +# spec, but they are used internally by this module as a convenience +_ECD_COMMENT = 8 +_ECD_LOCATION = 9 + +# The "central directory" structure, magic number, size, and indices +# of entries in the structure (section V.F in the format document) +structCentralDir = "<4s4B4HL2L5H2L" +stringCentralDir = "PK\001\002" +sizeCentralDir = struct.calcsize(structCentralDir) + +# indexes of entries in the central directory structure +_CD_SIGNATURE = 0 +_CD_CREATE_VERSION = 1 +_CD_CREATE_SYSTEM = 2 +_CD_EXTRACT_VERSION = 3 +_CD_EXTRACT_SYSTEM = 4 +_CD_FLAG_BITS = 5 +_CD_COMPRESS_TYPE = 6 +_CD_TIME = 7 +_CD_DATE = 8 +_CD_CRC = 9 +_CD_COMPRESSED_SIZE = 10 +_CD_UNCOMPRESSED_SIZE = 11 +_CD_FILENAME_LENGTH = 12 +_CD_EXTRA_FIELD_LENGTH = 13 +_CD_COMMENT_LENGTH = 14 +_CD_DISK_NUMBER_START = 15 +_CD_INTERNAL_FILE_ATTRIBUTES = 16 +_CD_EXTERNAL_FILE_ATTRIBUTES = 17 +_CD_LOCAL_HEADER_OFFSET = 18 + +# The "local file header" structure, magic number, size, and indices +# (section V.A in the format document) +structFileHeader = "<4s2B4HL2L2H" +stringFileHeader = "PK\003\004" +sizeFileHeader = struct.calcsize(structFileHeader) + +_FH_SIGNATURE = 0 +_FH_EXTRACT_VERSION = 1 +_FH_EXTRACT_SYSTEM = 2 +_FH_GENERAL_PURPOSE_FLAG_BITS = 3 +_FH_COMPRESSION_METHOD = 4 +_FH_LAST_MOD_TIME = 5 +_FH_LAST_MOD_DATE = 6 +_FH_CRC = 7 +_FH_COMPRESSED_SIZE = 8 +_FH_UNCOMPRESSED_SIZE = 9 +_FH_FILENAME_LENGTH = 10 +_FH_EXTRA_FIELD_LENGTH = 11 + +# The "Zip64 end of central directory locator" structure, magic number, and size +structEndArchive64Locator = "<4sLQL" +stringEndArchive64Locator = "PK\x06\x07" +sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator) + +# The "Zip64 end of central directory" record, magic number, size, and indices +# (section V.G in the format document) +structEndArchive64 = "<4sQ2H2L4Q" +stringEndArchive64 = "PK\x06\x06" +sizeEndCentDir64 = struct.calcsize(structEndArchive64) + +_CD64_SIGNATURE = 0 +_CD64_DIRECTORY_RECSIZE = 1 +_CD64_CREATE_VERSION = 2 +_CD64_EXTRACT_VERSION = 3 +_CD64_DISK_NUMBER = 4 +_CD64_DISK_NUMBER_START = 5 +_CD64_NUMBER_ENTRIES_THIS_DISK = 6 +_CD64_NUMBER_ENTRIES_TOTAL = 7 +_CD64_DIRECTORY_SIZE = 8 +_CD64_OFFSET_START_CENTDIR = 9 + +def _check_zipfile(fp): + try: + if _EndRecData(fp): + return True # file has correct magic number + except IOError: + pass + return False + +def is_zipfile(filename): + """Quickly see if a file is a ZIP file by checking the magic number. + + The filename argument may be a file or file-like object too. + """ + result = False + try: + if hasattr(filename, "read"): + result = _check_zipfile(fp=filename) + else: + with open(filename, "rb") as fp: + result = _check_zipfile(fp) + except IOError: + pass + return result + +def _EndRecData64(fpin, offset, endrec): + """ + Read the ZIP64 end-of-archive records and use that to update endrec + """ + try: + fpin.seek(offset - sizeEndCentDir64Locator, 2) + except IOError: + # If the seek fails, the file is not large enough to contain a ZIP64 + # end-of-archive record, so just return the end record we were given. + return endrec + + data = fpin.read(sizeEndCentDir64Locator) + sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data) + if sig != stringEndArchive64Locator: + return endrec + + if diskno != 0 or disks != 1: + raise BadZipfile("zipfiles that span multiple disks are not supported") + + # Assume no 'zip64 extensible data' + fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2) + data = fpin.read(sizeEndCentDir64) + sig, sz, create_version, read_version, disk_num, disk_dir, \ + dircount, dircount2, dirsize, diroffset = \ + struct.unpack(structEndArchive64, data) + if sig != stringEndArchive64: + return endrec + + # Update the original endrec using data from the ZIP64 record + endrec[_ECD_SIGNATURE] = sig + endrec[_ECD_DISK_NUMBER] = disk_num + endrec[_ECD_DISK_START] = disk_dir + endrec[_ECD_ENTRIES_THIS_DISK] = dircount + endrec[_ECD_ENTRIES_TOTAL] = dircount2 + endrec[_ECD_SIZE] = dirsize + endrec[_ECD_OFFSET] = diroffset + return endrec + + +def _EndRecData(fpin): + """Return data from the "End of Central Directory" record, or None. + + The data is a list of the nine items in the ZIP "End of central dir" + record followed by a tenth item, the file seek offset of this record.""" + + # Determine file size + fpin.seek(0, 2) + filesize = fpin.tell() + + # Check to see if this is ZIP file with no archive comment (the + # "end of central directory" structure should be the last item in the + # file if this is the case). + try: + fpin.seek(-sizeEndCentDir, 2) + except IOError: + return None + data = fpin.read() + if data[0:4] == stringEndArchive and data[-2:] == "\000\000": + # the signature is correct and there's no comment, unpack structure + endrec = struct.unpack(structEndArchive, data) + endrec=list(endrec) + + # Append a blank comment and record start offset + endrec.append("") + endrec.append(filesize - sizeEndCentDir) + + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, -sizeEndCentDir, endrec) + + # Either this is not a ZIP file, or it is a ZIP file with an archive + # comment. Search the end of the file for the "end of central directory" + # record signature. The comment is the last item in the ZIP file and may be + # up to 64K long. It is assumed that the "end of central directory" magic + # number does not appear in the comment. + maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0) + fpin.seek(maxCommentStart, 0) + data = fpin.read() + start = data.rfind(stringEndArchive) + if start >= 0: + # found the magic number; attempt to unpack and interpret + recData = data[start:start+sizeEndCentDir] + endrec = list(struct.unpack(structEndArchive, recData)) + comment = data[start+sizeEndCentDir:] + # check that comment length is correct + if endrec[_ECD_COMMENT_SIZE] == len(comment): + # Append the archive comment and start offset + endrec.append(comment) + endrec.append(maxCommentStart + start) + + # Try to read the "Zip64 end of central directory" structure + return _EndRecData64(fpin, maxCommentStart + start - filesize, + endrec) + + # Unable to find a valid end of central directory structure + return + + +class ZipInfo (object): + """Class with attributes describing each file in the ZIP archive.""" + + __slots__ = ( + 'orig_filename', + 'filename', + 'date_time', + 'compress_type', + 'comment', + 'extra', + 'create_system', + 'create_version', + 'extract_version', + 'reserved', + 'flag_bits', + 'volume', + 'internal_attr', + 'external_attr', + 'header_offset', + 'CRC', + 'compress_size', + 'file_size', + '_raw_time', + ) + + def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): + self.orig_filename = filename # Original file name in archive + + # Terminate the file name at the first null byte. Null bytes in file + # names are used as tricks by viruses in archives. + null_byte = filename.find(chr(0)) + if null_byte >= 0: + filename = filename[0:null_byte] + # This is used to ensure paths in generated ZIP files always use + # forward slashes as the directory separator, as required by the + # ZIP format specification. + if os.sep != "/" and os.sep in filename: + filename = filename.replace(os.sep, "/") + + self.filename = filename # Normalized file name + self.date_time = date_time # year, month, day, hour, min, sec + # Standard values: + self.compress_type = ZIP_STORED # Type of compression for the file + self.comment = "" # Comment for each file + self.extra = "" # ZIP extra data + if sys.platform == 'win32': + self.create_system = 0 # System which created ZIP archive + else: + # Assume everything else is unix-y + self.create_system = 3 # System which created ZIP archive + self.create_version = 20 # Version which created ZIP archive + self.extract_version = 20 # Version needed to extract archive + self.reserved = 0 # Must be zero + self.flag_bits = 0 # ZIP flag bits + self.volume = 0 # Volume number of file header + self.internal_attr = 0 # Internal attributes + self.external_attr = 0 # External file attributes + # Other attributes are set by class ZipFile: + # header_offset Byte offset to the file header + # CRC CRC-32 of the uncompressed file + # compress_size Size of the compressed file + # file_size Size of the uncompressed file + + def FileHeader(self): + """Return the per-file header as a string.""" + dt = self.date_time + dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] + dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) + if self.flag_bits & 0x08: + # Set these to zero because we write them after the file data + CRC = compress_size = file_size = 0 + else: + CRC = self.CRC + compress_size = self.compress_size + file_size = self.file_size + + extra = self.extra + + if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT: + # File is larger than what fits into a 4 byte integer, + # fall back to the ZIP64 extension + fmt = '<HHQQ' + extra = extra + struct.pack(fmt, + 1, struct.calcsize(fmt)-4, file_size, compress_size) + file_size = 0xffffffff + compress_size = 0xffffffff + self.extract_version = max(45, self.extract_version) + self.create_version = max(45, self.extract_version) + + filename, flag_bits = self._encodeFilenameFlags() + header = struct.pack(structFileHeader, stringFileHeader, + self.extract_version, self.reserved, flag_bits, + self.compress_type, dostime, dosdate, CRC, + compress_size, file_size, + len(filename), len(extra)) + return header + filename + extra + + def _encodeFilenameFlags(self): + if isinstance(self.filename, unicode): + try: + return self.filename.encode('ascii'), self.flag_bits + except UnicodeEncodeError: + return self.filename.encode('utf-8'), self.flag_bits | 0x800 + else: + return self.filename, self.flag_bits + + def _decodeFilename(self): + if self.flag_bits & 0x800: + return self.filename.decode('utf-8') + else: + return self.filename + + def _decodeExtra(self): + # Try to decode the extra field. + extra = self.extra + unpack = struct.unpack + while extra: + tp, ln = unpack('<HH', extra[:4]) + if tp == 1: + if ln >= 24: + counts = unpack('<QQQ', extra[4:28]) + elif ln == 16: + counts = unpack('<QQ', extra[4:20]) + elif ln == 8: + counts = unpack('<Q', extra[4:12]) + elif ln == 0: + counts = () + else: + raise RuntimeError, "Corrupt extra field %s"%(ln,) + + idx = 0 + + # ZIP64 extension (large files and/or large archives) + if self.file_size in (0xffffffffffffffffL, 0xffffffffL): + self.file_size = counts[idx] + idx += 1 + + if self.compress_size == 0xFFFFFFFFL: + self.compress_size = counts[idx] + idx += 1 + + if self.header_offset == 0xffffffffL: + old = self.header_offset + self.header_offset = counts[idx] + idx+=1 + + extra = extra[ln+4:] + + +class _ZipDecrypter: + """Class to handle decryption of files stored within a ZIP archive. + + ZIP supports a password-based form of encryption. Even though known + plaintext attacks have been found against it, it is still useful + to be able to get data out of such a file. + + Usage: + zd = _ZipDecrypter(mypwd) + plain_char = zd(cypher_char) + plain_text = map(zd, cypher_text) + """ + + def _GenerateCRCTable(): + """Generate a CRC-32 table. + + ZIP encryption uses the CRC32 one-byte primitive for scrambling some + internal keys. We noticed that a direct implementation is faster than + relying on binascii.crc32(). + """ + poly = 0xedb88320 + table = [0] * 256 + for i in range(256): + crc = i + for j in range(8): + if crc & 1: + crc = ((crc >> 1) & 0x7FFFFFFF) ^ poly + else: + crc = ((crc >> 1) & 0x7FFFFFFF) + table[i] = crc + return table + crctable = _GenerateCRCTable() + + def _crc32(self, ch, crc): + """Compute the CRC32 primitive on one byte.""" + return ((crc >> 8) & 0xffffff) ^ self.crctable[(crc ^ ord(ch)) & 0xff] + + def __init__(self, pwd): + self.key0 = 305419896 + self.key1 = 591751049 + self.key2 = 878082192 + for p in pwd: + self._UpdateKeys(p) + + def _UpdateKeys(self, c): + self.key0 = self._crc32(c, self.key0) + self.key1 = (self.key1 + (self.key0 & 255)) & 4294967295 + self.key1 = (self.key1 * 134775813 + 1) & 4294967295 + self.key2 = self._crc32(chr((self.key1 >> 24) & 255), self.key2) + + def __call__(self, c): + """Decrypt a single character.""" + c = ord(c) + k = self.key2 | 2 + c = c ^ (((k * (k^1)) >> 8) & 255) + c = chr(c) + self._UpdateKeys(c) + return c + +class ZipExtFile(io.BufferedIOBase): + """File-like object for reading an archive member. + Is returned by ZipFile.open(). + """ + + # Max size supported by decompressor. + MAX_N = 1 << 31 - 1 + + # Read from compressed files in 4k blocks. + MIN_READ_SIZE = 4096 + + # Search for universal newlines or line chunks. + PATTERN = re.compile(r'^(?P<chunk>[^\r\n]+)|(?P<newline>\n|\r\n?)') + + def __init__(self, fileobj, mode, zipinfo, decrypter=None): + self._fileobj = fileobj + self._decrypter = decrypter + + self._compress_type = zipinfo.compress_type + self._compress_size = zipinfo.compress_size + self._compress_left = zipinfo.compress_size + + if self._compress_type == ZIP_DEFLATED: + self._decompressor = zlib.decompressobj(-15) + self._unconsumed = '' + + self._readbuffer = '' + self._offset = 0 + + self._universal = 'U' in mode + self.newlines = None + + # Adjust read size for encrypted files since the first 12 bytes + # are for the encryption/password information. + if self._decrypter is not None: + self._compress_left -= 12 + + self.mode = mode + self.name = zipinfo.filename + + if hasattr(zipinfo, 'CRC'): + self._expected_crc = zipinfo.CRC + self._running_crc = crc32(b'') & 0xffffffff + else: + self._expected_crc = None + + def readline(self, limit=-1): + """Read and return a line from the stream. + + If limit is specified, at most limit bytes will be read. + """ + + if not self._universal and limit < 0: + # Shortcut common case - newline found in buffer. + i = self._readbuffer.find('\n', self._offset) + 1 + if i > 0: + line = self._readbuffer[self._offset: i] + self._offset = i + return line + + if not self._universal: + return io.BufferedIOBase.readline(self, limit) + + line = '' + while limit < 0 or len(line) < limit: + readahead = self.peek(2) + if readahead == '': + return line + + # + # Search for universal newlines or line chunks. + # + # The pattern returns either a line chunk or a newline, but not + # both. Combined with peek(2), we are assured that the sequence + # '\r\n' is always retrieved completely and never split into + # separate newlines - '\r', '\n' due to coincidental readaheads. + # + match = self.PATTERN.search(readahead) + newline = match.group('newline') + if newline is not None: + if self.newlines is None: + self.newlines = [] + if newline not in self.newlines: + self.newlines.append(newline) + self._offset += len(newline) + return line + '\n' + + chunk = match.group('chunk') + if limit >= 0: + chunk = chunk[: limit - len(line)] + + self._offset += len(chunk) + line += chunk + + return line + + def peek(self, n=1): + """Returns buffered bytes without advancing the position.""" + if n > len(self._readbuffer) - self._offset: + chunk = self.read(n) + self._offset -= len(chunk) + + # Return up to 512 bytes to reduce allocation overhead for tight loops. + return self._readbuffer[self._offset: self._offset + 512] + + def readable(self): + return True + + def read(self, n=-1): + """Read and return up to n bytes. + If the argument is omitted, None, or negative, data is read and returned until EOF is reached.. + """ + buf = '' + if n is None: + n = -1 + while True: + if n < 0: + data = self.read1(n) + elif n > len(buf): + data = self.read1(n - len(buf)) + else: + return buf + if len(data) == 0: + return buf + buf += data + + def _update_crc(self, newdata, eof): + # Update the CRC using the given data. + if self._expected_crc is None: + # No need to compute the CRC if we don't have a reference value + return + self._running_crc = crc32(newdata, self._running_crc) & 0xffffffff + # Check the CRC if we're at the end of the file + if eof and self._running_crc != self._expected_crc: + raise BadZipfile("Bad CRC-32 for file %r" % self.name) + + def read1(self, n): + """Read up to n bytes with at most one read() system call.""" + + # Simplify algorithm (branching) by transforming negative n to large n. + if n < 0 or n is None: + n = self.MAX_N + + # Bytes available in read buffer. + len_readbuffer = len(self._readbuffer) - self._offset + + # Read from file. + if self._compress_left > 0 and n > len_readbuffer + len(self._unconsumed): + nbytes = n - len_readbuffer - len(self._unconsumed) + nbytes = max(nbytes, self.MIN_READ_SIZE) + nbytes = min(nbytes, self._compress_left) + + data = self._fileobj.read(nbytes) + self._compress_left -= len(data) + + if data and self._decrypter is not None: + data = ''.join(map(self._decrypter, data)) + + if self._compress_type == ZIP_STORED: + self._update_crc(data, eof=(self._compress_left==0)) + self._readbuffer = self._readbuffer[self._offset:] + data + self._offset = 0 + else: + # Prepare deflated bytes for decompression. + self._unconsumed += data + + # Handle unconsumed data. + if (len(self._unconsumed) > 0 and n > len_readbuffer and + self._compress_type == ZIP_DEFLATED): + data = self._decompressor.decompress( + self._unconsumed, + max(n - len_readbuffer, self.MIN_READ_SIZE) + ) + + self._unconsumed = self._decompressor.unconsumed_tail + eof = len(self._unconsumed) == 0 and self._compress_left == 0 + if eof: + data += self._decompressor.flush() + + self._update_crc(data, eof=eof) + self._readbuffer = self._readbuffer[self._offset:] + data + self._offset = 0 + + # Read from buffer. + data = self._readbuffer[self._offset: self._offset + n] + self._offset += len(data) + return data + + + +class ZipFile: + """ Class with methods to open, read, write, close, list zip files. + + z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False) + + file: Either the path to the file, or a file-like object. + If it is a path, the file will be opened and closed by ZipFile. + mode: The mode can be either read "r", write "w" or append "a". + compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib). + allowZip64: if True ZipFile will create files with ZIP64 extensions when + needed, otherwise it will raise an exception when this would + be necessary. + + """ + + fp = None # Set here since __del__ checks it + + def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False): + """Open the ZIP file with mode read "r", write "w" or append "a".""" + if mode not in ("r", "w", "a"): + raise RuntimeError('ZipFile() requires mode "r", "w", or "a"') + + if compression == ZIP_STORED: + pass + elif compression == ZIP_DEFLATED: + if not zlib: + raise RuntimeError,\ + "Compression requires the (missing) zlib module" + else: + raise RuntimeError, "That compression method is not supported" + + self._allowZip64 = allowZip64 + self._didModify = False + self.debug = 0 # Level of printing: 0 through 3 + self.NameToInfo = {} # Find file info given name + self.filelist = [] # List of ZipInfo instances for archive + self.compression = compression # Method of compression + self.mode = key = mode.replace('b', '')[0] + self.pwd = None + self.comment = '' + + # Check if we were passed a file-like object + if isinstance(file, basestring): + self._filePassed = 0 + self.filename = file + modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'} + try: + self.fp = open(file, modeDict[mode]) + except IOError: + if mode == 'a': + mode = key = 'w' + self.fp = open(file, modeDict[mode]) + else: + raise + else: + self._filePassed = 1 + self.fp = file + self.filename = getattr(file, 'name', None) + + if key == 'r': + self._GetContents() + elif key == 'w': + # set the modified flag so central directory gets written + # even if no files are added to the archive + self._didModify = True + elif key == 'a': + try: + # See if file is a zip file + self._RealGetContents() + # seek to start of directory and overwrite + self.fp.seek(self.start_dir, 0) + except BadZipfile: + # file is not a zip file, just append + self.fp.seek(0, 2) + + # set the modified flag so central directory gets written + # even if no files are added to the archive + self._didModify = True + else: + if not self._filePassed: + self.fp.close() + self.fp = None + raise RuntimeError, 'Mode must be "r", "w" or "a"' + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + + def _GetContents(self): + """Read the directory, making sure we close the file if the format + is bad.""" + try: + self._RealGetContents() + except BadZipfile: + if not self._filePassed: + self.fp.close() + self.fp = None + raise + + def _RealGetContents(self): + """Read in the table of contents for the ZIP file.""" + fp = self.fp + try: + endrec = _EndRecData(fp) + except IOError: + raise BadZipfile("File is not a zip file") + if not endrec: + raise BadZipfile, "File is not a zip file" + if self.debug > 1: + print endrec + size_cd = endrec[_ECD_SIZE] # bytes in central directory + offset_cd = endrec[_ECD_OFFSET] # offset of central directory + self.comment = endrec[_ECD_COMMENT] # archive comment + + # "concat" is zero, unless zip was concatenated to another file + concat = endrec[_ECD_LOCATION] - size_cd - offset_cd + if endrec[_ECD_SIGNATURE] == stringEndArchive64: + # If Zip64 extension structures are present, account for them + concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator) + + if self.debug > 2: + inferred = concat + offset_cd + print "given, inferred, offset", offset_cd, inferred, concat + # self.start_dir: Position of start of central directory + self.start_dir = offset_cd + concat + fp.seek(self.start_dir, 0) + data = fp.read(size_cd) + fp = cStringIO.StringIO(data) + total = 0 + while total < size_cd: + centdir = fp.read(sizeCentralDir) + if centdir[0:4] != stringCentralDir: + raise BadZipfile, "Bad magic number for central directory" + centdir = struct.unpack(structCentralDir, centdir) + if self.debug > 2: + print centdir + filename = fp.read(centdir[_CD_FILENAME_LENGTH]) + # Create ZipInfo instance to store file information + x = ZipInfo(filename) + x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) + x.comment = fp.read(centdir[_CD_COMMENT_LENGTH]) + x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET] + (x.create_version, x.create_system, x.extract_version, x.reserved, + x.flag_bits, x.compress_type, t, d, + x.CRC, x.compress_size, x.file_size) = centdir[1:12] + x.volume, x.internal_attr, x.external_attr = centdir[15:18] + # Convert date/time code to (year, month, day, hour, min, sec) + x._raw_time = t + x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, + t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) + + x._decodeExtra() + x.header_offset = x.header_offset + concat + x.filename = x._decodeFilename() + self.filelist.append(x) + self.NameToInfo[x.filename] = x + + # update total bytes read from central directory + total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH] + + centdir[_CD_EXTRA_FIELD_LENGTH] + + centdir[_CD_COMMENT_LENGTH]) + + if self.debug > 2: + print "total", total + + + def namelist(self): + """Return a list of file names in the archive.""" + l = [] + for data in self.filelist: + l.append(data.filename) + return l + + def infolist(self): + """Return a list of class ZipInfo instances for files in the + archive.""" + return self.filelist + + def printdir(self): + """Print a table of contents for the zip file.""" + print "%-46s %19s %12s" % ("File Name", "Modified ", "Size") + for zinfo in self.filelist: + date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6] + print "%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size) + + def testzip(self): + """Read all the files and check the CRC.""" + chunk_size = 2 ** 20 + for zinfo in self.filelist: + try: + # Read by chunks, to avoid an OverflowError or a + # MemoryError with very large embedded files. + f = self.open(zinfo.filename, "r") + while f.read(chunk_size): # Check CRC-32 + pass + except BadZipfile: + return zinfo.filename + + def getinfo(self, name): + """Return the instance of ZipInfo given 'name'.""" + info = self.NameToInfo.get(name) + if info is None: + raise KeyError( + 'There is no item named %r in the archive' % name) + + return info + + def setpassword(self, pwd): + """Set default password for encrypted files.""" + self.pwd = pwd + + def read(self, name, pwd=None): + """Return file bytes (as a string) for name.""" + return self.open(name, "r", pwd).read() + + def open(self, name, mode="r", pwd=None): + """Return file-like object for 'name'.""" + if mode not in ("r", "U", "rU"): + raise RuntimeError, 'open() requires mode "r", "U", or "rU"' + if not self.fp: + raise RuntimeError, \ + "Attempt to read ZIP archive that was already closed" + + # Only open a new file for instances where we were not + # given a file object in the constructor + if self._filePassed: + zef_file = self.fp + else: + zef_file = open(self.filename, 'rb') + + # Make sure we have an info object + if isinstance(name, ZipInfo): + # 'name' is already an info object + zinfo = name + else: + # Get info object for name + zinfo = self.getinfo(name) + + zef_file.seek(zinfo.header_offset, 0) + + # Skip the file header: + fheader = zef_file.read(sizeFileHeader) + if fheader[0:4] != stringFileHeader: + raise BadZipfile, "Bad magic number for file header" + + fheader = struct.unpack(structFileHeader, fheader) + fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) + if fheader[_FH_EXTRA_FIELD_LENGTH]: + zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) + + if fname != zinfo.orig_filename: + raise BadZipfile, \ + 'File name in directory "%s" and header "%s" differ.' % ( + zinfo.orig_filename, fname) + + # check for encrypted flag & handle password + is_encrypted = zinfo.flag_bits & 0x1 + zd = None + if is_encrypted: + if not pwd: + pwd = self.pwd + if not pwd: + raise RuntimeError, "File %s is encrypted, " \ + "password required for extraction" % name + + zd = _ZipDecrypter(pwd) + # The first 12 bytes in the cypher stream is an encryption header + # used to strengthen the algorithm. The first 11 bytes are + # completely random, while the 12th contains the MSB of the CRC, + # or the MSB of the file time depending on the header type + # and is used to check the correctness of the password. + bytes = zef_file.read(12) + h = map(zd, bytes[0:12]) + if zinfo.flag_bits & 0x8: + # compare against the file type from extended local headers + check_byte = (zinfo._raw_time >> 8) & 0xff + else: + # compare against the CRC otherwise + check_byte = (zinfo.CRC >> 24) & 0xff + if ord(h[11]) != check_byte: + raise RuntimeError("Bad password for file", name) + + return ZipExtFile(zef_file, mode, zinfo, zd) + + def extract(self, member, path=None, pwd=None): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a ZipInfo object. You can + specify a different directory using `path'. + """ + if not isinstance(member, ZipInfo): + member = self.getinfo(member) + + if path is None: + path = os.getcwd() + + return self._extract_member(member, path, pwd) + + def extractall(self, path=None, members=None, pwd=None): + """Extract all members from the archive to the current working + directory. `path' specifies a different directory to extract to. + `members' is optional and must be a subset of the list returned + by namelist(). + """ + if members is None: + members = self.namelist() + + for zipinfo in members: + self.extract(zipinfo, path, pwd) + + def _extract_member(self, member, targetpath, pwd): + """Extract the ZipInfo object 'member' to a physical + file on the path targetpath. + """ + # build the destination pathname, replacing + # forward slashes to platform specific separators. + # Strip trailing path separator, unless it represents the root. + if (targetpath[-1:] in (os.path.sep, os.path.altsep) + and len(os.path.splitdrive(targetpath)[1]) > 1): + targetpath = targetpath[:-1] + + # don't include leading "/" from file name if present + if member.filename[0] == '/': + targetpath = os.path.join(targetpath, member.filename[1:]) + else: + targetpath = os.path.join(targetpath, member.filename) + + targetpath = os.path.normpath(targetpath) + + # Create all upper directories if necessary. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + os.makedirs(upperdirs) + + if member.filename[-1] == '/': + if not os.path.isdir(targetpath): + os.mkdir(targetpath) + return targetpath + + source = self.open(member, pwd=pwd) + target = file(targetpath, "wb") + shutil.copyfileobj(source, target) + source.close() + target.close() + + return targetpath + + def _writecheck(self, zinfo): + """Check for errors before writing a file to the archive.""" + if zinfo.filename in self.NameToInfo: + if self.debug: # Warning for duplicate names + print "Duplicate name:", zinfo.filename + if self.mode not in ("w", "a"): + raise RuntimeError, 'write() requires mode "w" or "a"' + if not self.fp: + raise RuntimeError, \ + "Attempt to write ZIP archive that was already closed" + if zinfo.compress_type == ZIP_DEFLATED and not zlib: + raise RuntimeError, \ + "Compression requires the (missing) zlib module" + if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED): + raise RuntimeError, \ + "That compression method is not supported" + if zinfo.file_size > ZIP64_LIMIT: + if not self._allowZip64: + raise LargeZipFile("Filesize would require ZIP64 extensions") + if zinfo.header_offset > ZIP64_LIMIT: + if not self._allowZip64: + raise LargeZipFile("Zipfile size would require ZIP64 extensions") + + def write(self, filename, arcname=None, compress_type=None): + """Put the bytes from filename into the archive under the name + arcname.""" + if not self.fp: + raise RuntimeError( + "Attempt to write to ZIP archive that was already closed") + + st = os.stat(filename) + isdir = stat.S_ISDIR(st.st_mode) + mtime = time.localtime(st.st_mtime) + date_time = mtime[0:6] + # Create ZipInfo instance to store file information + if arcname is None: + arcname = filename + arcname = os.path.normpath(os.path.splitdrive(arcname)[1]) + while arcname[0] in (os.sep, os.altsep): + arcname = arcname[1:] + if isdir: + arcname += '/' + zinfo = ZipInfo(arcname, date_time) + zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes + if compress_type is None: + zinfo.compress_type = self.compression + else: + zinfo.compress_type = compress_type + + zinfo.file_size = st.st_size + zinfo.flag_bits = 0x00 + zinfo.header_offset = self.fp.tell() # Start of header bytes + + self._writecheck(zinfo) + self._didModify = True + + if isdir: + zinfo.file_size = 0 + zinfo.compress_size = 0 + zinfo.CRC = 0 + self.filelist.append(zinfo) + self.NameToInfo[zinfo.filename] = zinfo + self.fp.write(zinfo.FileHeader()) + return + + with open(filename, "rb") as fp: + # Must overwrite CRC and sizes with correct data later + zinfo.CRC = CRC = 0 + zinfo.compress_size = compress_size = 0 + zinfo.file_size = file_size = 0 + self.fp.write(zinfo.FileHeader()) + if zinfo.compress_type == ZIP_DEFLATED: + cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, + zlib.DEFLATED, -15) + else: + cmpr = None + while 1: + buf = fp.read(1024 * 8) + if not buf: + break + file_size = file_size + len(buf) + CRC = crc32(buf, CRC) & 0xffffffff + if cmpr: + buf = cmpr.compress(buf) + compress_size = compress_size + len(buf) + self.fp.write(buf) + if cmpr: + buf = cmpr.flush() + compress_size = compress_size + len(buf) + self.fp.write(buf) + zinfo.compress_size = compress_size + else: + zinfo.compress_size = file_size + zinfo.CRC = CRC + zinfo.file_size = file_size + # Seek backwards and write CRC and file sizes + position = self.fp.tell() # Preserve current position in file + self.fp.seek(zinfo.header_offset + 14, 0) + self.fp.write(struct.pack("<LLL", zinfo.CRC, zinfo.compress_size, + zinfo.file_size)) + self.fp.seek(position, 0) + self.filelist.append(zinfo) + self.NameToInfo[zinfo.filename] = zinfo + + def writestr(self, zinfo_or_arcname, bytes, compress_type=None): + """Write a file into the archive. The contents is the string + 'bytes'. 'zinfo_or_arcname' is either a ZipInfo instance or + the name of the file in the archive.""" + if not isinstance(zinfo_or_arcname, ZipInfo): + zinfo = ZipInfo(filename=zinfo_or_arcname, + date_time=time.localtime(time.time())[:6]) + + zinfo.compress_type = self.compression + zinfo.external_attr = 0600 << 16 + else: + zinfo = zinfo_or_arcname + + if not self.fp: + raise RuntimeError( + "Attempt to write to ZIP archive that was already closed") + + if compress_type is not None: + zinfo.compress_type = compress_type + + zinfo.file_size = len(bytes) # Uncompressed size + zinfo.header_offset = self.fp.tell() # Start of header bytes + self._writecheck(zinfo) + self._didModify = True + zinfo.CRC = crc32(bytes) & 0xffffffff # CRC-32 checksum + if zinfo.compress_type == ZIP_DEFLATED: + co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, + zlib.DEFLATED, -15) + bytes = co.compress(bytes) + co.flush() + zinfo.compress_size = len(bytes) # Compressed size + else: + zinfo.compress_size = zinfo.file_size + zinfo.header_offset = self.fp.tell() # Start of header bytes + self.fp.write(zinfo.FileHeader()) + self.fp.write(bytes) + self.fp.flush() + if zinfo.flag_bits & 0x08: + # Write CRC and file sizes after the file data + self.fp.write(struct.pack("<LLL", zinfo.CRC, zinfo.compress_size, + zinfo.file_size)) + self.filelist.append(zinfo) + self.NameToInfo[zinfo.filename] = zinfo + + def __del__(self): + """Call the "close()" method in case the user forgot.""" + self.close() + + def close(self): + """Close the file, and for mode "w" and "a" write the ending + records.""" + if self.fp is None: + return + + if self.mode in ("w", "a") and self._didModify: # write ending records + count = 0 + pos1 = self.fp.tell() + for zinfo in self.filelist: # write central directory + count = count + 1 + dt = zinfo.date_time + dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] + dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) + extra = [] + if zinfo.file_size > ZIP64_LIMIT \ + or zinfo.compress_size > ZIP64_LIMIT: + extra.append(zinfo.file_size) + extra.append(zinfo.compress_size) + file_size = 0xffffffff + compress_size = 0xffffffff + else: + file_size = zinfo.file_size + compress_size = zinfo.compress_size + + if zinfo.header_offset > ZIP64_LIMIT: + extra.append(zinfo.header_offset) + header_offset = 0xffffffffL + else: + header_offset = zinfo.header_offset + + extra_data = zinfo.extra + if extra: + # Append a ZIP64 field to the extra's + extra_data = struct.pack( + '<HH' + 'Q'*len(extra), + 1, 8*len(extra), *extra) + extra_data + + extract_version = max(45, zinfo.extract_version) + create_version = max(45, zinfo.create_version) + else: + extract_version = zinfo.extract_version + create_version = zinfo.create_version + + try: + filename, flag_bits = zinfo._encodeFilenameFlags() + centdir = struct.pack(structCentralDir, + stringCentralDir, create_version, + zinfo.create_system, extract_version, zinfo.reserved, + flag_bits, zinfo.compress_type, dostime, dosdate, + zinfo.CRC, compress_size, file_size, + len(filename), len(extra_data), len(zinfo.comment), + 0, zinfo.internal_attr, zinfo.external_attr, + header_offset) + except DeprecationWarning: + print >>sys.stderr, (structCentralDir, + stringCentralDir, create_version, + zinfo.create_system, extract_version, zinfo.reserved, + zinfo.flag_bits, zinfo.compress_type, dostime, dosdate, + zinfo.CRC, compress_size, file_size, + len(zinfo.filename), len(extra_data), len(zinfo.comment), + 0, zinfo.internal_attr, zinfo.external_attr, + header_offset) + raise + self.fp.write(centdir) + self.fp.write(filename) + self.fp.write(extra_data) + self.fp.write(zinfo.comment) + + pos2 = self.fp.tell() + # Write end-of-zip-archive record + centDirCount = count + centDirSize = pos2 - pos1 + centDirOffset = pos1 + if (centDirCount >= ZIP_FILECOUNT_LIMIT or + centDirOffset > ZIP64_LIMIT or + centDirSize > ZIP64_LIMIT): + # Need to write the ZIP64 end-of-archive records + zip64endrec = struct.pack( + structEndArchive64, stringEndArchive64, + 44, 45, 45, 0, 0, centDirCount, centDirCount, + centDirSize, centDirOffset) + self.fp.write(zip64endrec) + + zip64locrec = struct.pack( + structEndArchive64Locator, + stringEndArchive64Locator, 0, pos2, 1) + self.fp.write(zip64locrec) + centDirCount = min(centDirCount, 0xFFFF) + centDirSize = min(centDirSize, 0xFFFFFFFF) + centDirOffset = min(centDirOffset, 0xFFFFFFFF) + + # check for valid comment length + if len(self.comment) >= ZIP_MAX_COMMENT: + if self.debug > 0: + msg = 'Archive comment is too long; truncating to %d bytes' \ + % ZIP_MAX_COMMENT + self.comment = self.comment[:ZIP_MAX_COMMENT] + + endrec = struct.pack(structEndArchive, stringEndArchive, + 0, 0, centDirCount, centDirCount, + centDirSize, centDirOffset, len(self.comment)) + self.fp.write(endrec) + self.fp.write(self.comment) + self.fp.flush() + + if not self._filePassed: + self.fp.close() + self.fp = None + + +class PyZipFile(ZipFile): + """Class to create ZIP archives with Python library files and packages.""" + + def writepy(self, pathname, basename = ""): + """Add all files from "pathname" to the ZIP archive. + + If pathname is a package directory, search the directory and + all package subdirectories recursively for all *.py and enter + the modules into the archive. If pathname is a plain + directory, listdir *.py and enter all modules. Else, pathname + must be a Python *.py file and the module will be put into the + archive. Added modules are always module.pyo or module.pyc. + This method will compile the module.py into module.pyc if + necessary. + """ + dir, name = os.path.split(pathname) + if os.path.isdir(pathname): + initname = os.path.join(pathname, "__init__.py") + if os.path.isfile(initname): + # This is a package directory, add it + if basename: + basename = "%s/%s" % (basename, name) + else: + basename = name + if self.debug: + print "Adding package in", pathname, "as", basename + fname, arcname = self._get_codename(initname[0:-3], basename) + if self.debug: + print "Adding", arcname + self.write(fname, arcname) + dirlist = os.listdir(pathname) + dirlist.remove("__init__.py") + # Add all *.py files and package subdirectories + for filename in dirlist: + path = os.path.join(pathname, filename) + root, ext = os.path.splitext(filename) + if os.path.isdir(path): + if os.path.isfile(os.path.join(path, "__init__.py")): + # This is a package directory, add it + self.writepy(path, basename) # Recursive call + elif ext == ".py": + fname, arcname = self._get_codename(path[0:-3], + basename) + if self.debug: + print "Adding", arcname + self.write(fname, arcname) + else: + # This is NOT a package directory, add its files at top level + if self.debug: + print "Adding files from directory", pathname + for filename in os.listdir(pathname): + path = os.path.join(pathname, filename) + root, ext = os.path.splitext(filename) + if ext == ".py": + fname, arcname = self._get_codename(path[0:-3], + basename) + if self.debug: + print "Adding", arcname + self.write(fname, arcname) + else: + if pathname[-3:] != ".py": + raise RuntimeError, \ + 'Files added with writepy() must end with ".py"' + fname, arcname = self._get_codename(pathname[0:-3], basename) + if self.debug: + print "Adding file", arcname + self.write(fname, arcname) + + def _get_codename(self, pathname, basename): + """Return (filename, archivename) for the path. + + Given a module name path, return the correct file path and + archive name, compiling if necessary. For example, given + /python/lib/string, return (/python/lib/string.pyc, string). + """ + file_py = pathname + ".py" + file_pyc = pathname + (".pyc" if not is_jython else "$py.class") + file_pyo = pathname + ".pyo" + if os.path.isfile(file_pyo) and \ + os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime: + fname = file_pyo # Use .pyo file + elif not os.path.isfile(file_pyc) or \ + os.stat(file_pyc).st_mtime < os.stat(file_py).st_mtime: + import py_compile + if self.debug: + print "Compiling", file_py + try: + py_compile.compile(file_py, file_pyc, None, True) + except py_compile.PyCompileError,err: + print err.msg + fname = file_pyc + else: + fname = file_pyc + archivename = os.path.split(fname)[1] + if basename: + archivename = "%s/%s" % (basename, archivename) + return (fname, archivename) + + +def main(args = None): + import textwrap + USAGE=textwrap.dedent("""\ + Usage: + zipfile.py -l zipfile.zip # Show listing of a zipfile + zipfile.py -t zipfile.zip # Test if a zipfile is valid + zipfile.py -e zipfile.zip target # Extract zipfile into target dir + zipfile.py -c zipfile.zip src ... # Create zipfile from sources + """) + if args is None: + args = sys.argv[1:] + + if not args or args[0] not in ('-l', '-c', '-e', '-t'): + print USAGE + sys.exit(1) + + if args[0] == '-l': + if len(args) != 2: + print USAGE + sys.exit(1) + zf = ZipFile(args[1], 'r') + zf.printdir() + zf.close() + + elif args[0] == '-t': + if len(args) != 2: + print USAGE + sys.exit(1) + zf = ZipFile(args[1], 'r') + badfile = zf.testzip() + if badfile: + print("The following enclosed file is corrupted: {!r}".format(badfile)) + print "Done testing" + + elif args[0] == '-e': + if len(args) != 3: + print USAGE + sys.exit(1) + + zf = ZipFile(args[1], 'r') + out = args[2] + for path in zf.namelist(): + if path.startswith('./'): + tgt = os.path.join(out, path[2:]) + else: + tgt = os.path.join(out, path) + + tgtdir = os.path.dirname(tgt) + if not os.path.exists(tgtdir): + os.makedirs(tgtdir) + with open(tgt, 'wb') as fp: + fp.write(zf.read(path)) + zf.close() + + elif args[0] == '-c': + if len(args) < 3: + print USAGE + sys.exit(1) + + def addToZip(zf, path, zippath): + if os.path.isfile(path): + zf.write(path, zippath, ZIP_DEFLATED) + elif os.path.isdir(path): + for nm in os.listdir(path): + addToZip(zf, + os.path.join(path, nm), os.path.join(zippath, nm)) + # else: ignore + + zf = ZipFile(args[1], 'w', allowZip64=True) + for src in args[2:]: + addToZip(zf, src, os.path.basename(src)) + + zf.close() + +if __name__ == "__main__": + main() diff --git a/src/main/resources/PythonLibs/zlib.py b/src/main/resources/PythonLibs/zlib.py new file mode 100644 index 0000000000000000000000000000000000000000..1aacd0d3445d065ffbc454ae70b1e2338c72e1e6 --- /dev/null +++ b/src/main/resources/PythonLibs/zlib.py @@ -0,0 +1,195 @@ +""" +The functions in this module allow compression and decompression using the +zlib library, which is based on GNU zip. + +adler32(string[, start]) -- Compute an Adler-32 checksum. +compress(string[, level]) -- Compress string, with compression level in 1-9. +compressobj([level]) -- Return a compressor object. +crc32(string[, start]) -- Compute a CRC-32 checksum. +decompress(string,[wbits],[bufsize]) -- Decompresses a compressed string. +decompressobj([wbits]) -- Return a decompressor object. + +'wbits' is window buffer size. +Compressor objects support compress() and flush() methods; decompressor +objects support decompress() and flush(). +""" +import array +import binascii +import jarray + +from java.util.zip import Adler32, Deflater, Inflater, DataFormatException +from java.lang import Long, String + +from cStringIO import StringIO + +class error(Exception): + pass + + +DEFLATED = 8 +MAX_WBITS = 15 +DEF_MEM_LEVEL = 8 +ZLIB_VERSION = "1.1.3" +Z_BEST_COMPRESSION = 9 +Z_BEST_SPEED = 1 + +Z_FILTERED = 1 +Z_HUFFMAN_ONLY = 2 + +Z_DEFAULT_COMPRESSION = -1 +Z_DEFAULT_STRATEGY = 0 + +# Most options are removed because java does not support them +# Z_NO_FLUSH = 0 +# Z_SYNC_FLUSH = 2 +# Z_FULL_FLUSH = 3 +Z_FINISH = 4 +_valid_flush_modes = (Z_FINISH,) + +def adler32(s, value=1): + if value != 1: + raise ValueError, "adler32 only support start value of 1" + checksum = Adler32() + checksum.update(String.getBytes(s, 'iso-8859-1')) + return Long(checksum.getValue()).intValue() + +def crc32(string, value=0): + return binascii.crc32(string, value) + + +def compress(string, level=6): + if level < Z_BEST_SPEED or level > Z_BEST_COMPRESSION: + raise error, "Bad compression level" + deflater = Deflater(level, 0) + try: + string = _to_input(string) + deflater.setInput(string, 0, len(string)) + deflater.finish() + return _get_deflate_data(deflater) + finally: + deflater.end() + +def decompress(string, wbits=0, bufsize=16384): + inflater = Inflater(wbits < 0) + try: + inflater.setInput(_to_input(string)) + return _get_inflate_data(inflater) + finally: + inflater.end() + +class compressobj: + # all jython uses wbits for is deciding whether to skip the header if it's negative + def __init__(self, level=6, method=DEFLATED, wbits=MAX_WBITS, + memLevel=0, strategy=0): + if abs(wbits) > MAX_WBITS or abs(wbits) < 8: + raise ValueError, "Invalid initialization option" + self.deflater = Deflater(level, wbits < 0) + self.deflater.setStrategy(strategy) + if wbits < 0: + _get_deflate_data(self.deflater) + self._ended = False + + def compress(self, string): + if self._ended: + raise error("compressobj may not be used after flush(Z_FINISH)") + string = _to_input(string) + self.deflater.setInput(string, 0, len(string)) + return _get_deflate_data(self.deflater) + + def flush(self, mode=Z_FINISH): + if self._ended: + raise error("compressobj may not be used after flush(Z_FINISH)") + if mode not in _valid_flush_modes: + raise ValueError, "Invalid flush option" + self.deflater.finish() + last = _get_deflate_data(self.deflater) + if mode == Z_FINISH: + self.deflater.end() + self._ended = True + return last + +class decompressobj: + # all jython uses wbits for is deciding whether to skip the header if it's negative + def __init__(self, wbits=MAX_WBITS): + if abs(wbits) > MAX_WBITS or abs(wbits) < 8: + raise ValueError, "Invalid initialization option" + self.inflater = Inflater(wbits < 0) + self.unused_data = "" + self._ended = False + + def decompress(self, string, max_length=0): + if self._ended: + raise error("decompressobj may not be used after flush()") + + # unused_data is always "" until inflation is finished; then it is + # the unused bytes of the input; + # unconsumed_tail is whatever input was not used because max_length + # was exceeded before inflation finished. + # Thus, at most one of {unused_data, unconsumed_tail} may be non-empty. + self.unused_data = "" + self.unconsumed_tail = "" + + if max_length < 0: + raise ValueError("max_length must be a positive integer") + + string = _to_input(string) + self.inflater.setInput(string) + inflated = _get_inflate_data(self.inflater, max_length) + + r = self.inflater.getRemaining() + if r: + if max_length: + self.unconsumed_tail = string[-r:] + else: + self.unused_data = string[-r:] + + return inflated + + def flush(self, length=None): + if self._ended: + raise error("decompressobj may not be used after flush()") + if length is None: + length = 0 + elif length <= 0: + raise ValueError('length must be greater than zero') + last = _get_inflate_data(self.inflater, length) + self.inflater.end() + return last + +def _to_input(string): + return string.tostring() if isinstance(string, array.array) else string + +def _get_deflate_data(deflater): + buf = jarray.zeros(1024, 'b') + s = StringIO() + while not deflater.finished(): + l = deflater.deflate(buf) + + if l == 0: + break + s.write(String(buf, 0, 0, l)) + s.seek(0) + return s.read() + +def _get_inflate_data(inflater, max_length=0): + buf = jarray.zeros(1024, 'b') + s = StringIO() + total = 0 + while not inflater.finished(): + try: + if max_length: + l = inflater.inflate(buf, 0, min(1024, max_length - total)) + else: + l = inflater.inflate(buf) + except DataFormatException, e: + raise error(str(e)) + + if l == 0: + break + + total += l + s.write(String(buf, 0, 0, l)) + if max_length and total == max_length: + break + s.seek(0) + return s.read() diff --git a/src/main/resources/com/google/common/base/package-info.class b/src/main/resources/com/google/common/base/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..0ec2c4e11872c8883d7e4e01828cdad475d25458 Binary files /dev/null and b/src/main/resources/com/google/common/base/package-info.class differ diff --git a/src/main/resources/com/google/common/cache/package-info.class b/src/main/resources/com/google/common/cache/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..5bdeb67b7a7102c916207a00be4e16fa2abebf29 Binary files /dev/null and b/src/main/resources/com/google/common/cache/package-info.class differ diff --git a/src/main/resources/com/google/common/collect/package-info.class b/src/main/resources/com/google/common/collect/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..e3921ab3645489b0524758c0bda34eb5dc1bf6a4 Binary files /dev/null and b/src/main/resources/com/google/common/collect/package-info.class differ diff --git a/src/main/resources/com/google/common/hash/package-info.class b/src/main/resources/com/google/common/hash/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..ed13122d495070cd3582e573b543cf471dfba187 Binary files /dev/null and b/src/main/resources/com/google/common/hash/package-info.class differ diff --git a/src/main/resources/com/google/common/io/package-info.class b/src/main/resources/com/google/common/io/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..d6d6bb7f9d4772259d3c86f7c509c26ad272646d Binary files /dev/null and b/src/main/resources/com/google/common/io/package-info.class differ diff --git a/src/main/resources/com/google/common/math/package-info.class b/src/main/resources/com/google/common/math/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..0d084e1eb415ffa14856e6f26317cabf8893088f Binary files /dev/null and b/src/main/resources/com/google/common/math/package-info.class differ diff --git a/src/main/resources/com/google/common/net/package-info.class b/src/main/resources/com/google/common/net/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..f2d488216574e0c83759077b35daee80722f5000 Binary files /dev/null and b/src/main/resources/com/google/common/net/package-info.class differ diff --git a/src/main/resources/com/google/common/primitives/package-info.class b/src/main/resources/com/google/common/primitives/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..0785e5e102346ba9775bd3d8b93dc47ebfb8ca5c Binary files /dev/null and b/src/main/resources/com/google/common/primitives/package-info.class differ diff --git a/src/main/resources/com/google/common/reflect/package-info.class b/src/main/resources/com/google/common/reflect/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..0281da1f800106722f58c95cccf04e742a2edee6 Binary files /dev/null and b/src/main/resources/com/google/common/reflect/package-info.class differ diff --git a/src/main/resources/com/google/common/util/concurrent/package-info.class b/src/main/resources/com/google/common/util/concurrent/package-info.class new file mode 100644 index 0000000000000000000000000000000000000000..c2199f5998c70c9580109a9df9e577ecfc108a8a Binary files /dev/null and b/src/main/resources/com/google/common/util/concurrent/package-info.class differ diff --git a/src/main/resources/com/kenai/constantine/Constant.class b/src/main/resources/com/kenai/constantine/Constant.class new file mode 100644 index 0000000000000000000000000000000000000000..a5df45d6b41d67c13b71c83f3ad6e7670ae4e739 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/Constant.class differ diff --git a/src/main/resources/com/kenai/constantine/ConstantSet$ConstantImpl.class b/src/main/resources/com/kenai/constantine/ConstantSet$ConstantImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..c8553042d5fe18ce74356702df1ebab82ce6e819 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/ConstantSet$ConstantImpl.class differ diff --git a/src/main/resources/com/kenai/constantine/ConstantSet$ConstantIterator.class b/src/main/resources/com/kenai/constantine/ConstantSet$ConstantIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..dbfbec3f854f843f49f2dd60c927d8eb8940ec61 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/ConstantSet$ConstantIterator.class differ diff --git a/src/main/resources/com/kenai/constantine/ConstantSet.class b/src/main/resources/com/kenai/constantine/ConstantSet.class new file mode 100644 index 0000000000000000000000000000000000000000..88caf376c853ee31f8de4c44405e0b87d35e40b1 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/ConstantSet.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/AddressFamily.class b/src/main/resources/com/kenai/constantine/platform/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..310bdacc170d155f9a95e01778c84e5a9842c917 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/AddressFamily.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/ConstantResolver$UnknownConstant.class b/src/main/resources/com/kenai/constantine/platform/ConstantResolver$UnknownConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..73fdff8ea232395f7160a92738f35affe5ed0f30 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/ConstantResolver$UnknownConstant.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/ConstantResolver.class b/src/main/resources/com/kenai/constantine/platform/ConstantResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..dc77855cec66e2af129b86bced1e36c65df6a0ca Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/ConstantResolver.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/Errno.class b/src/main/resources/com/kenai/constantine/platform/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..c610c95f36505d4f2b7f3f35d75bb37d07d2c11c Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/Errno.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/Fcntl.class b/src/main/resources/com/kenai/constantine/platform/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..8677a6cd77d39025b01abc3956e3051e3e917b08 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/Fcntl.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/INAddr.class b/src/main/resources/com/kenai/constantine/platform/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..a20cd12d8a8de27420da49d35e7ed13c9d523c9a Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/INAddr.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/IPProto.class b/src/main/resources/com/kenai/constantine/platform/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..77b8bbee1b193908745ee8aba19755feb0e8835f Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/IPProto.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/NameInfo.class b/src/main/resources/com/kenai/constantine/platform/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..7f2a832765c17f7d65da8fc7423c8050960b3c2b Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/NameInfo.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/OpenFlags.class b/src/main/resources/com/kenai/constantine/platform/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..d1e568a05b06cca74cfa93ecf091e0571714ed24 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/OpenFlags.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/PRIO.class b/src/main/resources/com/kenai/constantine/platform/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..66045aed86a50c8738cf6c8697a03a418322dbe3 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/PRIO.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/ProtocolFamily.class b/src/main/resources/com/kenai/constantine/platform/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..22bfd53a62fc00f9bf7568dae8cb9b936d7f1d66 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/ProtocolFamily.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/RLIM.class b/src/main/resources/com/kenai/constantine/platform/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..274ded9968deb5889f2a8e9f1b66c9fab553838f Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/RLIM.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/RLIMIT.class b/src/main/resources/com/kenai/constantine/platform/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..84cf2535cf038a0704575d88c89909347eb17fb9 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/RLIMIT.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/Shutdown.class b/src/main/resources/com/kenai/constantine/platform/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..14b4435a59e8a2fa87737069d87ac4f6dbc5a2bf Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/Shutdown.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/Signal.class b/src/main/resources/com/kenai/constantine/platform/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..26dca7b1a858d7e169ca09bf2366213c3c759077 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/Signal.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/Sock.class b/src/main/resources/com/kenai/constantine/platform/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..62b7c8815f467bfb61a7a1c06888a8fb6ead3a67 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/Sock.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/SocketLevel.class b/src/main/resources/com/kenai/constantine/platform/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..76c18c91b78523da8eeaf3152d2ffb5aca57681f Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/SocketLevel.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/SocketOption.class b/src/main/resources/com/kenai/constantine/platform/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..40d285c583892602141b25aa8f73d58e4b757b48 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/SocketOption.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/Sysconf.class b/src/main/resources/com/kenai/constantine/platform/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..3fb827bfdc9cbcd5d8359d9b95576f8587ced49e Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/Sysconf.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/TCP.class b/src/main/resources/com/kenai/constantine/platform/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..5ebf470a277a798be45e39c24c6dce3017b3130a Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/TCP.class differ diff --git a/src/main/resources/com/kenai/constantine/platform/WaitFlags.class b/src/main/resources/com/kenai/constantine/platform/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..36af8c541f4eead7a6a392ff3e2dd1a350745e60 Binary files /dev/null and b/src/main/resources/com/kenai/constantine/platform/WaitFlags.class differ diff --git a/src/main/resources/com/kenai/jffi/Aggregate.class b/src/main/resources/com/kenai/jffi/Aggregate.class new file mode 100644 index 0000000000000000000000000000000000000000..06fc549c3e5852b3c41862521191ab657a0b0415 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Aggregate.class differ diff --git a/src/main/resources/com/kenai/jffi/Array.class b/src/main/resources/com/kenai/jffi/Array.class new file mode 100644 index 0000000000000000000000000000000000000000..78b758bdd73de0001d75fceca7a6177dfa2216b7 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Array.class differ diff --git a/src/main/resources/com/kenai/jffi/ArrayFlags.class b/src/main/resources/com/kenai/jffi/ArrayFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..f851ed21266b1eac0ec666e294b0e063d37d1e77 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ArrayFlags.class differ diff --git a/src/main/resources/com/kenai/jffi/CallContext.class b/src/main/resources/com/kenai/jffi/CallContext.class new file mode 100644 index 0000000000000000000000000000000000000000..2570d0f9ade44f98b4ef82ff7aa8a67e7d253bfe Binary files /dev/null and b/src/main/resources/com/kenai/jffi/CallContext.class differ diff --git a/src/main/resources/com/kenai/jffi/CallContextCache$1.class b/src/main/resources/com/kenai/jffi/CallContextCache$1.class new file mode 100644 index 0000000000000000000000000000000000000000..bc5f3efec1924e9d04aa66c1fad5ab067f39f220 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/CallContextCache$1.class differ diff --git a/src/main/resources/com/kenai/jffi/CallContextCache$CallContextRef.class b/src/main/resources/com/kenai/jffi/CallContextCache$CallContextRef.class new file mode 100644 index 0000000000000000000000000000000000000000..3f858a046d62be8cd3cd9e0eec0486ea91033d84 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/CallContextCache$CallContextRef.class differ diff --git a/src/main/resources/com/kenai/jffi/CallContextCache$Signature.class b/src/main/resources/com/kenai/jffi/CallContextCache$Signature.class new file mode 100644 index 0000000000000000000000000000000000000000..0e9697dfc03f367e93239e4815589d331560c003 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/CallContextCache$Signature.class differ diff --git a/src/main/resources/com/kenai/jffi/CallContextCache$SingletonHolder.class b/src/main/resources/com/kenai/jffi/CallContextCache$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..d4845f4efe41362676d2c181bd450ded45301271 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/CallContextCache$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/CallContextCache.class b/src/main/resources/com/kenai/jffi/CallContextCache.class new file mode 100644 index 0000000000000000000000000000000000000000..d302b981771fc36631387b5f82d4e60745d5736b Binary files /dev/null and b/src/main/resources/com/kenai/jffi/CallContextCache.class differ diff --git a/src/main/resources/com/kenai/jffi/CallingConvention.class b/src/main/resources/com/kenai/jffi/CallingConvention.class new file mode 100644 index 0000000000000000000000000000000000000000..f599503c4f1dae64ac92522c16abcc8eb3bd7c73 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/CallingConvention.class differ diff --git a/src/main/resources/com/kenai/jffi/Closure$Buffer.class b/src/main/resources/com/kenai/jffi/Closure$Buffer.class new file mode 100644 index 0000000000000000000000000000000000000000..a3f973003c77f54c9142f5a608af4b3ad58a6bda Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Closure$Buffer.class differ diff --git a/src/main/resources/com/kenai/jffi/Closure$Handle.class b/src/main/resources/com/kenai/jffi/Closure$Handle.class new file mode 100644 index 0000000000000000000000000000000000000000..a93ad9d7ac8552f5d077780b07a882fbe6e344ed Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Closure$Handle.class differ diff --git a/src/main/resources/com/kenai/jffi/Closure.class b/src/main/resources/com/kenai/jffi/Closure.class new file mode 100644 index 0000000000000000000000000000000000000000..32956c7ed97c2d6df8ae88ba75eddae5edd2cb65 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Closure.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosureMagazine$1.class b/src/main/resources/com/kenai/jffi/ClosureMagazine$1.class new file mode 100644 index 0000000000000000000000000000000000000000..dcfabd014dfb269ed74623b5286b829afc29e401 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosureMagazine$1.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosureMagazine$Handle.class b/src/main/resources/com/kenai/jffi/ClosureMagazine$Handle.class new file mode 100644 index 0000000000000000000000000000000000000000..409e5a8a9595ef02c10da927c052f818ad8b827b Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosureMagazine$Handle.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosureMagazine.class b/src/main/resources/com/kenai/jffi/ClosureMagazine.class new file mode 100644 index 0000000000000000000000000000000000000000..2bec8da956aa48bb49f33d6c6b414c62a812d144 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosureMagazine.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosureManager$1.class b/src/main/resources/com/kenai/jffi/ClosureManager$1.class new file mode 100644 index 0000000000000000000000000000000000000000..845aa84b714a9d925f103fd88466fca9c14b5009 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosureManager$1.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosureManager$SingletonHolder.class b/src/main/resources/com/kenai/jffi/ClosureManager$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..7c2147b27914067b4a446d60076e5f8f09c06a3c Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosureManager$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosureManager.class b/src/main/resources/com/kenai/jffi/ClosureManager.class new file mode 100644 index 0000000000000000000000000000000000000000..17e6d719e625f4ccb5eb15aa86a8705d146df614 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosureManager.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosurePool$1.class b/src/main/resources/com/kenai/jffi/ClosurePool$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f396d601f1cd43a94afb7b391660c9cc865d4505 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosurePool$1.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosurePool$Handle.class b/src/main/resources/com/kenai/jffi/ClosurePool$Handle.class new file mode 100644 index 0000000000000000000000000000000000000000..7ad7501a080ed4493b6a6c4eddae6715c245600b Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosurePool$Handle.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosurePool$Magazine$Slot.class b/src/main/resources/com/kenai/jffi/ClosurePool$Magazine$Slot.class new file mode 100644 index 0000000000000000000000000000000000000000..0bbde8cf0873781a9693e0dac66830686b2dbec4 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosurePool$Magazine$Slot.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosurePool$Magazine.class b/src/main/resources/com/kenai/jffi/ClosurePool$Magazine.class new file mode 100644 index 0000000000000000000000000000000000000000..e178f12be2e734853330bdef0c90bda08d2588fb Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosurePool$Magazine.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosurePool$MagazineHolder.class b/src/main/resources/com/kenai/jffi/ClosurePool$MagazineHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..51c32aaa33590a47ad559a386089d076376e8182 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosurePool$MagazineHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosurePool$Proxy.class b/src/main/resources/com/kenai/jffi/ClosurePool$Proxy.class new file mode 100644 index 0000000000000000000000000000000000000000..751968f5a46626e17c314f9ff720b1132c162567 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosurePool$Proxy.class differ diff --git a/src/main/resources/com/kenai/jffi/ClosurePool.class b/src/main/resources/com/kenai/jffi/ClosurePool.class new file mode 100644 index 0000000000000000000000000000000000000000..7a0b3f30d2a46a54476fe3ef75f3893b5272fd61 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ClosurePool.class differ diff --git a/src/main/resources/com/kenai/jffi/DirectClosureBuffer$1.class b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f1f20a444058bfcf4ef355e77a3a70f0eb4c0ba4 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$1.class differ diff --git a/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO.class b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO.class new file mode 100644 index 0000000000000000000000000000000000000000..dee6606371e1869f7d781959df12a0f83fafa734 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO.class differ diff --git a/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO32.class b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO32.class new file mode 100644 index 0000000000000000000000000000000000000000..9c65cff68a9c15663ddbd478da1843fa981269ea Binary files /dev/null and b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO32.class differ diff --git a/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO64.class b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO64.class new file mode 100644 index 0000000000000000000000000000000000000000..3104a6f7302e042f4f9bc76a5c62a670d4740be2 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/DirectClosureBuffer$NativeWordIO64.class differ diff --git a/src/main/resources/com/kenai/jffi/DirectClosureBuffer.class b/src/main/resources/com/kenai/jffi/DirectClosureBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..3108f01e2485d03462efa84fd87bcbe88ee40a85 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/DirectClosureBuffer.class differ diff --git a/src/main/resources/com/kenai/jffi/DirectObjectParameterStrategy.class b/src/main/resources/com/kenai/jffi/DirectObjectParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..f0e6867c55522e52b60b8cbd55abbd41bbcf83a4 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/DirectObjectParameterStrategy.class differ diff --git a/src/main/resources/com/kenai/jffi/Foreign$1.class b/src/main/resources/com/kenai/jffi/Foreign$1.class new file mode 100644 index 0000000000000000000000000000000000000000..63ebd8fa0f541ba7c67b47ede832d5e1d533498c Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Foreign$1.class differ diff --git a/src/main/resources/com/kenai/jffi/Foreign$InValidInstanceHolder.class b/src/main/resources/com/kenai/jffi/Foreign$InValidInstanceHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..80b1d73066873a1e47edfd4f73a147c4835271e1 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Foreign$InValidInstanceHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/Foreign$InstanceHolder.class b/src/main/resources/com/kenai/jffi/Foreign$InstanceHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..57e2e6b69f2804aef7df3559b343375e318b60a5 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Foreign$InstanceHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/Foreign$ValidInstanceHolder.class b/src/main/resources/com/kenai/jffi/Foreign$ValidInstanceHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..7b9b5b683f62934f9b1799c362ba9feea0548831 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Foreign$ValidInstanceHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/Foreign.class b/src/main/resources/com/kenai/jffi/Foreign.class new file mode 100644 index 0000000000000000000000000000000000000000..c6119ebe7b20e3699605854ffdc2197d99c25e4d Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Foreign.class differ diff --git a/src/main/resources/com/kenai/jffi/Function.class b/src/main/resources/com/kenai/jffi/Function.class new file mode 100644 index 0000000000000000000000000000000000000000..638db7ffbce7247a8b1b0fb8842e0878e1464cbe Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Function.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$1.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$1.class new file mode 100644 index 0000000000000000000000000000000000000000..147f2ba1d82751774dfb253609c4edc1a0583e7f Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$1.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$ArrayIO.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..a5660a5cc166855eea8a0aef63a1db60f5497ffa Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$ArrayIO.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BE32ArrayIO.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BE32ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..f307cd5bc05c07953a2e32b3e9e6f81b3f80d5ef Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BE32ArrayIO.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BE64ArrayIO.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BE64ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..eff366a0676ad9c0c1fe2af392b7b471368b8dab Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BE64ArrayIO.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BigEndianArrayIO.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BigEndianArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..6509938e20ae1ad68adf09d08ac7afe3f0390519 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$BigEndianArrayIO.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$DefaultEncoder.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$DefaultEncoder.class new file mode 100644 index 0000000000000000000000000000000000000000..b6e4f1540402d19c86d9b016d74a1fa1e6753f4c Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$DefaultEncoder.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$Encoder.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$Encoder.class new file mode 100644 index 0000000000000000000000000000000000000000..fa63c0dea59c6848948308a10a83d45ec9794302 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$Encoder.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$I386RawEncoder.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$I386RawEncoder.class new file mode 100644 index 0000000000000000000000000000000000000000..2586e9bbcd775d807f41c8dee139b23d9ef64c42 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$I386RawEncoder.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LE32ArrayIO.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LE32ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..11e2c3c40366da7c09cf262c2ac6d8d0b9a31a32 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LE32ArrayIO.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LE64ArrayIO.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LE64ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..091c6958601c8affe83c564d01c2101c1d2812f6 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LE64ArrayIO.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LittleEndianArrayIO.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LittleEndianArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..d286ad1c022d6d00687cac0eabcd3c707ea8de47 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$LittleEndianArrayIO.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$RawEncoder.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$RawEncoder.class new file mode 100644 index 0000000000000000000000000000000000000000..751212afd0037be19cea5b512490067a3417568c Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer$RawEncoder.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapInvocationBuffer.class b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..14b355e2efd0b5f206d9cb2883a51a1555f13410 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapInvocationBuffer.class differ diff --git a/src/main/resources/com/kenai/jffi/HeapObjectParameterInvoker.class b/src/main/resources/com/kenai/jffi/HeapObjectParameterInvoker.class new file mode 100644 index 0000000000000000000000000000000000000000..753d23c11d2d9a61e7c20fb08bad6774e89e19d3 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/HeapObjectParameterInvoker.class differ diff --git a/src/main/resources/com/kenai/jffi/Init.class b/src/main/resources/com/kenai/jffi/Init.class new file mode 100644 index 0000000000000000000000000000000000000000..fb841627c01f67cb8048f6dbcd8b13296790c15e Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Init.class differ diff --git a/src/main/resources/com/kenai/jffi/Internals.class b/src/main/resources/com/kenai/jffi/Internals.class new file mode 100644 index 0000000000000000000000000000000000000000..cd378c01d9496cc1e31bae3e0c1de67e173382ec Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Internals.class differ diff --git a/src/main/resources/com/kenai/jffi/InvocationBuffer.class b/src/main/resources/com/kenai/jffi/InvocationBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..96ff5e11634fdead8bc0c89e6ea3b15837ffd073 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/InvocationBuffer.class differ diff --git a/src/main/resources/com/kenai/jffi/InvokeDynamicSupport$Invoker.class b/src/main/resources/com/kenai/jffi/InvokeDynamicSupport$Invoker.class new file mode 100644 index 0000000000000000000000000000000000000000..8d1bf9c615e721172313d04804fbee1d7c0864bf Binary files /dev/null and b/src/main/resources/com/kenai/jffi/InvokeDynamicSupport$Invoker.class differ diff --git a/src/main/resources/com/kenai/jffi/InvokeDynamicSupport$JSR292.class b/src/main/resources/com/kenai/jffi/InvokeDynamicSupport$JSR292.class new file mode 100644 index 0000000000000000000000000000000000000000..94f6ac63820190a2c37d1ac747929663c7f16ae2 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/InvokeDynamicSupport$JSR292.class differ diff --git a/src/main/resources/com/kenai/jffi/InvokeDynamicSupport.class b/src/main/resources/com/kenai/jffi/InvokeDynamicSupport.class new file mode 100644 index 0000000000000000000000000000000000000000..b8f4a294ad6337d58376f3b010552733930ce6e9 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/InvokeDynamicSupport.class differ diff --git a/src/main/resources/com/kenai/jffi/Invoker$1.class b/src/main/resources/com/kenai/jffi/Invoker$1.class new file mode 100644 index 0000000000000000000000000000000000000000..eff1ac90b2f89d47f1c328f0e66746e012158b53 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Invoker$1.class differ diff --git a/src/main/resources/com/kenai/jffi/Invoker$ILP32.class b/src/main/resources/com/kenai/jffi/Invoker$ILP32.class new file mode 100644 index 0000000000000000000000000000000000000000..4893bf4039bdb144467c012240195ce5e29f362a Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Invoker$ILP32.class differ diff --git a/src/main/resources/com/kenai/jffi/Invoker$LP64.class b/src/main/resources/com/kenai/jffi/Invoker$LP64.class new file mode 100644 index 0000000000000000000000000000000000000000..2128a024edfe43b221a7df1e672e2f728fc79728 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Invoker$LP64.class differ diff --git a/src/main/resources/com/kenai/jffi/Invoker$SingletonHolder.class b/src/main/resources/com/kenai/jffi/Invoker$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..ee631e74f5230677a3e9d277b53de06a0da20e81 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Invoker$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/Invoker.class b/src/main/resources/com/kenai/jffi/Invoker.class new file mode 100644 index 0000000000000000000000000000000000000000..9c276ca2bcb902ed67f1c4bf636ab43525223474 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Invoker.class differ diff --git a/src/main/resources/com/kenai/jffi/LastError$1.class b/src/main/resources/com/kenai/jffi/LastError$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f3bc32ee544919ac27de3732855f995aaf753aff Binary files /dev/null and b/src/main/resources/com/kenai/jffi/LastError$1.class differ diff --git a/src/main/resources/com/kenai/jffi/LastError$SingletonHolder.class b/src/main/resources/com/kenai/jffi/LastError$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..425f47a8176620bed0b7fb3cf131f8fba1340aaf Binary files /dev/null and b/src/main/resources/com/kenai/jffi/LastError$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/LastError.class b/src/main/resources/com/kenai/jffi/LastError.class new file mode 100644 index 0000000000000000000000000000000000000000..b519da2cdcbb8c13c2f930a9ab70086f11da8034 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/LastError.class differ diff --git a/src/main/resources/com/kenai/jffi/Library$DefaultLibrary.class b/src/main/resources/com/kenai/jffi/Library$DefaultLibrary.class new file mode 100644 index 0000000000000000000000000000000000000000..2374f7f401570ac63e6dd4ff42396ba2b66b8a02 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Library$DefaultLibrary.class differ diff --git a/src/main/resources/com/kenai/jffi/Library.class b/src/main/resources/com/kenai/jffi/Library.class new file mode 100644 index 0000000000000000000000000000000000000000..a77f9f4db79bee82720c079b0f46f9f22c8f326d Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Library.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$1.class b/src/main/resources/com/kenai/jffi/MemoryIO$1.class new file mode 100644 index 0000000000000000000000000000000000000000..384f5f71fa6b078ecbe4960dadf91dbd140cfa27 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$1.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl.class b/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..65910d5cb94c9ab865745675344746f007565a42 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl32.class b/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl32.class new file mode 100644 index 0000000000000000000000000000000000000000..bcf8d369c6b49d53698be4a2343294a22ffbc6f3 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl32.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl64.class b/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl64.class new file mode 100644 index 0000000000000000000000000000000000000000..e909eb1580dc3ec8c8d49649a0116a57777273d7 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$NativeImpl64.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$SingletonHolder.class b/src/main/resources/com/kenai/jffi/MemoryIO$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..352a21a3c19057c8eb7e2a0e7e171914ee5d57e9 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl.class b/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3019ff57964ac86fda9671593e4558064a59ba46 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl32.class b/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl32.class new file mode 100644 index 0000000000000000000000000000000000000000..51f3800cf30f982cb5dba38093c59e9feb2df214 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl32.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl64.class b/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl64.class new file mode 100644 index 0000000000000000000000000000000000000000..161817aee5806c4f169cac4701e120a900e1ff13 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO$UnsafeImpl64.class differ diff --git a/src/main/resources/com/kenai/jffi/MemoryIO.class b/src/main/resources/com/kenai/jffi/MemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..e85c07dd66bbe831ef551013f260d0ff0fd7228e Binary files /dev/null and b/src/main/resources/com/kenai/jffi/MemoryIO.class differ diff --git a/src/main/resources/com/kenai/jffi/NativeMethod.class b/src/main/resources/com/kenai/jffi/NativeMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..f4c8b6f09bbb1e9709245167a0abd9df3586a7d0 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/NativeMethod.class differ diff --git a/src/main/resources/com/kenai/jffi/NativeMethods$ResourceHolder.class b/src/main/resources/com/kenai/jffi/NativeMethods$ResourceHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..59fdd063e37949f474d7eefbb336826e17013369 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/NativeMethods$ResourceHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/NativeMethods.class b/src/main/resources/com/kenai/jffi/NativeMethods.class new file mode 100644 index 0000000000000000000000000000000000000000..4c4f23fee359257b29c7c8e2f941b9a6134923fc Binary files /dev/null and b/src/main/resources/com/kenai/jffi/NativeMethods.class differ diff --git a/src/main/resources/com/kenai/jffi/NativeObjectParameterInvoker.class b/src/main/resources/com/kenai/jffi/NativeObjectParameterInvoker.class new file mode 100644 index 0000000000000000000000000000000000000000..aa51cc5b7efd80d677fb09fbb8ecdb2d53302e5d Binary files /dev/null and b/src/main/resources/com/kenai/jffi/NativeObjectParameterInvoker.class differ diff --git a/src/main/resources/com/kenai/jffi/NativeType.class b/src/main/resources/com/kenai/jffi/NativeType.class new file mode 100644 index 0000000000000000000000000000000000000000..3ab49b0b6ee856caebe5b74ed1ab51ecaf8680f2 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/NativeType.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectBuffer.class b/src/main/resources/com/kenai/jffi/ObjectBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..bb77dedc31f3f30a117b3536c17d432c8b61d56b Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectBuffer.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterInfo$ComponentType.class b/src/main/resources/com/kenai/jffi/ObjectParameterInfo$ComponentType.class new file mode 100644 index 0000000000000000000000000000000000000000..61b848c4132c663d8660e6edf84d97e78bcccab1 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterInfo$ComponentType.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterInfo$ObjectType.class b/src/main/resources/com/kenai/jffi/ObjectParameterInfo$ObjectType.class new file mode 100644 index 0000000000000000000000000000000000000000..fbb1e54c02082df2d3a11c13e0db79d60137edde Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterInfo$ObjectType.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterInfo.class b/src/main/resources/com/kenai/jffi/ObjectParameterInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..26e3c7a0368c2bdcdfbd0035c7288231a286e2ce Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterInfo.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterInvoker$SingletonHolder.class b/src/main/resources/com/kenai/jffi/ObjectParameterInvoker$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..c725089f234bab606c5744cca62b0a47cc41dfa2 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterInvoker$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterInvoker.class b/src/main/resources/com/kenai/jffi/ObjectParameterInvoker.class new file mode 100644 index 0000000000000000000000000000000000000000..2892936aeddccbc5ca31208abbc6687a69a7c408 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterInvoker.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterStrategy$StrategyType.class b/src/main/resources/com/kenai/jffi/ObjectParameterStrategy$StrategyType.class new file mode 100644 index 0000000000000000000000000000000000000000..e3998f2fbc71133587a895b2eff093e7e40213fd Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterStrategy$StrategyType.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterStrategy.class b/src/main/resources/com/kenai/jffi/ObjectParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..33223087b5e193b2f01e5154421b86474b4c6419 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterStrategy.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterType$ComponentType.class b/src/main/resources/com/kenai/jffi/ObjectParameterType$ComponentType.class new file mode 100644 index 0000000000000000000000000000000000000000..3007287a3df6bdad513dc5263e7f12799b2d8d63 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterType$ComponentType.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterType$ObjectType.class b/src/main/resources/com/kenai/jffi/ObjectParameterType$ObjectType.class new file mode 100644 index 0000000000000000000000000000000000000000..9bd3032c52162ddb087bb56300f2bdf5ef24506e Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterType$ObjectType.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterType$TypeCache.class b/src/main/resources/com/kenai/jffi/ObjectParameterType$TypeCache.class new file mode 100644 index 0000000000000000000000000000000000000000..680c4219754a05b678b5925fe7e34b2b08320ff7 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterType$TypeCache.class differ diff --git a/src/main/resources/com/kenai/jffi/ObjectParameterType.class b/src/main/resources/com/kenai/jffi/ObjectParameterType.class new file mode 100644 index 0000000000000000000000000000000000000000..43ed4a070bafccc639ac6efb93f007d43e90baeb Binary files /dev/null and b/src/main/resources/com/kenai/jffi/ObjectParameterType.class differ diff --git a/src/main/resources/com/kenai/jffi/PageManager$SingletonHolder.class b/src/main/resources/com/kenai/jffi/PageManager$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..b22c9add759bc5cca49bc1e85f68a27f164afdb8 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/PageManager$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/PageManager$Unix.class b/src/main/resources/com/kenai/jffi/PageManager$Unix.class new file mode 100644 index 0000000000000000000000000000000000000000..3d1c8cbf6b83a45e3d4dadb6ffce9535032904ed Binary files /dev/null and b/src/main/resources/com/kenai/jffi/PageManager$Unix.class differ diff --git a/src/main/resources/com/kenai/jffi/PageManager$Windows.class b/src/main/resources/com/kenai/jffi/PageManager$Windows.class new file mode 100644 index 0000000000000000000000000000000000000000..f27873c9442da99020883120c0da89de6675820c Binary files /dev/null and b/src/main/resources/com/kenai/jffi/PageManager$Windows.class differ diff --git a/src/main/resources/com/kenai/jffi/PageManager.class b/src/main/resources/com/kenai/jffi/PageManager.class new file mode 100644 index 0000000000000000000000000000000000000000..0eb4efa34936ccbd6b829837722f660477da6c15 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/PageManager.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$1.class b/src/main/resources/com/kenai/jffi/Platform$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ab88adfdb64a07208333f88b566f70ebb3b00878 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$1.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$ArchHolder.class b/src/main/resources/com/kenai/jffi/Platform$ArchHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..6776d73c7c100ffb9b354d00405e50d9cce111a8 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$ArchHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$CPU.class b/src/main/resources/com/kenai/jffi/Platform$CPU.class new file mode 100644 index 0000000000000000000000000000000000000000..989869bd52aebbe7ffa5593c95585d7eea7ae9c2 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$CPU.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$Darwin.class b/src/main/resources/com/kenai/jffi/Platform$Darwin.class new file mode 100644 index 0000000000000000000000000000000000000000..d428af62909ad022e4074a0b2d74d9c4814f0201 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$Darwin.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$Default.class b/src/main/resources/com/kenai/jffi/Platform$Default.class new file mode 100644 index 0000000000000000000000000000000000000000..84a5c5b4e4eebafa733b49ae2853a0fcf1ec7a77 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$Default.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$OS.class b/src/main/resources/com/kenai/jffi/Platform$OS.class new file mode 100644 index 0000000000000000000000000000000000000000..6fe83827ac026255478aa1276db79d9f44c54b4d Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$OS.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$SingletonHolder.class b/src/main/resources/com/kenai/jffi/Platform$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..393e5d761ed1672b9cc8d4806ff5cb170038c354 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$SingletonHolder.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform$Windows.class b/src/main/resources/com/kenai/jffi/Platform$Windows.class new file mode 100644 index 0000000000000000000000000000000000000000..c431273837ad0487144b4699afc29aac26356c05 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform$Windows.class differ diff --git a/src/main/resources/com/kenai/jffi/Platform.class b/src/main/resources/com/kenai/jffi/Platform.class new file mode 100644 index 0000000000000000000000000000000000000000..dfdb8ca72575f84c85e9c1b50a97dd41282bed71 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Platform.class differ diff --git a/src/main/resources/com/kenai/jffi/Struct$1.class b/src/main/resources/com/kenai/jffi/Struct$1.class new file mode 100644 index 0000000000000000000000000000000000000000..989754dae68a20cf75d941c63a35fa915eda7a7c Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Struct$1.class differ diff --git a/src/main/resources/com/kenai/jffi/Struct$StructReference.class b/src/main/resources/com/kenai/jffi/Struct$StructReference.class new file mode 100644 index 0000000000000000000000000000000000000000..b39fcb7a256aabd5ce76c664fb5c884c777a0ad6 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Struct$StructReference.class differ diff --git a/src/main/resources/com/kenai/jffi/Struct.class b/src/main/resources/com/kenai/jffi/Struct.class new file mode 100644 index 0000000000000000000000000000000000000000..83e3de84acae77bcadc511609df177c5675f0e45 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Struct.class differ diff --git a/src/main/resources/com/kenai/jffi/Type$1.class b/src/main/resources/com/kenai/jffi/Type$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b1c9331ad8a826072b6a78b32421a359978d2faa Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Type$1.class differ diff --git a/src/main/resources/com/kenai/jffi/Type$Builtin.class b/src/main/resources/com/kenai/jffi/Type$Builtin.class new file mode 100644 index 0000000000000000000000000000000000000000..826c5a60764a06a3c32a4ba0a51254832f7ec596 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Type$Builtin.class differ diff --git a/src/main/resources/com/kenai/jffi/Type$BuiltinTypeInfo.class b/src/main/resources/com/kenai/jffi/Type$BuiltinTypeInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..32d8518cc9bebbad34c549bbe290baa27381723e Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Type$BuiltinTypeInfo.class differ diff --git a/src/main/resources/com/kenai/jffi/Type$InvalidLookupTable.class b/src/main/resources/com/kenai/jffi/Type$InvalidLookupTable.class new file mode 100644 index 0000000000000000000000000000000000000000..853af655cd18eda42978965cc68801ea6eb1be0c Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Type$InvalidLookupTable.class differ diff --git a/src/main/resources/com/kenai/jffi/Type$LookupTable.class b/src/main/resources/com/kenai/jffi/Type$LookupTable.class new file mode 100644 index 0000000000000000000000000000000000000000..1961663d360c1360e0107a51e01e9f1fe3f43353 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Type$LookupTable.class differ diff --git a/src/main/resources/com/kenai/jffi/Type$NativeLookupTable.class b/src/main/resources/com/kenai/jffi/Type$NativeLookupTable.class new file mode 100644 index 0000000000000000000000000000000000000000..af68c7e07a6fde33227db7057772e50ca58d86d8 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Type$NativeLookupTable.class differ diff --git a/src/main/resources/com/kenai/jffi/Type.class b/src/main/resources/com/kenai/jffi/Type.class new file mode 100644 index 0000000000000000000000000000000000000000..1cc18d52b4cf67df1f5e95f6a4f405bf538802d8 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Type.class differ diff --git a/src/main/resources/com/kenai/jffi/Union.class b/src/main/resources/com/kenai/jffi/Union.class new file mode 100644 index 0000000000000000000000000000000000000000..902925841d93de87f2864dc46a88581f33df422a Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Union.class differ diff --git a/src/main/resources/com/kenai/jffi/Version.class b/src/main/resources/com/kenai/jffi/Version.class new file mode 100644 index 0000000000000000000000000000000000000000..7ee6f376b305128f563aaf7fa5a1c37681c56bc7 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/Version.class differ diff --git a/src/main/resources/com/kenai/jffi/internal/StubLoader$CPU.class b/src/main/resources/com/kenai/jffi/internal/StubLoader$CPU.class new file mode 100644 index 0000000000000000000000000000000000000000..0c84992a16ebcaa56759a137170a00d87f07b75f Binary files /dev/null and b/src/main/resources/com/kenai/jffi/internal/StubLoader$CPU.class differ diff --git a/src/main/resources/com/kenai/jffi/internal/StubLoader$OS.class b/src/main/resources/com/kenai/jffi/internal/StubLoader$OS.class new file mode 100644 index 0000000000000000000000000000000000000000..d6cdab0d5df86e214429dc15abe8be54e2f603b8 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/internal/StubLoader$OS.class differ diff --git a/src/main/resources/com/kenai/jffi/internal/StubLoader.class b/src/main/resources/com/kenai/jffi/internal/StubLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..f97df4a38a626e8971d87162930e98ab27b0a1e7 Binary files /dev/null and b/src/main/resources/com/kenai/jffi/internal/StubLoader.class differ diff --git a/src/main/resources/com/xhaus/modjy/ModjyJServlet.class b/src/main/resources/com/xhaus/modjy/ModjyJServlet.class new file mode 100644 index 0000000000000000000000000000000000000000..304b000283b2ab6a47c7083970668db173dd20df Binary files /dev/null and b/src/main/resources/com/xhaus/modjy/ModjyJServlet.class differ diff --git a/src/main/resources/com/ziclix/python/sql/ConnectionFunc.class b/src/main/resources/com/ziclix/python/sql/ConnectionFunc.class new file mode 100644 index 0000000000000000000000000000000000000000..8e7bc8a4ab6b7442f9e87711673009e6bc52b7ba Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/ConnectionFunc.class differ diff --git a/src/main/resources/com/ziclix/python/sql/CursorFunc.class b/src/main/resources/com/ziclix/python/sql/CursorFunc.class new file mode 100644 index 0000000000000000000000000000000000000000..5ea7989e388593c3fb546d8eecca507eab6f9932 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/CursorFunc.class differ diff --git a/src/main/resources/com/ziclix/python/sql/DBApiType.class b/src/main/resources/com/ziclix/python/sql/DBApiType.class new file mode 100644 index 0000000000000000000000000000000000000000..6617e7198620ec6cb08a7ed00b94654f0b69f6f3 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/DBApiType.class differ diff --git a/src/main/resources/com/ziclix/python/sql/DataHandler.class b/src/main/resources/com/ziclix/python/sql/DataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..f106a476193ec16e202e213dad3998b957f6059b Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/DataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/DataHandlerTest$DefaultReturnHandler.class b/src/main/resources/com/ziclix/python/sql/DataHandlerTest$DefaultReturnHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..f8f0d33603ccdf49bd569e2a0a3ef8352ba850ea Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/DataHandlerTest$DefaultReturnHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/DataHandlerTest.class b/src/main/resources/com/ziclix/python/sql/DataHandlerTest.class new file mode 100644 index 0000000000000000000000000000000000000000..2cf6164abb897d77b210dc4e7e669b544573242c Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/DataHandlerTest.class differ diff --git a/src/main/resources/com/ziclix/python/sql/DateFactory.class b/src/main/resources/com/ziclix/python/sql/DateFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..a136d0a4f1ec4bbbcd2c4a8e1faa305c0f61835a Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/DateFactory.class differ diff --git a/src/main/resources/com/ziclix/python/sql/DynamicFetch.class b/src/main/resources/com/ziclix/python/sql/DynamicFetch.class new file mode 100644 index 0000000000000000000000000000000000000000..09d0874683b50a60369f8cfb2dd149239110aae0 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/DynamicFetch.class differ diff --git a/src/main/resources/com/ziclix/python/sql/ExtendedCursorFunc.class b/src/main/resources/com/ziclix/python/sql/ExtendedCursorFunc.class new file mode 100644 index 0000000000000000000000000000000000000000..336dae44f6a83e7eb0b18b8e1c0b4a70c8710365 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/ExtendedCursorFunc.class differ diff --git a/src/main/resources/com/ziclix/python/sql/Fetch.class b/src/main/resources/com/ziclix/python/sql/Fetch.class new file mode 100644 index 0000000000000000000000000000000000000000..179d4160fe7e86dc19ae29b3028b528b26c5dc33 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/Fetch.class differ diff --git a/src/main/resources/com/ziclix/python/sql/FilterDataHandler.class b/src/main/resources/com/ziclix/python/sql/FilterDataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..c1a287612ed29b3daecd76e85a7b89d8537c0dd5 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/FilterDataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/JDBC20DataHandler.class b/src/main/resources/com/ziclix/python/sql/JDBC20DataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..417c8faad7205e39e4b51769e43cb1dc94f52459 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/JDBC20DataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/JDBC30DataHandler.class b/src/main/resources/com/ziclix/python/sql/JDBC30DataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..bc0a548dda04ed13e7d8193425153238c60ebe0e Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/JDBC30DataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/JavaDateFactory.class b/src/main/resources/com/ziclix/python/sql/JavaDateFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..5c8cb6561c3d17fb55ddd6cd9f135a7b4b4fd3ee Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/JavaDateFactory.class differ diff --git a/src/main/resources/com/ziclix/python/sql/Jython22DataHandler.class b/src/main/resources/com/ziclix/python/sql/Jython22DataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..da8e81173afe0456df5ae6a40ae173853a29d8ee Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/Jython22DataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/Procedure.class b/src/main/resources/com/ziclix/python/sql/Procedure.class new file mode 100644 index 0000000000000000000000000000000000000000..af471c36e7e14f235f1de28554d9f6fadc5bd9dc Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/Procedure.class differ diff --git a/src/main/resources/com/ziclix/python/sql/PyConnection.class b/src/main/resources/com/ziclix/python/sql/PyConnection.class new file mode 100644 index 0000000000000000000000000000000000000000..be4cc473bd21eafbe0669eaf373c6acf40ecc57d Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/PyConnection.class differ diff --git a/src/main/resources/com/ziclix/python/sql/PyCursor.class b/src/main/resources/com/ziclix/python/sql/PyCursor.class new file mode 100644 index 0000000000000000000000000000000000000000..261ad6c163939290995694a14ae6deb6d67ef155 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/PyCursor.class differ diff --git a/src/main/resources/com/ziclix/python/sql/PyExtendedCursor.class b/src/main/resources/com/ziclix/python/sql/PyExtendedCursor.class new file mode 100644 index 0000000000000000000000000000000000000000..c1c77d05b075054a7407bccfcb3d98b565c46a2a Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/PyExtendedCursor.class differ diff --git a/src/main/resources/com/ziclix/python/sql/PyStatement.class b/src/main/resources/com/ziclix/python/sql/PyStatement.class new file mode 100644 index 0000000000000000000000000000000000000000..b19f0f6bdc5fd6e82020ad67a5959e24dadb6a11 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/PyStatement.class differ diff --git a/src/main/resources/com/ziclix/python/sql/StaticFetch.class b/src/main/resources/com/ziclix/python/sql/StaticFetch.class new file mode 100644 index 0000000000000000000000000000000000000000..699bfe06050ae976c157a4007ba9e088caf05ebc Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/StaticFetch.class differ diff --git a/src/main/resources/com/ziclix/python/sql/WarningEvent.class b/src/main/resources/com/ziclix/python/sql/WarningEvent.class new file mode 100644 index 0000000000000000000000000000000000000000..6c49be6d4aaf9f323d5285bb1b39981337e7c529 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/WarningEvent.class differ diff --git a/src/main/resources/com/ziclix/python/sql/WarningListener.class b/src/main/resources/com/ziclix/python/sql/WarningListener.class new file mode 100644 index 0000000000000000000000000000000000000000..9a104922f95a6cb168b795cd0d59d1d4fba68866 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/WarningListener.class differ diff --git a/src/main/resources/com/ziclix/python/sql/connect/Connect.class b/src/main/resources/com/ziclix/python/sql/connect/Connect.class new file mode 100644 index 0000000000000000000000000000000000000000..ae50dde683664839957f8aa5e6753a1d74531aa8 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/connect/Connect.class differ diff --git a/src/main/resources/com/ziclix/python/sql/connect/Connectx.class b/src/main/resources/com/ziclix/python/sql/connect/Connectx.class new file mode 100644 index 0000000000000000000000000000000000000000..a4554beca7b4f75f8fd989e86cc25c1ac326ea75 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/connect/Connectx.class differ diff --git a/src/main/resources/com/ziclix/python/sql/connect/Lookup.class b/src/main/resources/com/ziclix/python/sql/connect/Lookup.class new file mode 100644 index 0000000000000000000000000000000000000000..67ee071401e75bf28acae2ceedf9b0a722ea422a Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/connect/Lookup.class differ diff --git a/src/main/resources/com/ziclix/python/sql/handler/MySQLDataHandler.class b/src/main/resources/com/ziclix/python/sql/handler/MySQLDataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..2ebd866dcc5273df37937babe51517d50befcedf Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/handler/MySQLDataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/handler/PostgresqlDataHandler.class b/src/main/resources/com/ziclix/python/sql/handler/PostgresqlDataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..3e590ef3baa847c76be496afbd58977b36818570 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/handler/PostgresqlDataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/handler/RowIdHandler.class b/src/main/resources/com/ziclix/python/sql/handler/RowIdHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..4359710093c62bd96f034cf2f3a0cedc60a96fb7 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/handler/RowIdHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/handler/SQLServerDataHandler.class b/src/main/resources/com/ziclix/python/sql/handler/SQLServerDataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..cd742fc4a464f50fd524dde6fd8894b2576b92c5 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/handler/SQLServerDataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/handler/UpdateCountDataHandler.class b/src/main/resources/com/ziclix/python/sql/handler/UpdateCountDataHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..fbd78cf62dfa6d213fac8a0ceff7c4a1f3ec29a2 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/handler/UpdateCountDataHandler.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/Pipe.class b/src/main/resources/com/ziclix/python/sql/pipe/Pipe.class new file mode 100644 index 0000000000000000000000000000000000000000..5f9ab9febfbf8e030fa18cfdf19ee5d9a6544133 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/Pipe.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/PipeRunner.class b/src/main/resources/com/ziclix/python/sql/pipe/PipeRunner.class new file mode 100644 index 0000000000000000000000000000000000000000..2d99059d165fc4e03db8cec6c6a846d1536d5466 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/PipeRunner.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/Sink.class b/src/main/resources/com/ziclix/python/sql/pipe/Sink.class new file mode 100644 index 0000000000000000000000000000000000000000..037981257bab28063b23229103854590d1d6649c Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/Sink.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/SinkRunner.class b/src/main/resources/com/ziclix/python/sql/pipe/SinkRunner.class new file mode 100644 index 0000000000000000000000000000000000000000..a7c395338d010f057b8915ad77dfe2e7f4f5adc0 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/SinkRunner.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/Source.class b/src/main/resources/com/ziclix/python/sql/pipe/Source.class new file mode 100644 index 0000000000000000000000000000000000000000..3372c664a19c06fdb658ab27048a76a7531ac655 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/Source.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/SourceRunner.class b/src/main/resources/com/ziclix/python/sql/pipe/SourceRunner.class new file mode 100644 index 0000000000000000000000000000000000000000..dfc59b56b259ddf6157c4dda8833126bda441ba6 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/SourceRunner.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/csv/CSVSink.class b/src/main/resources/com/ziclix/python/sql/pipe/csv/CSVSink.class new file mode 100644 index 0000000000000000000000000000000000000000..ea0e241790d388d84d409d9bfe3fea1454df4fec Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/csv/CSVSink.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/csv/CSVString.class b/src/main/resources/com/ziclix/python/sql/pipe/csv/CSVString.class new file mode 100644 index 0000000000000000000000000000000000000000..34ee16cf78005a7c0e188f768d443b90d96ab4fa Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/csv/CSVString.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/db/BaseDB.class b/src/main/resources/com/ziclix/python/sql/pipe/db/BaseDB.class new file mode 100644 index 0000000000000000000000000000000000000000..4c969fb442a47bd537b01e57f2f0cee9d2adb517 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/db/BaseDB.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/db/DBSink.class b/src/main/resources/com/ziclix/python/sql/pipe/db/DBSink.class new file mode 100644 index 0000000000000000000000000000000000000000..29e44e794da6234f2554c4e63dfe587e0b498605 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/db/DBSink.class differ diff --git a/src/main/resources/com/ziclix/python/sql/pipe/db/DBSource.class b/src/main/resources/com/ziclix/python/sql/pipe/db/DBSource.class new file mode 100644 index 0000000000000000000000000000000000000000..c3381c7eb245e6197218ab51671222f402e20294 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/pipe/db/DBSource.class differ diff --git a/src/main/resources/com/ziclix/python/sql/procedure/SQLServerProcedure.class b/src/main/resources/com/ziclix/python/sql/procedure/SQLServerProcedure.class new file mode 100644 index 0000000000000000000000000000000000000000..50fd6cb0f7f72110dd654ae7cf050428da990866 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/procedure/SQLServerProcedure.class differ diff --git a/src/main/resources/com/ziclix/python/sql/resource/zxJDBCMessages.properties b/src/main/resources/com/ziclix/python/sql/resource/zxJDBCMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..23de55dc48ea5e8e23ee7ee70b91ec36063a7a88 --- /dev/null +++ b/src/main/resources/com/ziclix/python/sql/resource/zxJDBCMessages.properties @@ -0,0 +1,101 @@ + +# doc strings +Error=Exception that is the base class of all other error exceptions. + +Warning=Exception raised for important warnings like data truncations \ +while inserting, etc. + +InterfaceError=Exception raised for errors that are related to the database \ +interface rather than the database itself. + +DatabaseError=Exception raised for errors that are related to the database. + +InternalError=Exception raised when the database encounters an internal error, \ +e.g. the cursor is not valid anymore, the transaction is out of sync, etc. + +OperationalError=Exception raised for errors that are related to the database's \ +operation and not necessarily under the control of the programmer, e.g. an \ +unexpected disconnect occurs, the data source name is not found, a transaction \ +could not be processed, a memory allocation error occurred during processing, etc. + +ProgrammingError=Exception raised for programming errors, e.g. table not found or \ +already exists, syntax error in the SQL statement, wrong number of parameters \ +specified, etc. + +IntegrityError=Exception raised when the relational integrity of the database is \ +affected, e.g. a foreign key check fails. + +DataError=Exception raised for errors that are due to problems with the processed \ +data like division by zero, numeric value out of range, etc. + +NotSupportedError=Exception raised in case a method or database API was used which \ +is not supported by the database, e.g. requesting a .rollback() on a connection that \ +does not support transaction or has transactions turned off. + +# BCP +bcp.0=bcp(table, [where=None, params=None, include=None, exclude=None, toTable=None, bindings=None]) +bcp.1=\ Copies data resulting from a query on the source to the appropriate table on the \ +destination. Returns the count of the total number of rows bulk copied or -1 if the \ +query on the source returned no rows. If the destination excludes all the columns an \ +Error will be raised. +bcp.2=\ table - the table to query on the source database +bcp.3=\ where - an optional where clause, defaults to (1=1) if None +bcp.4=\ params - optional params to substituted in the where clause +bcp.5=\ include - the columns to be queried from the source, * if None +bcp.6=\ exclude - the columns to be excluded from insertion on the destination, all if None +bcp.7=\ toTable - if non-None, the table in the destination db, otherwise the same table as the source +bcp.8=\ bindings - the optional bindings for the destination, this allows morphing of types during the copy + +batchsize=the batch interval for inserts +queuesize=the maximum number of objects the queue can hold, 0 means unbounded (the default) + +# PyConnection + +close.0=Close the connection now (rather than whenever __del__ is called). +close.1=The connection will be unusable from this point forward; an Error \ +(or subclass) exception will be raised if any operation is attempted \ +with the connection. The same applies to all cursor objects trying \ +to use the connection. + +commit.0=Commit any pending transaction to the database. +commit.1=Note that if the database supports an auto-commit feature, this \ +must be initially off. An interface method may be provided to turn it back on. + +cursor.0=cursor([dynamic=0]) +cursor.1=\ Return a new Cursor Object using the connection. +cursor.2=\ dynamic - If non-zero, return a Cursor that does NOT iterate the results immediately. +cursor.3=\ This greatly increases the performance of large result sets, but fails to +cursor.4=\ set the .rowcount attribute on the Cursor. +cursor.5=If the database does not provide a direct cursor concept, the module \ +will have to emulate cursors using other means to the extent needed by this \ +specification. + +rollback.0=This method is optional since not all databases provide transaction support. +rollback.1=In case a database does provide transactions this method causes the database \ +to roll back to the start of any pending transaction. Closing a connection \ +without committing the changes first will cause an implicit rollback to be \ +performed. + +nativesql.0=Converts the given SQL statement into the system's native SQL grammar. +nativesql.1=A driver may convert the JDBC sql grammar into its system's native SQL \ +grammar prior to sending it; this method returns the native form of the statement \ +that the driver would have sent. + +updateCountDeprecation=The use of UpdateCountDataHandler is deprecated in favor of \ +the .updatecount attribute on a cursor. + +# exception messages +noStoredProc=stored procedures not implemented in db +optionalSecond=optional second argument must be a list or tuple +bindingValue=binding value must be a valid integer type from java.sql.Types +onlyOneResultSet=dynamic fetch allows only one result set +inconsistentRowCount=number of rows queried [{0,integer}] does not match number of rows inserted [{1,integer}] +invalidCons=invalid constructor for class [{0}] +noColInfo=unable to obtain column info +excludedAllCols=excluded all columns +invalidTableName=invalid table name [None] +unsupportedTypeForColumn=type [{0}] is not supported for column index: {1} +maybeCallproc=use .callproc() for stored procedures +nodynamiccursors=this version of jdbc does not support dynamic cursors +nocallprocsupport=dynamic cursor does not support .callproc; use static cursors instead + diff --git a/src/main/resources/com/ziclix/python/sql/util/BCP.class b/src/main/resources/com/ziclix/python/sql/util/BCP.class new file mode 100644 index 0000000000000000000000000000000000000000..dd66e781d107fe722052a0c82c33fe5514c76ae0 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/util/BCP.class differ diff --git a/src/main/resources/com/ziclix/python/sql/util/BCPFunc.class b/src/main/resources/com/ziclix/python/sql/util/BCPFunc.class new file mode 100644 index 0000000000000000000000000000000000000000..77591b8346f02fc2fd2017d19a2933836eb87fd1 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/util/BCPFunc.class differ diff --git a/src/main/resources/com/ziclix/python/sql/util/PyArgParser.class b/src/main/resources/com/ziclix/python/sql/util/PyArgParser.class new file mode 100644 index 0000000000000000000000000000000000000000..7cf67969eaa60ab651add4a4383e204d3a30795f Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/util/PyArgParser.class differ diff --git a/src/main/resources/com/ziclix/python/sql/util/Queue.class b/src/main/resources/com/ziclix/python/sql/util/Queue.class new file mode 100644 index 0000000000000000000000000000000000000000..8c8203f4cfbb66104489d370847eb2a342bac80f Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/util/Queue.class differ diff --git a/src/main/resources/com/ziclix/python/sql/util/QueueClosedException.class b/src/main/resources/com/ziclix/python/sql/util/QueueClosedException.class new file mode 100644 index 0000000000000000000000000000000000000000..a99e4940a03e92a63706784790e8fc81aa6d4736 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/util/QueueClosedException.class differ diff --git a/src/main/resources/com/ziclix/python/sql/zxJDBC.class b/src/main/resources/com/ziclix/python/sql/zxJDBC.class new file mode 100644 index 0000000000000000000000000000000000000000..bbcc29b8e161eeb26947da0d1f271148353afef7 Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/zxJDBC.class differ diff --git a/src/main/resources/com/ziclix/python/sql/zxJDBCFunc.class b/src/main/resources/com/ziclix/python/sql/zxJDBCFunc.class new file mode 100644 index 0000000000000000000000000000000000000000..746bddd344ea4f147a897763d77f76b8c275ef6e Binary files /dev/null and b/src/main/resources/com/ziclix/python/sql/zxJDBCFunc.class differ diff --git a/src/main/resources/javax/xml/XMLConstants.class b/src/main/resources/javax/xml/XMLConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..96d5f592466707bf81f73a84c9546914ba267850 Binary files /dev/null and b/src/main/resources/javax/xml/XMLConstants.class differ diff --git a/src/main/resources/javax/xml/datatype/DatatypeConfigurationException.class b/src/main/resources/javax/xml/datatype/DatatypeConfigurationException.class new file mode 100644 index 0000000000000000000000000000000000000000..54492507ad54c82ee219243e0914703ae6514b01 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/DatatypeConfigurationException.class differ diff --git a/src/main/resources/javax/xml/datatype/DatatypeConstants$1.class b/src/main/resources/javax/xml/datatype/DatatypeConstants$1.class new file mode 100644 index 0000000000000000000000000000000000000000..319b6e1b3a85277670726400c86bac6e7ae49e46 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/DatatypeConstants$1.class differ diff --git a/src/main/resources/javax/xml/datatype/DatatypeConstants$Field.class b/src/main/resources/javax/xml/datatype/DatatypeConstants$Field.class new file mode 100644 index 0000000000000000000000000000000000000000..db01a7d6af47284204643b3ce729919230a7d2de Binary files /dev/null and b/src/main/resources/javax/xml/datatype/DatatypeConstants$Field.class differ diff --git a/src/main/resources/javax/xml/datatype/DatatypeConstants.class b/src/main/resources/javax/xml/datatype/DatatypeConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..aae3192a1f83b3a5174c87c429bfd124edf518af Binary files /dev/null and b/src/main/resources/javax/xml/datatype/DatatypeConstants.class differ diff --git a/src/main/resources/javax/xml/datatype/DatatypeFactory.class b/src/main/resources/javax/xml/datatype/DatatypeFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..ace6f17900a30c263124119e8dd9831f728b09d0 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/DatatypeFactory.class differ diff --git a/src/main/resources/javax/xml/datatype/Duration.class b/src/main/resources/javax/xml/datatype/Duration.class new file mode 100644 index 0000000000000000000000000000000000000000..81b4b28f180408f53056727971e203143daadc2c Binary files /dev/null and b/src/main/resources/javax/xml/datatype/Duration.class differ diff --git a/src/main/resources/javax/xml/datatype/FactoryFinder$ConfigurationError.class b/src/main/resources/javax/xml/datatype/FactoryFinder$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..b657fbcb1f7ca54838aed56fcc6dc3066c7de22d Binary files /dev/null and b/src/main/resources/javax/xml/datatype/FactoryFinder$ConfigurationError.class differ diff --git a/src/main/resources/javax/xml/datatype/FactoryFinder.class b/src/main/resources/javax/xml/datatype/FactoryFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..59b1df33a08252233b60581072c7bc4f95e84819 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/FactoryFinder.class differ diff --git a/src/main/resources/javax/xml/datatype/SecuritySupport$1.class b/src/main/resources/javax/xml/datatype/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d666e12d6e9bb465dcc643b8465139650e9cef49 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/SecuritySupport$1.class differ diff --git a/src/main/resources/javax/xml/datatype/SecuritySupport$2.class b/src/main/resources/javax/xml/datatype/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5494be0910f5a9dbb69a2f6758425fda83b168b2 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/SecuritySupport$2.class differ diff --git a/src/main/resources/javax/xml/datatype/SecuritySupport$3.class b/src/main/resources/javax/xml/datatype/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..1f12720599d659c49e7ebbe3bea08a170bcc7e9c Binary files /dev/null and b/src/main/resources/javax/xml/datatype/SecuritySupport$3.class differ diff --git a/src/main/resources/javax/xml/datatype/SecuritySupport$4.class b/src/main/resources/javax/xml/datatype/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..814c647d731965d68b7932666d0194d56bd32e52 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/SecuritySupport$4.class differ diff --git a/src/main/resources/javax/xml/datatype/SecuritySupport$5.class b/src/main/resources/javax/xml/datatype/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..2a70d91d0b1eb4768809e2a917b12025c1c50cb2 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/SecuritySupport$5.class differ diff --git a/src/main/resources/javax/xml/datatype/SecuritySupport.class b/src/main/resources/javax/xml/datatype/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..674549afbf769ae9c8c1624f6f8e90b4cb3734c8 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/SecuritySupport.class differ diff --git a/src/main/resources/javax/xml/datatype/XMLGregorianCalendar.class b/src/main/resources/javax/xml/datatype/XMLGregorianCalendar.class new file mode 100644 index 0000000000000000000000000000000000000000..e1b3f45a77e32661b72b4a62c7a2fb6023e90228 Binary files /dev/null and b/src/main/resources/javax/xml/datatype/XMLGregorianCalendar.class differ diff --git a/src/main/resources/javax/xml/namespace/NamespaceContext.class b/src/main/resources/javax/xml/namespace/NamespaceContext.class new file mode 100644 index 0000000000000000000000000000000000000000..0590aaf6943bef5a1191e6bbfefc96f77c7c9e29 Binary files /dev/null and b/src/main/resources/javax/xml/namespace/NamespaceContext.class differ diff --git a/src/main/resources/javax/xml/namespace/QName$1.class b/src/main/resources/javax/xml/namespace/QName$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d679b3b3ccfa62104322919c269d989cebffc066 Binary files /dev/null and b/src/main/resources/javax/xml/namespace/QName$1.class differ diff --git a/src/main/resources/javax/xml/namespace/QName.class b/src/main/resources/javax/xml/namespace/QName.class new file mode 100644 index 0000000000000000000000000000000000000000..b9dafe71eeea4a7ac8ba109cf5c819321a2905c2 Binary files /dev/null and b/src/main/resources/javax/xml/namespace/QName.class differ diff --git a/src/main/resources/javax/xml/parsers/DocumentBuilder.class b/src/main/resources/javax/xml/parsers/DocumentBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..db3e7fcd7470d5085f9b1bde697e96839eb24937 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/DocumentBuilder.class differ diff --git a/src/main/resources/javax/xml/parsers/DocumentBuilderFactory.class b/src/main/resources/javax/xml/parsers/DocumentBuilderFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..c8e00f430de96a61e655bbfc21011036e1947b0c Binary files /dev/null and b/src/main/resources/javax/xml/parsers/DocumentBuilderFactory.class differ diff --git a/src/main/resources/javax/xml/parsers/FactoryConfigurationError.class b/src/main/resources/javax/xml/parsers/FactoryConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..523be853c02f0e11d772ea1e28085f9668ebc2c4 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/FactoryConfigurationError.class differ diff --git a/src/main/resources/javax/xml/parsers/FactoryFinder$ConfigurationError.class b/src/main/resources/javax/xml/parsers/FactoryFinder$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..8de4fbd37e149c16b1dfd7e4eae8d2fcf8963c40 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/FactoryFinder$ConfigurationError.class differ diff --git a/src/main/resources/javax/xml/parsers/FactoryFinder.class b/src/main/resources/javax/xml/parsers/FactoryFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..23feb470ee3b15e435b0eac24833cbd80a81abee Binary files /dev/null and b/src/main/resources/javax/xml/parsers/FactoryFinder.class differ diff --git a/src/main/resources/javax/xml/parsers/FilePathToURI.class b/src/main/resources/javax/xml/parsers/FilePathToURI.class new file mode 100644 index 0000000000000000000000000000000000000000..00dfe796d35abc52f45ed548007595a2572926c4 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/FilePathToURI.class differ diff --git a/src/main/resources/javax/xml/parsers/ParserConfigurationException.class b/src/main/resources/javax/xml/parsers/ParserConfigurationException.class new file mode 100644 index 0000000000000000000000000000000000000000..28d3ea9c63cc92cdf9fe2ae0ab5b8070fada157f Binary files /dev/null and b/src/main/resources/javax/xml/parsers/ParserConfigurationException.class differ diff --git a/src/main/resources/javax/xml/parsers/SAXParser.class b/src/main/resources/javax/xml/parsers/SAXParser.class new file mode 100644 index 0000000000000000000000000000000000000000..ddbbe625b98be21a093544ae7884db49c1f7ebea Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SAXParser.class differ diff --git a/src/main/resources/javax/xml/parsers/SAXParserFactory.class b/src/main/resources/javax/xml/parsers/SAXParserFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..790ea36c955098f7d0e3251a58d72618382446d9 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SAXParserFactory.class differ diff --git a/src/main/resources/javax/xml/parsers/SecuritySupport$1.class b/src/main/resources/javax/xml/parsers/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cd637c9da779ab716e02f3022af56c6fab76dfb7 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SecuritySupport$1.class differ diff --git a/src/main/resources/javax/xml/parsers/SecuritySupport$2.class b/src/main/resources/javax/xml/parsers/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..7c8c17049dfe028178bc75a58dc7f97691b4ab4b Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SecuritySupport$2.class differ diff --git a/src/main/resources/javax/xml/parsers/SecuritySupport$3.class b/src/main/resources/javax/xml/parsers/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..616092d8411583c7566084f63f41899416d4a99d Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SecuritySupport$3.class differ diff --git a/src/main/resources/javax/xml/parsers/SecuritySupport$4.class b/src/main/resources/javax/xml/parsers/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..d23e59f41e22022a3daf676342343d79ecd74953 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SecuritySupport$4.class differ diff --git a/src/main/resources/javax/xml/parsers/SecuritySupport$5.class b/src/main/resources/javax/xml/parsers/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..a92aeb00a38370fb29e2db6992b22f3b73e44283 Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SecuritySupport$5.class differ diff --git a/src/main/resources/javax/xml/parsers/SecuritySupport.class b/src/main/resources/javax/xml/parsers/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..e13578b8506387ca3753b876dfd3c926a05f7e0e Binary files /dev/null and b/src/main/resources/javax/xml/parsers/SecuritySupport.class differ diff --git a/src/main/resources/javax/xml/stream/EventFilter.class b/src/main/resources/javax/xml/stream/EventFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..600e73c8b47924e0295afee4579de7ba61fd4c16 Binary files /dev/null and b/src/main/resources/javax/xml/stream/EventFilter.class differ diff --git a/src/main/resources/javax/xml/stream/FactoryConfigurationError.class b/src/main/resources/javax/xml/stream/FactoryConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..01734f1da6bbb953c73a1c887969d83ca7738b0f Binary files /dev/null and b/src/main/resources/javax/xml/stream/FactoryConfigurationError.class differ diff --git a/src/main/resources/javax/xml/stream/FactoryFinder$ConfigurationError.class b/src/main/resources/javax/xml/stream/FactoryFinder$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..48d9c5fe6b1ee3ba755f35f4720b44a3159e7df3 Binary files /dev/null and b/src/main/resources/javax/xml/stream/FactoryFinder$ConfigurationError.class differ diff --git a/src/main/resources/javax/xml/stream/FactoryFinder.class b/src/main/resources/javax/xml/stream/FactoryFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..065ef07abd6b9918beb12c3b25bb4a8f56270f3a Binary files /dev/null and b/src/main/resources/javax/xml/stream/FactoryFinder.class differ diff --git a/src/main/resources/javax/xml/stream/Location.class b/src/main/resources/javax/xml/stream/Location.class new file mode 100644 index 0000000000000000000000000000000000000000..cd6c6a7714b9b95d46cd0ceb32146979cc336065 Binary files /dev/null and b/src/main/resources/javax/xml/stream/Location.class differ diff --git a/src/main/resources/javax/xml/stream/SecuritySupport$1.class b/src/main/resources/javax/xml/stream/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c0f2f14b78c780f924066b795e31acca37119819 Binary files /dev/null and b/src/main/resources/javax/xml/stream/SecuritySupport$1.class differ diff --git a/src/main/resources/javax/xml/stream/SecuritySupport$2.class b/src/main/resources/javax/xml/stream/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..85fb2c17877b9171be3d37ead9f340b41c6e6a8e Binary files /dev/null and b/src/main/resources/javax/xml/stream/SecuritySupport$2.class differ diff --git a/src/main/resources/javax/xml/stream/SecuritySupport$3.class b/src/main/resources/javax/xml/stream/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..fc44e41092579c99de2a030edad6e7f9a47aa866 Binary files /dev/null and b/src/main/resources/javax/xml/stream/SecuritySupport$3.class differ diff --git a/src/main/resources/javax/xml/stream/SecuritySupport$4.class b/src/main/resources/javax/xml/stream/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..66cf49616310afd1035dcd47bb818f711f747e6c Binary files /dev/null and b/src/main/resources/javax/xml/stream/SecuritySupport$4.class differ diff --git a/src/main/resources/javax/xml/stream/SecuritySupport$5.class b/src/main/resources/javax/xml/stream/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..f57251cab727e8d4a3707df6c75d76f3284d0adf Binary files /dev/null and b/src/main/resources/javax/xml/stream/SecuritySupport$5.class differ diff --git a/src/main/resources/javax/xml/stream/SecuritySupport.class b/src/main/resources/javax/xml/stream/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..cd65fb84dbc0a97674894724904dd6615b4f456c Binary files /dev/null and b/src/main/resources/javax/xml/stream/SecuritySupport.class differ diff --git a/src/main/resources/javax/xml/stream/StreamFilter.class b/src/main/resources/javax/xml/stream/StreamFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..039815d42c765f052d02a4ad66ed2b968d42f57b Binary files /dev/null and b/src/main/resources/javax/xml/stream/StreamFilter.class differ diff --git a/src/main/resources/javax/xml/stream/XMLEventFactory.class b/src/main/resources/javax/xml/stream/XMLEventFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..7a5d772660445d0d99f6dcfee5b3e8614d03a262 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLEventFactory.class differ diff --git a/src/main/resources/javax/xml/stream/XMLEventReader.class b/src/main/resources/javax/xml/stream/XMLEventReader.class new file mode 100644 index 0000000000000000000000000000000000000000..539ff5bcf337f2d002059c0270c59e7edddccb29 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLEventReader.class differ diff --git a/src/main/resources/javax/xml/stream/XMLEventWriter.class b/src/main/resources/javax/xml/stream/XMLEventWriter.class new file mode 100644 index 0000000000000000000000000000000000000000..ed1279d81e4b6d302572501b7857b35c5e42be85 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLEventWriter.class differ diff --git a/src/main/resources/javax/xml/stream/XMLInputFactory.class b/src/main/resources/javax/xml/stream/XMLInputFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..b0790ef64bce7befaf0e06a6832d4774758953dd Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLInputFactory.class differ diff --git a/src/main/resources/javax/xml/stream/XMLOutputFactory.class b/src/main/resources/javax/xml/stream/XMLOutputFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..18fd604b361310f902c6efd9619d072b77020879 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLOutputFactory.class differ diff --git a/src/main/resources/javax/xml/stream/XMLReporter.class b/src/main/resources/javax/xml/stream/XMLReporter.class new file mode 100644 index 0000000000000000000000000000000000000000..9c7afeb68d9c8bc4e495724bbb2aea2e00b24f5c Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLReporter.class differ diff --git a/src/main/resources/javax/xml/stream/XMLResolver.class b/src/main/resources/javax/xml/stream/XMLResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..1836f494e7489cf6e884cbf86ce36fda77d2c533 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLResolver.class differ diff --git a/src/main/resources/javax/xml/stream/XMLStreamConstants.class b/src/main/resources/javax/xml/stream/XMLStreamConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..e47129b2e28e8c998aaf8ffe8f1cdb7856139838 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLStreamConstants.class differ diff --git a/src/main/resources/javax/xml/stream/XMLStreamException.class b/src/main/resources/javax/xml/stream/XMLStreamException.class new file mode 100644 index 0000000000000000000000000000000000000000..caf330ce26f961f1d095746784ca3d79bb52a925 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLStreamException.class differ diff --git a/src/main/resources/javax/xml/stream/XMLStreamReader.class b/src/main/resources/javax/xml/stream/XMLStreamReader.class new file mode 100644 index 0000000000000000000000000000000000000000..7b091f0c24234b5a9059d62fea2bb9cc0f568a35 Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLStreamReader.class differ diff --git a/src/main/resources/javax/xml/stream/XMLStreamWriter.class b/src/main/resources/javax/xml/stream/XMLStreamWriter.class new file mode 100644 index 0000000000000000000000000000000000000000..187f138db0e3419b99361d62436205b7144f065b Binary files /dev/null and b/src/main/resources/javax/xml/stream/XMLStreamWriter.class differ diff --git a/src/main/resources/javax/xml/stream/events/Attribute.class b/src/main/resources/javax/xml/stream/events/Attribute.class new file mode 100644 index 0000000000000000000000000000000000000000..0059785fc9e81198fc1efd0273bf842bcfdf8551 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/Attribute.class differ diff --git a/src/main/resources/javax/xml/stream/events/Characters.class b/src/main/resources/javax/xml/stream/events/Characters.class new file mode 100644 index 0000000000000000000000000000000000000000..7ffb1c284589d6a0afbdfed2d39b4e1fd937406f Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/Characters.class differ diff --git a/src/main/resources/javax/xml/stream/events/Comment.class b/src/main/resources/javax/xml/stream/events/Comment.class new file mode 100644 index 0000000000000000000000000000000000000000..c339cb7e297dffdd77aaaa3f754f7f47f98c34c2 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/Comment.class differ diff --git a/src/main/resources/javax/xml/stream/events/DTD.class b/src/main/resources/javax/xml/stream/events/DTD.class new file mode 100644 index 0000000000000000000000000000000000000000..dc4e89e2b88b198cbaf919b0242af4dfbb65c70c Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/DTD.class differ diff --git a/src/main/resources/javax/xml/stream/events/EndDocument.class b/src/main/resources/javax/xml/stream/events/EndDocument.class new file mode 100644 index 0000000000000000000000000000000000000000..49a23960c4504baa176e047f9644face918c6e03 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/EndDocument.class differ diff --git a/src/main/resources/javax/xml/stream/events/EndElement.class b/src/main/resources/javax/xml/stream/events/EndElement.class new file mode 100644 index 0000000000000000000000000000000000000000..28f6568a3c2bd554a70b46aef198583a8b5dc2ff Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/EndElement.class differ diff --git a/src/main/resources/javax/xml/stream/events/EntityDeclaration.class b/src/main/resources/javax/xml/stream/events/EntityDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..745219598009d9b9c39f18a4607cf7886d096788 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/EntityDeclaration.class differ diff --git a/src/main/resources/javax/xml/stream/events/EntityReference.class b/src/main/resources/javax/xml/stream/events/EntityReference.class new file mode 100644 index 0000000000000000000000000000000000000000..3b55e22818b784dd3102a6274b62f62bbd615117 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/EntityReference.class differ diff --git a/src/main/resources/javax/xml/stream/events/Namespace.class b/src/main/resources/javax/xml/stream/events/Namespace.class new file mode 100644 index 0000000000000000000000000000000000000000..e66f157bb1a2501ad926b74d2096b391d3304159 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/Namespace.class differ diff --git a/src/main/resources/javax/xml/stream/events/NotationDeclaration.class b/src/main/resources/javax/xml/stream/events/NotationDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..787a2be570025d445d74a3b22c5c28b1eec8d521 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/NotationDeclaration.class differ diff --git a/src/main/resources/javax/xml/stream/events/ProcessingInstruction.class b/src/main/resources/javax/xml/stream/events/ProcessingInstruction.class new file mode 100644 index 0000000000000000000000000000000000000000..ae760e33af73ff07a6ad549cd0e78357675dd3bc Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/ProcessingInstruction.class differ diff --git a/src/main/resources/javax/xml/stream/events/StartDocument.class b/src/main/resources/javax/xml/stream/events/StartDocument.class new file mode 100644 index 0000000000000000000000000000000000000000..50d3130ef7b9af453a08c29c72f281fa7fd6bbbf Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/StartDocument.class differ diff --git a/src/main/resources/javax/xml/stream/events/StartElement.class b/src/main/resources/javax/xml/stream/events/StartElement.class new file mode 100644 index 0000000000000000000000000000000000000000..9660155b4b67a35101c038bcc5f336e504aa7843 Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/StartElement.class differ diff --git a/src/main/resources/javax/xml/stream/events/XMLEvent.class b/src/main/resources/javax/xml/stream/events/XMLEvent.class new file mode 100644 index 0000000000000000000000000000000000000000..1582aeaa9696aa8a6d2505eef221cc7cd505bcaf Binary files /dev/null and b/src/main/resources/javax/xml/stream/events/XMLEvent.class differ diff --git a/src/main/resources/javax/xml/stream/util/EventReaderDelegate.class b/src/main/resources/javax/xml/stream/util/EventReaderDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..0bc4cb2c434d1d80357e4076e610cdea8d096d67 Binary files /dev/null and b/src/main/resources/javax/xml/stream/util/EventReaderDelegate.class differ diff --git a/src/main/resources/javax/xml/stream/util/StreamReaderDelegate.class b/src/main/resources/javax/xml/stream/util/StreamReaderDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..cbc7df5d915e212fd732f49ee607946752c6009f Binary files /dev/null and b/src/main/resources/javax/xml/stream/util/StreamReaderDelegate.class differ diff --git a/src/main/resources/javax/xml/stream/util/XMLEventAllocator.class b/src/main/resources/javax/xml/stream/util/XMLEventAllocator.class new file mode 100644 index 0000000000000000000000000000000000000000..c3699fed2c3bc03b4d1aae06b8281fa7033f5f8f Binary files /dev/null and b/src/main/resources/javax/xml/stream/util/XMLEventAllocator.class differ diff --git a/src/main/resources/javax/xml/stream/util/XMLEventConsumer.class b/src/main/resources/javax/xml/stream/util/XMLEventConsumer.class new file mode 100644 index 0000000000000000000000000000000000000000..4e145f6cf8f2ec8eb474c76677f3a1eb59797743 Binary files /dev/null and b/src/main/resources/javax/xml/stream/util/XMLEventConsumer.class differ diff --git a/src/main/resources/javax/xml/transform/ErrorListener.class b/src/main/resources/javax/xml/transform/ErrorListener.class new file mode 100644 index 0000000000000000000000000000000000000000..b6b144739ae1fdb501ba7be2cf1cd2dddf72e2f2 Binary files /dev/null and b/src/main/resources/javax/xml/transform/ErrorListener.class differ diff --git a/src/main/resources/javax/xml/transform/FactoryFinder$ConfigurationError.class b/src/main/resources/javax/xml/transform/FactoryFinder$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..fcf73c1b750d3110cb050f1a22cb87acef89f1c2 Binary files /dev/null and b/src/main/resources/javax/xml/transform/FactoryFinder$ConfigurationError.class differ diff --git a/src/main/resources/javax/xml/transform/FactoryFinder.class b/src/main/resources/javax/xml/transform/FactoryFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..059979f79b008d44b61164ff856029956f873753 Binary files /dev/null and b/src/main/resources/javax/xml/transform/FactoryFinder.class differ diff --git a/src/main/resources/javax/xml/transform/OutputKeys.class b/src/main/resources/javax/xml/transform/OutputKeys.class new file mode 100644 index 0000000000000000000000000000000000000000..ead9bae2bdb989022c0fce39efb724890128cb4f Binary files /dev/null and b/src/main/resources/javax/xml/transform/OutputKeys.class differ diff --git a/src/main/resources/javax/xml/transform/Result.class b/src/main/resources/javax/xml/transform/Result.class new file mode 100644 index 0000000000000000000000000000000000000000..7629411871ccaeabb7598f926d8242f3b1e1dcdb Binary files /dev/null and b/src/main/resources/javax/xml/transform/Result.class differ diff --git a/src/main/resources/javax/xml/transform/SecuritySupport$1.class b/src/main/resources/javax/xml/transform/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a7f2e7be4ea65d03e972d78d0c29d1d248262ad0 Binary files /dev/null and b/src/main/resources/javax/xml/transform/SecuritySupport$1.class differ diff --git a/src/main/resources/javax/xml/transform/SecuritySupport$2.class b/src/main/resources/javax/xml/transform/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..3ffff417bbc723aacdd531fd4b5cda1e240b9b22 Binary files /dev/null and b/src/main/resources/javax/xml/transform/SecuritySupport$2.class differ diff --git a/src/main/resources/javax/xml/transform/SecuritySupport$3.class b/src/main/resources/javax/xml/transform/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..8e4426f821dab9a1bfe75d90d35057ac3f5dd874 Binary files /dev/null and b/src/main/resources/javax/xml/transform/SecuritySupport$3.class differ diff --git a/src/main/resources/javax/xml/transform/SecuritySupport$4.class b/src/main/resources/javax/xml/transform/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..98629e94dd3274e2f7c15176e2e43e1ae8ceb784 Binary files /dev/null and b/src/main/resources/javax/xml/transform/SecuritySupport$4.class differ diff --git a/src/main/resources/javax/xml/transform/SecuritySupport$5.class b/src/main/resources/javax/xml/transform/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..4ac7f61135f8c80f425c3f9cd617081c9ab29c67 Binary files /dev/null and b/src/main/resources/javax/xml/transform/SecuritySupport$5.class differ diff --git a/src/main/resources/javax/xml/transform/SecuritySupport.class b/src/main/resources/javax/xml/transform/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..2226b0a6340e347fcf577082aabe8085c9bb4332 Binary files /dev/null and b/src/main/resources/javax/xml/transform/SecuritySupport.class differ diff --git a/src/main/resources/javax/xml/transform/Source.class b/src/main/resources/javax/xml/transform/Source.class new file mode 100644 index 0000000000000000000000000000000000000000..91aab52b89f13c38340a7d64e3e36ce4d1812f50 Binary files /dev/null and b/src/main/resources/javax/xml/transform/Source.class differ diff --git a/src/main/resources/javax/xml/transform/SourceLocator.class b/src/main/resources/javax/xml/transform/SourceLocator.class new file mode 100644 index 0000000000000000000000000000000000000000..e61566a7b0793539151bbe90e16e6e697b8cb407 Binary files /dev/null and b/src/main/resources/javax/xml/transform/SourceLocator.class differ diff --git a/src/main/resources/javax/xml/transform/Templates.class b/src/main/resources/javax/xml/transform/Templates.class new file mode 100644 index 0000000000000000000000000000000000000000..588d0f8e1ebad4ddbb03dd70f64291178ac41440 Binary files /dev/null and b/src/main/resources/javax/xml/transform/Templates.class differ diff --git a/src/main/resources/javax/xml/transform/Transformer.class b/src/main/resources/javax/xml/transform/Transformer.class new file mode 100644 index 0000000000000000000000000000000000000000..46ef386a5f7b7cc665c7c532fcdbbc2928803da4 Binary files /dev/null and b/src/main/resources/javax/xml/transform/Transformer.class differ diff --git a/src/main/resources/javax/xml/transform/TransformerConfigurationException.class b/src/main/resources/javax/xml/transform/TransformerConfigurationException.class new file mode 100644 index 0000000000000000000000000000000000000000..9e6f931b238c45b9bde439b773b6df08335f37e0 Binary files /dev/null and b/src/main/resources/javax/xml/transform/TransformerConfigurationException.class differ diff --git a/src/main/resources/javax/xml/transform/TransformerException.class b/src/main/resources/javax/xml/transform/TransformerException.class new file mode 100644 index 0000000000000000000000000000000000000000..67f1f9fa405691c72f5b3302e86b60b19de27b77 Binary files /dev/null and b/src/main/resources/javax/xml/transform/TransformerException.class differ diff --git a/src/main/resources/javax/xml/transform/TransformerFactory.class b/src/main/resources/javax/xml/transform/TransformerFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..af8bd0fb7aecf2a77e25e853071de79b7812e1a5 Binary files /dev/null and b/src/main/resources/javax/xml/transform/TransformerFactory.class differ diff --git a/src/main/resources/javax/xml/transform/TransformerFactoryConfigurationError.class b/src/main/resources/javax/xml/transform/TransformerFactoryConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..80b00e92601d17548e38e21afa938f76dd29a030 Binary files /dev/null and b/src/main/resources/javax/xml/transform/TransformerFactoryConfigurationError.class differ diff --git a/src/main/resources/javax/xml/transform/URIResolver.class b/src/main/resources/javax/xml/transform/URIResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..0fd1d4808702d8cdf86acee980f11ecdadbdee94 Binary files /dev/null and b/src/main/resources/javax/xml/transform/URIResolver.class differ diff --git a/src/main/resources/javax/xml/transform/dom/DOMLocator.class b/src/main/resources/javax/xml/transform/dom/DOMLocator.class new file mode 100644 index 0000000000000000000000000000000000000000..9b52c107be30ce690a8d04fb8f1501d818fda9a3 Binary files /dev/null and b/src/main/resources/javax/xml/transform/dom/DOMLocator.class differ diff --git a/src/main/resources/javax/xml/transform/dom/DOMResult.class b/src/main/resources/javax/xml/transform/dom/DOMResult.class new file mode 100644 index 0000000000000000000000000000000000000000..d34a870802ad09a86c54dd2543d94d1aec64251b Binary files /dev/null and b/src/main/resources/javax/xml/transform/dom/DOMResult.class differ diff --git a/src/main/resources/javax/xml/transform/dom/DOMSource.class b/src/main/resources/javax/xml/transform/dom/DOMSource.class new file mode 100644 index 0000000000000000000000000000000000000000..38fc17f7dc5ca7490aadb74c4ed2f2ff77e400e0 Binary files /dev/null and b/src/main/resources/javax/xml/transform/dom/DOMSource.class differ diff --git a/src/main/resources/javax/xml/transform/sax/SAXResult.class b/src/main/resources/javax/xml/transform/sax/SAXResult.class new file mode 100644 index 0000000000000000000000000000000000000000..452b3b726d10abb4ba43a2fc5ddbf450c3f09adc Binary files /dev/null and b/src/main/resources/javax/xml/transform/sax/SAXResult.class differ diff --git a/src/main/resources/javax/xml/transform/sax/SAXSource.class b/src/main/resources/javax/xml/transform/sax/SAXSource.class new file mode 100644 index 0000000000000000000000000000000000000000..80e758ff867c18c918aae4b0bdba9c2c54f6b6c6 Binary files /dev/null and b/src/main/resources/javax/xml/transform/sax/SAXSource.class differ diff --git a/src/main/resources/javax/xml/transform/sax/SAXTransformerFactory.class b/src/main/resources/javax/xml/transform/sax/SAXTransformerFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..ef540678abb92a9e8e4bbfdcc3e996d6db142af2 Binary files /dev/null and b/src/main/resources/javax/xml/transform/sax/SAXTransformerFactory.class differ diff --git a/src/main/resources/javax/xml/transform/sax/TemplatesHandler.class b/src/main/resources/javax/xml/transform/sax/TemplatesHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..496f8da3d72b42c2b9e356744a5d5e0a4f856fc1 Binary files /dev/null and b/src/main/resources/javax/xml/transform/sax/TemplatesHandler.class differ diff --git a/src/main/resources/javax/xml/transform/sax/TransformerHandler.class b/src/main/resources/javax/xml/transform/sax/TransformerHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..3ea18c285b4149a7ad9c1972c35ba3379b483686 Binary files /dev/null and b/src/main/resources/javax/xml/transform/sax/TransformerHandler.class differ diff --git a/src/main/resources/javax/xml/transform/stax/StAXResult.class b/src/main/resources/javax/xml/transform/stax/StAXResult.class new file mode 100644 index 0000000000000000000000000000000000000000..f953e8652ea911b482efc21594bd9b3c92148dd1 Binary files /dev/null and b/src/main/resources/javax/xml/transform/stax/StAXResult.class differ diff --git a/src/main/resources/javax/xml/transform/stax/StAXSource.class b/src/main/resources/javax/xml/transform/stax/StAXSource.class new file mode 100644 index 0000000000000000000000000000000000000000..2615a333d528afa7357968cb6a7fd9f089329efb Binary files /dev/null and b/src/main/resources/javax/xml/transform/stax/StAXSource.class differ diff --git a/src/main/resources/javax/xml/transform/stream/FilePathToURI.class b/src/main/resources/javax/xml/transform/stream/FilePathToURI.class new file mode 100644 index 0000000000000000000000000000000000000000..65bb288a3a935ef45120c38438be5de713cda1fa Binary files /dev/null and b/src/main/resources/javax/xml/transform/stream/FilePathToURI.class differ diff --git a/src/main/resources/javax/xml/transform/stream/StreamResult.class b/src/main/resources/javax/xml/transform/stream/StreamResult.class new file mode 100644 index 0000000000000000000000000000000000000000..593bd86c5bae269b812708f3758fbeb7582b9833 Binary files /dev/null and b/src/main/resources/javax/xml/transform/stream/StreamResult.class differ diff --git a/src/main/resources/javax/xml/transform/stream/StreamSource.class b/src/main/resources/javax/xml/transform/stream/StreamSource.class new file mode 100644 index 0000000000000000000000000000000000000000..c39adb100e75a5d1542e554d3eeee1da8ca7f230 Binary files /dev/null and b/src/main/resources/javax/xml/transform/stream/StreamSource.class differ diff --git a/src/main/resources/javax/xml/validation/Schema.class b/src/main/resources/javax/xml/validation/Schema.class new file mode 100644 index 0000000000000000000000000000000000000000..85ceda1ed80e54c2ca79e027171b07a65c67cc11 Binary files /dev/null and b/src/main/resources/javax/xml/validation/Schema.class differ diff --git a/src/main/resources/javax/xml/validation/SchemaFactory.class b/src/main/resources/javax/xml/validation/SchemaFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..c9c17d4a8e2c310d02c82237e4911ef6f579e52b Binary files /dev/null and b/src/main/resources/javax/xml/validation/SchemaFactory.class differ diff --git a/src/main/resources/javax/xml/validation/SchemaFactoryFinder$1.class b/src/main/resources/javax/xml/validation/SchemaFactoryFinder$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6edfa086f9ba57465da770c1ef12a4463b2d4255 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SchemaFactoryFinder$1.class differ diff --git a/src/main/resources/javax/xml/validation/SchemaFactoryFinder$2.class b/src/main/resources/javax/xml/validation/SchemaFactoryFinder$2.class new file mode 100644 index 0000000000000000000000000000000000000000..42492faa78af82a361bba27fef77338a01a6a711 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SchemaFactoryFinder$2.class differ diff --git a/src/main/resources/javax/xml/validation/SchemaFactoryFinder$SingleIterator.class b/src/main/resources/javax/xml/validation/SchemaFactoryFinder$SingleIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..159b25a24a9b09ed2d670a680cfbfceff655cbbe Binary files /dev/null and b/src/main/resources/javax/xml/validation/SchemaFactoryFinder$SingleIterator.class differ diff --git a/src/main/resources/javax/xml/validation/SchemaFactoryFinder.class b/src/main/resources/javax/xml/validation/SchemaFactoryFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..5ccda8fa6b6f68419f352a0be1df3782e6f38051 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SchemaFactoryFinder.class differ diff --git a/src/main/resources/javax/xml/validation/SchemaFactoryLoader.class b/src/main/resources/javax/xml/validation/SchemaFactoryLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..c08e7da45d9e0c90e2b325d571c42a001e69c8bc Binary files /dev/null and b/src/main/resources/javax/xml/validation/SchemaFactoryLoader.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$1.class b/src/main/resources/javax/xml/validation/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9bc4248c0851e8adc3f4785efe72d325047c4a58 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$1.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$2.class b/src/main/resources/javax/xml/validation/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c2172b2ef9f45dde425f0b3d1e50e9307cfe1f73 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$2.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$3.class b/src/main/resources/javax/xml/validation/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..64e2fd30da34662c9d9ab80abefb3861dcb6c9a2 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$3.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$4.class b/src/main/resources/javax/xml/validation/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..1ffbce4b4744c558ac4d144f35f5f332554533cb Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$4.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$5.class b/src/main/resources/javax/xml/validation/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..3220a0769f5e92d789fe098868e5f130be8ccdf2 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$5.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$6.class b/src/main/resources/javax/xml/validation/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..ba79e74ba1c57607b1cd6a8c605f2015951dc775 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$6.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$7.class b/src/main/resources/javax/xml/validation/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..1c0bacf98149af0b367d5a64112bd8f818ad6c3d Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$7.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport$8.class b/src/main/resources/javax/xml/validation/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..119fb03dae90d3b44989b010d7fbb1c1ced12730 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport$8.class differ diff --git a/src/main/resources/javax/xml/validation/SecuritySupport.class b/src/main/resources/javax/xml/validation/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..51a5d80a088e6c92ca68b9611c884aba980d21f1 Binary files /dev/null and b/src/main/resources/javax/xml/validation/SecuritySupport.class differ diff --git a/src/main/resources/javax/xml/validation/TypeInfoProvider.class b/src/main/resources/javax/xml/validation/TypeInfoProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..b387ea752febe9018d26e80c4b70148865000da5 Binary files /dev/null and b/src/main/resources/javax/xml/validation/TypeInfoProvider.class differ diff --git a/src/main/resources/javax/xml/validation/Validator.class b/src/main/resources/javax/xml/validation/Validator.class new file mode 100644 index 0000000000000000000000000000000000000000..2dbd541b3539351bc24df6f8911ac61e2f18b67f Binary files /dev/null and b/src/main/resources/javax/xml/validation/Validator.class differ diff --git a/src/main/resources/javax/xml/validation/ValidatorHandler.class b/src/main/resources/javax/xml/validation/ValidatorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..7aafd295a4d9d156b1fa49819972eed24b54e6ab Binary files /dev/null and b/src/main/resources/javax/xml/validation/ValidatorHandler.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$1.class b/src/main/resources/javax/xml/xpath/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ad9e2317fb9a83cad46e8727e9e4626c551a46ec Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$1.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$2.class b/src/main/resources/javax/xml/xpath/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..4794dc237b2fd2a2fd3b76fc6de333b34b878ed3 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$2.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$3.class b/src/main/resources/javax/xml/xpath/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..1667148379459e3804d6df1cab002394d529a452 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$3.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$4.class b/src/main/resources/javax/xml/xpath/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..c0f47f573399f04859a08c7df9a3f0498561e823 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$4.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$5.class b/src/main/resources/javax/xml/xpath/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..dcb277ac04439e3edeef26d132149abcc647d613 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$5.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$6.class b/src/main/resources/javax/xml/xpath/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..47dd888f24c5083fc7399eb35ad5bf466465bc9e Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$6.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$7.class b/src/main/resources/javax/xml/xpath/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..428695241069ed8cf6ce57a0b198819daf47843b Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$7.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport$8.class b/src/main/resources/javax/xml/xpath/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..c904cc6908cfce489d2dfc20e963e0b9184f1d8f Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport$8.class differ diff --git a/src/main/resources/javax/xml/xpath/SecuritySupport.class b/src/main/resources/javax/xml/xpath/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..d6451616ddba62a9f33fd1d515d943ce74438073 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/SecuritySupport.class differ diff --git a/src/main/resources/javax/xml/xpath/XPath.class b/src/main/resources/javax/xml/xpath/XPath.class new file mode 100644 index 0000000000000000000000000000000000000000..7520d0d796119bcd0bdbf7f076af9890fc699919 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPath.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathConstants.class b/src/main/resources/javax/xml/xpath/XPathConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..a4aa782228dcea9b6583d7426b8c4405cb7308a6 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathConstants.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathException.class b/src/main/resources/javax/xml/xpath/XPathException.class new file mode 100644 index 0000000000000000000000000000000000000000..97ec99d4804ba6511cf30dda138dcee3012aa8e8 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathException.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathExpression.class b/src/main/resources/javax/xml/xpath/XPathExpression.class new file mode 100644 index 0000000000000000000000000000000000000000..e6b990e0d24e3f9e027353cfe4abf759e42994f7 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathExpression.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathExpressionException.class b/src/main/resources/javax/xml/xpath/XPathExpressionException.class new file mode 100644 index 0000000000000000000000000000000000000000..33955d1633ae4eeeeb99d720fc1e65b08806d9a9 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathExpressionException.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFactory.class b/src/main/resources/javax/xml/xpath/XPathFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..8f6bd22a76f03a27eeed1c12ed36aaeae423b431 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFactory.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFactoryConfigurationException.class b/src/main/resources/javax/xml/xpath/XPathFactoryConfigurationException.class new file mode 100644 index 0000000000000000000000000000000000000000..c19e010634e31a9cb90e980f7b86962d8f9f4e66 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFactoryConfigurationException.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFactoryFinder$1.class b/src/main/resources/javax/xml/xpath/XPathFactoryFinder$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8e3b4e9ef28b779993f7ad5fb7581045b84875a1 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFactoryFinder$1.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFactoryFinder$2.class b/src/main/resources/javax/xml/xpath/XPathFactoryFinder$2.class new file mode 100644 index 0000000000000000000000000000000000000000..d84843a89d61b2cfca518f7be02f1de1f6999ea2 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFactoryFinder$2.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFactoryFinder$SingleIterator.class b/src/main/resources/javax/xml/xpath/XPathFactoryFinder$SingleIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..2b6e2cb16a8388b93e8644bc259142f34e06fa32 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFactoryFinder$SingleIterator.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFactoryFinder.class b/src/main/resources/javax/xml/xpath/XPathFactoryFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..fc856138192c67f3b7a9ec934bfe91ff6f10ba16 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFactoryFinder.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFunction.class b/src/main/resources/javax/xml/xpath/XPathFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..b2744af7551b361fde2aec4a65199c288af6e47f Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFunction.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFunctionException.class b/src/main/resources/javax/xml/xpath/XPathFunctionException.class new file mode 100644 index 0000000000000000000000000000000000000000..0ffe4fb0e49f053d0f5b4bc8eb8c0a8dcf6b6e9e Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFunctionException.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathFunctionResolver.class b/src/main/resources/javax/xml/xpath/XPathFunctionResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..28c831a522ddb5ab20c2d04b1c102f0c481205d4 Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathFunctionResolver.class differ diff --git a/src/main/resources/javax/xml/xpath/XPathVariableResolver.class b/src/main/resources/javax/xml/xpath/XPathVariableResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..dc0bdcda2a9aa195a6f4fc7e4f8e4fc1e72be92f Binary files /dev/null and b/src/main/resources/javax/xml/xpath/XPathVariableResolver.class differ diff --git a/src/main/resources/jline/ANSIBuffer$ANSICodes.class b/src/main/resources/jline/ANSIBuffer$ANSICodes.class new file mode 100644 index 0000000000000000000000000000000000000000..3cbd22073f0c372a580466dd31e6840e70c93534 Binary files /dev/null and b/src/main/resources/jline/ANSIBuffer$ANSICodes.class differ diff --git a/src/main/resources/jline/ANSIBuffer.class b/src/main/resources/jline/ANSIBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..28cf5e637a130fd75e179d14193744e7576a4073 Binary files /dev/null and b/src/main/resources/jline/ANSIBuffer.class differ diff --git a/src/main/resources/jline/ArgumentCompletor$AbstractArgumentDelimiter.class b/src/main/resources/jline/ArgumentCompletor$AbstractArgumentDelimiter.class new file mode 100644 index 0000000000000000000000000000000000000000..b55b776993300a12c76c1aa3527461ecde5de5dd Binary files /dev/null and b/src/main/resources/jline/ArgumentCompletor$AbstractArgumentDelimiter.class differ diff --git a/src/main/resources/jline/ArgumentCompletor$ArgumentDelimiter.class b/src/main/resources/jline/ArgumentCompletor$ArgumentDelimiter.class new file mode 100644 index 0000000000000000000000000000000000000000..9ab236958c01c7411d336ffc7998eb795c979236 Binary files /dev/null and b/src/main/resources/jline/ArgumentCompletor$ArgumentDelimiter.class differ diff --git a/src/main/resources/jline/ArgumentCompletor$ArgumentList.class b/src/main/resources/jline/ArgumentCompletor$ArgumentList.class new file mode 100644 index 0000000000000000000000000000000000000000..21053fc7bacfa23831e81d797a50e71d1b4a6a95 Binary files /dev/null and b/src/main/resources/jline/ArgumentCompletor$ArgumentList.class differ diff --git a/src/main/resources/jline/ArgumentCompletor$WhitespaceArgumentDelimiter.class b/src/main/resources/jline/ArgumentCompletor$WhitespaceArgumentDelimiter.class new file mode 100644 index 0000000000000000000000000000000000000000..be0181f16bdbc58ecf7679cb049b36a1cd6bdc56 Binary files /dev/null and b/src/main/resources/jline/ArgumentCompletor$WhitespaceArgumentDelimiter.class differ diff --git a/src/main/resources/jline/ArgumentCompletor.class b/src/main/resources/jline/ArgumentCompletor.class new file mode 100644 index 0000000000000000000000000000000000000000..b74e8562967244fe19cd5b63582c0baaf0e8bbde Binary files /dev/null and b/src/main/resources/jline/ArgumentCompletor.class differ diff --git a/src/main/resources/jline/CandidateCycleCompletionHandler.class b/src/main/resources/jline/CandidateCycleCompletionHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..8404befea06c0f20ab6f2c168445b597c8d8a819 Binary files /dev/null and b/src/main/resources/jline/CandidateCycleCompletionHandler.class differ diff --git a/src/main/resources/jline/CandidateListCompletionHandler.class b/src/main/resources/jline/CandidateListCompletionHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..74ad124bb5eddf86be161076c1ca4c39e3b93488 Binary files /dev/null and b/src/main/resources/jline/CandidateListCompletionHandler.class differ diff --git a/src/main/resources/jline/CandidateListCompletionHandler.properties b/src/main/resources/jline/CandidateListCompletionHandler.properties new file mode 100644 index 0000000000000000000000000000000000000000..18ee221cc9ea8b68911aa28d5cbd4394c31ae020 --- /dev/null +++ b/src/main/resources/jline/CandidateListCompletionHandler.properties @@ -0,0 +1,5 @@ +display-candidates: Display all {0} possibilities? (y or n) +display-candidates-yes: y +display-candidates-no: n +display-more: --More-- + diff --git a/src/main/resources/jline/ClassNameCompletor.class b/src/main/resources/jline/ClassNameCompletor.class new file mode 100644 index 0000000000000000000000000000000000000000..124ae422738499d3a029f1efad626cef6a210e38 Binary files /dev/null and b/src/main/resources/jline/ClassNameCompletor.class differ diff --git a/src/main/resources/jline/CompletionHandler.class b/src/main/resources/jline/CompletionHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..638ddf0186fdd0b6a73c58bbab3b48552efd0dd8 Binary files /dev/null and b/src/main/resources/jline/CompletionHandler.class differ diff --git a/src/main/resources/jline/Completor.class b/src/main/resources/jline/Completor.class new file mode 100644 index 0000000000000000000000000000000000000000..554001585b6151bd65df91e4af4c79bd0f4ee8af Binary files /dev/null and b/src/main/resources/jline/Completor.class differ diff --git a/src/main/resources/jline/ConsoleOperations.class b/src/main/resources/jline/ConsoleOperations.class new file mode 100644 index 0000000000000000000000000000000000000000..9d19b18ab99d44640b323f204807cdbfa04dfb90 Binary files /dev/null and b/src/main/resources/jline/ConsoleOperations.class differ diff --git a/src/main/resources/jline/ConsoleReader.class b/src/main/resources/jline/ConsoleReader.class new file mode 100644 index 0000000000000000000000000000000000000000..1769da4afdb88aebb9d03e309b36ed3ad4b0adb9 Binary files /dev/null and b/src/main/resources/jline/ConsoleReader.class differ diff --git a/src/main/resources/jline/ConsoleReaderInputStream$ConsoleEnumeration.class b/src/main/resources/jline/ConsoleReaderInputStream$ConsoleEnumeration.class new file mode 100644 index 0000000000000000000000000000000000000000..72d744d5e584286f8355c11aa38d3f957152527b Binary files /dev/null and b/src/main/resources/jline/ConsoleReaderInputStream$ConsoleEnumeration.class differ diff --git a/src/main/resources/jline/ConsoleReaderInputStream$ConsoleLineInputStream.class b/src/main/resources/jline/ConsoleReaderInputStream$ConsoleLineInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..d9a267d73e05b7dfc6c395b0104d7c72f0ab5bbf Binary files /dev/null and b/src/main/resources/jline/ConsoleReaderInputStream$ConsoleLineInputStream.class differ diff --git a/src/main/resources/jline/ConsoleReaderInputStream.class b/src/main/resources/jline/ConsoleReaderInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..764e0b369d6e546e229df3ce486c8e9f8fb217e2 Binary files /dev/null and b/src/main/resources/jline/ConsoleReaderInputStream.class differ diff --git a/src/main/resources/jline/ConsoleRunner.class b/src/main/resources/jline/ConsoleRunner.class new file mode 100644 index 0000000000000000000000000000000000000000..3f22115e1c3817dc0c62464e0a3f9993853c73f7 Binary files /dev/null and b/src/main/resources/jline/ConsoleRunner.class differ diff --git a/src/main/resources/jline/CursorBuffer.class b/src/main/resources/jline/CursorBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..fb86db98145ca141229848a4b036fa5db0ed1c1a Binary files /dev/null and b/src/main/resources/jline/CursorBuffer.class differ diff --git a/src/main/resources/jline/FileNameCompletor.class b/src/main/resources/jline/FileNameCompletor.class new file mode 100644 index 0000000000000000000000000000000000000000..4b65985ac6ea0b49af709087f07e1bdf109f3393 Binary files /dev/null and b/src/main/resources/jline/FileNameCompletor.class differ diff --git a/src/main/resources/jline/History.class b/src/main/resources/jline/History.class new file mode 100644 index 0000000000000000000000000000000000000000..592827a2fbef2918ded33c3704baa5c1d9cef6e4 Binary files /dev/null and b/src/main/resources/jline/History.class differ diff --git a/src/main/resources/jline/MultiCompletor.class b/src/main/resources/jline/MultiCompletor.class new file mode 100644 index 0000000000000000000000000000000000000000..9e127b35d0717b10f37a10895ae23363eb56f9ae Binary files /dev/null and b/src/main/resources/jline/MultiCompletor.class differ diff --git a/src/main/resources/jline/NullCompletor.class b/src/main/resources/jline/NullCompletor.class new file mode 100644 index 0000000000000000000000000000000000000000..1e469db0aa4b3d63e7eff40b7507ba2770f400db Binary files /dev/null and b/src/main/resources/jline/NullCompletor.class differ diff --git a/src/main/resources/jline/SimpleCompletor$NoOpFilter.class b/src/main/resources/jline/SimpleCompletor$NoOpFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..fb85d04f512767457d298936b25341ac33ef3d77 Binary files /dev/null and b/src/main/resources/jline/SimpleCompletor$NoOpFilter.class differ diff --git a/src/main/resources/jline/SimpleCompletor$SimpleCompletorFilter.class b/src/main/resources/jline/SimpleCompletor$SimpleCompletorFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..f4f45dc49729431983bb719aaf4e67a0ae604c5a Binary files /dev/null and b/src/main/resources/jline/SimpleCompletor$SimpleCompletorFilter.class differ diff --git a/src/main/resources/jline/SimpleCompletor.class b/src/main/resources/jline/SimpleCompletor.class new file mode 100644 index 0000000000000000000000000000000000000000..0422562841c395a1477c08379e1a470699292ed9 Binary files /dev/null and b/src/main/resources/jline/SimpleCompletor.class differ diff --git a/src/main/resources/jline/Terminal.class b/src/main/resources/jline/Terminal.class new file mode 100644 index 0000000000000000000000000000000000000000..8a05ee4af2ea2c3baac179b19c93f2093be3f648 Binary files /dev/null and b/src/main/resources/jline/Terminal.class differ diff --git a/src/main/resources/jline/UnixTerminal$1.class b/src/main/resources/jline/UnixTerminal$1.class new file mode 100644 index 0000000000000000000000000000000000000000..11f96732fbe9776adac0a44e4385eb7457a24ac4 Binary files /dev/null and b/src/main/resources/jline/UnixTerminal$1.class differ diff --git a/src/main/resources/jline/UnixTerminal$ReplayPrefixOneCharInputStream.class b/src/main/resources/jline/UnixTerminal$ReplayPrefixOneCharInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..ab860f2fcbb4129c749e77943f0c6ce870865603 Binary files /dev/null and b/src/main/resources/jline/UnixTerminal$ReplayPrefixOneCharInputStream.class differ diff --git a/src/main/resources/jline/UnixTerminal.class b/src/main/resources/jline/UnixTerminal.class new file mode 100644 index 0000000000000000000000000000000000000000..5485036ab53e67a2bff1c5874af3f4e5d57ffba1 Binary files /dev/null and b/src/main/resources/jline/UnixTerminal.class differ diff --git a/src/main/resources/jline/UnsupportedTerminal$1.class b/src/main/resources/jline/UnsupportedTerminal$1.class new file mode 100644 index 0000000000000000000000000000000000000000..62e3b2277e1e314b92240fc58324a975378d4d5b Binary files /dev/null and b/src/main/resources/jline/UnsupportedTerminal$1.class differ diff --git a/src/main/resources/jline/UnsupportedTerminal.class b/src/main/resources/jline/UnsupportedTerminal.class new file mode 100644 index 0000000000000000000000000000000000000000..eda00168ac30b9f94ceaa62a2c4d1a032d2a10b3 Binary files /dev/null and b/src/main/resources/jline/UnsupportedTerminal.class differ diff --git a/src/main/resources/jline/WindowsTerminal$1.class b/src/main/resources/jline/WindowsTerminal$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c6ffc6e35408e3f35eef9f6ff901ab4f405c43ad Binary files /dev/null and b/src/main/resources/jline/WindowsTerminal$1.class differ diff --git a/src/main/resources/jline/WindowsTerminal$ReplayPrefixOneCharInputStream.class b/src/main/resources/jline/WindowsTerminal$ReplayPrefixOneCharInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..072fa7db092d4ff87009609b961db76fd3017aa9 Binary files /dev/null and b/src/main/resources/jline/WindowsTerminal$ReplayPrefixOneCharInputStream.class differ diff --git a/src/main/resources/jline/WindowsTerminal.class b/src/main/resources/jline/WindowsTerminal.class new file mode 100644 index 0000000000000000000000000000000000000000..ad677f02b9d08434facc88c7243f08292cb755a8 Binary files /dev/null and b/src/main/resources/jline/WindowsTerminal.class differ diff --git a/src/main/resources/jline/jline32.dll b/src/main/resources/jline/jline32.dll new file mode 100644 index 0000000000000000000000000000000000000000..a0d3b117ce19afe904437b62468253902db276c8 Binary files /dev/null and b/src/main/resources/jline/jline32.dll differ diff --git a/src/main/resources/jline/jline64.dll b/src/main/resources/jline/jline64.dll new file mode 100644 index 0000000000000000000000000000000000000000..922d6b01c5f51bccd690efd5dc8bbe78d44c37ce Binary files /dev/null and b/src/main/resources/jline/jline64.dll differ diff --git a/src/main/resources/jline/keybindings-mac.properties b/src/main/resources/jline/keybindings-mac.properties new file mode 100644 index 0000000000000000000000000000000000000000..6f13615d84c8addc4eee18e37d4b79dd390bdc4e --- /dev/null +++ b/src/main/resources/jline/keybindings-mac.properties @@ -0,0 +1,62 @@ +# Keybinding mapping for JLine. The format is: +# [key code]: [logical operation] + +# CTRL-B: move to the previous character +2: PREV_CHAR + +# CTRL-G: move to the previous word +7: PREV_WORD + +# CTRL-F: move to the next character +6: NEXT_CHAR + +# CTRL-A: move to the beginning of the line +1: MOVE_TO_BEG + +# CTRL-D: close out the input stream +4: EXIT + +# CTRL-E: move the cursor to the end of the line +5: MOVE_TO_END + +# BACKSPACE, CTRL-H: delete the previous character +# 8 is the ASCII code for backspace and therefor +# deleting the previous character +8: DELETE_PREV_CHAR + +# TAB, CTRL-I: signal that console completion should be attempted +9: COMPLETE + +# CTRL-J, CTRL-M: newline +10: NEWLINE + +# CTRL-K: erase the current line +11: KILL_LINE + +# ENTER: newline +13: NEWLINE + +# CTRL-L: clear screen +12: CLEAR_SCREEN + +# CTRL-N: scroll to the next element in the history buffer +14: NEXT_HISTORY + +# CTRL-P: scroll to the previous element in the history buffer +16: PREV_HISTORY + +# CTRL-R: redraw the current line +18: REDISPLAY + +# CTRL-U: delete all the characters before the cursor position +21: KILL_LINE_PREV + +# CTRL-V: paste the contents of the clipboard (useful for Windows terminal) +22: PASTE + +# CTRL-W: delete the word directly before the cursor +23: DELETE_PREV_WORD + +# DELETE, CTRL-?: delete the previous character +# 127 is the ASCII code for delete +127: DELETE_PREV_CHAR diff --git a/src/main/resources/jline/keybindings.properties b/src/main/resources/jline/keybindings.properties new file mode 100644 index 0000000000000000000000000000000000000000..9585e3a8ddd129fcc7182aa109cf8b8f0d945df7 --- /dev/null +++ b/src/main/resources/jline/keybindings.properties @@ -0,0 +1,68 @@ +# Keybinding mapping for JLine. The format is: +# [key code]: [logical operation] + +# CTRL-A: move to the beginning of the line +1: MOVE_TO_BEG + +# CTRL-B: move to the previous character +2: PREV_CHAR + +# CTRL-D: close out the input stream +4: EXIT + +# CTRL-E: move the cursor to the end of the line +5: MOVE_TO_END + +# CTRL-F: move to the next character +6: NEXT_CHAR + +# CTRL-G: move to the previous word +7: ABORT + +# BACKSPACE, CTRL-H: delete the previous character +# 8 is the ASCII code for backspace and therefor +# deleting the previous character +8: DELETE_PREV_CHAR + +# TAB, CTRL-I: signal that console completion should be attempted +9: COMPLETE + +# CTRL-J, CTRL-M: newline +10: NEWLINE + +# CTRL-K: erase the current line +11: KILL_LINE + +# CTRL-L: clear screen +12: CLEAR_SCREEN + +# ENTER: newline +13: NEWLINE + +# CTRL-N: scroll to the next element in the history buffer +14: NEXT_HISTORY + +# CTRL-P: scroll to the previous element in the history buffer +16: PREV_HISTORY + +# CTRL-R: redraw the current line +18: SEARCH_PREV + +# CTRL-U: delete all the characters before the cursor position +21: KILL_LINE_PREV + +# CTRL-V: paste the contents of the clipboard (useful for Windows terminal) +22: PASTE + +# CTRL-W: delete the word directly before the cursor +23: DELETE_PREV_WORD + +# CTRL-X: temporary location for PREV_WORD to make tests pass +24: PREV_WORD + +# ESCAPE probably not intended this way, but it does the right thing for now +27: REDISPLAY + +# DELETE, CTRL-?: delete the next character +# 127 is the ASCII code for delete +127: DELETE_NEXT_CHAR diff --git a/src/main/resources/jline/windowsbindings.properties b/src/main/resources/jline/windowsbindings.properties new file mode 100644 index 0000000000000000000000000000000000000000..d599c694ae77f4e0eb3b6f85119664911f0f469b --- /dev/null +++ b/src/main/resources/jline/windowsbindings.properties @@ -0,0 +1,68 @@ +# Keybinding mapping for JLine. The format is: +# [key code]: [logical operation] + +# CTRL-A: move to the beginning of the line +1: MOVE_TO_BEG + +# CTRL-B: move to the previous character +2: PREV_CHAR + +# CTRL-C: toggle overtype mode (frankly, I wasn't sure where to bind this) +3: INSERT + +# CTRL-D: close out the input stream +4: EXIT + +# CTRL-E: move the cursor to the end of the line +5: MOVE_TO_END + +# CTRL-F: move to the next character +6: NEXT_CHAR + +# CTRL-G: move to the previous word +7: ABORT + +# CTRL-H: delete the previous character +8: DELETE_PREV_CHAR + +# TAB, CTRL-I: signal that console completion should be attempted +9: COMPLETE + +# CTRL-J, CTRL-M: newline +10: NEWLINE + +# CTRL-K: Vertical tab - on windows we'll move to the start of the history +11: START_OF_HISTORY + +# CTRL-L: Form feed - on windows, we'll move to the end of the history +12: END_OF_HISTORY + +# ENTER: newline +13: NEWLINE + +# CTRL-N: scroll to the next element in the history buffer +14: NEXT_HISTORY + +# CTRL-P: scroll to the previous element in the history buffer +16: PREV_HISTORY + +# CTRL-R: search backwards in history +18: SEARCH_PREV + +# CTRL-U: delete all the characters before the cursor position +21: KILL_LINE_PREV + +# CTRL-V: paste the contents of the clipboard (useful for Windows terminal) +22: PASTE + +# CTRL-W: delete the word directly before the cursor +23: DELETE_PREV_WORD + +# CTRL-X: temporary location for PREV_WORD to make tests pass +24: PREV_WORD + +# CTRL-[: escape - clear the current line. +27: CLEAR_LINE + +# CTRL-?: delete the previous character +127: DELETE_NEXT_CHAR diff --git a/src/main/resources/jni/Darwin/libjffi-1.2.jnilib b/src/main/resources/jni/Darwin/libjffi-1.2.jnilib new file mode 100644 index 0000000000000000000000000000000000000000..cf5d35645ca6d84587cef474eb1252d71e93e87b Binary files /dev/null and b/src/main/resources/jni/Darwin/libjffi-1.2.jnilib differ diff --git a/src/main/resources/jni/arm-Linux/libjffi-1.2.so b/src/main/resources/jni/arm-Linux/libjffi-1.2.so new file mode 100644 index 0000000000000000000000000000000000000000..768b48931774e05fef2f2eca1ff0b5e2239d7e6c Binary files /dev/null and b/src/main/resources/jni/arm-Linux/libjffi-1.2.so differ diff --git a/src/main/resources/jni/i386-Linux/libjffi-1.2.so b/src/main/resources/jni/i386-Linux/libjffi-1.2.so new file mode 100644 index 0000000000000000000000000000000000000000..bec318991111ec672de56d9c7b0bd99e4d299434 Binary files /dev/null and b/src/main/resources/jni/i386-Linux/libjffi-1.2.so differ diff --git a/src/main/resources/jni/i386-SunOS/libjffi-1.2.so b/src/main/resources/jni/i386-SunOS/libjffi-1.2.so new file mode 100644 index 0000000000000000000000000000000000000000..70a45a33edaea8d74b61d4e56a4a3a145c509c68 Binary files /dev/null and b/src/main/resources/jni/i386-SunOS/libjffi-1.2.so differ diff --git a/src/main/resources/jni/i386-Windows/jffi-1.2.dll b/src/main/resources/jni/i386-Windows/jffi-1.2.dll new file mode 100644 index 0000000000000000000000000000000000000000..1795623c44e72c0875728ff057ec4c8bdba502b0 Binary files /dev/null and b/src/main/resources/jni/i386-Windows/jffi-1.2.dll differ diff --git a/src/main/resources/jni/sparcv9-SunOS/libjffi-1.2.so b/src/main/resources/jni/sparcv9-SunOS/libjffi-1.2.so new file mode 100644 index 0000000000000000000000000000000000000000..4e0f92aab584207f1f278a93862c0c9d319186b2 Binary files /dev/null and b/src/main/resources/jni/sparcv9-SunOS/libjffi-1.2.so differ diff --git a/src/main/resources/jni/x86_64-FreeBSD/libjffi-1.2.so b/src/main/resources/jni/x86_64-FreeBSD/libjffi-1.2.so new file mode 100644 index 0000000000000000000000000000000000000000..516acb096950e9832d7ae722a78e05ecc19368bc Binary files /dev/null and b/src/main/resources/jni/x86_64-FreeBSD/libjffi-1.2.so differ diff --git a/src/main/resources/jni/x86_64-Linux/libjffi-1.2.so b/src/main/resources/jni/x86_64-Linux/libjffi-1.2.so new file mode 100644 index 0000000000000000000000000000000000000000..c61095c8dfddffd9e3f50e3a06da714af4eaee99 Binary files /dev/null and b/src/main/resources/jni/x86_64-Linux/libjffi-1.2.so differ diff --git a/src/main/resources/jni/x86_64-SunOS/libjffi-1.2.so b/src/main/resources/jni/x86_64-SunOS/libjffi-1.2.so new file mode 100644 index 0000000000000000000000000000000000000000..48477ea4d6e93d00874117bea8890489ce7024be Binary files /dev/null and b/src/main/resources/jni/x86_64-SunOS/libjffi-1.2.so differ diff --git a/src/main/resources/jni/x86_64-Windows/jffi-1.2.dll b/src/main/resources/jni/x86_64-Windows/jffi-1.2.dll new file mode 100644 index 0000000000000000000000000000000000000000..9316aacbcfc8bc447d41ef7952d9bca25433105e Binary files /dev/null and b/src/main/resources/jni/x86_64-Windows/jffi-1.2.dll differ diff --git a/src/main/resources/jnr/constants/Constant.class b/src/main/resources/jnr/constants/Constant.class new file mode 100644 index 0000000000000000000000000000000000000000..c19e705bd50dbfb0a447074243a34c83cb852810 Binary files /dev/null and b/src/main/resources/jnr/constants/Constant.class differ diff --git a/src/main/resources/jnr/constants/ConstantSet$ConstantIterator.class b/src/main/resources/jnr/constants/ConstantSet$ConstantIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..2a67731ba3428b2184822fd36506e36dc73b8798 Binary files /dev/null and b/src/main/resources/jnr/constants/ConstantSet$ConstantIterator.class differ diff --git a/src/main/resources/jnr/constants/ConstantSet.class b/src/main/resources/jnr/constants/ConstantSet.class new file mode 100644 index 0000000000000000000000000000000000000000..9270af0ff4adb6ad02c7fdc776c0ceba534d79e7 Binary files /dev/null and b/src/main/resources/jnr/constants/ConstantSet.class differ diff --git a/src/main/resources/jnr/constants/Platform$1.class b/src/main/resources/jnr/constants/Platform$1.class new file mode 100644 index 0000000000000000000000000000000000000000..14a5e99bfca3cc27ebbba01873a9c5b5c691ce00 Binary files /dev/null and b/src/main/resources/jnr/constants/Platform$1.class differ diff --git a/src/main/resources/jnr/constants/Platform$2.class b/src/main/resources/jnr/constants/Platform$2.class new file mode 100644 index 0000000000000000000000000000000000000000..58aa3d4148acd60b389a9b5910fb4c19923d28c4 Binary files /dev/null and b/src/main/resources/jnr/constants/Platform$2.class differ diff --git a/src/main/resources/jnr/constants/Platform$PackageNameResolver.class b/src/main/resources/jnr/constants/Platform$PackageNameResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..d7d40974d68ab4d0ffcc099962a3522db49c54b0 Binary files /dev/null and b/src/main/resources/jnr/constants/Platform$PackageNameResolver.class differ diff --git a/src/main/resources/jnr/constants/Platform.class b/src/main/resources/jnr/constants/Platform.class new file mode 100644 index 0000000000000000000000000000000000000000..da37aef2724ad180498a1e6679219ec09cf8d379 Binary files /dev/null and b/src/main/resources/jnr/constants/Platform.class differ diff --git a/src/main/resources/jnr/constants/platform/AddressFamily.class b/src/main/resources/jnr/constants/platform/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..ecc6a2e52ad7e9e1ebc591d0b35b88f9e0936615 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/AddressFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/ConstantResolver$UnknownConstant.class b/src/main/resources/jnr/constants/platform/ConstantResolver$UnknownConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..eeb90add0d39a4ae5ae3bae48f5038ec3d2c7289 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/ConstantResolver$UnknownConstant.class differ diff --git a/src/main/resources/jnr/constants/platform/ConstantResolver.class b/src/main/resources/jnr/constants/platform/ConstantResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..670ab1b34bb0e7173cb159b9dd13983f0338580a Binary files /dev/null and b/src/main/resources/jnr/constants/platform/ConstantResolver.class differ diff --git a/src/main/resources/jnr/constants/platform/Errno.class b/src/main/resources/jnr/constants/platform/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..b96bf4c5c54f8739f57da2b72aa5947cd852f1a5 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/Fcntl.class b/src/main/resources/jnr/constants/platform/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..b8b129bef11d247f9223ca558a5bb11120b0466a Binary files /dev/null and b/src/main/resources/jnr/constants/platform/Fcntl.class differ diff --git a/src/main/resources/jnr/constants/platform/INAddr.class b/src/main/resources/jnr/constants/platform/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..b54dd5673310fbffdff5e843b6d5de14c38bf3b3 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/INAddr.class differ diff --git a/src/main/resources/jnr/constants/platform/IPProto.class b/src/main/resources/jnr/constants/platform/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..7769df9617492816ee7bbea2644d0d5300c0fb92 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/IPProto.class differ diff --git a/src/main/resources/jnr/constants/platform/NameInfo.class b/src/main/resources/jnr/constants/platform/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..474edba6ae672c27f9fd3c5abc2c6617afc4b0a1 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/NameInfo.class differ diff --git a/src/main/resources/jnr/constants/platform/OpenFlags.class b/src/main/resources/jnr/constants/platform/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..fe8e41b4e57f10a188a177dc08389b2bd2dd5649 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/PRIO.class b/src/main/resources/jnr/constants/platform/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..090a4ab764e03c5880bc66d58e8bc8d6b96bddc9 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/PRIO.class differ diff --git a/src/main/resources/jnr/constants/platform/ProtocolFamily.class b/src/main/resources/jnr/constants/platform/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..46745278f9259555385fee7b9f306fcb70b78110 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/ProtocolFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/RLIM.class b/src/main/resources/jnr/constants/platform/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..d46ec63dd3822e36d3648bed1232c2ea7a9d8d7d Binary files /dev/null and b/src/main/resources/jnr/constants/platform/RLIM.class differ diff --git a/src/main/resources/jnr/constants/platform/RLIMIT.class b/src/main/resources/jnr/constants/platform/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..4376afd4f5e7a137b11c2b9d3560087b3a8d686f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/RLIMIT.class differ diff --git a/src/main/resources/jnr/constants/platform/Shutdown.class b/src/main/resources/jnr/constants/platform/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..958c12fad15c298cde1317cf591cbaa6aa4785c2 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/Shutdown.class differ diff --git a/src/main/resources/jnr/constants/platform/Signal.class b/src/main/resources/jnr/constants/platform/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..80609ef14bc40c015de06a2482f7a23dc6a73d74 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/Signal.class differ diff --git a/src/main/resources/jnr/constants/platform/Sock.class b/src/main/resources/jnr/constants/platform/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..b3eb19aa5c3f9aced5bf734b8bc633f5cb918d10 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/Sock.class differ diff --git a/src/main/resources/jnr/constants/platform/SocketLevel.class b/src/main/resources/jnr/constants/platform/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..5afa0e2739b0838830a0bb68e0b085be6c2eccb2 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/SocketLevel.class differ diff --git a/src/main/resources/jnr/constants/platform/SocketOption.class b/src/main/resources/jnr/constants/platform/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..48cefc3ec92982eceadc77ae5b53750d3c2c88a4 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/SocketOption.class differ diff --git a/src/main/resources/jnr/constants/platform/Sysconf.class b/src/main/resources/jnr/constants/platform/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..e6af4497f8abd5983dfa5a2b33fb427ba3cdcc84 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/Sysconf.class differ diff --git a/src/main/resources/jnr/constants/platform/TCP.class b/src/main/resources/jnr/constants/platform/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..860cc10b75f55cc316d8d872e51ec7d4ffe98810 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/TCP.class differ diff --git a/src/main/resources/jnr/constants/platform/WaitFlags.class b/src/main/resources/jnr/constants/platform/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..439f139e6e3bf8e549767cdad3ad4dfd15da20c9 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/WaitFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/AddressFamily.class b/src/main/resources/jnr/constants/platform/darwin/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..43bfd2116e2d82fa5a483b5137279ab8198cd04b Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/AddressFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/Errno$StringTable.class b/src/main/resources/jnr/constants/platform/darwin/Errno$StringTable.class new file mode 100644 index 0000000000000000000000000000000000000000..577c895f2d09d5b00490322b428308ea0f361579 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/Errno$StringTable.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/Errno.class b/src/main/resources/jnr/constants/platform/darwin/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..f341b829f57ec06340b7d1a0265921fba839fa60 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/Fcntl.class b/src/main/resources/jnr/constants/platform/darwin/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..0ff6be3437be6131db1f2c2226379387d5b42031 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/Fcntl.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/INAddr.class b/src/main/resources/jnr/constants/platform/darwin/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..3288890f403630ff049e6fcacd2c8f92c0f80810 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/INAddr.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/IPProto.class b/src/main/resources/jnr/constants/platform/darwin/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..accf8e631a99d4502caab6bb3f64fe0edf246acf Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/IPProto.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/NameInfo.class b/src/main/resources/jnr/constants/platform/darwin/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..55ad81e4e5aca96b681a02d80c4d62b1d0888d74 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/NameInfo.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/OpenFlags.class b/src/main/resources/jnr/constants/platform/darwin/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..af72c1715566e1204e2b2d4bd13902baabbea15f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/PRIO.class b/src/main/resources/jnr/constants/platform/darwin/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..e3c166edeefa0a7de79baee02864b63ea1371375 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/PRIO.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/ProtocolFamily.class b/src/main/resources/jnr/constants/platform/darwin/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..de90a4582140ac9f36ba90a14904c480eeab4ca4 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/ProtocolFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/RLIM.class b/src/main/resources/jnr/constants/platform/darwin/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..bf5ea7d2456ba94ccaf9ecabf43b0f07a82422d0 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/RLIM.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/RLIMIT.class b/src/main/resources/jnr/constants/platform/darwin/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..fa483112325dcfc6ba99f10ea34477764c5165dd Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/RLIMIT.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/Shutdown.class b/src/main/resources/jnr/constants/platform/darwin/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..570b44fe2973d57ef3646dd5ba243c6fb400fe64 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/Shutdown.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/Signal.class b/src/main/resources/jnr/constants/platform/darwin/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..d4730e3d3203225860a3024f3d0059aeff3d2ad8 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/Signal.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/Sock.class b/src/main/resources/jnr/constants/platform/darwin/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..3dcf7036e955521fdda60799ed3f348fac0ae1fa Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/Sock.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/SocketLevel.class b/src/main/resources/jnr/constants/platform/darwin/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..b29d88f58062748aeefde3fda25501402cb56944 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/SocketLevel.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/SocketOption.class b/src/main/resources/jnr/constants/platform/darwin/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..09e80da0e5ca54bcf94831a670e94d97e68f4705 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/SocketOption.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/Sysconf.class b/src/main/resources/jnr/constants/platform/darwin/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..2f4b5fff38a55e56a4eda657d94c26cfdeee1dab Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/Sysconf.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/TCP.class b/src/main/resources/jnr/constants/platform/darwin/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..8c1ff470a8c65491e5ca0ca544aafcaf8658950a Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/TCP.class differ diff --git a/src/main/resources/jnr/constants/platform/darwin/WaitFlags.class b/src/main/resources/jnr/constants/platform/darwin/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..3ba4dec54230685f999a908db35059f00998ec23 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/darwin/WaitFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/AddressFamily.class b/src/main/resources/jnr/constants/platform/fake/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..93a1e8febd3cfd6c729138bf896d5741a03337a7 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/AddressFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/Errno.class b/src/main/resources/jnr/constants/platform/fake/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..a473782e9c0bdedf63e026d5acaf958665f3c9dd Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/Fcntl.class b/src/main/resources/jnr/constants/platform/fake/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..275de74e49716e061f5e607e596d12f611b5311d Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/Fcntl.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/INAddr.class b/src/main/resources/jnr/constants/platform/fake/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..da7d4001abbde2a2a93e1e7eb26f2a4b51509407 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/INAddr.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/IPProto.class b/src/main/resources/jnr/constants/platform/fake/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..3a2d2610229101798c0fb03d7e85b941a55f8e4f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/IPProto.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/NameInfo.class b/src/main/resources/jnr/constants/platform/fake/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..de6c9eb925992db8b6f1f63c50c619581ebe8aff Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/NameInfo.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/OpenFlags.class b/src/main/resources/jnr/constants/platform/fake/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..6e179368601ccb095153088cf42d32193bd96299 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/PRIO.class b/src/main/resources/jnr/constants/platform/fake/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..763e9b58d6b6ec4e0c88f1da1b8ee898057a2ff1 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/PRIO.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/ProtocolFamily.class b/src/main/resources/jnr/constants/platform/fake/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..ae8dc0cb5dbc52e24379679cf03042b8fd86b0ad Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/ProtocolFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/RLIM.class b/src/main/resources/jnr/constants/platform/fake/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..e5d0b6008301f72e3aa3e0c2bfa6eb52e2e77840 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/RLIM.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/RLIMIT.class b/src/main/resources/jnr/constants/platform/fake/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..2193059c86a3aba4a0c41d92d0e5f4281c7ed03f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/RLIMIT.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/Shutdown.class b/src/main/resources/jnr/constants/platform/fake/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..d728697ed1f60cadaf70300435a68b7919b37eeb Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/Shutdown.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/Signal.class b/src/main/resources/jnr/constants/platform/fake/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..6ad94ea6e9561c67201c3f835fd5fe5e5c0ec662 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/Signal.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/Sock.class b/src/main/resources/jnr/constants/platform/fake/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..0e27d4c0c978b7f1edcb0c9bdbe1ee96430e4bb7 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/Sock.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/SocketLevel.class b/src/main/resources/jnr/constants/platform/fake/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..0b18a4594835712178c3389006c5b624c9c3afbd Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/SocketLevel.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/SocketOption.class b/src/main/resources/jnr/constants/platform/fake/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..12dbb819ecc3d916349339a49ce15ed592460b98 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/SocketOption.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/Sysconf.class b/src/main/resources/jnr/constants/platform/fake/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..2c06f1961836685e1d39d8f50de86fadd62a5771 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/Sysconf.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/TCP.class b/src/main/resources/jnr/constants/platform/fake/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..c200bb315a7bc6faaeec5441aa7c6ab415db5ad6 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/TCP.class differ diff --git a/src/main/resources/jnr/constants/platform/fake/WaitFlags.class b/src/main/resources/jnr/constants/platform/fake/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..8104e73830719bb542b90dcdd41160f0eec66b52 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/fake/WaitFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/AddressFamily.class b/src/main/resources/jnr/constants/platform/freebsd/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..3e1b40b7a2c235c2f37d9b4efe3749751bbb0f2d Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/AddressFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/Errno$StringTable.class b/src/main/resources/jnr/constants/platform/freebsd/Errno$StringTable.class new file mode 100644 index 0000000000000000000000000000000000000000..432458b1eaf70706542fbb6e674220add2343f50 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/Errno$StringTable.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/Errno.class b/src/main/resources/jnr/constants/platform/freebsd/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..61a7a0a178d28b8295fd0bfdd5830c834646501a Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/Fcntl.class b/src/main/resources/jnr/constants/platform/freebsd/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..ff11a786c8da7d7b538e8deff07143c8d0a9d0f3 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/Fcntl.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/INAddr.class b/src/main/resources/jnr/constants/platform/freebsd/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..093f6ca602337ae2a2a9366a29bc7718b7aa4bfc Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/INAddr.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/IPProto.class b/src/main/resources/jnr/constants/platform/freebsd/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..3576fb7ab92ea90fcab3b3aaf10c30d603d58bfe Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/IPProto.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/NameInfo.class b/src/main/resources/jnr/constants/platform/freebsd/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..0dedeb106ad9c91950f04335ca72de6e5297b415 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/NameInfo.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/OpenFlags.class b/src/main/resources/jnr/constants/platform/freebsd/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..5bd34ee49ac3ecc1f89293613c5cda690d381b62 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/PRIO.class b/src/main/resources/jnr/constants/platform/freebsd/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..934b760d0d4c2ab38779bf1fbec9f5d004357478 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/PRIO.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/ProtocolFamily.class b/src/main/resources/jnr/constants/platform/freebsd/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..0f997c514ab05c76b6fd6856f238654579eea6be Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/ProtocolFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/RLIM.class b/src/main/resources/jnr/constants/platform/freebsd/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..9d091d2971af55d5ee420c53b56795d94ba40b59 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/RLIM.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/RLIMIT.class b/src/main/resources/jnr/constants/platform/freebsd/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..b309d1a65aeb620e4d1405e2b7745371d4601203 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/RLIMIT.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/Shutdown.class b/src/main/resources/jnr/constants/platform/freebsd/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..4c3941f392f986045a2658f74c024671d27447a5 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/Shutdown.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/Signal.class b/src/main/resources/jnr/constants/platform/freebsd/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..87a244cacd678d57216238db89f8f365a08e440e Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/Signal.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/Sock.class b/src/main/resources/jnr/constants/platform/freebsd/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..bb7059d1c36ee2803a33da0a15a6e46a0d27d329 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/Sock.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/SocketLevel.class b/src/main/resources/jnr/constants/platform/freebsd/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..1f82cb910130fc0b3e627abe78f229de7cd08000 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/SocketLevel.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/SocketOption.class b/src/main/resources/jnr/constants/platform/freebsd/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..91d6a212256ed2dc31bc073733e908f58b266678 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/SocketOption.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/Sysconf.class b/src/main/resources/jnr/constants/platform/freebsd/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..525589dcd28b974df9f0dae6f170156468bd3c2e Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/Sysconf.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/TCP.class b/src/main/resources/jnr/constants/platform/freebsd/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..ae26e03e892e3bf8af303e111f09b5cdf8255bd8 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/TCP.class differ diff --git a/src/main/resources/jnr/constants/platform/freebsd/WaitFlags.class b/src/main/resources/jnr/constants/platform/freebsd/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..d0f9e532b4599bd8e5e439f3e21cb7d0caeb18e5 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/freebsd/WaitFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/AddressFamily.class b/src/main/resources/jnr/constants/platform/linux/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..8eb4d087265790027e71586a042eb5a1c1b7c7de Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/AddressFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/Errno$StringTable.class b/src/main/resources/jnr/constants/platform/linux/Errno$StringTable.class new file mode 100644 index 0000000000000000000000000000000000000000..58b6171b01921320d75302e185c0794664ff9e7c Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/Errno$StringTable.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/Errno.class b/src/main/resources/jnr/constants/platform/linux/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..2f1e6884566ca44004a4e11fba9975c651665022 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/Fcntl.class b/src/main/resources/jnr/constants/platform/linux/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..f24cff8bd3975452c3ee8644228d0a227528a514 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/Fcntl.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/INAddr.class b/src/main/resources/jnr/constants/platform/linux/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..30dc12d5471427b309d05e6b0c93937296045f54 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/INAddr.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/IPProto.class b/src/main/resources/jnr/constants/platform/linux/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..29c2ecb0dbf805da15914e14525453788e486afa Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/IPProto.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/NameInfo.class b/src/main/resources/jnr/constants/platform/linux/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..234b6a7e21b1832cc8ad824ab48a66b244c67b48 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/NameInfo.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/OpenFlags.class b/src/main/resources/jnr/constants/platform/linux/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..8bebd768a1f77b6cb1cfeb95938926a25158bc77 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/PRIO.class b/src/main/resources/jnr/constants/platform/linux/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..0a8bc04b5422917e803beefaac5197d82b401fc1 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/PRIO.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/ProtocolFamily.class b/src/main/resources/jnr/constants/platform/linux/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..0c09183a91100203af50bfece3061910c8123ed2 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/ProtocolFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/RLIM.class b/src/main/resources/jnr/constants/platform/linux/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..a79690dc21d85585baa72f5bb463146bbc2a2d39 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/RLIM.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/RLIMIT.class b/src/main/resources/jnr/constants/platform/linux/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..4b071133f2bb272f7297ca53a7f68b1e163d93bf Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/RLIMIT.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/Shutdown.class b/src/main/resources/jnr/constants/platform/linux/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..6945a19f3f9691206a5bd3593023c04237b8b037 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/Shutdown.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/Signal.class b/src/main/resources/jnr/constants/platform/linux/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..104ef308010c297c260f07bdbc16d38557ca829b Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/Signal.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/Sock.class b/src/main/resources/jnr/constants/platform/linux/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..9656be4f192bd6048bbab1e1fbfec78ac966dfa9 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/Sock.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/SocketLevel.class b/src/main/resources/jnr/constants/platform/linux/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..da017b60b018096dc6a24f8e9dd4a0fd0a95ab66 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/SocketLevel.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/SocketOption.class b/src/main/resources/jnr/constants/platform/linux/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..a250b7e09f385c885e4ab9e3012067370b8c9976 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/SocketOption.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/Sysconf.class b/src/main/resources/jnr/constants/platform/linux/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..64a4b49ef54f62ce45494596f99187dd2eaf2948 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/Sysconf.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/TCP.class b/src/main/resources/jnr/constants/platform/linux/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..e082457f9c3b86fd0ba38b9378b057b061f92fc5 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/TCP.class differ diff --git a/src/main/resources/jnr/constants/platform/linux/WaitFlags.class b/src/main/resources/jnr/constants/platform/linux/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..9c0fade016906decfd453d42cb75e23f9d599d5f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/linux/WaitFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/AddressFamily.class b/src/main/resources/jnr/constants/platform/openbsd/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..161feab7273ee032e2561bc829d12d704644e213 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/AddressFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/Errno$StringTable.class b/src/main/resources/jnr/constants/platform/openbsd/Errno$StringTable.class new file mode 100644 index 0000000000000000000000000000000000000000..adccbf2b85cef649856e809a9390ff714efa688e Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/Errno$StringTable.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/Errno.class b/src/main/resources/jnr/constants/platform/openbsd/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..cb8a5c18d5e4656b812f8c482159868c706556a9 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/Fcntl.class b/src/main/resources/jnr/constants/platform/openbsd/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..cc8b5664ad0d869384d99077e383d49e85b4adb7 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/Fcntl.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/INAddr.class b/src/main/resources/jnr/constants/platform/openbsd/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..345443fdffe1fb030bdd7de10300e96784ac929b Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/INAddr.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/IPProto.class b/src/main/resources/jnr/constants/platform/openbsd/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..d5fff1d1cdf605f5fb796ddcaeaeb149db37ad54 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/IPProto.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/NameInfo.class b/src/main/resources/jnr/constants/platform/openbsd/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..0a5b32ece48fca92321b086d88227cf890d6929f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/NameInfo.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/OpenFlags.class b/src/main/resources/jnr/constants/platform/openbsd/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..87f7702bb78aded5ca8eed7ffbfd880d20d5ae0d Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/PRIO.class b/src/main/resources/jnr/constants/platform/openbsd/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..fce2c4d4719362a1f2c1941fdbb1f126db17d7e3 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/PRIO.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/ProtocolFamily.class b/src/main/resources/jnr/constants/platform/openbsd/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..c6d42113e95361cd24b9100db9da36c0de22fc5f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/ProtocolFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/RLIM.class b/src/main/resources/jnr/constants/platform/openbsd/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..57193c3ccaafb1c30e73534f3c1b5a8ef60074e8 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/RLIM.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/RLIMIT.class b/src/main/resources/jnr/constants/platform/openbsd/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..16e67f1f37c791f749694241a9998ed00a85bf54 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/RLIMIT.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/Shutdown.class b/src/main/resources/jnr/constants/platform/openbsd/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..e003e53fe99b2e0c9041f1b22c193e0cc97fff4c Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/Shutdown.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/Signal.class b/src/main/resources/jnr/constants/platform/openbsd/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..68c3d3109cccd44f733fd9cb3cf852ae0db23a72 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/Signal.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/Sock.class b/src/main/resources/jnr/constants/platform/openbsd/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..476d5335519726f3599eec61bbb90473fa4926a9 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/Sock.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/SocketLevel.class b/src/main/resources/jnr/constants/platform/openbsd/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..ed28c0d65ec9d7ed98109e7ee5e2b935fc4b00f0 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/SocketLevel.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/SocketOption.class b/src/main/resources/jnr/constants/platform/openbsd/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..8e5302c57a8d4452a36a2a9cdc0412fd4a431cfe Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/SocketOption.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/Sysconf.class b/src/main/resources/jnr/constants/platform/openbsd/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..a3bb34f619629b405d406d9ddc9178ce898a56b6 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/Sysconf.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/TCP.class b/src/main/resources/jnr/constants/platform/openbsd/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..dcea7326ef9d7678dcac1cb38bfbfe4aa1967871 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/TCP.class differ diff --git a/src/main/resources/jnr/constants/platform/openbsd/WaitFlags.class b/src/main/resources/jnr/constants/platform/openbsd/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..05909a74f78d37e68329cfdcec2a527ba769f2a8 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/openbsd/WaitFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/AddressFamily.class b/src/main/resources/jnr/constants/platform/sunos/AddressFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..dd831664a92c91f714cd9caa271d78826d8ab885 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/AddressFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/Errno$StringTable.class b/src/main/resources/jnr/constants/platform/sunos/Errno$StringTable.class new file mode 100644 index 0000000000000000000000000000000000000000..b6bfa209c84eeff01be8c36cc84c36e1df0fb76c Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/Errno$StringTable.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/Errno.class b/src/main/resources/jnr/constants/platform/sunos/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..ac86cf7c9bc4d393088e88a52475f7e5a18d04e5 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/Fcntl.class b/src/main/resources/jnr/constants/platform/sunos/Fcntl.class new file mode 100644 index 0000000000000000000000000000000000000000..8ea7f65b8a5c45967abe643720c20b6b6d089bd8 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/Fcntl.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/INAddr.class b/src/main/resources/jnr/constants/platform/sunos/INAddr.class new file mode 100644 index 0000000000000000000000000000000000000000..7ae5ee8171f8aa629136c115d8f5bb920eea222c Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/INAddr.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/IPProto.class b/src/main/resources/jnr/constants/platform/sunos/IPProto.class new file mode 100644 index 0000000000000000000000000000000000000000..c44d49dd28dd6e0ed12657300da76f85d79e8b06 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/IPProto.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/NameInfo.class b/src/main/resources/jnr/constants/platform/sunos/NameInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..b73fa7e1a49a4a3f581ecbccfb4bcd41f8080511 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/NameInfo.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/OpenFlags.class b/src/main/resources/jnr/constants/platform/sunos/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..d14eeb645c0529e27d067821ea06d1b38b65e922 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/PRIO.class b/src/main/resources/jnr/constants/platform/sunos/PRIO.class new file mode 100644 index 0000000000000000000000000000000000000000..b007586773e3d56476f2c2f0042d4d7e490e49b7 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/PRIO.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/ProtocolFamily.class b/src/main/resources/jnr/constants/platform/sunos/ProtocolFamily.class new file mode 100644 index 0000000000000000000000000000000000000000..4b739a6ccdd5f2c5233dcc82e54430b11469b575 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/ProtocolFamily.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/RLIM.class b/src/main/resources/jnr/constants/platform/sunos/RLIM.class new file mode 100644 index 0000000000000000000000000000000000000000..cc0a5d0bf6cf7e553e90a37e4a565b575cf2cfd2 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/RLIM.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/RLIMIT.class b/src/main/resources/jnr/constants/platform/sunos/RLIMIT.class new file mode 100644 index 0000000000000000000000000000000000000000..d2e82ac42bf1a5e8c4130794b7dc4a1f40d54bf1 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/RLIMIT.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/Shutdown.class b/src/main/resources/jnr/constants/platform/sunos/Shutdown.class new file mode 100644 index 0000000000000000000000000000000000000000..b01240c074971128807e100a7b27606195bd329d Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/Shutdown.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/Signal.class b/src/main/resources/jnr/constants/platform/sunos/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..a29b6ddef47b37684d9092a03c2b2a586c125159 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/Signal.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/Sock.class b/src/main/resources/jnr/constants/platform/sunos/Sock.class new file mode 100644 index 0000000000000000000000000000000000000000..1aa204e6c770648bf48e3755094549ae0f2c16e7 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/Sock.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/SocketLevel.class b/src/main/resources/jnr/constants/platform/sunos/SocketLevel.class new file mode 100644 index 0000000000000000000000000000000000000000..d5def8be682ba4d0763adbbf79c32896b2f06978 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/SocketLevel.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/SocketOption.class b/src/main/resources/jnr/constants/platform/sunos/SocketOption.class new file mode 100644 index 0000000000000000000000000000000000000000..3587595f06798437bd1df3f11807d160e2833fa1 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/SocketOption.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/Sysconf.class b/src/main/resources/jnr/constants/platform/sunos/Sysconf.class new file mode 100644 index 0000000000000000000000000000000000000000..df3907e3ae42e2377ab5aa802320f57c31aa2100 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/Sysconf.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/TCP.class b/src/main/resources/jnr/constants/platform/sunos/TCP.class new file mode 100644 index 0000000000000000000000000000000000000000..fa848ca5617ce71cd5a2536e898d3ec7af8e589f Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/TCP.class differ diff --git a/src/main/resources/jnr/constants/platform/sunos/WaitFlags.class b/src/main/resources/jnr/constants/platform/sunos/WaitFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..f43ccf9632c7b559dcccef7974ca4e91b8882af0 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/sunos/WaitFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/windows/Errno$StringTable.class b/src/main/resources/jnr/constants/platform/windows/Errno$StringTable.class new file mode 100644 index 0000000000000000000000000000000000000000..b2ff1d552198b10fc94b4c2132f67a47d4927c5c Binary files /dev/null and b/src/main/resources/jnr/constants/platform/windows/Errno$StringTable.class differ diff --git a/src/main/resources/jnr/constants/platform/windows/Errno.class b/src/main/resources/jnr/constants/platform/windows/Errno.class new file mode 100644 index 0000000000000000000000000000000000000000..d162c052487bb939a1192c8225411a7cb6840f78 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/windows/Errno.class differ diff --git a/src/main/resources/jnr/constants/platform/windows/LastError$StringTable.class b/src/main/resources/jnr/constants/platform/windows/LastError$StringTable.class new file mode 100644 index 0000000000000000000000000000000000000000..561c612035c15ef3ba2e253bfc812f85948e6b39 Binary files /dev/null and b/src/main/resources/jnr/constants/platform/windows/LastError$StringTable.class differ diff --git a/src/main/resources/jnr/constants/platform/windows/LastError.class b/src/main/resources/jnr/constants/platform/windows/LastError.class new file mode 100644 index 0000000000000000000000000000000000000000..5ce80fe0e9fb61a8eca99fcb96aa2cb737cbc6af Binary files /dev/null and b/src/main/resources/jnr/constants/platform/windows/LastError.class differ diff --git a/src/main/resources/jnr/constants/platform/windows/OpenFlags.class b/src/main/resources/jnr/constants/platform/windows/OpenFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..e3fb5da7c5bddb43ed1524e83094b7031f5b18ca Binary files /dev/null and b/src/main/resources/jnr/constants/platform/windows/OpenFlags.class differ diff --git a/src/main/resources/jnr/constants/platform/windows/Signal.class b/src/main/resources/jnr/constants/platform/windows/Signal.class new file mode 100644 index 0000000000000000000000000000000000000000..e5489cb53093044e6e8b09de1b7ffe5495abeaac Binary files /dev/null and b/src/main/resources/jnr/constants/platform/windows/Signal.class differ diff --git a/src/main/resources/jnr/ffi/Address.class b/src/main/resources/jnr/ffi/Address.class new file mode 100644 index 0000000000000000000000000000000000000000..f7ca963fec1824e101a1cae0482d6a1d745192f0 Binary files /dev/null and b/src/main/resources/jnr/ffi/Address.class differ diff --git a/src/main/resources/jnr/ffi/CallingConvention.class b/src/main/resources/jnr/ffi/CallingConvention.class new file mode 100644 index 0000000000000000000000000000000000000000..7f5735982e5a1d1bda07a66fe9f5dc2aadd4727e Binary files /dev/null and b/src/main/resources/jnr/ffi/CallingConvention.class differ diff --git a/src/main/resources/jnr/ffi/FFIProvider$SystemProviderSingletonHolder.class b/src/main/resources/jnr/ffi/FFIProvider$SystemProviderSingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..93a91038dda88e5cab6675b9d2851806080123b6 Binary files /dev/null and b/src/main/resources/jnr/ffi/FFIProvider$SystemProviderSingletonHolder.class differ diff --git a/src/main/resources/jnr/ffi/FFIProvider.class b/src/main/resources/jnr/ffi/FFIProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..5ad1f39a8a4c96514669e7cfc35a02b1edc5cb38 Binary files /dev/null and b/src/main/resources/jnr/ffi/FFIProvider.class differ diff --git a/src/main/resources/jnr/ffi/InvalidProvider.class b/src/main/resources/jnr/ffi/InvalidProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..175f6783c307efb3a9f3604d3e85b3e14b80bec7 Binary files /dev/null and b/src/main/resources/jnr/ffi/InvalidProvider.class differ diff --git a/src/main/resources/jnr/ffi/InvalidRuntime.class b/src/main/resources/jnr/ffi/InvalidRuntime.class new file mode 100644 index 0000000000000000000000000000000000000000..0e7261c1bc86783b20b598eeb4e060b07c73dd3c Binary files /dev/null and b/src/main/resources/jnr/ffi/InvalidRuntime.class differ diff --git a/src/main/resources/jnr/ffi/LastError.class b/src/main/resources/jnr/ffi/LastError.class new file mode 100644 index 0000000000000000000000000000000000000000..46e59289a935837ef60e57cb483cc40eabb9f1f7 Binary files /dev/null and b/src/main/resources/jnr/ffi/LastError.class differ diff --git a/src/main/resources/jnr/ffi/Library.class b/src/main/resources/jnr/ffi/Library.class new file mode 100644 index 0000000000000000000000000000000000000000..08ec52632b701838d18f4c66c7685950f47d8f2c Binary files /dev/null and b/src/main/resources/jnr/ffi/Library.class differ diff --git a/src/main/resources/jnr/ffi/LibraryOption.class b/src/main/resources/jnr/ffi/LibraryOption.class new file mode 100644 index 0000000000000000000000000000000000000000..829e9ed42cd558a45cf1654001e6bedeb85402f4 Binary files /dev/null and b/src/main/resources/jnr/ffi/LibraryOption.class differ diff --git a/src/main/resources/jnr/ffi/Memory.class b/src/main/resources/jnr/ffi/Memory.class new file mode 100644 index 0000000000000000000000000000000000000000..8b3b03579d65ce31a4ea966ca7bfdb6d804a71e5 Binary files /dev/null and b/src/main/resources/jnr/ffi/Memory.class differ diff --git a/src/main/resources/jnr/ffi/NativeLong$Cache.class b/src/main/resources/jnr/ffi/NativeLong$Cache.class new file mode 100644 index 0000000000000000000000000000000000000000..3f4fb503368f258070b8edb425ae80a20a877126 Binary files /dev/null and b/src/main/resources/jnr/ffi/NativeLong$Cache.class differ diff --git a/src/main/resources/jnr/ffi/NativeLong.class b/src/main/resources/jnr/ffi/NativeLong.class new file mode 100644 index 0000000000000000000000000000000000000000..994c4090cd8eb283d22859f0a61baa47d515210e Binary files /dev/null and b/src/main/resources/jnr/ffi/NativeLong.class differ diff --git a/src/main/resources/jnr/ffi/NativeType.class b/src/main/resources/jnr/ffi/NativeType.class new file mode 100644 index 0000000000000000000000000000000000000000..14816499844f47dcfdc074bc66f40eb19d306538 Binary files /dev/null and b/src/main/resources/jnr/ffi/NativeType.class differ diff --git a/src/main/resources/jnr/ffi/ObjectReferenceManager.class b/src/main/resources/jnr/ffi/ObjectReferenceManager.class new file mode 100644 index 0000000000000000000000000000000000000000..196703737d95cf5a31f456fca341e80eaf386dfe Binary files /dev/null and b/src/main/resources/jnr/ffi/ObjectReferenceManager.class differ diff --git a/src/main/resources/jnr/ffi/Platform$1.class b/src/main/resources/jnr/ffi/Platform$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cd2cf8b856e142e870dab72a3954b6e371c5f9cb Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$1.class differ diff --git a/src/main/resources/jnr/ffi/Platform$CPU.class b/src/main/resources/jnr/ffi/Platform$CPU.class new file mode 100644 index 0000000000000000000000000000000000000000..ed11f75abb3a7d6b05b1382944837f0afb7b3625 Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$CPU.class differ diff --git a/src/main/resources/jnr/ffi/Platform$Darwin.class b/src/main/resources/jnr/ffi/Platform$Darwin.class new file mode 100644 index 0000000000000000000000000000000000000000..85421970bc5bdab949d18863489134a34ea208a6 Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$Darwin.class differ diff --git a/src/main/resources/jnr/ffi/Platform$Default.class b/src/main/resources/jnr/ffi/Platform$Default.class new file mode 100644 index 0000000000000000000000000000000000000000..8f56d0acd0fa6a3d3bf3f65056fb2f37ba6ab9e0 Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$Default.class differ diff --git a/src/main/resources/jnr/ffi/Platform$Linux$1.class b/src/main/resources/jnr/ffi/Platform$Linux$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9b6654fa4616957e13361585a3e030723aabf97e Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$Linux$1.class differ diff --git a/src/main/resources/jnr/ffi/Platform$Linux.class b/src/main/resources/jnr/ffi/Platform$Linux.class new file mode 100644 index 0000000000000000000000000000000000000000..397bcec429a1b3d1d9e5d0668e0c6b53eb2e06a4 Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$Linux.class differ diff --git a/src/main/resources/jnr/ffi/Platform$OS.class b/src/main/resources/jnr/ffi/Platform$OS.class new file mode 100644 index 0000000000000000000000000000000000000000..a2862cdec20a1d3c805672531e592cfe725399ff Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$OS.class differ diff --git a/src/main/resources/jnr/ffi/Platform$SingletonHolder.class b/src/main/resources/jnr/ffi/Platform$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..918723d0eaa871f40170e3d4d01cd01d3ca0dee6 Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$SingletonHolder.class differ diff --git a/src/main/resources/jnr/ffi/Platform$Supported.class b/src/main/resources/jnr/ffi/Platform$Supported.class new file mode 100644 index 0000000000000000000000000000000000000000..aeb960e6632147b2c12e011c0aef1e14adc9af26 Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$Supported.class differ diff --git a/src/main/resources/jnr/ffi/Platform$Unsupported.class b/src/main/resources/jnr/ffi/Platform$Unsupported.class new file mode 100644 index 0000000000000000000000000000000000000000..de192c6706189ee2b0eb5b505f3c9c9eba9e9c4d Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$Unsupported.class differ diff --git a/src/main/resources/jnr/ffi/Platform$Windows.class b/src/main/resources/jnr/ffi/Platform$Windows.class new file mode 100644 index 0000000000000000000000000000000000000000..886c93e1cf3972d18245a775edddf5f84de7f8d3 Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform$Windows.class differ diff --git a/src/main/resources/jnr/ffi/Platform.class b/src/main/resources/jnr/ffi/Platform.class new file mode 100644 index 0000000000000000000000000000000000000000..90c690f6a904dd6f02204fe5a9c1143d3472b2fa Binary files /dev/null and b/src/main/resources/jnr/ffi/Platform.class differ diff --git a/src/main/resources/jnr/ffi/Pointer.class b/src/main/resources/jnr/ffi/Pointer.class new file mode 100644 index 0000000000000000000000000000000000000000..b94be40ee9bc5c027d60c9d5ef728820bc081756 Binary files /dev/null and b/src/main/resources/jnr/ffi/Pointer.class differ diff --git a/src/main/resources/jnr/ffi/Runtime$SingletonHolder.class b/src/main/resources/jnr/ffi/Runtime$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..a3434e9aa019a5bea74ddcbe98575cc03055b343 Binary files /dev/null and b/src/main/resources/jnr/ffi/Runtime$SingletonHolder.class differ diff --git a/src/main/resources/jnr/ffi/Runtime.class b/src/main/resources/jnr/ffi/Runtime.class new file mode 100644 index 0000000000000000000000000000000000000000..0429ac5461f16bf56d94bdb5979bb989b8b9a1f1 Binary files /dev/null and b/src/main/resources/jnr/ffi/Runtime.class differ diff --git a/src/main/resources/jnr/ffi/Struct$AbstractBoolean.class b/src/main/resources/jnr/ffi/Struct$AbstractBoolean.class new file mode 100644 index 0000000000000000000000000000000000000000..1c2138de734f2f92e32a636328a8c744f831cea8 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$AbstractBoolean.class differ diff --git a/src/main/resources/jnr/ffi/Struct$AbstractMember.class b/src/main/resources/jnr/ffi/Struct$AbstractMember.class new file mode 100644 index 0000000000000000000000000000000000000000..7f26b7ba489bf845f7fd619fcebf08f2167cb4e2 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$AbstractMember.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Address.class b/src/main/resources/jnr/ffi/Struct$Address.class new file mode 100644 index 0000000000000000000000000000000000000000..b93b3c46e159e5533d7e220d78a2ae3006e9e87c Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Address.class differ diff --git a/src/main/resources/jnr/ffi/Struct$AsciiString.class b/src/main/resources/jnr/ffi/Struct$AsciiString.class new file mode 100644 index 0000000000000000000000000000000000000000..7cab522cda1c0663cbf89269e366027c759a03a6 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$AsciiString.class differ diff --git a/src/main/resources/jnr/ffi/Struct$AsciiStringRef.class b/src/main/resources/jnr/ffi/Struct$AsciiStringRef.class new file mode 100644 index 0000000000000000000000000000000000000000..354b5715ce849f63943c8c69f5edc1c9d466c068 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$AsciiStringRef.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Boolean.class b/src/main/resources/jnr/ffi/Struct$Boolean.class new file mode 100644 index 0000000000000000000000000000000000000000..89ddf5218e65967c7920f06dcea33011538f329c Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Boolean.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Double.class b/src/main/resources/jnr/ffi/Struct$Double.class new file mode 100644 index 0000000000000000000000000000000000000000..28d56e354df411522b02a4ba5772d8374548d200 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Double.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Enum.class b/src/main/resources/jnr/ffi/Struct$Enum.class new file mode 100644 index 0000000000000000000000000000000000000000..82e8c19a56c82b39b8af7d11ddd6160eb7632320 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Enum.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Enum16.class b/src/main/resources/jnr/ffi/Struct$Enum16.class new file mode 100644 index 0000000000000000000000000000000000000000..974bde255b4d202554bddcc54da6788ff9453a93 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Enum16.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Enum32.class b/src/main/resources/jnr/ffi/Struct$Enum32.class new file mode 100644 index 0000000000000000000000000000000000000000..d76f7c44e762e8a749fca37245bcf712806a21ce Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Enum32.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Enum64.class b/src/main/resources/jnr/ffi/Struct$Enum64.class new file mode 100644 index 0000000000000000000000000000000000000000..c2e38ec6ed34179d7937cda58c06bbedd10c3174 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Enum64.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Enum8.class b/src/main/resources/jnr/ffi/Struct$Enum8.class new file mode 100644 index 0000000000000000000000000000000000000000..4d54b5b58e7c27e340658cde4dc32c757e10b750 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Enum8.class differ diff --git a/src/main/resources/jnr/ffi/Struct$EnumField.class b/src/main/resources/jnr/ffi/Struct$EnumField.class new file mode 100644 index 0000000000000000000000000000000000000000..73b6d6d98021d6a38ef1657608b98b6b9ba26c4a Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$EnumField.class differ diff --git a/src/main/resources/jnr/ffi/Struct$EnumLong.class b/src/main/resources/jnr/ffi/Struct$EnumLong.class new file mode 100644 index 0000000000000000000000000000000000000000..df15dbce1f2f3df44f0f77a1619c3f5feb5fe6f4 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$EnumLong.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Float.class b/src/main/resources/jnr/ffi/Struct$Float.class new file mode 100644 index 0000000000000000000000000000000000000000..0ffcd511fb7a246720d3806280549bd2bdb25db3 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Float.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Info.class b/src/main/resources/jnr/ffi/Struct$Info.class new file mode 100644 index 0000000000000000000000000000000000000000..c8cc5f97249df045ea89784c3cc0c4d3421ce7d4 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Info.class differ diff --git a/src/main/resources/jnr/ffi/Struct$IntegerAlias.class b/src/main/resources/jnr/ffi/Struct$IntegerAlias.class new file mode 100644 index 0000000000000000000000000000000000000000..06542f218c97ae7959e8d31d326943369a9c4504 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$IntegerAlias.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Member.class b/src/main/resources/jnr/ffi/Struct$Member.class new file mode 100644 index 0000000000000000000000000000000000000000..26adce470ca624d617bb4e9d33692a7ee4876bf9 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Member.class differ diff --git a/src/main/resources/jnr/ffi/Struct$NumberField.class b/src/main/resources/jnr/ffi/Struct$NumberField.class new file mode 100644 index 0000000000000000000000000000000000000000..df6b44dd46d60d0b7467f0f291f96525464af2c4 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$NumberField.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Offset.class b/src/main/resources/jnr/ffi/Struct$Offset.class new file mode 100644 index 0000000000000000000000000000000000000000..81d0844c0cd8e3c10ad64f432fdf63c1eb0bff21 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Offset.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Padding.class b/src/main/resources/jnr/ffi/Struct$Padding.class new file mode 100644 index 0000000000000000000000000000000000000000..28aaa0999cc25b460f633b069f0a4798d144e394 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Padding.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Pointer.class b/src/main/resources/jnr/ffi/Struct$Pointer.class new file mode 100644 index 0000000000000000000000000000000000000000..15d0f78ea50cd8e5be9bf19c6259109c64350114 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Pointer.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Signed16.class b/src/main/resources/jnr/ffi/Struct$Signed16.class new file mode 100644 index 0000000000000000000000000000000000000000..80e73a7959a1a7f827ff7b216b85149377419431 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Signed16.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Signed32.class b/src/main/resources/jnr/ffi/Struct$Signed32.class new file mode 100644 index 0000000000000000000000000000000000000000..a8c38674f8a504d31f7d4f2fb87aad79bd6b2d2b Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Signed32.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Signed64.class b/src/main/resources/jnr/ffi/Struct$Signed64.class new file mode 100644 index 0000000000000000000000000000000000000000..5caf3629d19c55d4b05e7ca7bd90296e07cd3c8a Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Signed64.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Signed8.class b/src/main/resources/jnr/ffi/Struct$Signed8.class new file mode 100644 index 0000000000000000000000000000000000000000..eeb167afcaa2d68ada4e1cff6cc2ed5484060ffc Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Signed8.class differ diff --git a/src/main/resources/jnr/ffi/Struct$SignedLong.class b/src/main/resources/jnr/ffi/Struct$SignedLong.class new file mode 100644 index 0000000000000000000000000000000000000000..bcf2ad6408efe5bd95b89042bf96c034ae58f7ed Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$SignedLong.class differ diff --git a/src/main/resources/jnr/ffi/Struct$String.class b/src/main/resources/jnr/ffi/Struct$String.class new file mode 100644 index 0000000000000000000000000000000000000000..4367918348b52a9ba798e1f7519324b4ae621b02 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$String.class differ diff --git a/src/main/resources/jnr/ffi/Struct$UTF8String.class b/src/main/resources/jnr/ffi/Struct$UTF8String.class new file mode 100644 index 0000000000000000000000000000000000000000..7213ad3d9a3d5cedfa43aeaa26647a43499db678 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$UTF8String.class differ diff --git a/src/main/resources/jnr/ffi/Struct$UTF8StringRef.class b/src/main/resources/jnr/ffi/Struct$UTF8StringRef.class new file mode 100644 index 0000000000000000000000000000000000000000..aa010e5385d9eb8b3200db31a4b3740b20a03596 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$UTF8StringRef.class differ diff --git a/src/main/resources/jnr/ffi/Struct$UTFString.class b/src/main/resources/jnr/ffi/Struct$UTFString.class new file mode 100644 index 0000000000000000000000000000000000000000..a2a794e4fa1e79903106de39e60dc8a1d07badd3 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$UTFString.class differ diff --git a/src/main/resources/jnr/ffi/Struct$UTFStringRef.class b/src/main/resources/jnr/ffi/Struct$UTFStringRef.class new file mode 100644 index 0000000000000000000000000000000000000000..ba4d3d1ee8d2e121e3e54ab209e9141fe09aaec0 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$UTFStringRef.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Unsigned16.class b/src/main/resources/jnr/ffi/Struct$Unsigned16.class new file mode 100644 index 0000000000000000000000000000000000000000..1091467d375870566cc09210a846e324faa7810a Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Unsigned16.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Unsigned32.class b/src/main/resources/jnr/ffi/Struct$Unsigned32.class new file mode 100644 index 0000000000000000000000000000000000000000..0a546adf1a1832b32c03f8db7ab9bf2512656cb4 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Unsigned32.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Unsigned64.class b/src/main/resources/jnr/ffi/Struct$Unsigned64.class new file mode 100644 index 0000000000000000000000000000000000000000..c783e4053fafae7913a54f6bfd9266cac15d30ef Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Unsigned64.class differ diff --git a/src/main/resources/jnr/ffi/Struct$Unsigned8.class b/src/main/resources/jnr/ffi/Struct$Unsigned8.class new file mode 100644 index 0000000000000000000000000000000000000000..a25103ea2ad51a2c7432d427a7bf9232d78047b3 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$Unsigned8.class differ diff --git a/src/main/resources/jnr/ffi/Struct$UnsignedLong.class b/src/main/resources/jnr/ffi/Struct$UnsignedLong.class new file mode 100644 index 0000000000000000000000000000000000000000..d35e94cfe8a257d3969c0d5f57a7cec541009e59 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$UnsignedLong.class differ diff --git a/src/main/resources/jnr/ffi/Struct$WBOOL.class b/src/main/resources/jnr/ffi/Struct$WBOOL.class new file mode 100644 index 0000000000000000000000000000000000000000..dc06c8dfc1731c87350a4a3f4abe487f79f8b571 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$WBOOL.class differ diff --git a/src/main/resources/jnr/ffi/Struct$blkcnt_t.class b/src/main/resources/jnr/ffi/Struct$blkcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..bcc72a43caf44f51cdebf6d91af1de86380ef850 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$blkcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$blksize_t.class b/src/main/resources/jnr/ffi/Struct$blksize_t.class new file mode 100644 index 0000000000000000000000000000000000000000..3c355b38c7aefd4a73bee0d1b867520206139e74 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$blksize_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$caddr_t.class b/src/main/resources/jnr/ffi/Struct$caddr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..f5adf504ac2f18da36dae318b697ba68830cc856 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$caddr_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$clock_t.class b/src/main/resources/jnr/ffi/Struct$clock_t.class new file mode 100644 index 0000000000000000000000000000000000000000..8b923d764655638e5972b1bb59e5a4ad0be5adb2 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$clock_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$dev_t.class b/src/main/resources/jnr/ffi/Struct$dev_t.class new file mode 100644 index 0000000000000000000000000000000000000000..15683a6746991e2117bf5aea9c4bab0c538ebc31 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$dev_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$fsblkcnt_t.class b/src/main/resources/jnr/ffi/Struct$fsblkcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..634abc9a54d3ec1e22188461823aa722a63e9842 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$fsblkcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$fsfilcnt_t.class b/src/main/resources/jnr/ffi/Struct$fsfilcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..c8e834258c7473e16922aac18469371937924dec Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$fsfilcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$gid_t.class b/src/main/resources/jnr/ffi/Struct$gid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..829ad4c78b4f38d9e9a10c735df34a0daff5e639 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$gid_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$id_t.class b/src/main/resources/jnr/ffi/Struct$id_t.class new file mode 100644 index 0000000000000000000000000000000000000000..3c192dce92fe2684f57ad847f60479bbb44b2ca8 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$id_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$in_addr_t.class b/src/main/resources/jnr/ffi/Struct$in_addr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..076d10f84fa26238ac4b6be0914d4fd201c50cc2 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$in_addr_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$in_port_t.class b/src/main/resources/jnr/ffi/Struct$in_port_t.class new file mode 100644 index 0000000000000000000000000000000000000000..6a99ef7e210e5be5506ee70d472889cbe20635fe Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$in_port_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$ino64_t.class b/src/main/resources/jnr/ffi/Struct$ino64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..7979b91da10273ac3163b1aaeb3ea58dc9ee8148 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$ino64_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$ino_t.class b/src/main/resources/jnr/ffi/Struct$ino_t.class new file mode 100644 index 0000000000000000000000000000000000000000..cca5c0f98bddf82fc29830e7af945801aefd1442 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$ino_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$int16_t.class b/src/main/resources/jnr/ffi/Struct$int16_t.class new file mode 100644 index 0000000000000000000000000000000000000000..344b5f0fba9da1e2b535619ddd6592413d7881d6 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$int16_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$int32_t.class b/src/main/resources/jnr/ffi/Struct$int32_t.class new file mode 100644 index 0000000000000000000000000000000000000000..e78f26a2e7b43998f137a511a8296f53fd1d1dfd Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$int32_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$int64_t.class b/src/main/resources/jnr/ffi/Struct$int64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..a7cd8c9adf8aeeedcdff4d3f499c9a19f3595063 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$int64_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$int8_t.class b/src/main/resources/jnr/ffi/Struct$int8_t.class new file mode 100644 index 0000000000000000000000000000000000000000..eb1fadc02ccff13eadce996539cd3a7d60051d5c Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$int8_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$intptr_t.class b/src/main/resources/jnr/ffi/Struct$intptr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..53adda2ac6f1bd9af48540f289eebc45caa6f1c3 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$intptr_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$key_t.class b/src/main/resources/jnr/ffi/Struct$key_t.class new file mode 100644 index 0000000000000000000000000000000000000000..e0ec7647673a513ae4aa2fe78d33383c1cd20fdd Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$key_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$mode_t.class b/src/main/resources/jnr/ffi/Struct$mode_t.class new file mode 100644 index 0000000000000000000000000000000000000000..5c2328c6586a74d5e00ee10ea48cf3aef16ca325 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$mode_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$nlink_t.class b/src/main/resources/jnr/ffi/Struct$nlink_t.class new file mode 100644 index 0000000000000000000000000000000000000000..a6810ae208b0b97964ef851d2a4e2f2b04ab7959 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$nlink_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$off_t.class b/src/main/resources/jnr/ffi/Struct$off_t.class new file mode 100644 index 0000000000000000000000000000000000000000..0e43e84dfb356ab659de5af8fcd44fcca6931627 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$off_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$pid_t.class b/src/main/resources/jnr/ffi/Struct$pid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..258a296506ecfe330e011edffcbe9265ee034835 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$pid_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$rlim_t.class b/src/main/resources/jnr/ffi/Struct$rlim_t.class new file mode 100644 index 0000000000000000000000000000000000000000..ad2d0468242851c606e4ca272ac5bc7746dd68f9 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$rlim_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$sa_family_t.class b/src/main/resources/jnr/ffi/Struct$sa_family_t.class new file mode 100644 index 0000000000000000000000000000000000000000..9401bd7aba4c719d3a3a1cd09a600f9bd4c6072b Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$sa_family_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$size_t.class b/src/main/resources/jnr/ffi/Struct$size_t.class new file mode 100644 index 0000000000000000000000000000000000000000..895c543e6c800554470b90dba13ad4537385c72b Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$size_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$socklen_t.class b/src/main/resources/jnr/ffi/Struct$socklen_t.class new file mode 100644 index 0000000000000000000000000000000000000000..45c7c1adfe04f02b3fe7f491169b411f4bade3af Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$socklen_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$ssize_t.class b/src/main/resources/jnr/ffi/Struct$ssize_t.class new file mode 100644 index 0000000000000000000000000000000000000000..f1aaac69fb59dc980039b589b8faccfa054d13fe Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$ssize_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$swblk_t.class b/src/main/resources/jnr/ffi/Struct$swblk_t.class new file mode 100644 index 0000000000000000000000000000000000000000..6aafa90f286bd75a8892cc570e8bbe19cd81465b Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$swblk_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$time_t.class b/src/main/resources/jnr/ffi/Struct$time_t.class new file mode 100644 index 0000000000000000000000000000000000000000..daf503c29a9ec4cbdca90316aa29d7019964da33 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$time_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$u_int16_t.class b/src/main/resources/jnr/ffi/Struct$u_int16_t.class new file mode 100644 index 0000000000000000000000000000000000000000..d3cd7394f2e52a9cd664c521e6957cc40672d550 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$u_int16_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$u_int32_t.class b/src/main/resources/jnr/ffi/Struct$u_int32_t.class new file mode 100644 index 0000000000000000000000000000000000000000..a6ebd703df49d90df0e0dd98024f8fabe321dfe5 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$u_int32_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$u_int64_t.class b/src/main/resources/jnr/ffi/Struct$u_int64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..8c061b029143779a0c6a0801bc70bd4f6a40c48c Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$u_int64_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$u_int8_t.class b/src/main/resources/jnr/ffi/Struct$u_int8_t.class new file mode 100644 index 0000000000000000000000000000000000000000..cfaf77e71854128cf13f417f22ec31c46c5a502f Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$u_int8_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$uid_t.class b/src/main/resources/jnr/ffi/Struct$uid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..9190c3be49806107023fd79eb028504e170a92a7 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$uid_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct$uintptr_t.class b/src/main/resources/jnr/ffi/Struct$uintptr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..b29a3fb564c022959a6ae870f1044def9d77d603 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct$uintptr_t.class differ diff --git a/src/main/resources/jnr/ffi/Struct.class b/src/main/resources/jnr/ffi/Struct.class new file mode 100644 index 0000000000000000000000000000000000000000..9ec19fcf4bfe7201b055772ac256648abaa25679 Binary files /dev/null and b/src/main/resources/jnr/ffi/Struct.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$AbstractBoolean.class b/src/main/resources/jnr/ffi/StructLayout$AbstractBoolean.class new file mode 100644 index 0000000000000000000000000000000000000000..034d0daad237f21637a1d1420df9e9c2559fd831 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$AbstractBoolean.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$AbstractField.class b/src/main/resources/jnr/ffi/StructLayout$AbstractField.class new file mode 100644 index 0000000000000000000000000000000000000000..d75290e6a147ef56a0d4ad30257a30b01ea68a7d Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$AbstractField.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$AsciiString.class b/src/main/resources/jnr/ffi/StructLayout$AsciiString.class new file mode 100644 index 0000000000000000000000000000000000000000..fb0a8e8dfb46c9fb7fc75c9b7fbbf1d4c626080e Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$AsciiString.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$AsciiStringRef.class b/src/main/resources/jnr/ffi/StructLayout$AsciiStringRef.class new file mode 100644 index 0000000000000000000000000000000000000000..9df9f0afb9a16281c1dd86c1f2edf31166a7cdb2 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$AsciiStringRef.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Boolean.class b/src/main/resources/jnr/ffi/StructLayout$Boolean.class new file mode 100644 index 0000000000000000000000000000000000000000..686e94f1671b9014928d6ebde242cab14ef90f0a Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Boolean.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Double.class b/src/main/resources/jnr/ffi/StructLayout$Double.class new file mode 100644 index 0000000000000000000000000000000000000000..2d7c2571b80f938a6ed87081a88d17e298749b0f Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Double.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Enum.class b/src/main/resources/jnr/ffi/StructLayout$Enum.class new file mode 100644 index 0000000000000000000000000000000000000000..88cc81ecac222e75e2b7c91dab5469453ba41342 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Enum.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Enum16.class b/src/main/resources/jnr/ffi/StructLayout$Enum16.class new file mode 100644 index 0000000000000000000000000000000000000000..7939cba32c0dc77d8d936a76015579aae8d96397 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Enum16.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Enum32.class b/src/main/resources/jnr/ffi/StructLayout$Enum32.class new file mode 100644 index 0000000000000000000000000000000000000000..7f17002dbf069a38039e9fd5b25153e466d6fb5a Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Enum32.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Enum64.class b/src/main/resources/jnr/ffi/StructLayout$Enum64.class new file mode 100644 index 0000000000000000000000000000000000000000..b1a8057a2fbc64d8e5904d1fe33245eb54945248 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Enum64.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Enum8.class b/src/main/resources/jnr/ffi/StructLayout$Enum8.class new file mode 100644 index 0000000000000000000000000000000000000000..ac12a75d450f950f81560c1f0daf28995e326c3d Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Enum8.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$EnumField.class b/src/main/resources/jnr/ffi/StructLayout$EnumField.class new file mode 100644 index 0000000000000000000000000000000000000000..8da36cf59ac81822ef030245cca62ae8cae33a20 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$EnumField.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$EnumLong.class b/src/main/resources/jnr/ffi/StructLayout$EnumLong.class new file mode 100644 index 0000000000000000000000000000000000000000..26809d3b313fde80b944dfcca1236f9e79be096d Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$EnumLong.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Field.class b/src/main/resources/jnr/ffi/StructLayout$Field.class new file mode 100644 index 0000000000000000000000000000000000000000..da9842863b458f3e7333398b11e6f8e5575d593d Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Field.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Float.class b/src/main/resources/jnr/ffi/StructLayout$Float.class new file mode 100644 index 0000000000000000000000000000000000000000..18405a807a4b819fefa45fe02551c994caa1f888 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Float.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$IntegerAlias.class b/src/main/resources/jnr/ffi/StructLayout$IntegerAlias.class new file mode 100644 index 0000000000000000000000000000000000000000..2eb3ac800565f8dd323f0cf67f1fea21b995789d Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$IntegerAlias.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$NumberField.class b/src/main/resources/jnr/ffi/StructLayout$NumberField.class new file mode 100644 index 0000000000000000000000000000000000000000..58a7b1aa8473a9f83f64b7fa09a686a14740a213 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$NumberField.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Padding.class b/src/main/resources/jnr/ffi/StructLayout$Padding.class new file mode 100644 index 0000000000000000000000000000000000000000..d3955144a3f1d4e4b7fd9c88c93974215b4bf61c Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Padding.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Pointer.class b/src/main/resources/jnr/ffi/StructLayout$Pointer.class new file mode 100644 index 0000000000000000000000000000000000000000..7297bf20b91d3b2bb7770a54efed184099a5e7ce Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Pointer.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Signed16.class b/src/main/resources/jnr/ffi/StructLayout$Signed16.class new file mode 100644 index 0000000000000000000000000000000000000000..ddda3916d17a3f3fe56a8413ea44ee12425f7425 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Signed16.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Signed32.class b/src/main/resources/jnr/ffi/StructLayout$Signed32.class new file mode 100644 index 0000000000000000000000000000000000000000..8dd3c8b7b2ed6fbbc714bd5b1e3f49109cc68126 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Signed32.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Signed64.class b/src/main/resources/jnr/ffi/StructLayout$Signed64.class new file mode 100644 index 0000000000000000000000000000000000000000..47ea2a959b102d4f1b0bc93b6ca5828d4429a8ee Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Signed64.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Signed8.class b/src/main/resources/jnr/ffi/StructLayout$Signed8.class new file mode 100644 index 0000000000000000000000000000000000000000..f385efb60063c83957179ede2ecb8b913ade99bc Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Signed8.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$SignedLong.class b/src/main/resources/jnr/ffi/StructLayout$SignedLong.class new file mode 100644 index 0000000000000000000000000000000000000000..c2822014f8f58fa5f2d266ee690fa7554aead8dc Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$SignedLong.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$String.class b/src/main/resources/jnr/ffi/StructLayout$String.class new file mode 100644 index 0000000000000000000000000000000000000000..fbc843a707a8474d0637ecc1b556132c13bc8a7e Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$String.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$UTF8String.class b/src/main/resources/jnr/ffi/StructLayout$UTF8String.class new file mode 100644 index 0000000000000000000000000000000000000000..15b179825fa8b8250363506219304a71e708750b Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$UTF8String.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$UTF8StringRef.class b/src/main/resources/jnr/ffi/StructLayout$UTF8StringRef.class new file mode 100644 index 0000000000000000000000000000000000000000..53619cf1aee658b4b3f629cf8ff97425533235ac Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$UTF8StringRef.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$UTFString.class b/src/main/resources/jnr/ffi/StructLayout$UTFString.class new file mode 100644 index 0000000000000000000000000000000000000000..ccd29638eb6fe4f74349775deb25e1fdf986c46b Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$UTFString.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$UTFStringRef.class b/src/main/resources/jnr/ffi/StructLayout$UTFStringRef.class new file mode 100644 index 0000000000000000000000000000000000000000..12e3d72d512aaa9e91aaedcb373688f20258ba86 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$UTFStringRef.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Unsigned16.class b/src/main/resources/jnr/ffi/StructLayout$Unsigned16.class new file mode 100644 index 0000000000000000000000000000000000000000..ef7abac17a6d83a5cc6a313fa7cff0b9979dfc0a Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Unsigned16.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Unsigned32.class b/src/main/resources/jnr/ffi/StructLayout$Unsigned32.class new file mode 100644 index 0000000000000000000000000000000000000000..33ce64f821f438bf5b8aa1e7bad26af0cb7402ab Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Unsigned32.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Unsigned64.class b/src/main/resources/jnr/ffi/StructLayout$Unsigned64.class new file mode 100644 index 0000000000000000000000000000000000000000..a4795f7ab0ed8d65a48b411f102e753fb559afe3 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Unsigned64.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$Unsigned8.class b/src/main/resources/jnr/ffi/StructLayout$Unsigned8.class new file mode 100644 index 0000000000000000000000000000000000000000..2713b62a735e681d5bce2365335d29470701ace9 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$Unsigned8.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$UnsignedLong.class b/src/main/resources/jnr/ffi/StructLayout$UnsignedLong.class new file mode 100644 index 0000000000000000000000000000000000000000..96a0d7ded4426d9f37b54c6e3cf703818ada11ac Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$UnsignedLong.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$WBOOL.class b/src/main/resources/jnr/ffi/StructLayout$WBOOL.class new file mode 100644 index 0000000000000000000000000000000000000000..cf2c21921fda25bec792c456af32654a3049fe72 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$WBOOL.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$blkcnt_t.class b/src/main/resources/jnr/ffi/StructLayout$blkcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..08b3c003a1956e854e78a7f72e41269a976a62df Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$blkcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$blksize_t.class b/src/main/resources/jnr/ffi/StructLayout$blksize_t.class new file mode 100644 index 0000000000000000000000000000000000000000..c97a81a99a325c43c0847fbfb1ca85cdc9457317 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$blksize_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$caddr_t.class b/src/main/resources/jnr/ffi/StructLayout$caddr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..04ee3472296e29fde5700649fcfeb11ec2e6438b Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$caddr_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$clock_t.class b/src/main/resources/jnr/ffi/StructLayout$clock_t.class new file mode 100644 index 0000000000000000000000000000000000000000..76cbca3af1ab233af37eaacf85c2e0b8466da6e3 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$clock_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$dev_t.class b/src/main/resources/jnr/ffi/StructLayout$dev_t.class new file mode 100644 index 0000000000000000000000000000000000000000..dbbf4e48474e710d9c2e11ff5d5a83d0418b00b4 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$dev_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$fsblkcnt_t.class b/src/main/resources/jnr/ffi/StructLayout$fsblkcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..2d3cc031858ccf5b5cfe609f3be890d1350fbaaa Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$fsblkcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$fsfilcnt_t.class b/src/main/resources/jnr/ffi/StructLayout$fsfilcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..4a9e4e83cbe9aa78ae52c7372f01b5690affa8f8 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$fsfilcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$gid_t.class b/src/main/resources/jnr/ffi/StructLayout$gid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..4df46f55f9e740ebd9e3ae7dc90dacaf6e872469 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$gid_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$id_t.class b/src/main/resources/jnr/ffi/StructLayout$id_t.class new file mode 100644 index 0000000000000000000000000000000000000000..f2246afa7c6a4fa57e4931a271978fe0f275c6b3 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$id_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$in_addr_t.class b/src/main/resources/jnr/ffi/StructLayout$in_addr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..8c80a22712eed7d76ef0fae9ffa103c921615248 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$in_addr_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$in_port_t.class b/src/main/resources/jnr/ffi/StructLayout$in_port_t.class new file mode 100644 index 0000000000000000000000000000000000000000..b28a4808ae5f5ae03bffdaaecceae6096d1276b2 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$in_port_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$ino64_t.class b/src/main/resources/jnr/ffi/StructLayout$ino64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..63ad10aa94c9be9645fa59c9b1218047742fff18 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$ino64_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$ino_t.class b/src/main/resources/jnr/ffi/StructLayout$ino_t.class new file mode 100644 index 0000000000000000000000000000000000000000..93592ca4f772f8cb6c22dec5b548aedb6ea02d5f Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$ino_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$int16_t.class b/src/main/resources/jnr/ffi/StructLayout$int16_t.class new file mode 100644 index 0000000000000000000000000000000000000000..89d24794766d6c24cd7c3e4647ea62a28000ed0b Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$int16_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$int32_t.class b/src/main/resources/jnr/ffi/StructLayout$int32_t.class new file mode 100644 index 0000000000000000000000000000000000000000..4f584267038665fd510137ad1d27839f7c6aa98e Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$int32_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$int64_t.class b/src/main/resources/jnr/ffi/StructLayout$int64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..fd35a931bd6506c34d37a650e8bb2c0f57c89612 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$int64_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$int8_t.class b/src/main/resources/jnr/ffi/StructLayout$int8_t.class new file mode 100644 index 0000000000000000000000000000000000000000..10352913e8361b0916b880d9ac3f531fdb4d1ee3 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$int8_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$intptr_t.class b/src/main/resources/jnr/ffi/StructLayout$intptr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..110fd17172354c972064bb2a7ca309e5d3110612 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$intptr_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$key_t.class b/src/main/resources/jnr/ffi/StructLayout$key_t.class new file mode 100644 index 0000000000000000000000000000000000000000..c85f96416a3b439dcae2216495caa1ecf8adee7b Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$key_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$mode_t.class b/src/main/resources/jnr/ffi/StructLayout$mode_t.class new file mode 100644 index 0000000000000000000000000000000000000000..8f85b67e3e6d799c758a4838a719991eceeeb0b6 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$mode_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$nlink_t.class b/src/main/resources/jnr/ffi/StructLayout$nlink_t.class new file mode 100644 index 0000000000000000000000000000000000000000..e5a392c974c9721919ce06f5c49b5b5861931e65 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$nlink_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$off_t.class b/src/main/resources/jnr/ffi/StructLayout$off_t.class new file mode 100644 index 0000000000000000000000000000000000000000..39800e88295bf9b411b651fdea2f5bc8988cb6cb Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$off_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$pid_t.class b/src/main/resources/jnr/ffi/StructLayout$pid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..4efcabfce01e9660b4e9ddd408697b2bdb774b3e Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$pid_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$rlim_t.class b/src/main/resources/jnr/ffi/StructLayout$rlim_t.class new file mode 100644 index 0000000000000000000000000000000000000000..3c9fb67fd3f815bcbe32fd87726b70abc9caf16f Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$rlim_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$sa_family_t.class b/src/main/resources/jnr/ffi/StructLayout$sa_family_t.class new file mode 100644 index 0000000000000000000000000000000000000000..6a048aa71c7f008052254a06b8ac3b62e49f0833 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$sa_family_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$size_t.class b/src/main/resources/jnr/ffi/StructLayout$size_t.class new file mode 100644 index 0000000000000000000000000000000000000000..429dcf8d821f854d948986025434b1df145d3f11 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$size_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$socklen_t.class b/src/main/resources/jnr/ffi/StructLayout$socklen_t.class new file mode 100644 index 0000000000000000000000000000000000000000..12a9256de8f87a5f5a08f68660d868a43cb42ed5 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$socklen_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$ssize_t.class b/src/main/resources/jnr/ffi/StructLayout$ssize_t.class new file mode 100644 index 0000000000000000000000000000000000000000..fa7b16439650bde5a19f361c6da5f3850c085ba3 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$ssize_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$swblk_t.class b/src/main/resources/jnr/ffi/StructLayout$swblk_t.class new file mode 100644 index 0000000000000000000000000000000000000000..ca3b78bc79106811c8b7e3895d0b193e61b4d366 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$swblk_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$time_t.class b/src/main/resources/jnr/ffi/StructLayout$time_t.class new file mode 100644 index 0000000000000000000000000000000000000000..e00d493dd2eb46bab646011a258f1f619517ac56 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$time_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$u_int16_t.class b/src/main/resources/jnr/ffi/StructLayout$u_int16_t.class new file mode 100644 index 0000000000000000000000000000000000000000..d6aef8710074a8313b6ee5ba50afee2281fe7dd4 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$u_int16_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$u_int32_t.class b/src/main/resources/jnr/ffi/StructLayout$u_int32_t.class new file mode 100644 index 0000000000000000000000000000000000000000..e4e939cfe3a8601b5c11b27760ac7a7f5677285c Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$u_int32_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$u_int64_t.class b/src/main/resources/jnr/ffi/StructLayout$u_int64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..2100de84cbab9908dbed161917895d9a645176f0 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$u_int64_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$u_int8_t.class b/src/main/resources/jnr/ffi/StructLayout$u_int8_t.class new file mode 100644 index 0000000000000000000000000000000000000000..df621f7719980dc9c99fe9a6f4c74008bab51640 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$u_int8_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$uid_t.class b/src/main/resources/jnr/ffi/StructLayout$uid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..4462be738dda3b6f9c827616b457844b7109b9e3 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$uid_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout$uintptr_t.class b/src/main/resources/jnr/ffi/StructLayout$uintptr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..1c4734dd97fe6182ba33040a6eb015233a4ee306 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout$uintptr_t.class differ diff --git a/src/main/resources/jnr/ffi/StructLayout.class b/src/main/resources/jnr/ffi/StructLayout.class new file mode 100644 index 0000000000000000000000000000000000000000..eafe012ec0cccce658bab3340c23a6edcf862794 Binary files /dev/null and b/src/main/resources/jnr/ffi/StructLayout.class differ diff --git a/src/main/resources/jnr/ffi/Type.class b/src/main/resources/jnr/ffi/Type.class new file mode 100644 index 0000000000000000000000000000000000000000..610cf7403678b928792e62b065d1bfe4d423142b Binary files /dev/null and b/src/main/resources/jnr/ffi/Type.class differ diff --git a/src/main/resources/jnr/ffi/TypeAlias.class b/src/main/resources/jnr/ffi/TypeAlias.class new file mode 100644 index 0000000000000000000000000000000000000000..9dc07ab1495a91adafb56603006f24e32e849a64 Binary files /dev/null and b/src/main/resources/jnr/ffi/TypeAlias.class differ diff --git a/src/main/resources/jnr/ffi/Union.class b/src/main/resources/jnr/ffi/Union.class new file mode 100644 index 0000000000000000000000000000000000000000..371208f4aed22861ebc5dd30ce832afb4eafc461 Binary files /dev/null and b/src/main/resources/jnr/ffi/Union.class differ diff --git a/src/main/resources/jnr/ffi/annotations/Clear.class b/src/main/resources/jnr/ffi/annotations/Clear.class new file mode 100644 index 0000000000000000000000000000000000000000..e7f9c5c4a25dd48da87a35aa231787245d62d08e Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/Clear.class differ diff --git a/src/main/resources/jnr/ffi/annotations/Delegate.class b/src/main/resources/jnr/ffi/annotations/Delegate.class new file mode 100644 index 0000000000000000000000000000000000000000..b35b6b2c135a4358607f73ff172eb1069cfd6674 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/Delegate.class differ diff --git a/src/main/resources/jnr/ffi/annotations/Direct.class b/src/main/resources/jnr/ffi/annotations/Direct.class new file mode 100644 index 0000000000000000000000000000000000000000..cc2cba55833bf83ee56f3c25dfdd2cd2c0051b3a Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/Direct.class differ diff --git a/src/main/resources/jnr/ffi/annotations/IgnoreError.class b/src/main/resources/jnr/ffi/annotations/IgnoreError.class new file mode 100644 index 0000000000000000000000000000000000000000..5e216bb516c0fce1bc83bc495be0c9e3b7324a4b Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/IgnoreError.class differ diff --git a/src/main/resources/jnr/ffi/annotations/In.class b/src/main/resources/jnr/ffi/annotations/In.class new file mode 100644 index 0000000000000000000000000000000000000000..e578a61091b45b35915f6237d7c9339ac0ba1337 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/In.class differ diff --git a/src/main/resources/jnr/ffi/annotations/LongLong.class b/src/main/resources/jnr/ffi/annotations/LongLong.class new file mode 100644 index 0000000000000000000000000000000000000000..7a28bf8ba238b89e4fe2cf52e18ef13f2428dd63 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/LongLong.class differ diff --git a/src/main/resources/jnr/ffi/annotations/NulTerminate.class b/src/main/resources/jnr/ffi/annotations/NulTerminate.class new file mode 100644 index 0000000000000000000000000000000000000000..79dd7e516054864617460aeeb7624c56703da217 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/NulTerminate.class differ diff --git a/src/main/resources/jnr/ffi/annotations/Out.class b/src/main/resources/jnr/ffi/annotations/Out.class new file mode 100644 index 0000000000000000000000000000000000000000..be53df48bec0ed316ea49e5a0929c7a52cec3242 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/Out.class differ diff --git a/src/main/resources/jnr/ffi/annotations/Pinned.class b/src/main/resources/jnr/ffi/annotations/Pinned.class new file mode 100644 index 0000000000000000000000000000000000000000..3baef1ccfcdc6aa6d5b11d5834e591c3dae888e4 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/Pinned.class differ diff --git a/src/main/resources/jnr/ffi/annotations/SaveError.class b/src/main/resources/jnr/ffi/annotations/SaveError.class new file mode 100644 index 0000000000000000000000000000000000000000..8bc421c7e04e821afc6a3d92ce6c20a3bf924be0 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/SaveError.class differ diff --git a/src/main/resources/jnr/ffi/annotations/StdCall.class b/src/main/resources/jnr/ffi/annotations/StdCall.class new file mode 100644 index 0000000000000000000000000000000000000000..96548ee80f68b1b2b64fedf51fcbecea34709668 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/StdCall.class differ diff --git a/src/main/resources/jnr/ffi/annotations/Synchronized.class b/src/main/resources/jnr/ffi/annotations/Synchronized.class new file mode 100644 index 0000000000000000000000000000000000000000..0b044744d556ba378e7a94bbf36cf060d5c19396 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/Synchronized.class differ diff --git a/src/main/resources/jnr/ffi/annotations/Transient.class b/src/main/resources/jnr/ffi/annotations/Transient.class new file mode 100644 index 0000000000000000000000000000000000000000..099fe639cb9059cd09ec3b6e8f4cfe18b3a1a7b7 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/Transient.class differ diff --git a/src/main/resources/jnr/ffi/annotations/TypeDefinition.class b/src/main/resources/jnr/ffi/annotations/TypeDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..d917bf8a2aa775afb03bace932460e1964dabcc9 Binary files /dev/null and b/src/main/resources/jnr/ffi/annotations/TypeDefinition.class differ diff --git a/src/main/resources/jnr/ffi/byref/AbstractNumberReference.class b/src/main/resources/jnr/ffi/byref/AbstractNumberReference.class new file mode 100644 index 0000000000000000000000000000000000000000..24869049d9a87e85d11439734e316f913260833d Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/AbstractNumberReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/AbstractReference.class b/src/main/resources/jnr/ffi/byref/AbstractReference.class new file mode 100644 index 0000000000000000000000000000000000000000..ad6a5a59af359791e8b24a3483fb94762bf15f50 Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/AbstractReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/AddressByReference.class b/src/main/resources/jnr/ffi/byref/AddressByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..a436a0f4cda4c1d4fc35706d652bc82372f32b3d Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/AddressByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/ByReference.class b/src/main/resources/jnr/ffi/byref/ByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..897021d1964d1d3014ec3bc0e458c345e66eef16 Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/ByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/ByteByReference.class b/src/main/resources/jnr/ffi/byref/ByteByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..576e45b11c7facf0593f705f66afece6561df74e Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/ByteByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/DoubleByReference.class b/src/main/resources/jnr/ffi/byref/DoubleByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..97ada4c1b8829f7914297416fea0d82aba13a040 Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/DoubleByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/FloatByReference.class b/src/main/resources/jnr/ffi/byref/FloatByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..9046ccda1ac93e092f0203dcf39e3b829736cccd Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/FloatByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/IntByReference.class b/src/main/resources/jnr/ffi/byref/IntByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..7261745e89ebbf766e9d2121269b23784686fbf8 Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/IntByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/LongLongByReference.class b/src/main/resources/jnr/ffi/byref/LongLongByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..314da9d6964d52d272e85098a3ab3e216339b06b Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/LongLongByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/NativeLongByReference.class b/src/main/resources/jnr/ffi/byref/NativeLongByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..c7f5dbda8f5397bb3fdd0b9bc28f5bbdd458aa46 Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/NativeLongByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/PointerByReference.class b/src/main/resources/jnr/ffi/byref/PointerByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..b8febc24134992ac970237227229e8cbffb82a57 Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/PointerByReference.class differ diff --git a/src/main/resources/jnr/ffi/byref/ShortByReference.class b/src/main/resources/jnr/ffi/byref/ShortByReference.class new file mode 100644 index 0000000000000000000000000000000000000000..10768f57ec4ef75a3dc28411eb85861bccf97d6e Binary files /dev/null and b/src/main/resources/jnr/ffi/byref/ShortByReference.class differ diff --git a/src/main/resources/jnr/ffi/mapper/AbstractDataConverter.class b/src/main/resources/jnr/ffi/mapper/AbstractDataConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..5ac855f2e0ebabfe6ffb5ebf89c700550fbebad6 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/AbstractDataConverter.class differ diff --git a/src/main/resources/jnr/ffi/mapper/DataConverter.class b/src/main/resources/jnr/ffi/mapper/DataConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..c42839cf8e36390bcea92524af0bbeee7490e725 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/DataConverter.class differ diff --git a/src/main/resources/jnr/ffi/mapper/DefaultTypeMapper.class b/src/main/resources/jnr/ffi/mapper/DefaultTypeMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..6df7e4d4ab33de80b76b5aa13dcb7f15fab64ac8 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/DefaultTypeMapper.class differ diff --git a/src/main/resources/jnr/ffi/mapper/FromNativeContext.class b/src/main/resources/jnr/ffi/mapper/FromNativeContext.class new file mode 100644 index 0000000000000000000000000000000000000000..080eb0c1e2de4d870c48a5531958b3823214cd41 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/FromNativeContext.class differ diff --git a/src/main/resources/jnr/ffi/mapper/FromNativeConverter.class b/src/main/resources/jnr/ffi/mapper/FromNativeConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..9583e374d4cfbcb6ec6fca174efd91e3b80abb31 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/FromNativeConverter.class differ diff --git a/src/main/resources/jnr/ffi/mapper/FunctionMapper$Context.class b/src/main/resources/jnr/ffi/mapper/FunctionMapper$Context.class new file mode 100644 index 0000000000000000000000000000000000000000..8911f616e06d248878dd9c1ac87b1294fee2ac1d Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/FunctionMapper$Context.class differ diff --git a/src/main/resources/jnr/ffi/mapper/FunctionMapper.class b/src/main/resources/jnr/ffi/mapper/FunctionMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..4bf5c5a7abbe51f5fc4820b9876e7125e8c7ba8d Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/FunctionMapper.class differ diff --git a/src/main/resources/jnr/ffi/mapper/MethodParameterContext.class b/src/main/resources/jnr/ffi/mapper/MethodParameterContext.class new file mode 100644 index 0000000000000000000000000000000000000000..44d219728da8cdf35513aa71f22d6069bd13098c Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/MethodParameterContext.class differ diff --git a/src/main/resources/jnr/ffi/mapper/MethodResultContext.class b/src/main/resources/jnr/ffi/mapper/MethodResultContext.class new file mode 100644 index 0000000000000000000000000000000000000000..35cce2249bc29bbc603ec3c914e50e9700f11ade Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/MethodResultContext.class differ diff --git a/src/main/resources/jnr/ffi/mapper/ToNativeContext.class b/src/main/resources/jnr/ffi/mapper/ToNativeContext.class new file mode 100644 index 0000000000000000000000000000000000000000..ea248d8c8141ccc5c6b52be6a04a1b0e16c85352 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/ToNativeContext.class differ diff --git a/src/main/resources/jnr/ffi/mapper/ToNativeConverter$PostInvocation.class b/src/main/resources/jnr/ffi/mapper/ToNativeConverter$PostInvocation.class new file mode 100644 index 0000000000000000000000000000000000000000..337c5f54950030e6732706d1cb075d8a7187f277 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/ToNativeConverter$PostInvocation.class differ diff --git a/src/main/resources/jnr/ffi/mapper/ToNativeConverter.class b/src/main/resources/jnr/ffi/mapper/ToNativeConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..1727d14d6cfe0f4e1a9b2be96f7f30b075c1d664 Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/ToNativeConverter.class differ diff --git a/src/main/resources/jnr/ffi/mapper/TypeMapper.class b/src/main/resources/jnr/ffi/mapper/TypeMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..9046689d22e95cc332ff34c5b7412902d780747e Binary files /dev/null and b/src/main/resources/jnr/ffi/mapper/TypeMapper.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$1.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$1.class new file mode 100644 index 0000000000000000000000000000000000000000..927da13f22e439ffbdd18fb7ac8ee5630fc818e6 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$ArrayIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..b8e43012414e6d6d2649cc7e42d533319edef4dd Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$ArrayIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BE32ArrayIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BE32ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..f74fcb30eca484fbb575208f2faed96a23d6f818 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BE32ArrayIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BE64ArrayIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BE64ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..fe334457e601ae78cf92fcdfdd2b60bb9b5d2f33 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BE64ArrayIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BigEndianArrayIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BigEndianArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..5b96220c2cccf53bf6410c52121629ab258d4717 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$BigEndianArrayIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LE32ArrayIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LE32ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..5910e3a02cf8fbf229e4cf2e21c7a7e4eaeaff4e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LE32ArrayIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LE64ArrayIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LE64ArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..2cae138196c155e15633ae1742bc6ae3d3506692 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LE64ArrayIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LittleEndianArrayIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LittleEndianArrayIO.class new file mode 100644 index 0000000000000000000000000000000000000000..db003f529344fcff309811c11ecc767b051b927a Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO$LittleEndianArrayIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO.class b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..f522003d114114e94bd4adf61e510eec402b78c9 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractArrayMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractBufferMemoryIO.class b/src/main/resources/jnr/ffi/provider/AbstractBufferMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..841f38b35038ad94238e822eb3ba36bbe6c2ef78 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractBufferMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractMemoryIO$1.class b/src/main/resources/jnr/ffi/provider/AbstractMemoryIO$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ad4384da26e64ff0358ec1248c6083386d076988 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractMemoryIO$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractMemoryIO.class b/src/main/resources/jnr/ffi/provider/AbstractMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..421f34f33d4b6b2084bcb712ca5373285455de98 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/AbstractRuntime.class b/src/main/resources/jnr/ffi/provider/AbstractRuntime.class new file mode 100644 index 0000000000000000000000000000000000000000..7ddee27981c3bf3edefccc5d5f52c8eca46e9796 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/AbstractRuntime.class differ diff --git a/src/main/resources/jnr/ffi/provider/BadType.class b/src/main/resources/jnr/ffi/provider/BadType.class new file mode 100644 index 0000000000000000000000000000000000000000..ce999021c34d2edb3c09af19df02c52cf9504bf6 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/BadType.class differ diff --git a/src/main/resources/jnr/ffi/provider/BoundedMemoryIO.class b/src/main/resources/jnr/ffi/provider/BoundedMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..edc92afe484642643d6e94b2a1574d4ea2494f4c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/BoundedMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/ClosureManager.class b/src/main/resources/jnr/ffi/provider/ClosureManager.class new file mode 100644 index 0000000000000000000000000000000000000000..217bc6843941d62d5f98117a331fa3e25693de5c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/ClosureManager.class differ diff --git a/src/main/resources/jnr/ffi/provider/DefaultObjectReferenceManager$ObjectReference.class b/src/main/resources/jnr/ffi/provider/DefaultObjectReferenceManager$ObjectReference.class new file mode 100644 index 0000000000000000000000000000000000000000..44e4d7705724a322f1ec40cc13095ac4294147cb Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/DefaultObjectReferenceManager$ObjectReference.class differ diff --git a/src/main/resources/jnr/ffi/provider/DefaultObjectReferenceManager.class b/src/main/resources/jnr/ffi/provider/DefaultObjectReferenceManager.class new file mode 100644 index 0000000000000000000000000000000000000000..60db20b95112da9b532ccb0e6bdb14070a3ea169 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/DefaultObjectReferenceManager.class differ diff --git a/src/main/resources/jnr/ffi/provider/DelegatingMemoryIO.class b/src/main/resources/jnr/ffi/provider/DelegatingMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..069fdea6c4f2fe8265c4d1ca161fb4314d851915 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/DelegatingMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/EnumResultConverter.class b/src/main/resources/jnr/ffi/provider/EnumResultConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..39613279b149e81d98d758c7e70ebb6462c94dce Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/EnumResultConverter.class differ diff --git a/src/main/resources/jnr/ffi/provider/IdentityFunctionMapper$SingletonHolder.class b/src/main/resources/jnr/ffi/provider/IdentityFunctionMapper$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..e01f3a5c7d6570fc8fb0c4bf72b00033d10e9ee4 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/IdentityFunctionMapper$SingletonHolder.class differ diff --git a/src/main/resources/jnr/ffi/provider/IdentityFunctionMapper.class b/src/main/resources/jnr/ffi/provider/IdentityFunctionMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..d0ebec8365707f9258710f4908b2b3139d3504e4 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/IdentityFunctionMapper.class differ diff --git a/src/main/resources/jnr/ffi/provider/InAccessibleMemoryIO.class b/src/main/resources/jnr/ffi/provider/InAccessibleMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..5dd646a16566e80ae7fe184e8459f404e42adeaf Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/InAccessibleMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/IntPointer.class b/src/main/resources/jnr/ffi/provider/IntPointer.class new file mode 100644 index 0000000000000000000000000000000000000000..4d6ad526d616b068eff1a76f77130a8e89547bc6 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/IntPointer.class differ diff --git a/src/main/resources/jnr/ffi/provider/InvocationSession$PostInvoke.class b/src/main/resources/jnr/ffi/provider/InvocationSession$PostInvoke.class new file mode 100644 index 0000000000000000000000000000000000000000..365dcb3b62038e2083689e4ed0a454c3e3adca4e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/InvocationSession$PostInvoke.class differ diff --git a/src/main/resources/jnr/ffi/provider/InvocationSession.class b/src/main/resources/jnr/ffi/provider/InvocationSession.class new file mode 100644 index 0000000000000000000000000000000000000000..c78c3e91109c51ab242f1a523eba6658d2e95977 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/InvocationSession.class differ diff --git a/src/main/resources/jnr/ffi/provider/LoadedLibrary.class b/src/main/resources/jnr/ffi/provider/LoadedLibrary.class new file mode 100644 index 0000000000000000000000000000000000000000..057f5a8e6efc7fa2fe578bf601e5e8e6b7fa580f Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/LoadedLibrary.class differ diff --git a/src/main/resources/jnr/ffi/provider/MemoryManager.class b/src/main/resources/jnr/ffi/provider/MemoryManager.class new file mode 100644 index 0000000000000000000000000000000000000000..4fab22ea23899b8a135c91dc7ee4270c46a3ae12 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/MemoryManager.class differ diff --git a/src/main/resources/jnr/ffi/provider/NullMemoryIO.class b/src/main/resources/jnr/ffi/provider/NullMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..06bb1b9ed5734d678501f2cb3b867ecc7e9d65ce Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/NullMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/NullTypeMapper.class b/src/main/resources/jnr/ffi/provider/NullTypeMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..24ea848c70391f9ab04f860f683f10631cdb0b43 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/NullTypeMapper.class differ diff --git a/src/main/resources/jnr/ffi/provider/ParameterFlags.class b/src/main/resources/jnr/ffi/provider/ParameterFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..b4c521b918efc7bd88c7ac3df46186ce9f7073e8 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/ParameterFlags.class differ diff --git a/src/main/resources/jnr/ffi/provider/ShareMemoryIO.class b/src/main/resources/jnr/ffi/provider/ShareMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..108e1b963c48377c4a567a8eaa5f8caeadd8ec80 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/ShareMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AbstractAsmLibraryInterface.class b/src/main/resources/jnr/ffi/provider/jffi/AbstractAsmLibraryInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..b5734a14f908dd41bd6f5a1cd7ac793e656f21f0 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AbstractAsmLibraryInterface.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AbstractDirectPointerParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/AbstractDirectPointerParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..24df74b27a696c045ebfb111441fd6990f0ae6c9 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AbstractDirectPointerParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AbstractFastNumericMethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/AbstractFastNumericMethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..c40ffece79ac6e88fc1f4af5dc6c3d8074347528 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AbstractFastNumericMethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$PageHolder.class b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$PageHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..195f3c7ae2400ad303b4e38472c4d08085310c40 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$PageHolder.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$StaticDataHolder.class b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$StaticDataHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..f8a46d287487ee3335fc5993ee49cae19c350035 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$StaticDataHolder.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$Stub.class b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$Stub.class new file mode 100644 index 0000000000000000000000000000000000000000..3e0974e1c2ce57c5ff32587209db7515ef4891e1 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler$Stub.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler.class b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..309d287d5c95d5908ed3ba259454c66b8660fe2d Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AbstractX86StubCompiler.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AllocatedDirectMemoryIO.class b/src/main/resources/jnr/ffi/provider/jffi/AllocatedDirectMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..2c8b148e0ad5a964911907e39961a67f51358bf2 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AllocatedDirectMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ArrayMemoryIO.class b/src/main/resources/jnr/ffi/provider/jffi/ArrayMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..b4f88d400006d2ca479095d55d65b0cc8c0a3fe2 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ArrayMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ArrayMemoryParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/ArrayMemoryParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..1cad591ad78972633bec21815cb61f6b267ecfe3 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ArrayMemoryParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder$ObjectField.class b/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder$ObjectField.class new file mode 100644 index 0000000000000000000000000000000000000000..570e5e4a65928e5db710ae7e035d8276d1994024 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder$ObjectField.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder$ObjectNameGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder$ObjectNameGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..3fa4232ca3be537d680e1fa290c0bedc9d5119f1 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder$ObjectNameGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder.class b/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..445d1d1f8d14e2ed8701149c01269d8d10518e66 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmBuilder.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmClassLoader.class b/src/main/resources/jnr/ffi/provider/jffi/AsmClassLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..de49503fa09613adfad163b64d50a8e18278aac0 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmClassLoader.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmLibraryLoader.class b/src/main/resources/jnr/ffi/provider/jffi/AsmLibraryLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..7c35fd19992c338ad1a2d43fdc89638a83e51fa9 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmLibraryLoader.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$1.class b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c077bb0e726145289b26ca4eb5c9b82cfc7beab8 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$2.class b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$2.class new file mode 100644 index 0000000000000000000000000000000000000000..9064c0631059c10b2a1818af210a1b30515d0b69 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$2.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$3.class b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$3.class new file mode 100644 index 0000000000000000000000000000000000000000..a041ba679610c833e7f7225dfc957f0967c4b036 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$3.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$4.class b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$4.class new file mode 100644 index 0000000000000000000000000000000000000000..8e70cb981c6494c91a61cac6b8889aa94924c05b Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$4.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$5.class b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$5.class new file mode 100644 index 0000000000000000000000000000000000000000..ef96f3289d3d5795d46b817a19b573b51b364cbf Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$5.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$6.class b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$6.class new file mode 100644 index 0000000000000000000000000000000000000000..593ad4af66f47e21dd30f2155040d11846bd81d3 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime$6.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime.class b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime.class new file mode 100644 index 0000000000000000000000000000000000000000..951169318863e258b63b37f2dcc9818f8bc6b709 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmRuntime.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmUtil$1.class b/src/main/resources/jnr/ffi/provider/jffi/AsmUtil$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5b7b7ce894d7d224ea0ad18fb486b83c9bff127a Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmUtil$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/AsmUtil.class b/src/main/resources/jnr/ffi/provider/jffi/AsmUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..88acbdfa6416953537f7994b96c09f29246a4b7b Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/AsmUtil.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/BaseMethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/BaseMethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..a7bf69b54a606e5a0f55497b24b6fbda07253620 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/BaseMethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/BufferMethodGenerator$1.class b/src/main/resources/jnr/ffi/provider/jffi/BufferMethodGenerator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cf9a83980a6d92e373d6d3a1b386176b304495a3 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/BufferMethodGenerator$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/BufferMethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/BufferMethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..9fc62577499a01614fce8c9d19df9b6bbb9a8a48 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/BufferMethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ByReferenceParameterConverter.class b/src/main/resources/jnr/ffi/provider/jffi/ByReferenceParameterConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..2517c6db500dd778a758c902d3499e81a99728ed Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ByReferenceParameterConverter.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ByteBufferMemoryIO.class b/src/main/resources/jnr/ffi/provider/jffi/ByteBufferMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..2bd978130a8466f0571dcb78a3a0456268f41900 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ByteBufferMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ClosureUtil.class b/src/main/resources/jnr/ffi/provider/jffi/ClosureUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..37772262729901317569377ca39353b551fff566 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ClosureUtil.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/CodegenUtils.class b/src/main/resources/jnr/ffi/provider/jffi/CodegenUtils.class new file mode 100644 index 0000000000000000000000000000000000000000..218f0ef3ed64a99dbc7a8c907be67fbf3affd541 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/CodegenUtils.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/DirectBufferMemoryParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/DirectBufferMemoryParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..b85caf3b0915ab1a0f9b07a62e4468aaa0e63b9c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/DirectBufferMemoryParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/DirectBufferParameterStrategy$1.class b/src/main/resources/jnr/ffi/provider/jffi/DirectBufferParameterStrategy$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f50892bf1ac573d8f5a4bcb55386e99707221ee5 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/DirectBufferParameterStrategy$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/DirectBufferParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/DirectBufferParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..7ec2dd7e467be9bfd0573409cf0372055d03064b Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/DirectBufferParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/DirectMemoryIO.class b/src/main/resources/jnr/ffi/provider/jffi/DirectMemoryIO.class new file mode 100644 index 0000000000000000000000000000000000000000..f3fe38b0128450c7143bb350512ebd94119bc6c3 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/DirectMemoryIO.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/DirectMemoryParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/DirectMemoryParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..87b4aef779b66869357d3eedde3b148dffca357e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/DirectMemoryParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/DirectPointerParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/DirectPointerParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..250bdfb380dc0132414a0b6b6403f8d0646fea3f Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/DirectPointerParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/DirectStructParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/DirectStructParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..b9a7e338259549bb6775f10a1cabf58f8e6cc85a Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/DirectStructParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/FastIntMethodGenerator$1.class b/src/main/resources/jnr/ffi/provider/jffi/FastIntMethodGenerator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fd5d1fb658f77f4470c6f9c73cff6bdc7ed06ef7 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/FastIntMethodGenerator$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/FastIntMethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/FastIntMethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..39ac0c468c5c3ec2297cf9ba19d081399eeecdd6 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/FastIntMethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/FastLongMethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/FastLongMethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..278be9949077a25e03b37824840a6ebdfca8d86d Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/FastLongMethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/FastNumericMethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/FastNumericMethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..f116d2bd44e8ae2390e725e8b8637f599c9e8401 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/FastNumericMethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/FromNativeType.class b/src/main/resources/jnr/ffi/provider/jffi/FromNativeType.class new file mode 100644 index 0000000000000000000000000000000000000000..973ead82cb8247c3d4d9b7ec81b5e696eca4a684 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/FromNativeType.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/HeapBufferMemoryParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/HeapBufferMemoryParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..1ab3cd23e982f73a2415b2f69db6f49214807d70 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/HeapBufferMemoryParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/HeapBufferParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/HeapBufferParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..45e57fabf2a91589dff0a309560efc2cffba9d52 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/HeapBufferParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/HeapStructParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/HeapStructParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..d2155f373342ea1437eaf1dccfa1cd341cc786a9 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/HeapStructParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/InvokerUtil$1.class b/src/main/resources/jnr/ffi/provider/jffi/InvokerUtil$1.class new file mode 100644 index 0000000000000000000000000000000000000000..989f1d605dbece2d89d47f5555379d0fcb328f50 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/InvokerUtil$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/InvokerUtil.class b/src/main/resources/jnr/ffi/provider/jffi/InvokerUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..9d95b1d8d37f6ab17f8683bcdfaba0955fb56bc7 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/InvokerUtil.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/JNIInvokeInterface.class b/src/main/resources/jnr/ffi/provider/jffi/JNIInvokeInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..4345935c58390cbdb47f2a58cad8701eaeb0887e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/JNIInvokeInterface.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/JNINativeInterface.class b/src/main/resources/jnr/ffi/provider/jffi/JNINativeInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..f9fd0c0c5073b8b43031d86188eaf68a3d77344c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/JNINativeInterface.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/LibraryLoader.class b/src/main/resources/jnr/ffi/provider/jffi/LibraryLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..e3fca578b8df999cc94739260813eca9c5b80dfe Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/LibraryLoader.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/LocalVariable.class b/src/main/resources/jnr/ffi/provider/jffi/LocalVariable.class new file mode 100644 index 0000000000000000000000000000000000000000..816d8fd2b80d814c030fbd486074043bec21b305 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/LocalVariable.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/LocalVariableAllocator.class b/src/main/resources/jnr/ffi/provider/jffi/LocalVariableAllocator.class new file mode 100644 index 0000000000000000000000000000000000000000..6be35de6998b48ebc740a785fc376e806890036a Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/LocalVariableAllocator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/MemoryUtil.class b/src/main/resources/jnr/ffi/provider/jffi/MemoryUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..fe2491e79617077df6e66554b3c2f72d36696375 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/MemoryUtil.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/MethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/MethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..2ed862d922153b5e8841d8b4e0cd394419a9f376 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/MethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory$1.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory$1.class new file mode 100644 index 0000000000000000000000000000000000000000..947014c95082bdf51faa5b5b42c9f25cd52689eb Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory$ClosureReference.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory$ClosureReference.class new file mode 100644 index 0000000000000000000000000000000000000000..c5830ccf45add016b6adda211f42a9ee3ddf123e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory$ClosureReference.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..a2116fa15785d4bf099e281029c862fa9928a586 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureFactory.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager$1.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a496275f83cd6e118044c75c65359c22ffe56d6d Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager$ClosureSite.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager$ClosureSite.class new file mode 100644 index 0000000000000000000000000000000000000000..ba3f10375cccd138999669c7b594d00bcb06fced Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager$ClosureSite.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager.class new file mode 100644 index 0000000000000000000000000000000000000000..03bcb8a59695ff1856709690d210b8b2a031d1a1 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureManager.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosurePointer.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosurePointer.class new file mode 100644 index 0000000000000000000000000000000000000000..74609eca2b06fb2be53d2f2db414acf114e86ce6 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosurePointer.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy$1.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8bc962bbe33b1c12634ad9da7b576bb3368a7b25 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy$Factory.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy$Factory.class new file mode 100644 index 0000000000000000000000000000000000000000..656431cec5958b8e226a77254418d55ed6eeabf5 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy$Factory.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy.class b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..3f86f628bef4cc2598ab77783f1f8be9cd00954e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeClosureProxy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeFinalizer$SingletonHolder.class b/src/main/resources/jnr/ffi/provider/jffi/NativeFinalizer$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..10142b1142f58287aaf3306b2b449bd71bb4800a Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeFinalizer$SingletonHolder.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeFinalizer.class b/src/main/resources/jnr/ffi/provider/jffi/NativeFinalizer.class new file mode 100644 index 0000000000000000000000000000000000000000..a4835129478b2c2e1e4afef8c10ce494a9854146 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeFinalizer.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeLibrary$StaticDataHolder.class b/src/main/resources/jnr/ffi/provider/jffi/NativeLibrary$StaticDataHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..034f91df9e462ec089508fa9d8f1ca7445aa4a04 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeLibrary$StaticDataHolder.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeLibrary.class b/src/main/resources/jnr/ffi/provider/jffi/NativeLibrary.class new file mode 100644 index 0000000000000000000000000000000000000000..d6463ed5210b22e77693e4d9e610dc375e701679 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeLibrary.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeMemoryManager.class b/src/main/resources/jnr/ffi/provider/jffi/NativeMemoryManager.class new file mode 100644 index 0000000000000000000000000000000000000000..3cef93ea358a5f88e0488788f65ef7c97ee91190 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeMemoryManager.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$1.class b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$1.class new file mode 100644 index 0000000000000000000000000000000000000000..646824939f6b743c849c2f3bc7794504df7a6953 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$SingletonHolder.class b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..eaf96c7e0cc5fab3231ddd304df7b5c6d58e9f19 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$SingletonHolder.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$TypeDelegate.class b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$TypeDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..0d9cba05f11257b5a4817426313eba05c8c5b3e2 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime$TypeDelegate.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime.class b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime.class new file mode 100644 index 0000000000000000000000000000000000000000..77b5f78033ea9527fcd579eea5ee92b944918f8c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NativeRuntime.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NoTrace.class b/src/main/resources/jnr/ffi/provider/jffi/NoTrace.class new file mode 100644 index 0000000000000000000000000000000000000000..0a7385a91bbf8d6f660624270e453e2f5dff237b Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NoTrace.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NoX86.class b/src/main/resources/jnr/ffi/provider/jffi/NoX86.class new file mode 100644 index 0000000000000000000000000000000000000000..1231009b0eb71b3eda8deea2b482c635fb93f5f2 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NoX86.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NotImplMethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/NotImplMethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..1edfa522199f2d519a36c137cd289fa3d19e9444 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NotImplMethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NullPointerParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/NullPointerParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..da9fc8e68e827398555a6a19f6556df522f09b17 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NullPointerParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NumberUtil$1.class b/src/main/resources/jnr/ffi/provider/jffi/NumberUtil$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0b78c8af46d0bbd9fd9933f63bed0380ad4a1bec Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NumberUtil$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/NumberUtil.class b/src/main/resources/jnr/ffi/provider/jffi/NumberUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..c6dfc8ea1538d7d6e5526cb50b186df23ffad89f Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/NumberUtil.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ParameterConverter.class b/src/main/resources/jnr/ffi/provider/jffi/ParameterConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..5acdd7a8fe2459e6ced35211d3115c507363f9ff Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ParameterConverter.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ParameterType.class b/src/main/resources/jnr/ffi/provider/jffi/ParameterType.class new file mode 100644 index 0000000000000000000000000000000000000000..7ff9fc92b2a1e9093c38c7c20fd06d4e2d5de861 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ParameterType.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PointerParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/PointerParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..2a6dbaf16f197724f6d94bdf7cf258d913bb5c23 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PointerParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$1.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2edc71cbc9e688c6d0bc63bc0540b878ba5b1ad8 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$2.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$2.class new file mode 100644 index 0000000000000000000000000000000000000000..b8e87f6ced60c10a641cda03e833dd1ba6744691 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$2.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$3.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$3.class new file mode 100644 index 0000000000000000000000000000000000000000..4d73a495365443fdcfd741b7e4c371b610351f14 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$3.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$4.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$4.class new file mode 100644 index 0000000000000000000000000000000000000000..40c0847d33e927e81aaada821306725b7631d91a Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$4.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$5.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$5.class new file mode 100644 index 0000000000000000000000000000000000000000..6468d26b84ce4c8693ead86a8d826aa65d0df520 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$5.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$6.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$6.class new file mode 100644 index 0000000000000000000000000000000000000000..25b9edcaece179279c7752c8963fef0c9e4c2193 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$6.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$7.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$7.class new file mode 100644 index 0000000000000000000000000000000000000000..b6f35d8490746c116ecf631fa5bc38c2c1bc3efe Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$7.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$8.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$8.class new file mode 100644 index 0000000000000000000000000000000000000000..801218a540c0c0274de8baedcd6df790eb29ca56 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy$8.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..84f00746f9cefccdc17219c7dd3aeebef6db87af Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/Provider.class b/src/main/resources/jnr/ffi/provider/jffi/Provider.class new file mode 100644 index 0000000000000000000000000000000000000000..f161cad310c3d3e5634a670dafba76a6148d4920 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/Provider.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ResultConverter.class b/src/main/resources/jnr/ffi/provider/jffi/ResultConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..ae7652d93f74ff02d12b156f1b0ae38ae7ad806d Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ResultConverter.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ResultType.class b/src/main/resources/jnr/ffi/provider/jffi/ResultType.class new file mode 100644 index 0000000000000000000000000000000000000000..98ceae2acb7caf0b149f5f49360f459f646be451 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ResultType.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/SigType.class b/src/main/resources/jnr/ffi/provider/jffi/SigType.class new file mode 100644 index 0000000000000000000000000000000000000000..e7bc4a6492c37b619980bf7b79649691506b8652 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/SigType.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/Signature.class b/src/main/resources/jnr/ffi/provider/jffi/Signature.class new file mode 100644 index 0000000000000000000000000000000000000000..0523368f304fdce251c6bdfeaaa31266adaf6481 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/Signature.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/SkinnyMethodAdapter.class b/src/main/resources/jnr/ffi/provider/jffi/SkinnyMethodAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..8a30084a445561eb8a6ca9152433f5453ac6331b Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/SkinnyMethodAdapter.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/StringParameterStrategy.class b/src/main/resources/jnr/ffi/provider/jffi/StringParameterStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..1b1ce0617e5ae039a5e7e0cf61c3472ccab459db Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/StringParameterStrategy.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/StubCompiler$1.class b/src/main/resources/jnr/ffi/provider/jffi/StubCompiler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..472ee12ba9675ad981edbebaa27a84b6d2492f37 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/StubCompiler$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/StubCompiler$DummyStubCompiler.class b/src/main/resources/jnr/ffi/provider/jffi/StubCompiler$DummyStubCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..54150513eae83646e585f1595c731f576320181a Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/StubCompiler$DummyStubCompiler.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/StubCompiler.class b/src/main/resources/jnr/ffi/provider/jffi/StubCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..32c49cd083ece591a71ae5c7f8d3790d72d42dda Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/StubCompiler.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/SymbolNotFoundError.class b/src/main/resources/jnr/ffi/provider/jffi/SymbolNotFoundError.class new file mode 100644 index 0000000000000000000000000000000000000000..dcf7c9106ce73f4835d3eb3c84aefde5888343a3 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/SymbolNotFoundError.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/ToNativeType.class b/src/main/resources/jnr/ffi/provider/jffi/ToNativeType.class new file mode 100644 index 0000000000000000000000000000000000000000..40fd670fd7d2d062851990288c73b2d2edd12ca1 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/ToNativeType.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$1.class b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$1.class new file mode 100644 index 0000000000000000000000000000000000000000..57c4e043ef1768fc0a3cb798b3985fd607dcea03 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$Magazine.class b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$Magazine.class new file mode 100644 index 0000000000000000000000000000000000000000..84532662273a8bc0ad2fbe0d12cbda684e8966a7 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$Magazine.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$Sentinel.class b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$Sentinel.class new file mode 100644 index 0000000000000000000000000000000000000000..691832eda78b36a56b0aeca8e2c8f0aaefb605ab Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory$Sentinel.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory.class b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory.class new file mode 100644 index 0000000000000000000000000000000000000000..66e15ec8c2c2a59d0bdf4c406e9a24bbfd498ce1 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/TransientNativeMemory.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$Mode.class b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$Mode.class new file mode 100644 index 0000000000000000000000000000000000000000..dacedb2f76c5c92194a5c0c3075557373fa22149 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$Mode.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$SingletonHolder.class b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..0f718d576a5caaedddbed60e57d006b739bb6e53 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$SingletonHolder.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$Syntax.class b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$Syntax.class new file mode 100644 index 0000000000000000000000000000000000000000..77bf30daf6e8493e9da9e7b4d6aaf23ab49a5784 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$Syntax.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$UDis86.class b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$UDis86.class new file mode 100644 index 0000000000000000000000000000000000000000..610ea523e6630243bf04029bf42c44246835ac9d Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$UDis86.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$X86DisassemblerConverter.class b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$X86DisassemblerConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..b2c6c14a81a68a66be1021bce6f703978b82750c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler$X86DisassemblerConverter.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler.class b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler.class new file mode 100644 index 0000000000000000000000000000000000000000..77c2953938199761783d9b0b0ce4caf2fb9b6cb6 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86Disassembler.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86MethodGenerator$1.class b/src/main/resources/jnr/ffi/provider/jffi/X86MethodGenerator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..40a77a35fa0ce82d498b6cdba598d13a8430cd80 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86MethodGenerator$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86MethodGenerator.class b/src/main/resources/jnr/ffi/provider/jffi/X86MethodGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..6d76afc0425c552b1967d4c34d96163a2bb1b8a0 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86MethodGenerator.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86_32StubCompiler$1.class b/src/main/resources/jnr/ffi/provider/jffi/X86_32StubCompiler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6f7ef290747921480f0a4421d039ac16c5d49f32 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86_32StubCompiler$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86_32StubCompiler.class b/src/main/resources/jnr/ffi/provider/jffi/X86_32StubCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..64b7fae7a0f5884409cb538380a591f028bb8b0c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86_32StubCompiler.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86_64StubCompiler$1.class b/src/main/resources/jnr/ffi/provider/jffi/X86_64StubCompiler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..af4a9bf7c67ccdb82a9ec5ba9264810c4722d864 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86_64StubCompiler$1.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/X86_64StubCompiler.class b/src/main/resources/jnr/ffi/provider/jffi/X86_64StubCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..5ae139852e7ff77a008574b68bbfa41762a3feb0 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/X86_64StubCompiler.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/arm/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/arm/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..cb65938cf5a5c5963607af56bf0141767055c04d Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/arm/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/i386/darwin/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/darwin/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..b7c76c30f419c87dc957a13aa6ae92c41f77cf01 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/darwin/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/i386/freebsd/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/freebsd/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..37f41e6472a1ae503ddff6aad4262f7c13d1eee2 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/freebsd/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/i386/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..b3050994a695b5bc5534d6158d50ca4d5abe9c03 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/i386/openbsd/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/openbsd/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..0645fcffe47a1f00151227998c270228129813e3 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/openbsd/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/i386/solaris/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/solaris/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..ccf24cf539cf4b4cb55da674e7375241b67b3d71 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/solaris/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/i386/windows/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/windows/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..d82883977d441d2ef39edc9a0fa61ab66e50e198 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/i386/windows/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/mips/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/mips/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..47e16fa7cf8ebd7c316ee4260e41f6ca1feff487 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/mips/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/mipsel/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/mipsel/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..8d0db9125fbb12588509d365fff90d0199c95596 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/mipsel/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/aix/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/aix/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..6f30eb40c3e3f1c4c7bf297b749d73c69b8490dc Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/aix/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/darwin/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/darwin/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..b45f6848b1722199967dbb97f024f30ef30a7714 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/darwin/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..c46e289873ebffa6afdb02ef22ea05e1e8d170e4 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/powerpc/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/s390/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/s390/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..153d61ca2a97bc58d3557574b21baf941483780e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/s390/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/s390x/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/s390x/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..55ef59f4f380562ed36a38022bd1f72513dd40ba Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/s390x/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/sparc/solaris/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/sparc/solaris/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..ad7e6e4a59ddc8f951576705622451b090352d83 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/sparc/solaris/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/sparcv9/solaris/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/sparcv9/solaris/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..0aaac874e48973f0d41c21573fbccf442706ce3c Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/sparcv9/solaris/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/darwin/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/darwin/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..67dbccf7cd667a6dd7d71d52be9e33a2fd4302f3 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/darwin/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/freebsd/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/freebsd/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..8c98e227fc8853c48d339d06e17028a02bf872c4 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/freebsd/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/linux/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/linux/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..4c8dde64e161fd56039bdb9a5d23ef8bdab2ca7f Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/linux/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/openbsd/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/openbsd/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..f3452a03cbbe27a9aee4c685c7031b3763f9902e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/openbsd/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/solaris/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/solaris/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..79ae28798b2619911e4751432b276d1f40608159 Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/solaris/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/windows/TypeAliases.class b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/windows/TypeAliases.class new file mode 100644 index 0000000000000000000000000000000000000000..f151a129af382dd32f925b509ee3837b37001c7e Binary files /dev/null and b/src/main/resources/jnr/ffi/provider/jffi/platform/x86_64/windows/TypeAliases.class differ diff --git a/src/main/resources/jnr/ffi/types/blkcnt_t.class b/src/main/resources/jnr/ffi/types/blkcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..79c0b2877f6a2a61513d106428a252e5bca37bb3 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/blkcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/types/blksize_t.class b/src/main/resources/jnr/ffi/types/blksize_t.class new file mode 100644 index 0000000000000000000000000000000000000000..4c584269744e1c8e1f52f23f52edd035580e874d Binary files /dev/null and b/src/main/resources/jnr/ffi/types/blksize_t.class differ diff --git a/src/main/resources/jnr/ffi/types/caddr_t.class b/src/main/resources/jnr/ffi/types/caddr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..6fa09db0a56b1c88c026974d7e774a5cef205c8b Binary files /dev/null and b/src/main/resources/jnr/ffi/types/caddr_t.class differ diff --git a/src/main/resources/jnr/ffi/types/clock_t.class b/src/main/resources/jnr/ffi/types/clock_t.class new file mode 100644 index 0000000000000000000000000000000000000000..1a8e4b44371b41a12e955fb0b077685f6d92311f Binary files /dev/null and b/src/main/resources/jnr/ffi/types/clock_t.class differ diff --git a/src/main/resources/jnr/ffi/types/dev_t.class b/src/main/resources/jnr/ffi/types/dev_t.class new file mode 100644 index 0000000000000000000000000000000000000000..112e03cbd6f919cb5970ae2f44c0ec6768e7b6a5 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/dev_t.class differ diff --git a/src/main/resources/jnr/ffi/types/fsblkcnt_t.class b/src/main/resources/jnr/ffi/types/fsblkcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..75c8ebe5cf83c9494871b2bf7a2cbdb944f7f260 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/fsblkcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/types/fsfilcnt_t.class b/src/main/resources/jnr/ffi/types/fsfilcnt_t.class new file mode 100644 index 0000000000000000000000000000000000000000..d45bb2de1d31a23d61b3d2ac0332cae70336b916 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/fsfilcnt_t.class differ diff --git a/src/main/resources/jnr/ffi/types/gid_t.class b/src/main/resources/jnr/ffi/types/gid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..50e422117d37f2a526929a26b72674127c7ec14d Binary files /dev/null and b/src/main/resources/jnr/ffi/types/gid_t.class differ diff --git a/src/main/resources/jnr/ffi/types/id_t.class b/src/main/resources/jnr/ffi/types/id_t.class new file mode 100644 index 0000000000000000000000000000000000000000..46ba5190ef8103e67d9b28acc5d9a56ca4541633 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/id_t.class differ diff --git a/src/main/resources/jnr/ffi/types/in_addr_t.class b/src/main/resources/jnr/ffi/types/in_addr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..7781823ec5bde076bf0858baca16db2945cc75c1 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/in_addr_t.class differ diff --git a/src/main/resources/jnr/ffi/types/in_port_t.class b/src/main/resources/jnr/ffi/types/in_port_t.class new file mode 100644 index 0000000000000000000000000000000000000000..45c8b62e97081ad70d05c31058c9681fa3977e56 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/in_port_t.class differ diff --git a/src/main/resources/jnr/ffi/types/ino64_t.class b/src/main/resources/jnr/ffi/types/ino64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..f902faf7e90e019e3bb88071ba77e8b4767ff414 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/ino64_t.class differ diff --git a/src/main/resources/jnr/ffi/types/ino_t.class b/src/main/resources/jnr/ffi/types/ino_t.class new file mode 100644 index 0000000000000000000000000000000000000000..b5f6ea4f9eb43abeb1a6895647dea444df8dbd86 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/ino_t.class differ diff --git a/src/main/resources/jnr/ffi/types/int16_t.class b/src/main/resources/jnr/ffi/types/int16_t.class new file mode 100644 index 0000000000000000000000000000000000000000..a2e982e252d561e5bc3ed3cc7cfb37886c98794e Binary files /dev/null and b/src/main/resources/jnr/ffi/types/int16_t.class differ diff --git a/src/main/resources/jnr/ffi/types/int32_t.class b/src/main/resources/jnr/ffi/types/int32_t.class new file mode 100644 index 0000000000000000000000000000000000000000..58ec4596f269f04d97f752944232565436549a3b Binary files /dev/null and b/src/main/resources/jnr/ffi/types/int32_t.class differ diff --git a/src/main/resources/jnr/ffi/types/int64_t.class b/src/main/resources/jnr/ffi/types/int64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..2465120d767e20647dcb3788e9b18f46fe34bafd Binary files /dev/null and b/src/main/resources/jnr/ffi/types/int64_t.class differ diff --git a/src/main/resources/jnr/ffi/types/int8_t.class b/src/main/resources/jnr/ffi/types/int8_t.class new file mode 100644 index 0000000000000000000000000000000000000000..909f86561cfb3d3004f6579ff22c0a9eee7e96d0 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/int8_t.class differ diff --git a/src/main/resources/jnr/ffi/types/intptr_t.class b/src/main/resources/jnr/ffi/types/intptr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..7c829f8c593068b92c6372b059bb747eca24168f Binary files /dev/null and b/src/main/resources/jnr/ffi/types/intptr_t.class differ diff --git a/src/main/resources/jnr/ffi/types/key_t.class b/src/main/resources/jnr/ffi/types/key_t.class new file mode 100644 index 0000000000000000000000000000000000000000..13aa9468ed42b7bcee802d457d6e9ee84e1b7a3e Binary files /dev/null and b/src/main/resources/jnr/ffi/types/key_t.class differ diff --git a/src/main/resources/jnr/ffi/types/mode_t.class b/src/main/resources/jnr/ffi/types/mode_t.class new file mode 100644 index 0000000000000000000000000000000000000000..f2cc249462d4c41800e1005077e195b54ed458a0 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/mode_t.class differ diff --git a/src/main/resources/jnr/ffi/types/nlink_t.class b/src/main/resources/jnr/ffi/types/nlink_t.class new file mode 100644 index 0000000000000000000000000000000000000000..06bcfc0b61609d4aa71972ca8c6d7def1339be14 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/nlink_t.class differ diff --git a/src/main/resources/jnr/ffi/types/off_t.class b/src/main/resources/jnr/ffi/types/off_t.class new file mode 100644 index 0000000000000000000000000000000000000000..16dbdda4ca15af5f895765897ac8244427285ff4 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/off_t.class differ diff --git a/src/main/resources/jnr/ffi/types/pid_t.class b/src/main/resources/jnr/ffi/types/pid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..c2e1d0d245ec1624b98d2e5938914347839c4517 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/pid_t.class differ diff --git a/src/main/resources/jnr/ffi/types/rlim_t.class b/src/main/resources/jnr/ffi/types/rlim_t.class new file mode 100644 index 0000000000000000000000000000000000000000..f61bafd0efa8fd3ed22b6ed093ab2de8d784b956 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/rlim_t.class differ diff --git a/src/main/resources/jnr/ffi/types/sa_family_t.class b/src/main/resources/jnr/ffi/types/sa_family_t.class new file mode 100644 index 0000000000000000000000000000000000000000..a10d23f6205c104b17b7ceb34df812f2de4196d2 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/sa_family_t.class differ diff --git a/src/main/resources/jnr/ffi/types/size_t.class b/src/main/resources/jnr/ffi/types/size_t.class new file mode 100644 index 0000000000000000000000000000000000000000..c11cf7251a8806b6efd46749f1069cab262163d5 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/size_t.class differ diff --git a/src/main/resources/jnr/ffi/types/socklen_t.class b/src/main/resources/jnr/ffi/types/socklen_t.class new file mode 100644 index 0000000000000000000000000000000000000000..3eb82583075a60cac63e6baba3256ff9fb1e0153 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/socklen_t.class differ diff --git a/src/main/resources/jnr/ffi/types/ssize_t.class b/src/main/resources/jnr/ffi/types/ssize_t.class new file mode 100644 index 0000000000000000000000000000000000000000..36ef36eda747ca014040e4b64a254e994e57e8da Binary files /dev/null and b/src/main/resources/jnr/ffi/types/ssize_t.class differ diff --git a/src/main/resources/jnr/ffi/types/swblk_t.class b/src/main/resources/jnr/ffi/types/swblk_t.class new file mode 100644 index 0000000000000000000000000000000000000000..46d49fa31464d00a007991430b471cb7eef05b25 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/swblk_t.class differ diff --git a/src/main/resources/jnr/ffi/types/time_t.class b/src/main/resources/jnr/ffi/types/time_t.class new file mode 100644 index 0000000000000000000000000000000000000000..d679c439a6faec374e64aee81adf4fe7649150b5 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/time_t.class differ diff --git a/src/main/resources/jnr/ffi/types/u_int16_t.class b/src/main/resources/jnr/ffi/types/u_int16_t.class new file mode 100644 index 0000000000000000000000000000000000000000..5131580a24cb15a226ffe70adf991e0a40798fed Binary files /dev/null and b/src/main/resources/jnr/ffi/types/u_int16_t.class differ diff --git a/src/main/resources/jnr/ffi/types/u_int32_t.class b/src/main/resources/jnr/ffi/types/u_int32_t.class new file mode 100644 index 0000000000000000000000000000000000000000..093f800950538387e9b105b2a40003891a4d2cdd Binary files /dev/null and b/src/main/resources/jnr/ffi/types/u_int32_t.class differ diff --git a/src/main/resources/jnr/ffi/types/u_int64_t.class b/src/main/resources/jnr/ffi/types/u_int64_t.class new file mode 100644 index 0000000000000000000000000000000000000000..2fafce30b58022c76ef4461d006a5b4c452baebb Binary files /dev/null and b/src/main/resources/jnr/ffi/types/u_int64_t.class differ diff --git a/src/main/resources/jnr/ffi/types/u_int8_t.class b/src/main/resources/jnr/ffi/types/u_int8_t.class new file mode 100644 index 0000000000000000000000000000000000000000..b7c5e302d8cb8bf053114991875c755aa040a3d0 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/u_int8_t.class differ diff --git a/src/main/resources/jnr/ffi/types/uid_t.class b/src/main/resources/jnr/ffi/types/uid_t.class new file mode 100644 index 0000000000000000000000000000000000000000..d429537af493e0d12d4eb543207c03450dd7a481 Binary files /dev/null and b/src/main/resources/jnr/ffi/types/uid_t.class differ diff --git a/src/main/resources/jnr/ffi/types/uintptr_t.class b/src/main/resources/jnr/ffi/types/uintptr_t.class new file mode 100644 index 0000000000000000000000000000000000000000..b67733b21f290bbe9dd5432d98101a2347b17dad Binary files /dev/null and b/src/main/resources/jnr/ffi/types/uintptr_t.class differ diff --git a/src/main/resources/jnr/ffi/util/BufferUtil.class b/src/main/resources/jnr/ffi/util/BufferUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..6cf4961f34c4b453f76bcc0a95efbe9c94800ba4 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/BufferUtil.class differ diff --git a/src/main/resources/jnr/ffi/util/EnumMapper$IntegerEnum.class b/src/main/resources/jnr/ffi/util/EnumMapper$IntegerEnum.class new file mode 100644 index 0000000000000000000000000000000000000000..147909ced52ec325f68bedf6ea7bc91e8974299c Binary files /dev/null and b/src/main/resources/jnr/ffi/util/EnumMapper$IntegerEnum.class differ diff --git a/src/main/resources/jnr/ffi/util/EnumMapper$StaticDataHolder.class b/src/main/resources/jnr/ffi/util/EnumMapper$StaticDataHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..d84653a7dce4f06b3142b22c39df5bda6a43f49a Binary files /dev/null and b/src/main/resources/jnr/ffi/util/EnumMapper$StaticDataHolder.class differ diff --git a/src/main/resources/jnr/ffi/util/EnumMapper.class b/src/main/resources/jnr/ffi/util/EnumMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..c1c42d66674fe49231d8f393ade8c6631d0e7267 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/EnumMapper.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizablePhantomReference.class b/src/main/resources/jnr/ffi/util/ref/FinalizablePhantomReference.class new file mode 100644 index 0000000000000000000000000000000000000000..3357091381ff84eef7b7e624f9e89de6e57b4a3e Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizablePhantomReference.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableReference.class b/src/main/resources/jnr/ffi/util/ref/FinalizableReference.class new file mode 100644 index 0000000000000000000000000000000000000000..7452ee04ab50e6bfb48bba00d5a7d603e1f23376 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableReference.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$DecoupledLoader.class b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$DecoupledLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..a49468481222d68161d5dd70f74a80d0121feea2 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$DecoupledLoader.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$DirectLoader.class b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$DirectLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..6d025a1df5bc840890f32303b098f7c1472c0564 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$DirectLoader.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$FinalizerLoader.class b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$FinalizerLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..cca956b418cd0cf7e8bb33f3c2367e3a27c56ab5 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$FinalizerLoader.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$SystemLoader.class b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$SystemLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..b09b69471deaef39e2627d9587a073e82c17a355 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue$SystemLoader.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue.class b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..b332b9554036dc0b305757e54abca7c9b72efaa5 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableReferenceQueue.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableSoftReference.class b/src/main/resources/jnr/ffi/util/ref/FinalizableSoftReference.class new file mode 100644 index 0000000000000000000000000000000000000000..ecbabbc9e3ccc34daac931034126f15ba3212768 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableSoftReference.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/FinalizableWeakReference.class b/src/main/resources/jnr/ffi/util/ref/FinalizableWeakReference.class new file mode 100644 index 0000000000000000000000000000000000000000..8bdc2e0a186f728d1630ed597927d4f623794035 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/FinalizableWeakReference.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/internal/Finalizer$1.class b/src/main/resources/jnr/ffi/util/ref/internal/Finalizer$1.class new file mode 100644 index 0000000000000000000000000000000000000000..326d1c70cb12eaea753a4b4112cd39bb431660ae Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/internal/Finalizer$1.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/internal/Finalizer$ShutDown.class b/src/main/resources/jnr/ffi/util/ref/internal/Finalizer$ShutDown.class new file mode 100644 index 0000000000000000000000000000000000000000..f7dabe6bebeb48bc2080fb519bef8d7ecb10b9d5 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/internal/Finalizer$ShutDown.class differ diff --git a/src/main/resources/jnr/ffi/util/ref/internal/Finalizer.class b/src/main/resources/jnr/ffi/util/ref/internal/Finalizer.class new file mode 100644 index 0000000000000000000000000000000000000000..bdb108489299bdde8a7e9a7a12a6a70194af0513 Binary files /dev/null and b/src/main/resources/jnr/ffi/util/ref/internal/Finalizer.class differ diff --git a/src/main/resources/jnr/netdb/FileProtocolsDB$1.class b/src/main/resources/jnr/netdb/FileProtocolsDB$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a928e76628d9380fe09c5983a4dedb99f4ed61d7 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileProtocolsDB$1.class differ diff --git a/src/main/resources/jnr/netdb/FileProtocolsDB$2.class b/src/main/resources/jnr/netdb/FileProtocolsDB$2.class new file mode 100644 index 0000000000000000000000000000000000000000..33109a8bc4bcafad0000869b87a93b7f851efcd4 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileProtocolsDB$2.class differ diff --git a/src/main/resources/jnr/netdb/FileProtocolsDB$3.class b/src/main/resources/jnr/netdb/FileProtocolsDB$3.class new file mode 100644 index 0000000000000000000000000000000000000000..74cadb2000796ff7e01b7b7900e2a159284edc05 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileProtocolsDB$3.class differ diff --git a/src/main/resources/jnr/netdb/FileProtocolsDB$Filter.class b/src/main/resources/jnr/netdb/FileProtocolsDB$Filter.class new file mode 100644 index 0000000000000000000000000000000000000000..c60c0949dcfda651091dfdcd0b3aeacfcb4745e3 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileProtocolsDB$Filter.class differ diff --git a/src/main/resources/jnr/netdb/FileProtocolsDB$SingletonHolder.class b/src/main/resources/jnr/netdb/FileProtocolsDB$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..e810fec23f46e4101232d3dcd8a2e3e946f7fa57 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileProtocolsDB$SingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/FileProtocolsDB.class b/src/main/resources/jnr/netdb/FileProtocolsDB.class new file mode 100644 index 0000000000000000000000000000000000000000..a803280538a7e47074f33a083e671d134162afbd Binary files /dev/null and b/src/main/resources/jnr/netdb/FileProtocolsDB.class differ diff --git a/src/main/resources/jnr/netdb/FileServicesDB$1.class b/src/main/resources/jnr/netdb/FileServicesDB$1.class new file mode 100644 index 0000000000000000000000000000000000000000..845ede1c4c241ec3b088dcb2feefe964c111ce3d Binary files /dev/null and b/src/main/resources/jnr/netdb/FileServicesDB$1.class differ diff --git a/src/main/resources/jnr/netdb/FileServicesDB$2.class b/src/main/resources/jnr/netdb/FileServicesDB$2.class new file mode 100644 index 0000000000000000000000000000000000000000..f675f3e5d783f1446280eed8edf5bb72dc69db49 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileServicesDB$2.class differ diff --git a/src/main/resources/jnr/netdb/FileServicesDB$3.class b/src/main/resources/jnr/netdb/FileServicesDB$3.class new file mode 100644 index 0000000000000000000000000000000000000000..7ad09b5b733b29185bbae98b8351f534a4364ab3 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileServicesDB$3.class differ diff --git a/src/main/resources/jnr/netdb/FileServicesDB$Filter.class b/src/main/resources/jnr/netdb/FileServicesDB$Filter.class new file mode 100644 index 0000000000000000000000000000000000000000..03ed9d0d49d6d510435310ffc19155ad6601288e Binary files /dev/null and b/src/main/resources/jnr/netdb/FileServicesDB$Filter.class differ diff --git a/src/main/resources/jnr/netdb/FileServicesDB$SingletonHolder.class b/src/main/resources/jnr/netdb/FileServicesDB$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..01966d04676469e55e18be47d551489b4e83495b Binary files /dev/null and b/src/main/resources/jnr/netdb/FileServicesDB$SingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/FileServicesDB.class b/src/main/resources/jnr/netdb/FileServicesDB.class new file mode 100644 index 0000000000000000000000000000000000000000..1cd43c4e41a26576bb6407ad9e9bfba8d4ca33e5 Binary files /dev/null and b/src/main/resources/jnr/netdb/FileServicesDB.class differ diff --git a/src/main/resources/jnr/netdb/IANAProtocolsDB$1.class b/src/main/resources/jnr/netdb/IANAProtocolsDB$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e17b220a607a9c36e5cc36e46fbf26a6b20c222f Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAProtocolsDB$1.class differ diff --git a/src/main/resources/jnr/netdb/IANAProtocolsDB$ProtocolDBBuilder.class b/src/main/resources/jnr/netdb/IANAProtocolsDB$ProtocolDBBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..6cde568724aa88d808e18098e9295059af1acafb Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAProtocolsDB$ProtocolDBBuilder.class differ diff --git a/src/main/resources/jnr/netdb/IANAProtocolsDB$SingletonHolder.class b/src/main/resources/jnr/netdb/IANAProtocolsDB$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..c42a943e28375676255b33be0ca4edb6757928c2 Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAProtocolsDB$SingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/IANAProtocolsDB.class b/src/main/resources/jnr/netdb/IANAProtocolsDB.class new file mode 100644 index 0000000000000000000000000000000000000000..23e64b6a3d921a0755f202e53dddfbcbda3dfead Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAProtocolsDB.class differ diff --git a/src/main/resources/jnr/netdb/IANAServicesDB$1.class b/src/main/resources/jnr/netdb/IANAServicesDB$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1e2a821acc7af1f9d562e7180024de05871fe741 Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAServicesDB$1.class differ diff --git a/src/main/resources/jnr/netdb/IANAServicesDB$ServicesBuilder.class b/src/main/resources/jnr/netdb/IANAServicesDB$ServicesBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..6d09e2e3d653097d5dde01dba168c5e724e7f7de Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAServicesDB$ServicesBuilder.class differ diff --git a/src/main/resources/jnr/netdb/IANAServicesDB$SingletonHolder.class b/src/main/resources/jnr/netdb/IANAServicesDB$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..aa2b5e838e38f85bec2c5156f9463e1c05712e74 Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAServicesDB$SingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/IANAServicesDB.class b/src/main/resources/jnr/netdb/IANAServicesDB.class new file mode 100644 index 0000000000000000000000000000000000000000..b5084e1acf4ddca149379451cc0d1df19d70dd26 Binary files /dev/null and b/src/main/resources/jnr/netdb/IANAServicesDB.class differ diff --git a/src/main/resources/jnr/netdb/NativeProtocolsDB$DefaultNativeProtocolsDB.class b/src/main/resources/jnr/netdb/NativeProtocolsDB$DefaultNativeProtocolsDB.class new file mode 100644 index 0000000000000000000000000000000000000000..cb4a45520c67cbdf5ad6282725f74f1c2d48ceb7 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeProtocolsDB$DefaultNativeProtocolsDB.class differ diff --git a/src/main/resources/jnr/netdb/NativeProtocolsDB$LibProto.class b/src/main/resources/jnr/netdb/NativeProtocolsDB$LibProto.class new file mode 100644 index 0000000000000000000000000000000000000000..4b78fb253bccb7f80890d53bb2eea6a150dcf6ae Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeProtocolsDB$LibProto.class differ diff --git a/src/main/resources/jnr/netdb/NativeProtocolsDB$LinuxLibProto.class b/src/main/resources/jnr/netdb/NativeProtocolsDB$LinuxLibProto.class new file mode 100644 index 0000000000000000000000000000000000000000..d02bda47c7bd851634c8215cb6cbcdc990edc5c4 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeProtocolsDB$LinuxLibProto.class differ diff --git a/src/main/resources/jnr/netdb/NativeProtocolsDB$LinuxNativeProtocolsDB.class b/src/main/resources/jnr/netdb/NativeProtocolsDB$LinuxNativeProtocolsDB.class new file mode 100644 index 0000000000000000000000000000000000000000..47708976e05645577757a0b8f72dd53e23026a0a Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeProtocolsDB$LinuxNativeProtocolsDB.class differ diff --git a/src/main/resources/jnr/netdb/NativeProtocolsDB$SingletonHolder.class b/src/main/resources/jnr/netdb/NativeProtocolsDB$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..16e32cb4e7d1d4bc260c450acc6583f23f0dabbc Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeProtocolsDB$SingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/NativeProtocolsDB$UnixProtoent.class b/src/main/resources/jnr/netdb/NativeProtocolsDB$UnixProtoent.class new file mode 100644 index 0000000000000000000000000000000000000000..0474b60dc21b5df1f06f3f30a0b08cf879694f7c Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeProtocolsDB$UnixProtoent.class differ diff --git a/src/main/resources/jnr/netdb/NativeProtocolsDB.class b/src/main/resources/jnr/netdb/NativeProtocolsDB.class new file mode 100644 index 0000000000000000000000000000000000000000..25a714861c24d1d399c837d29efc78c606838353 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeProtocolsDB.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB$DefaultNativeServicesDB.class b/src/main/resources/jnr/netdb/NativeServicesDB$DefaultNativeServicesDB.class new file mode 100644 index 0000000000000000000000000000000000000000..3bd9742f2e9fa3f89f8619827db6d269b3966273 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB$DefaultNativeServicesDB.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB$LibServices.class b/src/main/resources/jnr/netdb/NativeServicesDB$LibServices.class new file mode 100644 index 0000000000000000000000000000000000000000..98b98168c0b67e20e4139c7b7d199a36a632a25e Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB$LibServices.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB$LinuxLibServices.class b/src/main/resources/jnr/netdb/NativeServicesDB$LinuxLibServices.class new file mode 100644 index 0000000000000000000000000000000000000000..939abb669c3c8aa1c19b9c47c50e4ac819231f49 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB$LinuxLibServices.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB$LinuxServent.class b/src/main/resources/jnr/netdb/NativeServicesDB$LinuxServent.class new file mode 100644 index 0000000000000000000000000000000000000000..8f611e46a6314b42c13d29e71fc4d2a6b044d455 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB$LinuxServent.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB$LinuxServicesDB.class b/src/main/resources/jnr/netdb/NativeServicesDB$LinuxServicesDB.class new file mode 100644 index 0000000000000000000000000000000000000000..b723cd5c09d1e756b0697683789f627fae52b058 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB$LinuxServicesDB.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB$SingletonHolder.class b/src/main/resources/jnr/netdb/NativeServicesDB$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..fd489500d8769268cff40f9feab0d2c2684a8512 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB$SingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB$UnixServent.class b/src/main/resources/jnr/netdb/NativeServicesDB$UnixServent.class new file mode 100644 index 0000000000000000000000000000000000000000..5a1632b0f242d605505f2cd74bad4004a3649cd7 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB$UnixServent.class differ diff --git a/src/main/resources/jnr/netdb/NativeServicesDB.class b/src/main/resources/jnr/netdb/NativeServicesDB.class new file mode 100644 index 0000000000000000000000000000000000000000..cbb80372a778fa2d185d00ea1d7d5d71ebd85766 Binary files /dev/null and b/src/main/resources/jnr/netdb/NativeServicesDB.class differ diff --git a/src/main/resources/jnr/netdb/NetDBEntry.class b/src/main/resources/jnr/netdb/NetDBEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..46ee2cd14ed485dd06c5c62fc8eaa95112902f81 Binary files /dev/null and b/src/main/resources/jnr/netdb/NetDBEntry.class differ diff --git a/src/main/resources/jnr/netdb/NetDBFilter.class b/src/main/resources/jnr/netdb/NetDBFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..15f009eaf88a7d145f82a50a2b4bd6faf31f31b9 Binary files /dev/null and b/src/main/resources/jnr/netdb/NetDBFilter.class differ diff --git a/src/main/resources/jnr/netdb/NetDBIterator.class b/src/main/resources/jnr/netdb/NetDBIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..297d9bb9eb363470ce0bec497d46f9486524ed38 Binary files /dev/null and b/src/main/resources/jnr/netdb/NetDBIterator.class differ diff --git a/src/main/resources/jnr/netdb/NetDBParser.class b/src/main/resources/jnr/netdb/NetDBParser.class new file mode 100644 index 0000000000000000000000000000000000000000..98266cdc78732f6ea21daf7c5951f24ccc7b42e5 Binary files /dev/null and b/src/main/resources/jnr/netdb/NetDBParser.class differ diff --git a/src/main/resources/jnr/netdb/Protocol$ProtocolDBSingletonHolder.class b/src/main/resources/jnr/netdb/Protocol$ProtocolDBSingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..fa7818b2d0834e64a8ee6f408c17117c33d8e81b Binary files /dev/null and b/src/main/resources/jnr/netdb/Protocol$ProtocolDBSingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/Protocol.class b/src/main/resources/jnr/netdb/Protocol.class new file mode 100644 index 0000000000000000000000000000000000000000..6320d6a2b8eac1e108c4f7f1b97492b8d7b2f83c Binary files /dev/null and b/src/main/resources/jnr/netdb/Protocol.class differ diff --git a/src/main/resources/jnr/netdb/ProtocolsDB.class b/src/main/resources/jnr/netdb/ProtocolsDB.class new file mode 100644 index 0000000000000000000000000000000000000000..cfdff45c4579a6885f835a94cd778c5a47d40cbf Binary files /dev/null and b/src/main/resources/jnr/netdb/ProtocolsDB.class differ diff --git a/src/main/resources/jnr/netdb/Service$ServicesDBSingletonHolder.class b/src/main/resources/jnr/netdb/Service$ServicesDBSingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..19cdc2a43d05473c475b124a3562bc943925ea7a Binary files /dev/null and b/src/main/resources/jnr/netdb/Service$ServicesDBSingletonHolder.class differ diff --git a/src/main/resources/jnr/netdb/Service.class b/src/main/resources/jnr/netdb/Service.class new file mode 100644 index 0000000000000000000000000000000000000000..b382a9a3075b1de301c983a63ed3739361f13f16 Binary files /dev/null and b/src/main/resources/jnr/netdb/Service.class differ diff --git a/src/main/resources/jnr/netdb/ServicesDB.class b/src/main/resources/jnr/netdb/ServicesDB.class new file mode 100644 index 0000000000000000000000000000000000000000..d0a008b8b24fc5d2fffabb718efdc44f9391c724 Binary files /dev/null and b/src/main/resources/jnr/netdb/ServicesDB.class differ diff --git a/src/main/resources/jnr/netdb/StringUtil.class b/src/main/resources/jnr/netdb/StringUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..73c1a2a20ba63b7c4dcf3a0718554a82a96abe4e Binary files /dev/null and b/src/main/resources/jnr/netdb/StringUtil.class differ diff --git a/src/main/resources/jnr/posix/BaseFileStat.class b/src/main/resources/jnr/posix/BaseFileStat.class new file mode 100644 index 0000000000000000000000000000000000000000..e931b4c617b041c877db0de2de0152a3f7d97b4b Binary files /dev/null and b/src/main/resources/jnr/posix/BaseFileStat.class differ diff --git a/src/main/resources/jnr/posix/BaseNativePOSIX$1.class b/src/main/resources/jnr/posix/BaseNativePOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ff9ae7f486825a3befe9191c1661d57f5954510d Binary files /dev/null and b/src/main/resources/jnr/posix/BaseNativePOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/BaseNativePOSIX$2.class b/src/main/resources/jnr/posix/BaseNativePOSIX$2.class new file mode 100644 index 0000000000000000000000000000000000000000..11f7e61b6618ce06e61cd293ec925729c2b535f0 Binary files /dev/null and b/src/main/resources/jnr/posix/BaseNativePOSIX$2.class differ diff --git a/src/main/resources/jnr/posix/BaseNativePOSIX$3.class b/src/main/resources/jnr/posix/BaseNativePOSIX$3.class new file mode 100644 index 0000000000000000000000000000000000000000..2a9550d862a48b2f16582f9b0188505c0213a3bf Binary files /dev/null and b/src/main/resources/jnr/posix/BaseNativePOSIX$3.class differ diff --git a/src/main/resources/jnr/posix/BaseNativePOSIX$4.class b/src/main/resources/jnr/posix/BaseNativePOSIX$4.class new file mode 100644 index 0000000000000000000000000000000000000000..49d44f3bd33b73ab5264f36f0192ee3bbff3fe59 Binary files /dev/null and b/src/main/resources/jnr/posix/BaseNativePOSIX$4.class differ diff --git a/src/main/resources/jnr/posix/BaseNativePOSIX$5.class b/src/main/resources/jnr/posix/BaseNativePOSIX$5.class new file mode 100644 index 0000000000000000000000000000000000000000..3aabb2af7455fdc78f3d75acb59d419b20369cdc Binary files /dev/null and b/src/main/resources/jnr/posix/BaseNativePOSIX$5.class differ diff --git a/src/main/resources/jnr/posix/BaseNativePOSIX$PointerConverter.class b/src/main/resources/jnr/posix/BaseNativePOSIX$PointerConverter.class new file mode 100644 index 0000000000000000000000000000000000000000..b6d6fa968ea2b9305fc939b5b4406a7abd6e9cf7 Binary files /dev/null and b/src/main/resources/jnr/posix/BaseNativePOSIX$PointerConverter.class differ diff --git a/src/main/resources/jnr/posix/BaseNativePOSIX.class b/src/main/resources/jnr/posix/BaseNativePOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..976d6677d2f7f00ea9cc91b5801f148d21c88018 Binary files /dev/null and b/src/main/resources/jnr/posix/BaseNativePOSIX.class differ diff --git a/src/main/resources/jnr/posix/DefaultNativeGroup$Layout.class b/src/main/resources/jnr/posix/DefaultNativeGroup$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..fefd296604bd72ba907d186a5321bfac92dbcae9 Binary files /dev/null and b/src/main/resources/jnr/posix/DefaultNativeGroup$Layout.class differ diff --git a/src/main/resources/jnr/posix/DefaultNativeGroup.class b/src/main/resources/jnr/posix/DefaultNativeGroup.class new file mode 100644 index 0000000000000000000000000000000000000000..02841507e79f40d98f4bb2506c1d91d46c41e656 Binary files /dev/null and b/src/main/resources/jnr/posix/DefaultNativeGroup.class differ diff --git a/src/main/resources/jnr/posix/DefaultNativeTimeval.class b/src/main/resources/jnr/posix/DefaultNativeTimeval.class new file mode 100644 index 0000000000000000000000000000000000000000..291f0fddca10913d07784cbc1219595e0e255b1b Binary files /dev/null and b/src/main/resources/jnr/posix/DefaultNativeTimeval.class differ diff --git a/src/main/resources/jnr/posix/FileStat.class b/src/main/resources/jnr/posix/FileStat.class new file mode 100644 index 0000000000000000000000000000000000000000..d8504a92a2e26f4d77b08a5563bbbe8f18a71f22 Binary files /dev/null and b/src/main/resources/jnr/posix/FileStat.class differ diff --git a/src/main/resources/jnr/posix/FileTime.class b/src/main/resources/jnr/posix/FileTime.class new file mode 100644 index 0000000000000000000000000000000000000000..fd5e3537690c5bac1d69d5d74d17732e6333b4fe Binary files /dev/null and b/src/main/resources/jnr/posix/FileTime.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDFileStat$1.class b/src/main/resources/jnr/posix/FreeBSDFileStat$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cb3d75237f84a1c64f6e8fc10667eb2c5bdaa9e1 Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDFileStat$1.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDFileStat$Layout$dev_t.class b/src/main/resources/jnr/posix/FreeBSDFileStat$Layout$dev_t.class new file mode 100644 index 0000000000000000000000000000000000000000..9cbf13a3a449e152aa0499bd0d777653b2cc3efc Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDFileStat$Layout$dev_t.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDFileStat$Layout$time_t.class b/src/main/resources/jnr/posix/FreeBSDFileStat$Layout$time_t.class new file mode 100644 index 0000000000000000000000000000000000000000..f8be01ec05dc0d9cfe8525b165edaceda59be723 Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDFileStat$Layout$time_t.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDFileStat$Layout.class b/src/main/resources/jnr/posix/FreeBSDFileStat$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..82590ba4a58574c3d7a40cd097f91124056fa296 Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDFileStat$Layout.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDFileStat.class b/src/main/resources/jnr/posix/FreeBSDFileStat.class new file mode 100644 index 0000000000000000000000000000000000000000..e7f072c9db405a72d8c69e72e6d9e6b961c34f5b Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDFileStat.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDPOSIX$1.class b/src/main/resources/jnr/posix/FreeBSDPOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6905ad74994785e50eb81e1545ceb50161d65943 Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDPOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDPOSIX.class b/src/main/resources/jnr/posix/FreeBSDPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..c81d70c1d769029aadc0fafa92f1d02597386db1 Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDPOSIX.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDPasswd$1.class b/src/main/resources/jnr/posix/FreeBSDPasswd$1.class new file mode 100644 index 0000000000000000000000000000000000000000..dbf73ce20dbe44016698b7a6a3716e16dae43ed4 Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDPasswd$1.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDPasswd$Layout.class b/src/main/resources/jnr/posix/FreeBSDPasswd$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..d127a7686badc35a6c85efc49c19ffc81e47b3d3 Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDPasswd$Layout.class differ diff --git a/src/main/resources/jnr/posix/FreeBSDPasswd.class b/src/main/resources/jnr/posix/FreeBSDPasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..8b53b121ff01915660ed3e29055d72c66d4a7c0e Binary files /dev/null and b/src/main/resources/jnr/posix/FreeBSDPasswd.class differ diff --git a/src/main/resources/jnr/posix/Group.class b/src/main/resources/jnr/posix/Group.class new file mode 100644 index 0000000000000000000000000000000000000000..94c462b5dbae9b44fd43cecdc1787b1c4e17cef0 Binary files /dev/null and b/src/main/resources/jnr/posix/Group.class differ diff --git a/src/main/resources/jnr/posix/HANDLE$1.class b/src/main/resources/jnr/posix/HANDLE$1.class new file mode 100644 index 0000000000000000000000000000000000000000..70ee30d541f0644ea20e03b53d2fa3443a8cd9d5 Binary files /dev/null and b/src/main/resources/jnr/posix/HANDLE$1.class differ diff --git a/src/main/resources/jnr/posix/HANDLE.class b/src/main/resources/jnr/posix/HANDLE.class new file mode 100644 index 0000000000000000000000000000000000000000..c56cc2d2f09ccdcef7f3dbb3ef9cedf3d0b51284 Binary files /dev/null and b/src/main/resources/jnr/posix/HANDLE.class differ diff --git a/src/main/resources/jnr/posix/JavaFileStat.class b/src/main/resources/jnr/posix/JavaFileStat.class new file mode 100644 index 0000000000000000000000000000000000000000..b2dd49f3a361b268a3a82e354cc5d7a3111381f5 Binary files /dev/null and b/src/main/resources/jnr/posix/JavaFileStat.class differ diff --git a/src/main/resources/jnr/posix/JavaLibCHelper$1.class b/src/main/resources/jnr/posix/JavaLibCHelper$1.class new file mode 100644 index 0000000000000000000000000000000000000000..45dd8248dce92ea63d8637adcd4ddc542c0f5410 Binary files /dev/null and b/src/main/resources/jnr/posix/JavaLibCHelper$1.class differ diff --git a/src/main/resources/jnr/posix/JavaLibCHelper$ErrnoParsingOutputStream.class b/src/main/resources/jnr/posix/JavaLibCHelper$ErrnoParsingOutputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..64e6fdfc2324769f80d415f045de977f1c1026b6 Binary files /dev/null and b/src/main/resources/jnr/posix/JavaLibCHelper$ErrnoParsingOutputStream.class differ diff --git a/src/main/resources/jnr/posix/JavaLibCHelper$PosixExec.class b/src/main/resources/jnr/posix/JavaLibCHelper$PosixExec.class new file mode 100644 index 0000000000000000000000000000000000000000..c999456e21a3987d87f6e815f9e87ce61d2a4fb7 Binary files /dev/null and b/src/main/resources/jnr/posix/JavaLibCHelper$PosixExec.class differ diff --git a/src/main/resources/jnr/posix/JavaLibCHelper.class b/src/main/resources/jnr/posix/JavaLibCHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..70a982ee6cc18b6f7e53cc28417576c5ba720f6a Binary files /dev/null and b/src/main/resources/jnr/posix/JavaLibCHelper.class differ diff --git a/src/main/resources/jnr/posix/JavaPOSIX$1.class b/src/main/resources/jnr/posix/JavaPOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c6a765b4478b41cff2a7ab81143fb3c4f4ae1d4d Binary files /dev/null and b/src/main/resources/jnr/posix/JavaPOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/JavaPOSIX$FakePasswd.class b/src/main/resources/jnr/posix/JavaPOSIX$FakePasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..16aff6d227d0b6d1fc0ca54e12230902ce3503a1 Binary files /dev/null and b/src/main/resources/jnr/posix/JavaPOSIX$FakePasswd.class differ diff --git a/src/main/resources/jnr/posix/JavaPOSIX$IDHelper.class b/src/main/resources/jnr/posix/JavaPOSIX$IDHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..86dd17bb8c7a4845176cc361f9e84b16ee85c5ca Binary files /dev/null and b/src/main/resources/jnr/posix/JavaPOSIX$IDHelper.class differ diff --git a/src/main/resources/jnr/posix/JavaPOSIX$LoginInfo.class b/src/main/resources/jnr/posix/JavaPOSIX$LoginInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..342ef3838da3f6658920aaa346a2fd246aa359bb Binary files /dev/null and b/src/main/resources/jnr/posix/JavaPOSIX$LoginInfo.class differ diff --git a/src/main/resources/jnr/posix/JavaPOSIX.class b/src/main/resources/jnr/posix/JavaPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..fc7630dbf0148145dff1c10b9898980211e478c7 Binary files /dev/null and b/src/main/resources/jnr/posix/JavaPOSIX.class differ diff --git a/src/main/resources/jnr/posix/JavaPasswd.class b/src/main/resources/jnr/posix/JavaPasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..fee95a9ae41abe9834ed6a37df792fa1a2610e15 Binary files /dev/null and b/src/main/resources/jnr/posix/JavaPasswd.class differ diff --git a/src/main/resources/jnr/posix/JavaSecuredFile.class b/src/main/resources/jnr/posix/JavaSecuredFile.class new file mode 100644 index 0000000000000000000000000000000000000000..e221895a05d29b4469cdcefc668e6d91afe3f17a Binary files /dev/null and b/src/main/resources/jnr/posix/JavaSecuredFile.class differ diff --git a/src/main/resources/jnr/posix/JavaTimes.class b/src/main/resources/jnr/posix/JavaTimes.class new file mode 100644 index 0000000000000000000000000000000000000000..9b0e4d25d21209958b4642dd8de3876bd7aa336e Binary files /dev/null and b/src/main/resources/jnr/posix/JavaTimes.class differ diff --git a/src/main/resources/jnr/posix/LazyPOSIX.class b/src/main/resources/jnr/posix/LazyPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..667d69022641ba1557956a49886cb4ff363a0481 Binary files /dev/null and b/src/main/resources/jnr/posix/LazyPOSIX.class differ diff --git a/src/main/resources/jnr/posix/LibC.class b/src/main/resources/jnr/posix/LibC.class new file mode 100644 index 0000000000000000000000000000000000000000..fac439c2b7a6e289ba850fe071883f64a2d706e8 Binary files /dev/null and b/src/main/resources/jnr/posix/LibC.class differ diff --git a/src/main/resources/jnr/posix/LibCProvider.class b/src/main/resources/jnr/posix/LibCProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..0b5956e8e4cf603e8850c6ca3598da392cb1de1c Binary files /dev/null and b/src/main/resources/jnr/posix/LibCProvider.class differ diff --git a/src/main/resources/jnr/posix/LinuxFileStat32$1.class b/src/main/resources/jnr/posix/LinuxFileStat32$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f37f56289a0931882134de04b25cba5af8856016 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxFileStat32$1.class differ diff --git a/src/main/resources/jnr/posix/LinuxFileStat32$Layout.class b/src/main/resources/jnr/posix/LinuxFileStat32$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..220c1062b131be55e299effc351a45e20f67b835 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxFileStat32$Layout.class differ diff --git a/src/main/resources/jnr/posix/LinuxFileStat32.class b/src/main/resources/jnr/posix/LinuxFileStat32.class new file mode 100644 index 0000000000000000000000000000000000000000..561ecda593c1c076a0ba6d677a38b92f9d9e773a Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxFileStat32.class differ diff --git a/src/main/resources/jnr/posix/LinuxFileStat64$Layout.class b/src/main/resources/jnr/posix/LinuxFileStat64$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..cbf4457c7b8574773b57df0561074d68a40180ac Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxFileStat64$Layout.class differ diff --git a/src/main/resources/jnr/posix/LinuxFileStat64.class b/src/main/resources/jnr/posix/LinuxFileStat64.class new file mode 100644 index 0000000000000000000000000000000000000000..819d3e0cf0d1e9d9e44f16e5f65f4206d2894bc1 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxFileStat64.class differ diff --git a/src/main/resources/jnr/posix/LinuxLibC.class b/src/main/resources/jnr/posix/LinuxLibC.class new file mode 100644 index 0000000000000000000000000000000000000000..66a1dc8c1aae81f3436a3215240feff722373906 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxLibC.class differ diff --git a/src/main/resources/jnr/posix/LinuxPOSIX$1.class b/src/main/resources/jnr/posix/LinuxPOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..be0d321a838cb1bd1abfca544c3de07012b368f9 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxPOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/LinuxPOSIX.class b/src/main/resources/jnr/posix/LinuxPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..291905346000ceefbc92bc17a53c6a9f987f4004 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxPOSIX.class differ diff --git a/src/main/resources/jnr/posix/LinuxPasswd$1.class b/src/main/resources/jnr/posix/LinuxPasswd$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f78e128ff069d370d55add144f3adbedc37423d8 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxPasswd$1.class differ diff --git a/src/main/resources/jnr/posix/LinuxPasswd$Layout.class b/src/main/resources/jnr/posix/LinuxPasswd$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..36427ef33dd3cd0a486b17ae1f55c000a9f311fb Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxPasswd$Layout.class differ diff --git a/src/main/resources/jnr/posix/LinuxPasswd.class b/src/main/resources/jnr/posix/LinuxPasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..ada83e7f30aed0e98177339e712a25a325f56d13 Binary files /dev/null and b/src/main/resources/jnr/posix/LinuxPasswd.class differ diff --git a/src/main/resources/jnr/posix/MacOSFileStat$Layout$time_t.class b/src/main/resources/jnr/posix/MacOSFileStat$Layout$time_t.class new file mode 100644 index 0000000000000000000000000000000000000000..a2d920657e197defedc187a5fe39a6d9b30257a5 Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSFileStat$Layout$time_t.class differ diff --git a/src/main/resources/jnr/posix/MacOSFileStat$Layout.class b/src/main/resources/jnr/posix/MacOSFileStat$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..d4526c643d297a28db2a877da32308fb57f6e4c9 Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSFileStat$Layout.class differ diff --git a/src/main/resources/jnr/posix/MacOSFileStat.class b/src/main/resources/jnr/posix/MacOSFileStat.class new file mode 100644 index 0000000000000000000000000000000000000000..a8246b2af61cc34d0f0d3a7e896884613ec00c3c Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSFileStat.class differ diff --git a/src/main/resources/jnr/posix/MacOSPOSIX$1.class b/src/main/resources/jnr/posix/MacOSPOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e96a0b8bd0e7384b8b56aa2462f199e5cad2b428 Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSPOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/MacOSPOSIX.class b/src/main/resources/jnr/posix/MacOSPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..0537175694816eff0c62f76ab27fe96eda5ed915 Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSPOSIX.class differ diff --git a/src/main/resources/jnr/posix/MacOSPasswd$1.class b/src/main/resources/jnr/posix/MacOSPasswd$1.class new file mode 100644 index 0000000000000000000000000000000000000000..74f577e33a204d1805af266bf2c0d0774422509d Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSPasswd$1.class differ diff --git a/src/main/resources/jnr/posix/MacOSPasswd$Layout.class b/src/main/resources/jnr/posix/MacOSPasswd$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..ca143bf3d326e9e8432dd7fb7f8e0da3c2803933 Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSPasswd$Layout.class differ diff --git a/src/main/resources/jnr/posix/MacOSPasswd.class b/src/main/resources/jnr/posix/MacOSPasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..d99d0d635c9f13ab7fdde04bd01288bbe2e41295 Binary files /dev/null and b/src/main/resources/jnr/posix/MacOSPasswd.class differ diff --git a/src/main/resources/jnr/posix/NativeGroup.class b/src/main/resources/jnr/posix/NativeGroup.class new file mode 100644 index 0000000000000000000000000000000000000000..2f015b008998fdb22d8bda9597d9107f7fbc2954 Binary files /dev/null and b/src/main/resources/jnr/posix/NativeGroup.class differ diff --git a/src/main/resources/jnr/posix/NativePOSIX.class b/src/main/resources/jnr/posix/NativePOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..391d1df78d7b811d578996b7470f0b78768206e4 Binary files /dev/null and b/src/main/resources/jnr/posix/NativePOSIX.class differ diff --git a/src/main/resources/jnr/posix/NativePasswd.class b/src/main/resources/jnr/posix/NativePasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..f5aaf9d92f8518acf41e130eea0ece849039fdea Binary files /dev/null and b/src/main/resources/jnr/posix/NativePasswd.class differ diff --git a/src/main/resources/jnr/posix/NativeTimes$Layout.class b/src/main/resources/jnr/posix/NativeTimes$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..3ebfb74f56e559f88e709c53cc2b18841889dbe1 Binary files /dev/null and b/src/main/resources/jnr/posix/NativeTimes$Layout.class differ diff --git a/src/main/resources/jnr/posix/NativeTimes.class b/src/main/resources/jnr/posix/NativeTimes.class new file mode 100644 index 0000000000000000000000000000000000000000..e3e38fcd9f7abe96a54142a3636bb8233b6cb4d6 Binary files /dev/null and b/src/main/resources/jnr/posix/NativeTimes.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDFileStat$1.class b/src/main/resources/jnr/posix/OpenBSDFileStat$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f27acae9bcfef391002393b9c50c6af4890199b1 Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDFileStat$1.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDFileStat$Layout$dev_t.class b/src/main/resources/jnr/posix/OpenBSDFileStat$Layout$dev_t.class new file mode 100644 index 0000000000000000000000000000000000000000..9ad20988902c03d17bd06162a69cc9f9bcaec6c5 Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDFileStat$Layout$dev_t.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDFileStat$Layout$time_t.class b/src/main/resources/jnr/posix/OpenBSDFileStat$Layout$time_t.class new file mode 100644 index 0000000000000000000000000000000000000000..d0488b92d0a6a6b7fbd341633a7b69cf16b4d20b Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDFileStat$Layout$time_t.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDFileStat$Layout.class b/src/main/resources/jnr/posix/OpenBSDFileStat$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..5a824d68992ff19ea86cd732333c8e198f1e83c7 Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDFileStat$Layout.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDFileStat.class b/src/main/resources/jnr/posix/OpenBSDFileStat.class new file mode 100644 index 0000000000000000000000000000000000000000..4f0472c17050a3878b4e347d2eef0915ab2a7904 Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDFileStat.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDPOSIX$1.class b/src/main/resources/jnr/posix/OpenBSDPOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3ae9ca64cbb017cbe6f43a379ce77ef8d4165737 Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDPOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDPOSIX.class b/src/main/resources/jnr/posix/OpenBSDPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..d31a4cebdd12a8018362cb75f78507efb316779a Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDPOSIX.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDPasswd$1.class b/src/main/resources/jnr/posix/OpenBSDPasswd$1.class new file mode 100644 index 0000000000000000000000000000000000000000..384565e1a404ffc9df06d1a495dcc0f3c0fd98b8 Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDPasswd$1.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDPasswd$Layout.class b/src/main/resources/jnr/posix/OpenBSDPasswd$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..d16bf2aadc590dd47b7d1d9e2044713ab53537fd Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDPasswd$Layout.class differ diff --git a/src/main/resources/jnr/posix/OpenBSDPasswd.class b/src/main/resources/jnr/posix/OpenBSDPasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..a137b84272b86c3403b5dc14ca259002bbb3bb77 Binary files /dev/null and b/src/main/resources/jnr/posix/OpenBSDPasswd.class differ diff --git a/src/main/resources/jnr/posix/POSIX.class b/src/main/resources/jnr/posix/POSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..ca6ca5fa35abe98529c5432b5a15a924f916cc81 Binary files /dev/null and b/src/main/resources/jnr/posix/POSIX.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$1.class b/src/main/resources/jnr/posix/POSIXFactory$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4b8034a7629b85ceb5a08d187ada1dd38d3889e4 Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$1.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$DefaultLibCProvider$SingletonHolder.class b/src/main/resources/jnr/posix/POSIXFactory$DefaultLibCProvider$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..0d4d3348af81fe8b11ef599b8e7a2dca52b40df8 Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$DefaultLibCProvider$SingletonHolder.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$DefaultLibCProvider.class b/src/main/resources/jnr/posix/POSIXFactory$DefaultLibCProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..468be323a75526f585c01c2c399e7b804aab300f Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$DefaultLibCProvider.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$LinuxLibCProvider$SingletonHolder.class b/src/main/resources/jnr/posix/POSIXFactory$LinuxLibCProvider$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..8da329155d3a79ff5819cad008746bc8199635be Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$LinuxLibCProvider$SingletonHolder.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$LinuxLibCProvider.class b/src/main/resources/jnr/posix/POSIXFactory$LinuxLibCProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..afbc5eac04ad14116260eb650e6d0c302e51458c Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$LinuxLibCProvider.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$SolarisLibCProvider$SingletonHolder.class b/src/main/resources/jnr/posix/POSIXFactory$SolarisLibCProvider$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..4c7c3d54b9936db46c505083ccbd00aa9e29dde1 Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$SolarisLibCProvider$SingletonHolder.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$SolarisLibCProvider.class b/src/main/resources/jnr/posix/POSIXFactory$SolarisLibCProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..0ba87f827b0b747e529c3f24eeb0e2b529ae972f Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$SolarisLibCProvider.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$WindowsLibCProvider$SingletonHolder.class b/src/main/resources/jnr/posix/POSIXFactory$WindowsLibCProvider$SingletonHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..f60503c4e8de0923cd8fff86311e05814e00560c Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$WindowsLibCProvider$SingletonHolder.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory$WindowsLibCProvider.class b/src/main/resources/jnr/posix/POSIXFactory$WindowsLibCProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..4ae9c4a43a18cc337fec8b2a8d7f61a0772a350c Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory$WindowsLibCProvider.class differ diff --git a/src/main/resources/jnr/posix/POSIXFactory.class b/src/main/resources/jnr/posix/POSIXFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..6e1262bffc721a3b37c5905b13e415630ecd1380 Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFactory.class differ diff --git a/src/main/resources/jnr/posix/POSIXFunctionMapper.class b/src/main/resources/jnr/posix/POSIXFunctionMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..ec0022d1776e84e3e5bc672f3ec7460038b068dc Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXFunctionMapper.class differ diff --git a/src/main/resources/jnr/posix/POSIXHandler$WARNING_ID.class b/src/main/resources/jnr/posix/POSIXHandler$WARNING_ID.class new file mode 100644 index 0000000000000000000000000000000000000000..5fbbbe399d9c6e33305cbe937b0f50875138c8a6 Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXHandler$WARNING_ID.class differ diff --git a/src/main/resources/jnr/posix/POSIXHandler.class b/src/main/resources/jnr/posix/POSIXHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..24e048070ac5cb4a8e8a500714a4c124b5b0e30a Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXHandler.class differ diff --git a/src/main/resources/jnr/posix/POSIXTypeMapper.class b/src/main/resources/jnr/posix/POSIXTypeMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..65b356b188e9aefc8684136dcc30fd4d305f576f Binary files /dev/null and b/src/main/resources/jnr/posix/POSIXTypeMapper.class differ diff --git a/src/main/resources/jnr/posix/Passwd.class b/src/main/resources/jnr/posix/Passwd.class new file mode 100644 index 0000000000000000000000000000000000000000..83c8593755e991bb33b7ec5d85e910bc6726a6fb Binary files /dev/null and b/src/main/resources/jnr/posix/Passwd.class differ diff --git a/src/main/resources/jnr/posix/SolarisFileStat32$Layout.class b/src/main/resources/jnr/posix/SolarisFileStat32$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..d1befe6ad274f47d465d7b565d17542ddad04fb9 Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisFileStat32$Layout.class differ diff --git a/src/main/resources/jnr/posix/SolarisFileStat32.class b/src/main/resources/jnr/posix/SolarisFileStat32.class new file mode 100644 index 0000000000000000000000000000000000000000..1b0256e1ee8560c82eeec069ff38b0f9806b6bcc Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisFileStat32.class differ diff --git a/src/main/resources/jnr/posix/SolarisFileStat64$Layout.class b/src/main/resources/jnr/posix/SolarisFileStat64$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..d0040ceb71233d61ad7bba229c7ed72e9c32252c Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisFileStat64$Layout.class differ diff --git a/src/main/resources/jnr/posix/SolarisFileStat64.class b/src/main/resources/jnr/posix/SolarisFileStat64.class new file mode 100644 index 0000000000000000000000000000000000000000..0bbf87676af068771decfc8b3383ef608d929e28 Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisFileStat64.class differ diff --git a/src/main/resources/jnr/posix/SolarisLibC.class b/src/main/resources/jnr/posix/SolarisLibC.class new file mode 100644 index 0000000000000000000000000000000000000000..86ff1592e749e2e98a955cf4ee7ae3b464019be3 Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisLibC.class differ diff --git a/src/main/resources/jnr/posix/SolarisPOSIX$1.class b/src/main/resources/jnr/posix/SolarisPOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9d74930b1a9ff54f1aaeb090b171738caf55af9d Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisPOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/SolarisPOSIX.class b/src/main/resources/jnr/posix/SolarisPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..451e1dadbda9a39acb1a7518f6e0ce21e42a4014 Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisPOSIX.class differ diff --git a/src/main/resources/jnr/posix/SolarisPasswd$1.class b/src/main/resources/jnr/posix/SolarisPasswd$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ce5765fb16b7875176449811d9ec1b8e26e64fde Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisPasswd$1.class differ diff --git a/src/main/resources/jnr/posix/SolarisPasswd$Layout.class b/src/main/resources/jnr/posix/SolarisPasswd$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..0172878720a23bcfe110b44bd918ebbadbf42f80 Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisPasswd$Layout.class differ diff --git a/src/main/resources/jnr/posix/SolarisPasswd.class b/src/main/resources/jnr/posix/SolarisPasswd.class new file mode 100644 index 0000000000000000000000000000000000000000..8a9ac468eefd046d8f0c4c69bb1dbaa2d718727e Binary files /dev/null and b/src/main/resources/jnr/posix/SolarisPasswd.class differ diff --git a/src/main/resources/jnr/posix/SpawnFileAction$Close.class b/src/main/resources/jnr/posix/SpawnFileAction$Close.class new file mode 100644 index 0000000000000000000000000000000000000000..4db96f648fc75db97810bda6ac459c691e88cb80 Binary files /dev/null and b/src/main/resources/jnr/posix/SpawnFileAction$Close.class differ diff --git a/src/main/resources/jnr/posix/SpawnFileAction$Dup.class b/src/main/resources/jnr/posix/SpawnFileAction$Dup.class new file mode 100644 index 0000000000000000000000000000000000000000..f563bebe79051ad5c56640b2958f524827c2d4c9 Binary files /dev/null and b/src/main/resources/jnr/posix/SpawnFileAction$Dup.class differ diff --git a/src/main/resources/jnr/posix/SpawnFileAction$Open.class b/src/main/resources/jnr/posix/SpawnFileAction$Open.class new file mode 100644 index 0000000000000000000000000000000000000000..87b5af2cd12e3146c5d191ca258acc81a795dccb Binary files /dev/null and b/src/main/resources/jnr/posix/SpawnFileAction$Open.class differ diff --git a/src/main/resources/jnr/posix/SpawnFileAction.class b/src/main/resources/jnr/posix/SpawnFileAction.class new file mode 100644 index 0000000000000000000000000000000000000000..2485096624c4dbdaf503196ef6f421d065e5c795 Binary files /dev/null and b/src/main/resources/jnr/posix/SpawnFileAction.class differ diff --git a/src/main/resources/jnr/posix/Times.class b/src/main/resources/jnr/posix/Times.class new file mode 100644 index 0000000000000000000000000000000000000000..df302e20bc1c94baf07c2e1ca5050502a57702e1 Binary files /dev/null and b/src/main/resources/jnr/posix/Times.class differ diff --git a/src/main/resources/jnr/posix/Timeval.class b/src/main/resources/jnr/posix/Timeval.class new file mode 100644 index 0000000000000000000000000000000000000000..d8408a90af443bf7140953a0524a605640c3d4d9 Binary files /dev/null and b/src/main/resources/jnr/posix/Timeval.class differ diff --git a/src/main/resources/jnr/posix/UTimBuf64.class b/src/main/resources/jnr/posix/UTimBuf64.class new file mode 100644 index 0000000000000000000000000000000000000000..8eef0e76e7788d9e6428289c5ab93615fa111a35 Binary files /dev/null and b/src/main/resources/jnr/posix/UTimBuf64.class differ diff --git a/src/main/resources/jnr/posix/UnixLibC.class b/src/main/resources/jnr/posix/UnixLibC.class new file mode 100644 index 0000000000000000000000000000000000000000..64929615d34b969e973f738da77fda239b6653c0 Binary files /dev/null and b/src/main/resources/jnr/posix/UnixLibC.class differ diff --git a/src/main/resources/jnr/posix/WString$1.class b/src/main/resources/jnr/posix/WString$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0ba887d7f946edfd861a7018b1c5e43af7d0d46c Binary files /dev/null and b/src/main/resources/jnr/posix/WString$1.class differ diff --git a/src/main/resources/jnr/posix/WString.class b/src/main/resources/jnr/posix/WString.class new file mode 100644 index 0000000000000000000000000000000000000000..896cec3cd8df5d9ca7539cf5def21a35e2a31582 Binary files /dev/null and b/src/main/resources/jnr/posix/WString.class differ diff --git a/src/main/resources/jnr/posix/WindowsChildRecord.class b/src/main/resources/jnr/posix/WindowsChildRecord.class new file mode 100644 index 0000000000000000000000000000000000000000..174649a4a48c3fd4e82de8e1b3f188db1d46f177 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsChildRecord.class differ diff --git a/src/main/resources/jnr/posix/WindowsFileStat$1.class b/src/main/resources/jnr/posix/WindowsFileStat$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2c0455fe043f269dd7d9df0aa91a94e52a4d2cd0 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsFileStat$1.class differ diff --git a/src/main/resources/jnr/posix/WindowsFileStat$Layout.class b/src/main/resources/jnr/posix/WindowsFileStat$Layout.class new file mode 100644 index 0000000000000000000000000000000000000000..151e11009d6d47607d09f71f36992c0c19f1f578 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsFileStat$Layout.class differ diff --git a/src/main/resources/jnr/posix/WindowsFileStat.class b/src/main/resources/jnr/posix/WindowsFileStat.class new file mode 100644 index 0000000000000000000000000000000000000000..b295fd60297df13c6c1bb35a3c291e91fec01fef Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsFileStat.class differ diff --git a/src/main/resources/jnr/posix/WindowsLibC.class b/src/main/resources/jnr/posix/WindowsLibC.class new file mode 100644 index 0000000000000000000000000000000000000000..a8ff0dd04ecfa9f4bccca3d25a67a9c11f71d4c5 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsLibC.class differ diff --git a/src/main/resources/jnr/posix/WindowsLibCFunctionMapper.class b/src/main/resources/jnr/posix/WindowsLibCFunctionMapper.class new file mode 100644 index 0000000000000000000000000000000000000000..56abc443308ebb33e01996cab2510ecf28e34eb7 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsLibCFunctionMapper.class differ diff --git a/src/main/resources/jnr/posix/WindowsPOSIX$1.class b/src/main/resources/jnr/posix/WindowsPOSIX$1.class new file mode 100644 index 0000000000000000000000000000000000000000..100ae705803e65ca96c3a31d0f8fe98f24debbc1 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsPOSIX$1.class differ diff --git a/src/main/resources/jnr/posix/WindowsPOSIX.class b/src/main/resources/jnr/posix/WindowsPOSIX.class new file mode 100644 index 0000000000000000000000000000000000000000..d785319cac8f6a1d220e38172db484c2cd768fd4 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsPOSIX.class differ diff --git a/src/main/resources/jnr/posix/WindowsProcessInformation.class b/src/main/resources/jnr/posix/WindowsProcessInformation.class new file mode 100644 index 0000000000000000000000000000000000000000..30816a6a074744c54493a29d7dde71e41c37285b Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsProcessInformation.class differ diff --git a/src/main/resources/jnr/posix/WindowsSecurityAttributes.class b/src/main/resources/jnr/posix/WindowsSecurityAttributes.class new file mode 100644 index 0000000000000000000000000000000000000000..642fcafc5333efe30a5650505e9f062e50d3a607 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsSecurityAttributes.class differ diff --git a/src/main/resources/jnr/posix/WindowsStartupInfo.class b/src/main/resources/jnr/posix/WindowsStartupInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..7833931542124632b524849542b2fcb4fb51eab6 Binary files /dev/null and b/src/main/resources/jnr/posix/WindowsStartupInfo.class differ diff --git a/src/main/resources/jnr/posix/util/Chmod.class b/src/main/resources/jnr/posix/util/Chmod.class new file mode 100644 index 0000000000000000000000000000000000000000..fdac52a7568bbf0a1368c231653e91289594d73f Binary files /dev/null and b/src/main/resources/jnr/posix/util/Chmod.class differ diff --git a/src/main/resources/jnr/posix/util/DefaultPOSIXHandler.class b/src/main/resources/jnr/posix/util/DefaultPOSIXHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..478bd13793d4c5bdc94a1877413b5c2ba0fefe13 Binary files /dev/null and b/src/main/resources/jnr/posix/util/DefaultPOSIXHandler.class differ diff --git a/src/main/resources/jnr/posix/util/ExecIt$StreamPumper.class b/src/main/resources/jnr/posix/util/ExecIt$StreamPumper.class new file mode 100644 index 0000000000000000000000000000000000000000..3dc23e6716b2a5527811c9af9e81154e462021bf Binary files /dev/null and b/src/main/resources/jnr/posix/util/ExecIt$StreamPumper.class differ diff --git a/src/main/resources/jnr/posix/util/ExecIt.class b/src/main/resources/jnr/posix/util/ExecIt.class new file mode 100644 index 0000000000000000000000000000000000000000..2a24edb0dd08429da76dede4c1bee2f6c1ebeeee Binary files /dev/null and b/src/main/resources/jnr/posix/util/ExecIt.class differ diff --git a/src/main/resources/jnr/posix/util/FieldAccess.class b/src/main/resources/jnr/posix/util/FieldAccess.class new file mode 100644 index 0000000000000000000000000000000000000000..39b3fef5039b529150d4d9a2144c419bcef5dbb0 Binary files /dev/null and b/src/main/resources/jnr/posix/util/FieldAccess.class differ diff --git a/src/main/resources/jnr/posix/util/Finder.class b/src/main/resources/jnr/posix/util/Finder.class new file mode 100644 index 0000000000000000000000000000000000000000..6fddfd1ab3d523a9d266399883b7977a664cc2d2 Binary files /dev/null and b/src/main/resources/jnr/posix/util/Finder.class differ diff --git a/src/main/resources/jnr/posix/util/Java5ProcessMaker.class b/src/main/resources/jnr/posix/util/Java5ProcessMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..f4193dab71ce1e00e8ea77c1cb1856d0565bd891 Binary files /dev/null and b/src/main/resources/jnr/posix/util/Java5ProcessMaker.class differ diff --git a/src/main/resources/jnr/posix/util/Platform.class b/src/main/resources/jnr/posix/util/Platform.class new file mode 100644 index 0000000000000000000000000000000000000000..8e42c9557dea3de303176270aa54e56158a85e9a Binary files /dev/null and b/src/main/resources/jnr/posix/util/Platform.class differ diff --git a/src/main/resources/jnr/posix/util/ProcessMaker$Redirect$Type.class b/src/main/resources/jnr/posix/util/ProcessMaker$Redirect$Type.class new file mode 100644 index 0000000000000000000000000000000000000000..928bc578b07e35dd84c89e2c12f42a61efbb93e4 Binary files /dev/null and b/src/main/resources/jnr/posix/util/ProcessMaker$Redirect$Type.class differ diff --git a/src/main/resources/jnr/posix/util/ProcessMaker$Redirect.class b/src/main/resources/jnr/posix/util/ProcessMaker$Redirect.class new file mode 100644 index 0000000000000000000000000000000000000000..cc6525e583626f599806b87ff325535ee791627c Binary files /dev/null and b/src/main/resources/jnr/posix/util/ProcessMaker$Redirect.class differ diff --git a/src/main/resources/jnr/posix/util/ProcessMaker.class b/src/main/resources/jnr/posix/util/ProcessMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..7456b56283563a38040e7e83ecd7a0ae7290ece6 Binary files /dev/null and b/src/main/resources/jnr/posix/util/ProcessMaker.class differ diff --git a/src/main/resources/jnr/posix/util/WindowsHelpers$1.class b/src/main/resources/jnr/posix/util/WindowsHelpers$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d46522ba6e2dcf4c87d1c36be5a18bee5216da72 Binary files /dev/null and b/src/main/resources/jnr/posix/util/WindowsHelpers$1.class differ diff --git a/src/main/resources/jnr/posix/util/WindowsHelpers$InternalType.class b/src/main/resources/jnr/posix/util/WindowsHelpers$InternalType.class new file mode 100644 index 0000000000000000000000000000000000000000..9743b041280b783742174854053e636beb9916f8 Binary files /dev/null and b/src/main/resources/jnr/posix/util/WindowsHelpers$InternalType.class differ diff --git a/src/main/resources/jnr/posix/util/WindowsHelpers.class b/src/main/resources/jnr/posix/util/WindowsHelpers.class new file mode 100644 index 0000000000000000000000000000000000000000..f6d510934c8b2227a27d43430daf6a441c6d90dc Binary files /dev/null and b/src/main/resources/jnr/posix/util/WindowsHelpers.class differ diff --git a/src/main/resources/org/apache/xmlcommons/Version.class b/src/main/resources/org/apache/xmlcommons/Version.class new file mode 100644 index 0000000000000000000000000000000000000000..898d3ea24cb5f16424c0be6e3eaaad01e8467257 Binary files /dev/null and b/src/main/resources/org/apache/xmlcommons/Version.class differ diff --git a/src/main/resources/org/python/Version.class b/src/main/resources/org/python/Version.class new file mode 100644 index 0000000000000000000000000000000000000000..ee077be66e488331477d84050f28f174f8a06930 Binary files /dev/null and b/src/main/resources/org/python/Version.class differ diff --git a/src/main/resources/org/python/antlr/AST$PyExposer.class b/src/main/resources/org/python/antlr/AST$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e415bdcf46f244a778a4e5a0a766b321cab789eb Binary files /dev/null and b/src/main/resources/org/python/antlr/AST$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/AST.class b/src/main/resources/org/python/antlr/AST.class new file mode 100644 index 0000000000000000000000000000000000000000..ea5356cf14960c05e9eb7871d1ee2b6e28d323f6 Binary files /dev/null and b/src/main/resources/org/python/antlr/AST.class differ diff --git a/src/main/resources/org/python/antlr/AnalyzingParser$AnalyzerTreeAdaptor.class b/src/main/resources/org/python/antlr/AnalyzingParser$AnalyzerTreeAdaptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e475954f471891c60b566bd9a6bad5877d569991 Binary files /dev/null and b/src/main/resources/org/python/antlr/AnalyzingParser$AnalyzerTreeAdaptor.class differ diff --git a/src/main/resources/org/python/antlr/AnalyzingParser.class b/src/main/resources/org/python/antlr/AnalyzingParser.class new file mode 100644 index 0000000000000000000000000000000000000000..8a0815f2d599bf48c3fd3f51388eaf1cb9f79d91 Binary files /dev/null and b/src/main/resources/org/python/antlr/AnalyzingParser.class differ diff --git a/src/main/resources/org/python/antlr/BaseParser.class b/src/main/resources/org/python/antlr/BaseParser.class new file mode 100644 index 0000000000000000000000000000000000000000..ebb7b5f9f3aebbfaa8291216600478dd7472f2a7 Binary files /dev/null and b/src/main/resources/org/python/antlr/BaseParser.class differ diff --git a/src/main/resources/org/python/antlr/ErrorHandler.class b/src/main/resources/org/python/antlr/ErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..38de33a7292b326deaf8c85fef8d65cb2c2725ab Binary files /dev/null and b/src/main/resources/org/python/antlr/ErrorHandler.class differ diff --git a/src/main/resources/org/python/antlr/FailFastHandler.class b/src/main/resources/org/python/antlr/FailFastHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..726a1e4034a960d37f34e8012303e3d29195c754 Binary files /dev/null and b/src/main/resources/org/python/antlr/FailFastHandler.class differ diff --git a/src/main/resources/org/python/antlr/GrammarActions$StringPair.class b/src/main/resources/org/python/antlr/GrammarActions$StringPair.class new file mode 100644 index 0000000000000000000000000000000000000000..e768602657e6a221cce5fd573f1fe27aefb0c646 Binary files /dev/null and b/src/main/resources/org/python/antlr/GrammarActions$StringPair.class differ diff --git a/src/main/resources/org/python/antlr/GrammarActions.class b/src/main/resources/org/python/antlr/GrammarActions.class new file mode 100644 index 0000000000000000000000000000000000000000..af4052f857aaacebd11e0d5c1d307a69c6c3db8f Binary files /dev/null and b/src/main/resources/org/python/antlr/GrammarActions.class differ diff --git a/src/main/resources/org/python/antlr/GrammarTester.class b/src/main/resources/org/python/antlr/GrammarTester.class new file mode 100644 index 0000000000000000000000000000000000000000..995d87790c8c963ee7445a7776584208a15a1303 Binary files /dev/null and b/src/main/resources/org/python/antlr/GrammarTester.class differ diff --git a/src/main/resources/org/python/antlr/ListErrorHandler.class b/src/main/resources/org/python/antlr/ListErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..4cbbf5a910d3c19f732ea1cb35136601bd76009a Binary files /dev/null and b/src/main/resources/org/python/antlr/ListErrorHandler.class differ diff --git a/src/main/resources/org/python/antlr/NoCloseReaderStream.class b/src/main/resources/org/python/antlr/NoCloseReaderStream.class new file mode 100644 index 0000000000000000000000000000000000000000..2fe6f4fdbdeb9307d408b40be30355e2e1a6dc92 Binary files /dev/null and b/src/main/resources/org/python/antlr/NoCloseReaderStream.class differ diff --git a/src/main/resources/org/python/antlr/ParseException.class b/src/main/resources/org/python/antlr/ParseException.class new file mode 100644 index 0000000000000000000000000000000000000000..ffc92f91e695b897e4f35900ad9aa08e1265c5e9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ParseException.class differ diff --git a/src/main/resources/org/python/antlr/PythonErrorNode.class b/src/main/resources/org/python/antlr/PythonErrorNode.class new file mode 100644 index 0000000000000000000000000000000000000000..dbc89ec0927cd3432232fdf730d00424fc64c930 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonErrorNode.class differ diff --git a/src/main/resources/org/python/antlr/PythonLexer$DFA14.class b/src/main/resources/org/python/antlr/PythonLexer$DFA14.class new file mode 100644 index 0000000000000000000000000000000000000000..6ed13ce5fc424023c9c3dbb40f74d678777fa356 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonLexer$DFA14.class differ diff --git a/src/main/resources/org/python/antlr/PythonLexer$DFA17.class b/src/main/resources/org/python/antlr/PythonLexer$DFA17.class new file mode 100644 index 0000000000000000000000000000000000000000..69731ca41e1a8031be81914e5f3cd1844218a5dd Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonLexer$DFA17.class differ diff --git a/src/main/resources/org/python/antlr/PythonLexer$DFA45.class b/src/main/resources/org/python/antlr/PythonLexer$DFA45.class new file mode 100644 index 0000000000000000000000000000000000000000..9a4e8ce7becefbda8bb44262de8b6da8f0e24010 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonLexer$DFA45.class differ diff --git a/src/main/resources/org/python/antlr/PythonLexer$DFA46.class b/src/main/resources/org/python/antlr/PythonLexer$DFA46.class new file mode 100644 index 0000000000000000000000000000000000000000..68ef087e3e2867db3a598d7bbc7e0eff2775c33b Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonLexer$DFA46.class differ diff --git a/src/main/resources/org/python/antlr/PythonLexer$DFA5.class b/src/main/resources/org/python/antlr/PythonLexer$DFA5.class new file mode 100644 index 0000000000000000000000000000000000000000..7a0323c537f3373e6803ec3e5d2bf4059eeee610 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonLexer$DFA5.class differ diff --git a/src/main/resources/org/python/antlr/PythonLexer.class b/src/main/resources/org/python/antlr/PythonLexer.class new file mode 100644 index 0000000000000000000000000000000000000000..9c2589863a5a3767eaa25cabfcce983e599d1524 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonLexer.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA112.class b/src/main/resources/org/python/antlr/PythonParser$DFA112.class new file mode 100644 index 0000000000000000000000000000000000000000..af432cd09080336ac5a21269c64f6a2e078b31d4 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA112.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA116.class b/src/main/resources/org/python/antlr/PythonParser$DFA116.class new file mode 100644 index 0000000000000000000000000000000000000000..6e3071745c49c56bdb3eaae75fb85e940f57d41c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA116.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA129.class b/src/main/resources/org/python/antlr/PythonParser$DFA129.class new file mode 100644 index 0000000000000000000000000000000000000000..0ec04b31e89020db8c62642e272da5e7ad405257 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA129.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA131.class b/src/main/resources/org/python/antlr/PythonParser$DFA131.class new file mode 100644 index 0000000000000000000000000000000000000000..dad99f4895b61ad43b791999eb106df86c4eb02e Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA131.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA133.class b/src/main/resources/org/python/antlr/PythonParser$DFA133.class new file mode 100644 index 0000000000000000000000000000000000000000..e55ff975c1316f87372df32f6fb3350e68ca56bf Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA133.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA134.class b/src/main/resources/org/python/antlr/PythonParser$DFA134.class new file mode 100644 index 0000000000000000000000000000000000000000..948b131793ca40c79fd658aade9872c6e891fdaa Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA134.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA136.class b/src/main/resources/org/python/antlr/PythonParser$DFA136.class new file mode 100644 index 0000000000000000000000000000000000000000..8e45666eccbcaee32876823cb1abf81b8bcf8196 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA136.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA138.class b/src/main/resources/org/python/antlr/PythonParser$DFA138.class new file mode 100644 index 0000000000000000000000000000000000000000..3506e6eb232e58cc358b6392d9e4a7f9807ef1f4 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA138.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA139.class b/src/main/resources/org/python/antlr/PythonParser$DFA139.class new file mode 100644 index 0000000000000000000000000000000000000000..2354c6d73d1e7c339dc3c032644fddcdcf0614d8 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA139.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA30.class b/src/main/resources/org/python/antlr/PythonParser$DFA30.class new file mode 100644 index 0000000000000000000000000000000000000000..f9f84664bd2d81d7633839f93edf3dee8189970c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA30.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA31.class b/src/main/resources/org/python/antlr/PythonParser$DFA31.class new file mode 100644 index 0000000000000000000000000000000000000000..591ace25314932030df523b61542d90bc86247ae Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA31.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA35.class b/src/main/resources/org/python/antlr/PythonParser$DFA35.class new file mode 100644 index 0000000000000000000000000000000000000000..d024d0f864336a92e81fcf8bd65197765db2e39b Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA35.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA38.class b/src/main/resources/org/python/antlr/PythonParser$DFA38.class new file mode 100644 index 0000000000000000000000000000000000000000..b545a62fa192a6e36ee1eac8c15acb377068c56e Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA38.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA40.class b/src/main/resources/org/python/antlr/PythonParser$DFA40.class new file mode 100644 index 0000000000000000000000000000000000000000..d7f009cf114e6cb89b24b8b1205329ecb03545ed Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA40.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA41.class b/src/main/resources/org/python/antlr/PythonParser$DFA41.class new file mode 100644 index 0000000000000000000000000000000000000000..062adf7e73bd81e3c2b1c7c108e7d8e67b56d27d Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA41.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA43.class b/src/main/resources/org/python/antlr/PythonParser$DFA43.class new file mode 100644 index 0000000000000000000000000000000000000000..8d23aac1e5574001584803d0e8a9d2fb836a718f Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA43.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA52.class b/src/main/resources/org/python/antlr/PythonParser$DFA52.class new file mode 100644 index 0000000000000000000000000000000000000000..14410a931c194464df4fb15b69391168c1ec0246 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA52.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA80.class b/src/main/resources/org/python/antlr/PythonParser$DFA80.class new file mode 100644 index 0000000000000000000000000000000000000000..494d554c3dc2f93ab54300d3e56cb461b942daf7 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA80.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$DFA89.class b/src/main/resources/org/python/antlr/PythonParser$DFA89.class new file mode 100644 index 0000000000000000000000000000000000000000..d12f9467a44a745624b05f43ba119908823c6f27 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$DFA89.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$and_expr_return.class b/src/main/resources/org/python/antlr/PythonParser$and_expr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..cb166f295fcc74c84e16df5d92ccd34c18f0dc86 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$and_expr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$and_test_return.class b/src/main/resources/org/python/antlr/PythonParser$and_test_return.class new file mode 100644 index 0000000000000000000000000000000000000000..64973f6e2e0cdc9b2912ad9a29152c8e1017c64e Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$and_test_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$arglist_return.class b/src/main/resources/org/python/antlr/PythonParser$arglist_return.class new file mode 100644 index 0000000000000000000000000000000000000000..091f08fba0827bc85f9446a618c487e4975c99a1 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$arglist_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$argument_return.class b/src/main/resources/org/python/antlr/PythonParser$argument_return.class new file mode 100644 index 0000000000000000000000000000000000000000..efbab0d41952ace19a41db0c81d6147e19a8dda4 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$argument_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$arith_expr_return.class b/src/main/resources/org/python/antlr/PythonParser$arith_expr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..80c7f1bc7e323939c801318a260e92be12e77b4d Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$arith_expr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$arith_op_return.class b/src/main/resources/org/python/antlr/PythonParser$arith_op_return.class new file mode 100644 index 0000000000000000000000000000000000000000..5a560125813010f33959d52ce0d6bb92bbe148b4 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$arith_op_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$assert_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$assert_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..ce0bb4e228a2f4c6ba49447e3b1cafd750fc115d Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$assert_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$atom_return.class b/src/main/resources/org/python/antlr/PythonParser$atom_return.class new file mode 100644 index 0000000000000000000000000000000000000000..14e3f6e9bece9f8db85811e085719e2f1690bb17 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$atom_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$attr_return.class b/src/main/resources/org/python/antlr/PythonParser$attr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..6ade506ba1a3b609bd7b44fe170a15c9778aafe5 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$attr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$augassign_return.class b/src/main/resources/org/python/antlr/PythonParser$augassign_return.class new file mode 100644 index 0000000000000000000000000000000000000000..5409d3dd2a828f175b4f3f285322c983d4abe82a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$augassign_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$break_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$break_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..d5a06c4c247d438b4f4c9dfc021349ce350f5138 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$break_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$classdef_return.class b/src/main/resources/org/python/antlr/PythonParser$classdef_return.class new file mode 100644 index 0000000000000000000000000000000000000000..d7b6527d077a03527413fc4576518c00c0a38451 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$classdef_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$comp_for_return.class b/src/main/resources/org/python/antlr/PythonParser$comp_for_return.class new file mode 100644 index 0000000000000000000000000000000000000000..b82b10163b06201fd0c7c6a0fc947eb7507ea79c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$comp_for_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$comp_if_return.class b/src/main/resources/org/python/antlr/PythonParser$comp_if_return.class new file mode 100644 index 0000000000000000000000000000000000000000..3331a30219b3a58c24831ad04235bdc766d29ec5 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$comp_if_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$comp_iter_return.class b/src/main/resources/org/python/antlr/PythonParser$comp_iter_return.class new file mode 100644 index 0000000000000000000000000000000000000000..6ff84649cfad9fee355fa24f7d67818a6971baef Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$comp_iter_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$comp_op_return.class b/src/main/resources/org/python/antlr/PythonParser$comp_op_return.class new file mode 100644 index 0000000000000000000000000000000000000000..ba81941c1f02698c089aa0325b87867484ef5098 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$comp_op_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$comparison_return.class b/src/main/resources/org/python/antlr/PythonParser$comparison_return.class new file mode 100644 index 0000000000000000000000000000000000000000..b25a170ca57854c80db5e82c317811dcfb2be48c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$comparison_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$compound_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$compound_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..8c50934d012bc2ec054fa82e9d6c315f06bfa6ed Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$compound_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$continue_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$continue_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..7bd2b60175749d09416a48c475abb2ec43acf354 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$continue_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$decorator_return.class b/src/main/resources/org/python/antlr/PythonParser$decorator_return.class new file mode 100644 index 0000000000000000000000000000000000000000..834414ab0bbf732e262123f0459d6c3df5b1b856 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$decorator_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$decorators_return.class b/src/main/resources/org/python/antlr/PythonParser$decorators_return.class new file mode 100644 index 0000000000000000000000000000000000000000..8520ac46fb7a15cf9e8257455808ea6bed34e27a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$decorators_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$defparameter_return.class b/src/main/resources/org/python/antlr/PythonParser$defparameter_return.class new file mode 100644 index 0000000000000000000000000000000000000000..19569e58299770f6813223623a06c39478fe4172 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$defparameter_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$del_list_return.class b/src/main/resources/org/python/antlr/PythonParser$del_list_return.class new file mode 100644 index 0000000000000000000000000000000000000000..ef16d9633a389cea6fbe29f054371638f98d697a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$del_list_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$del_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$del_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..e84203ec0980b7e7d12d7916570e7326d79da17c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$del_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$dictorsetmaker_return.class b/src/main/resources/org/python/antlr/PythonParser$dictorsetmaker_return.class new file mode 100644 index 0000000000000000000000000000000000000000..e0d3c1e42068da3126a5c3cb6293d07616868374 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$dictorsetmaker_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$dotted_as_name_return.class b/src/main/resources/org/python/antlr/PythonParser$dotted_as_name_return.class new file mode 100644 index 0000000000000000000000000000000000000000..d178d2b1aa3d7dae7b94a1e11075f322122b6997 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$dotted_as_name_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$dotted_as_names_return.class b/src/main/resources/org/python/antlr/PythonParser$dotted_as_names_return.class new file mode 100644 index 0000000000000000000000000000000000000000..65493aa089d2a91b178ed8198f4ae6e177427a03 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$dotted_as_names_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$dotted_attr_return.class b/src/main/resources/org/python/antlr/PythonParser$dotted_attr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..76d681cbf2231924fba98e7a878ff82c59b372b8 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$dotted_attr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$dotted_name_return.class b/src/main/resources/org/python/antlr/PythonParser$dotted_name_return.class new file mode 100644 index 0000000000000000000000000000000000000000..41bd9e898177009aa0ae14e474fb7ff79b4d02d3 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$dotted_name_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$elif_clause_return.class b/src/main/resources/org/python/antlr/PythonParser$elif_clause_return.class new file mode 100644 index 0000000000000000000000000000000000000000..df05ab2d567f5b858b9a38ff72b43087ac8d0184 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$elif_clause_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$else_clause_return.class b/src/main/resources/org/python/antlr/PythonParser$else_clause_return.class new file mode 100644 index 0000000000000000000000000000000000000000..c47df3ba605f7131cb93375768fed49205b757fd Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$else_clause_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$eval_input_return.class b/src/main/resources/org/python/antlr/PythonParser$eval_input_return.class new file mode 100644 index 0000000000000000000000000000000000000000..5f9f637f8f67316b7d06568dfd9d081a75bc9d5d Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$eval_input_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$except_clause_return.class b/src/main/resources/org/python/antlr/PythonParser$except_clause_return.class new file mode 100644 index 0000000000000000000000000000000000000000..a44220567f0d14b9b5c035dbec4b30f689325cf1 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$except_clause_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$exec_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$exec_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..a3b3f63d60f703c6499e7250574f43b49bf409ea Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$exec_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$expr_return.class b/src/main/resources/org/python/antlr/PythonParser$expr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..3c78b26e20ee33cfdc9d25e851e05f78b6022623 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$expr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$expr_scope.class b/src/main/resources/org/python/antlr/PythonParser$expr_scope.class new file mode 100644 index 0000000000000000000000000000000000000000..1562c3791e46d8bc11c01000e9759b62f9d638f1 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$expr_scope.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$expr_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$expr_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..c3f633e115b2002c8f82959335347d39cb6496b3 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$expr_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$exprlist_return.class b/src/main/resources/org/python/antlr/PythonParser$exprlist_return.class new file mode 100644 index 0000000000000000000000000000000000000000..00ac671e7bb45e11847b68848fbd4c1a6bde5c6b Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$exprlist_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$factor_return.class b/src/main/resources/org/python/antlr/PythonParser$factor_return.class new file mode 100644 index 0000000000000000000000000000000000000000..5673dc2af88721b4def6cda08202570935c8146e Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$factor_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$file_input_return.class b/src/main/resources/org/python/antlr/PythonParser$file_input_return.class new file mode 100644 index 0000000000000000000000000000000000000000..be699dde49ef668a995533ea7b8f0a7b2c81a11d Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$file_input_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$flow_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$flow_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..34a52c06bc4989ba603d76e11d5ca2b73a7c61aa Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$flow_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$for_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$for_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..ee0f414ae613cd3e1d35ef907d76d4e39ca5bef2 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$for_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$fpdef_return.class b/src/main/resources/org/python/antlr/PythonParser$fpdef_return.class new file mode 100644 index 0000000000000000000000000000000000000000..010e8f1f1f889120cb6c1f0eb8d8161f331dff2b Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$fpdef_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$fplist_return.class b/src/main/resources/org/python/antlr/PythonParser$fplist_return.class new file mode 100644 index 0000000000000000000000000000000000000000..1fee9bdddcfc9b18107fcea299281ff8ecd41738 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$fplist_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$funcdef_return.class b/src/main/resources/org/python/antlr/PythonParser$funcdef_return.class new file mode 100644 index 0000000000000000000000000000000000000000..a24983ce38aef2a07af156af1d9179f393c3d211 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$funcdef_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$global_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$global_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..3e03985e6325a8f3699242da9e3be4a6395f138d Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$global_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$if_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$if_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..679cce60a86fd17d0f0e335b5c7fc91ba3e00ed5 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$if_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$import_as_name_return.class b/src/main/resources/org/python/antlr/PythonParser$import_as_name_return.class new file mode 100644 index 0000000000000000000000000000000000000000..8ac77399a7a5faed6551d527e2fb80ecb61d858c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$import_as_name_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$import_as_names_return.class b/src/main/resources/org/python/antlr/PythonParser$import_as_names_return.class new file mode 100644 index 0000000000000000000000000000000000000000..418a968b83b5e69e41ce144ac0cf72dde984199c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$import_as_names_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$import_from_return.class b/src/main/resources/org/python/antlr/PythonParser$import_from_return.class new file mode 100644 index 0000000000000000000000000000000000000000..fe6281712475ee883a0258a9fe54e8c6c373fa99 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$import_from_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$import_name_return.class b/src/main/resources/org/python/antlr/PythonParser$import_name_return.class new file mode 100644 index 0000000000000000000000000000000000000000..c8a5e4ca8efc1c3f11db5a198f3f95b614c838dd Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$import_name_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$import_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$import_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..b069ead664d8511621b9fbc8fbe34865e4420962 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$import_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$lambdef_return.class b/src/main/resources/org/python/antlr/PythonParser$lambdef_return.class new file mode 100644 index 0000000000000000000000000000000000000000..2aeeb83d4d0d5b670a6e4f9c1a86e7a383e9366c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$lambdef_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$list_for_return.class b/src/main/resources/org/python/antlr/PythonParser$list_for_return.class new file mode 100644 index 0000000000000000000000000000000000000000..e1a9caa50cf0d05b8722a57191ea508e23630ee2 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$list_for_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$list_if_return.class b/src/main/resources/org/python/antlr/PythonParser$list_if_return.class new file mode 100644 index 0000000000000000000000000000000000000000..9d70b261d7e38d17b860d6da2f957765c01004fd Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$list_if_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$list_iter_return.class b/src/main/resources/org/python/antlr/PythonParser$list_iter_return.class new file mode 100644 index 0000000000000000000000000000000000000000..b2c4c54acb04c04ccf545cf85dd82d61358f2ac3 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$list_iter_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$listmaker_return.class b/src/main/resources/org/python/antlr/PythonParser$listmaker_return.class new file mode 100644 index 0000000000000000000000000000000000000000..d25a8a64d687f3de1f9dc092b74ab9630a8747a7 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$listmaker_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$name_or_print_return.class b/src/main/resources/org/python/antlr/PythonParser$name_or_print_return.class new file mode 100644 index 0000000000000000000000000000000000000000..78e987af19ec466c55c6118c0833caa995cad108 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$name_or_print_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$not_test_return.class b/src/main/resources/org/python/antlr/PythonParser$not_test_return.class new file mode 100644 index 0000000000000000000000000000000000000000..a828491aee4fa0293375cb5957a2d069a327b3d3 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$not_test_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$or_test_return.class b/src/main/resources/org/python/antlr/PythonParser$or_test_return.class new file mode 100644 index 0000000000000000000000000000000000000000..308ab9172b123ded987af45599613466f858de3c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$or_test_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$parameters_return.class b/src/main/resources/org/python/antlr/PythonParser$parameters_return.class new file mode 100644 index 0000000000000000000000000000000000000000..112727e382537578a22f0830bc6c301c5cd161fc Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$parameters_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$pass_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$pass_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..a60412e6499a9e2783dd65c719573037efccde87 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$pass_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$power_return.class b/src/main/resources/org/python/antlr/PythonParser$power_return.class new file mode 100644 index 0000000000000000000000000000000000000000..2a09f659eae917fd6638f11d97972cf90f081837 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$power_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$print_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$print_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..14b18f5c6e717f5364dc987426e21ad5077e241b Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$print_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$printlist2_return.class b/src/main/resources/org/python/antlr/PythonParser$printlist2_return.class new file mode 100644 index 0000000000000000000000000000000000000000..6ca8732728257ad8f0f5ab8a75488af35d4647a6 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$printlist2_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$printlist_return.class b/src/main/resources/org/python/antlr/PythonParser$printlist_return.class new file mode 100644 index 0000000000000000000000000000000000000000..6a4acebf44aa56cc631b73795308c8aed58eee19 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$printlist_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$raise_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$raise_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..467706d6aa7effb191c955ac4c8f163a79aefa42 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$raise_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$return_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$return_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..e9ad4f1c184bcc1be5f65cebca132c2f4e2bfddd Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$return_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$shift_expr_return.class b/src/main/resources/org/python/antlr/PythonParser$shift_expr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..7ac548bcf17597dd52de5641722ffa1de39acbd5 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$shift_expr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$shift_op_return.class b/src/main/resources/org/python/antlr/PythonParser$shift_op_return.class new file mode 100644 index 0000000000000000000000000000000000000000..224d0560e2be13a6981f90a6f231e32f5e3ea072 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$shift_op_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$simple_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$simple_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..dc742ba0e23267d05c8833599d1c1441a1cc4926 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$simple_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$single_input_return.class b/src/main/resources/org/python/antlr/PythonParser$single_input_return.class new file mode 100644 index 0000000000000000000000000000000000000000..26c52674dc524c43e07f7bdc6930c530574de779 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$single_input_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$sliceop_return.class b/src/main/resources/org/python/antlr/PythonParser$sliceop_return.class new file mode 100644 index 0000000000000000000000000000000000000000..babefb791a8aca8b2450e6141195c18c2f875bd3 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$sliceop_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$small_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$small_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..43b27e6a2529bbf1119b9176cb6942e2a02646ca Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$small_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..90de4d0e7571052b3bad3a5ab37724331b764fe6 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$subscript_return.class b/src/main/resources/org/python/antlr/PythonParser$subscript_return.class new file mode 100644 index 0000000000000000000000000000000000000000..dd611f8fc04fc3e05f6a4f677ca92324c69b0a3c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$subscript_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$subscriptlist_return.class b/src/main/resources/org/python/antlr/PythonParser$subscriptlist_return.class new file mode 100644 index 0000000000000000000000000000000000000000..54d1bb1d3f714ddce31516ddb509d068b7d65e4e Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$subscriptlist_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$suite_return.class b/src/main/resources/org/python/antlr/PythonParser$suite_return.class new file mode 100644 index 0000000000000000000000000000000000000000..a2988ea967949a6085b70407938b0e353c335d1a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$suite_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$suite_scope.class b/src/main/resources/org/python/antlr/PythonParser$suite_scope.class new file mode 100644 index 0000000000000000000000000000000000000000..fe66a90594620c43e9600181face525e6e46c1e5 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$suite_scope.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$term_op_return.class b/src/main/resources/org/python/antlr/PythonParser$term_op_return.class new file mode 100644 index 0000000000000000000000000000000000000000..13d1986f0d58904d13e41c0c92f3ed8d3477c386 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$term_op_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$term_return.class b/src/main/resources/org/python/antlr/PythonParser$term_return.class new file mode 100644 index 0000000000000000000000000000000000000000..7b82b39b8ff5a3d3d501bc1f529f70d21057d82b Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$term_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$test_return.class b/src/main/resources/org/python/antlr/PythonParser$test_return.class new file mode 100644 index 0000000000000000000000000000000000000000..b4d1c4182d29dfc789b1154b209352f5cb4fb2b7 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$test_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$testlist_gexp_return.class b/src/main/resources/org/python/antlr/PythonParser$testlist_gexp_return.class new file mode 100644 index 0000000000000000000000000000000000000000..895ad8d5e1adab6b4f3ef269c52f999040276a54 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$testlist_gexp_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$testlist_return.class b/src/main/resources/org/python/antlr/PythonParser$testlist_return.class new file mode 100644 index 0000000000000000000000000000000000000000..804df121f0953cf469c9efd0c27a326e03540692 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$testlist_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$trailer_return.class b/src/main/resources/org/python/antlr/PythonParser$trailer_return.class new file mode 100644 index 0000000000000000000000000000000000000000..90f3461f9e7e63b0d5a480b0fe445586d5278a03 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$trailer_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$try_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$try_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..4e6664ad2e6d2575bcb697f76a1597222e0f6980 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$try_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$varargslist_return.class b/src/main/resources/org/python/antlr/PythonParser$varargslist_return.class new file mode 100644 index 0000000000000000000000000000000000000000..1fd12a2111ae2b7f514a2863b05e11a5d3169d75 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$varargslist_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$while_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$while_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..8a25c94e51d3c03aa0a8cdcf74d55f80be7d60fe Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$while_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$with_item_return.class b/src/main/resources/org/python/antlr/PythonParser$with_item_return.class new file mode 100644 index 0000000000000000000000000000000000000000..ad6dc2e5e6d08ad48a5ffe1df448e1fe4c242173 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$with_item_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$with_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$with_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..33fd7175dc0364eee3b287645c5ae793341a6860 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$with_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$xor_expr_return.class b/src/main/resources/org/python/antlr/PythonParser$xor_expr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..8f7c90599e068b06aad3a309e050ffe5a84c5a51 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$xor_expr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$yield_expr_return.class b/src/main/resources/org/python/antlr/PythonParser$yield_expr_return.class new file mode 100644 index 0000000000000000000000000000000000000000..22f1f98f4310efbaa17e6fcd7c21753490773acc Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$yield_expr_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser$yield_stmt_return.class b/src/main/resources/org/python/antlr/PythonParser$yield_stmt_return.class new file mode 100644 index 0000000000000000000000000000000000000000..7720679a52aff6197a1236a3d6d1006038a1c256 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser$yield_stmt_return.class differ diff --git a/src/main/resources/org/python/antlr/PythonParser.class b/src/main/resources/org/python/antlr/PythonParser.class new file mode 100644 index 0000000000000000000000000000000000000000..a712e4df59ac7c886804ee422d4f72af8e9f50ba Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonParser.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA12.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA12.class new file mode 100644 index 0000000000000000000000000000000000000000..5d1b3a89264f66333b5ec7ce4cd17df6a608a432 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA12.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA15.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA15.class new file mode 100644 index 0000000000000000000000000000000000000000..9d61237817e6d7c8ee1eb3e82585bb175d06799f Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA15.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA21.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA21.class new file mode 100644 index 0000000000000000000000000000000000000000..01678201ba2ffb838681c5cd7e0d460ddf86546a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA21.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA25.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA25.class new file mode 100644 index 0000000000000000000000000000000000000000..8edf37619cb8a91b509205bbc5c98a2762d94551 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA25.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA26.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA26.class new file mode 100644 index 0000000000000000000000000000000000000000..f4814c464c4c9b99508e0976bf9c8c05a1218823 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA26.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA27.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA27.class new file mode 100644 index 0000000000000000000000000000000000000000..6791e45f108153f22713ec2d0d91df0fc75f4b00 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA27.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA5.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA5.class new file mode 100644 index 0000000000000000000000000000000000000000..51e40a1c50c53ded07ef91ac1cb79e123296e65c Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA5.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA51.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA51.class new file mode 100644 index 0000000000000000000000000000000000000000..24d95a0d5e7f49076221a51c2a66ac1431f14c98 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA51.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer$DFA52.class b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA52.class new file mode 100644 index 0000000000000000000000000000000000000000..aa45e379ad375ee121b400fc4d492499fca16dee Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer$DFA52.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialLexer.class b/src/main/resources/org/python/antlr/PythonPartialLexer.class new file mode 100644 index 0000000000000000000000000000000000000000..9c9615ca93821069b0c615f08894a3c90ca95af9 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialLexer.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA107.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA107.class new file mode 100644 index 0000000000000000000000000000000000000000..04d51a7e6a5762881cc9bc36847a51f43eee971f Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA107.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA120.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA120.class new file mode 100644 index 0000000000000000000000000000000000000000..efe8b02d427d23efc1030a2cc3662c21e54fa2e2 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA120.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA122.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA122.class new file mode 100644 index 0000000000000000000000000000000000000000..51223cb0b56c8a6f6129fda3a64e5843d9998764 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA122.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA124.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA124.class new file mode 100644 index 0000000000000000000000000000000000000000..41cbf639b8488579201d9712151233e71a3b414e Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA124.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA125.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA125.class new file mode 100644 index 0000000000000000000000000000000000000000..fc17d615c8a29ee88acf502f0eac0552fad073e1 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA125.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA127.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA127.class new file mode 100644 index 0000000000000000000000000000000000000000..a50ce13c7051aa587a10fb6d7651f66e8e2eb9e8 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA127.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA129.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA129.class new file mode 100644 index 0000000000000000000000000000000000000000..b633b1ad3963d7e07d1bb116aaaba61dbd816568 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA129.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA130.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA130.class new file mode 100644 index 0000000000000000000000000000000000000000..ab0827f597f78845462b673c51bc07d390a9908d Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA130.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA27.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA27.class new file mode 100644 index 0000000000000000000000000000000000000000..375eece03b40ad7fb04eb224f4f02fbc73345c8e Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA27.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA32.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA32.class new file mode 100644 index 0000000000000000000000000000000000000000..13031a15f1f5baea3b5c765690fae887bc55dcc3 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA32.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA34.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA34.class new file mode 100644 index 0000000000000000000000000000000000000000..68efd68e8b7c3982362d1c772886f572a0c4b94a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA34.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA36.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA36.class new file mode 100644 index 0000000000000000000000000000000000000000..e6de06fa89b6d8c1ae61caabbaab68a58f540e98 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA36.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA45.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA45.class new file mode 100644 index 0000000000000000000000000000000000000000..914cca6d247e69a86f73850afad21d8b41f70712 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA45.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA57.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA57.class new file mode 100644 index 0000000000000000000000000000000000000000..1a0a0ea8980b3474b4221ba1849830fcf89e821a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA57.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA74.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA74.class new file mode 100644 index 0000000000000000000000000000000000000000..7831d8642d7a142ea8790ac8ff4739b9133aff23 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA74.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser$DFA83.class b/src/main/resources/org/python/antlr/PythonPartialParser$DFA83.class new file mode 100644 index 0000000000000000000000000000000000000000..3ffb71e2385c9acba0546915dcba4e280bdef3a1 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser$DFA83.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialParser.class b/src/main/resources/org/python/antlr/PythonPartialParser.class new file mode 100644 index 0000000000000000000000000000000000000000..c0a180b8135e4c769956098171e6bdff17aced80 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialParser.class differ diff --git a/src/main/resources/org/python/antlr/PythonPartialTester.class b/src/main/resources/org/python/antlr/PythonPartialTester.class new file mode 100644 index 0000000000000000000000000000000000000000..a64427b15e937927e3a421e67abdfa2492d47ff0 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonPartialTester.class differ diff --git a/src/main/resources/org/python/antlr/PythonTokenSource.class b/src/main/resources/org/python/antlr/PythonTokenSource.class new file mode 100644 index 0000000000000000000000000000000000000000..3141209289f5c0f8e2691c180c96d0defdb00d5a Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonTokenSource.class differ diff --git a/src/main/resources/org/python/antlr/PythonTree.class b/src/main/resources/org/python/antlr/PythonTree.class new file mode 100644 index 0000000000000000000000000000000000000000..988c03676b4161fb29f0c665f17ae2de081cbba4 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonTree.class differ diff --git a/src/main/resources/org/python/antlr/PythonTreeAdaptor.class b/src/main/resources/org/python/antlr/PythonTreeAdaptor.class new file mode 100644 index 0000000000000000000000000000000000000000..eab19be8448a3790850ec7f637bbdae91d8594d3 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonTreeAdaptor.class differ diff --git a/src/main/resources/org/python/antlr/PythonTreeTester$1.class b/src/main/resources/org/python/antlr/PythonTreeTester$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3193aa1fb1bef859a07bdac05c10fdf419e1abd2 Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonTreeTester$1.class differ diff --git a/src/main/resources/org/python/antlr/PythonTreeTester$Block.class b/src/main/resources/org/python/antlr/PythonTreeTester$Block.class new file mode 100644 index 0000000000000000000000000000000000000000..ebe6a743115f0d9a2983ded218cfe12f4c8705ae Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonTreeTester$Block.class differ diff --git a/src/main/resources/org/python/antlr/PythonTreeTester.class b/src/main/resources/org/python/antlr/PythonTreeTester.class new file mode 100644 index 0000000000000000000000000000000000000000..7e273543978c4a01e24ff564f2d9bf94a8b1953f Binary files /dev/null and b/src/main/resources/org/python/antlr/PythonTreeTester.class differ diff --git a/src/main/resources/org/python/antlr/RecordingErrorHandler.class b/src/main/resources/org/python/antlr/RecordingErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..d8185c5a43a789f144c921c7b2ceb516c54a7e08 Binary files /dev/null and b/src/main/resources/org/python/antlr/RecordingErrorHandler.class differ diff --git a/src/main/resources/org/python/antlr/Visitor.class b/src/main/resources/org/python/antlr/Visitor.class new file mode 100644 index 0000000000000000000000000000000000000000..9b724dd0737d6e8250fecdc6de9d7cb4656511ea Binary files /dev/null and b/src/main/resources/org/python/antlr/Visitor.class differ diff --git a/src/main/resources/org/python/antlr/WalkerTester.class b/src/main/resources/org/python/antlr/WalkerTester.class new file mode 100644 index 0000000000000000000000000000000000000000..5887b4498731be405c4f86200fbfc3bad419b695 Binary files /dev/null and b/src/main/resources/org/python/antlr/WalkerTester.class differ diff --git a/src/main/resources/org/python/antlr/adapter/AliasAdapter.class b/src/main/resources/org/python/antlr/adapter/AliasAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..65b152f5e441805f21ff86cf673edff96fd207cd Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/AliasAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/AstAdapter.class b/src/main/resources/org/python/antlr/adapter/AstAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..66c2487e0f2010a7e274d42fccc8aeaad744091c Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/AstAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/AstAdapters$1.class b/src/main/resources/org/python/antlr/adapter/AstAdapters$1.class new file mode 100644 index 0000000000000000000000000000000000000000..bb6a8eb28e5a17e1e788a3e16d056dd330587ae0 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/AstAdapters$1.class differ diff --git a/src/main/resources/org/python/antlr/adapter/AstAdapters.class b/src/main/resources/org/python/antlr/adapter/AstAdapters.class new file mode 100644 index 0000000000000000000000000000000000000000..8e71a6958514f0f09450823f56c4be6ddbe53aa1 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/AstAdapters.class differ diff --git a/src/main/resources/org/python/antlr/adapter/CmpopAdapter$1.class b/src/main/resources/org/python/antlr/adapter/CmpopAdapter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d64c12906f406e0e755b3f4114aa25caf49941d1 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/CmpopAdapter$1.class differ diff --git a/src/main/resources/org/python/antlr/adapter/CmpopAdapter.class b/src/main/resources/org/python/antlr/adapter/CmpopAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..8f01c13367f889722169b99500f9a70afe15c159 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/CmpopAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/ComprehensionAdapter.class b/src/main/resources/org/python/antlr/adapter/ComprehensionAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..c3ff7c419866381763769ec82e18a71f608ae044 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/ComprehensionAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/ExcepthandlerAdapter.class b/src/main/resources/org/python/antlr/adapter/ExcepthandlerAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..4061596e8d97ceb2bde6c3ad4a382d56e3d70a45 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/ExcepthandlerAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/ExprAdapter.class b/src/main/resources/org/python/antlr/adapter/ExprAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..f5065cf97e38244bd2a38ed109d13a206cda8382 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/ExprAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/IdentifierAdapter.class b/src/main/resources/org/python/antlr/adapter/IdentifierAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..dc8011a37667e86d186b130f34cb0d16635b9f50 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/IdentifierAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/KeywordAdapter.class b/src/main/resources/org/python/antlr/adapter/KeywordAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..8dc8c2f32d2c458110e8b93b7b3334a608d42c6b Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/KeywordAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/SliceAdapter.class b/src/main/resources/org/python/antlr/adapter/SliceAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..57a2472af98767cec5fabc94c58d399af0c31410 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/SliceAdapter.class differ diff --git a/src/main/resources/org/python/antlr/adapter/StmtAdapter.class b/src/main/resources/org/python/antlr/adapter/StmtAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..4c3341707516c413b3fe784ea37d47aeef6f9b02 Binary files /dev/null and b/src/main/resources/org/python/antlr/adapter/StmtAdapter.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$Assert___init___exposer.class b/src/main/resources/org/python/antlr/ast/Assert$Assert___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..78181b068fb38f4242e73dc77f4d6f5602178c36 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$Assert___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$PyExposer.class b/src/main/resources/org/python/antlr/ast/Assert$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..19efcc09bae0163e63d30905bc0e1bd127480522 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Assert$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..042b5eee8c3fe2db8e895e337d1f286028d06d66 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Assert$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a927246a1387f6d9797e4ee830838cdf0cc8fe38 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Assert$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f4467a0c4971c8f27707afbf109e887c770a2484 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Assert$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..d63949ee906f7811ac9cc38e00219954c943929d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Assert$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b41003337f5b7a1299cb1f15a52692f686dbcf22 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$msg_descriptor.class b/src/main/resources/org/python/antlr/ast/Assert$msg_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5025066228abea91728867bb1b7b71a64b2a7726 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$msg_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Assert$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9dca735cf46e8ccab10631be8d244592e67a52a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert$test_descriptor.class b/src/main/resources/org/python/antlr/ast/Assert$test_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cde32a314c8970b4fb00ad6d65e55b0d39ca0eee Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert$test_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assert.class b/src/main/resources/org/python/antlr/ast/Assert.class new file mode 100644 index 0000000000000000000000000000000000000000..630852248bdbe654a539c6ca851695fa9fd1a761 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assert.class differ diff --git a/src/main/resources/org/python/antlr/ast/AssertDerived.class b/src/main/resources/org/python/antlr/ast/AssertDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..f892bd8e0e71a49ace5d96c310240983b2608af7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AssertDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$Assign___init___exposer.class b/src/main/resources/org/python/antlr/ast/Assign$Assign___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5b8937eb7c7b25e35a85158711f001aff7aafdf0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$Assign___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$PyExposer.class b/src/main/resources/org/python/antlr/ast/Assign$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f2d81c7bc7f077eb63c013ce6f15963e09c049ca Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Assign$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d6174c19f9fc3c563db13d281d7a5d81b897d5d7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Assign$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..50c5bde4f52d91b357f92813a2760a5ad2979769 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Assign$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..30040db14287a6fc76febab9b31d646f977fc0b9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Assign$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b4d14ba173ee4b32e6f6b96b5a6685e9cf5ca8f2 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Assign$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..18c553208e8f0aa9422427ca43aa9bd550d3db03 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Assign$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..229dab050dc2c3de94d1d69d1b828b32cf0851dc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$targets_descriptor.class b/src/main/resources/org/python/antlr/ast/Assign$targets_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f1553ee9f2846ea9b63d33285611bba79a89347d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$targets_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Assign$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9f29a3945dccf38f8d4557655338cbd33b2ec171 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Assign.class b/src/main/resources/org/python/antlr/ast/Assign.class new file mode 100644 index 0000000000000000000000000000000000000000..ad61e2a22ab39fdcd19c306e4221ba921b651272 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Assign.class differ diff --git a/src/main/resources/org/python/antlr/ast/AssignDerived.class b/src/main/resources/org/python/antlr/ast/AssignDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..7ade2a9615e95dd1eeb32ffe657712680fe6fd64 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AssignDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/AstModule.class b/src/main/resources/org/python/antlr/ast/AstModule.class new file mode 100644 index 0000000000000000000000000000000000000000..6ab09baa652749df7d62dc2381b5ed296605831d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AstModule.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$Attribute___init___exposer.class b/src/main/resources/org/python/antlr/ast/Attribute$Attribute___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f028a07d9cbf40e1ef1bf79f69c3b5466f7d59b7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$Attribute___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$PyExposer.class b/src/main/resources/org/python/antlr/ast/Attribute$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a5886353d81b921959589793c645da05f0b0f480 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7e5cc7ce8c696057a837137cd03714bd54838515 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..621f2133ed0f0a6c45348e8601f0c5d426330905 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$attr_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$attr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..731e6e52be55d058ce62d7156ab89476bb16eccf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$attr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..39c165a0545c4eb8036e18452a37a45eb6617906 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$ctx_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$ctx_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a8e949d3f5d67847edc81c4c4ac056f8ea27b292 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$ctx_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Attribute$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b15b3cdb5d9a0073b2408d94f0675b380100bb53 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e9054e5e9be70ea7177eddd75212300896f78df9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3770b4238f7af3e7116b6921acf814346fa83328 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Attribute$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3078d4b5568cf1582b0b8a0388cadba875c4110a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Attribute.class b/src/main/resources/org/python/antlr/ast/Attribute.class new file mode 100644 index 0000000000000000000000000000000000000000..34917de8a826b0c9fd81e786724a4333ec0f39f1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Attribute.class differ diff --git a/src/main/resources/org/python/antlr/ast/AttributeDerived.class b/src/main/resources/org/python/antlr/ast/AttributeDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..818f4047b4a130ab5a7ea35670e321dd30dc3aa1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AttributeDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$AugAssign___init___exposer.class b/src/main/resources/org/python/antlr/ast/AugAssign$AugAssign___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b0fc3c40d32a43d71553fcbeb8a93b996b562bbc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$AugAssign___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$PyExposer.class b/src/main/resources/org/python/antlr/ast/AugAssign$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..73b4eaab37c961f01fe78bbfe282ea8a083e8936 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..030fa90c33734b4743c67c3ff533f206c4ddc0a6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..79136600b43ad495a11ed88710329956410c12d0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..56540fda2fda5e3b9961dd5feaca5c45bf73204c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$exposed___new__.class b/src/main/resources/org/python/antlr/ast/AugAssign$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..8cfef675bd21ade1e95fc8b93d6644ac22b0dfbe Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2034d2636e157b36be726843b30940873a09ec84 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$op_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$op_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e5ff14c2c669f9fb604d980427b62d2ababd13de Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$op_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..213ca66dbb2f2e62eb7df5e36c211a4b265a10a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$target_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$target_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b875e21dba1ed19e2a4a62501593b11644eb5de2 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$target_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign$value_descriptor.class b/src/main/resources/org/python/antlr/ast/AugAssign$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..de20a8160990ac855f49b53daaab0b3da6c22e64 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssign.class b/src/main/resources/org/python/antlr/ast/AugAssign.class new file mode 100644 index 0000000000000000000000000000000000000000..941d78fc95ec145ca3ba42c3fd4ce65b72763820 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssign.class differ diff --git a/src/main/resources/org/python/antlr/ast/AugAssignDerived.class b/src/main/resources/org/python/antlr/ast/AugAssignDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..1168adf58bffe266045fa77cb722b984ad4096c5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/AugAssignDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$BinOp___init___exposer.class b/src/main/resources/org/python/antlr/ast/BinOp$BinOp___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..31ea5e68f93c3442cd842e7403794177b9f3994d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$BinOp___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$PyExposer.class b/src/main/resources/org/python/antlr/ast/BinOp$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c0c946ed6c8cd233a83da3e891ecd9634bc3147d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..233252541c1857c05fccf53fa7d4395dc717aa21 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9d8f625a28c28d011fe738d9166dd3607de45f77 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1edfc55913c9941cbf4e53e4e9182a2137e87829 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$exposed___new__.class b/src/main/resources/org/python/antlr/ast/BinOp$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b915f70ab5cfee5bf1ddd2392c57ed029f3415f6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$left_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$left_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c8263876692765bfedccc7b19238c03544cc9de4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$left_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c6a51512810f4b0d07488db29c417d106ae455ae Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$op_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$op_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a65968733517d821314a8ee0eccb63caa07b68f9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$op_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..67dd7091afa8d73f22e5489ca23c00d11559f972 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp$right_descriptor.class b/src/main/resources/org/python/antlr/ast/BinOp$right_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f687574d3402ed19153494943d9c2692c490eb08 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp$right_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOp.class b/src/main/resources/org/python/antlr/ast/BinOp.class new file mode 100644 index 0000000000000000000000000000000000000000..69d3628d27e596a3fce6b7716af0e52c970a96a7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOp.class differ diff --git a/src/main/resources/org/python/antlr/ast/BinOpDerived.class b/src/main/resources/org/python/antlr/ast/BinOpDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..90e9ac6e50b8cd657bf92b698c00e8ff734382e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BinOpDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$BoolOp___init___exposer.class b/src/main/resources/org/python/antlr/ast/BoolOp$BoolOp___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0415094941c9756a3bc536cdf69eab3bb56d1a7b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$BoolOp___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$PyExposer.class b/src/main/resources/org/python/antlr/ast/BoolOp$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f7bfad5c51768ad9cdf1f8e5d3142ea2fff776a6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/BoolOp$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..75d88b802805f0acbef6d2c98a1e38e1062ec230 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/BoolOp$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b110fbb747614dd2770745d231494d189c6e9e34 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/BoolOp$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e28e08440b749587cc5649ac566fb06248f6a8a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$exposed___new__.class b/src/main/resources/org/python/antlr/ast/BoolOp$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..049a6fb4ce4a3a8e44d333820e9083da2e528bcb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/BoolOp$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8994d343b432f1daf8d6df863ea610d866face41 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$op_descriptor.class b/src/main/resources/org/python/antlr/ast/BoolOp$op_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..195510324069b97f1407c8f28f5cc1e91446268e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$op_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/BoolOp$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d17494440d13e55c08efc7aeccb6a6a6397a3648 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp$values_descriptor.class b/src/main/resources/org/python/antlr/ast/BoolOp$values_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a281c3f0b0992171bef37930cd7f7b6b1fee7e5d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp$values_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOp.class b/src/main/resources/org/python/antlr/ast/BoolOp.class new file mode 100644 index 0000000000000000000000000000000000000000..40e3da8501f1ee4000201425da6841776666ed0f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOp.class differ diff --git a/src/main/resources/org/python/antlr/ast/BoolOpDerived.class b/src/main/resources/org/python/antlr/ast/BoolOpDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..9fdbf23229de3d0360826a2074aac9f0684588f0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BoolOpDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$Break___init___exposer.class b/src/main/resources/org/python/antlr/ast/Break$Break___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..531ddb8cbd67d11239aa91fbe5661a43717fe7de Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$Break___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$PyExposer.class b/src/main/resources/org/python/antlr/ast/Break$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..61435787bfcb5ab601324f55c263395c76becc06 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Break$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..33f097db95151d77e872bac67c57bc9d8eaf3bd9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Break$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ccb9441f80471e6608c6b65c0b10a034ff985c5a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Break$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..500d0ef408ead7dcbebc4ce9aa2c0d783f0dc871 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Break$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..0cff7dfe74c27841925a14feced5ce10b21722ce Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Break$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..20c0d5511094f7e32d1f50453bd3794a75fe6fe7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Break$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aab8f4f14447523ac36f13c80a9cfe814c04eb6d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Break.class b/src/main/resources/org/python/antlr/ast/Break.class new file mode 100644 index 0000000000000000000000000000000000000000..f6206459028d54bef11cc755af1ed7ae6a247a3d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Break.class differ diff --git a/src/main/resources/org/python/antlr/ast/BreakDerived.class b/src/main/resources/org/python/antlr/ast/BreakDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..e038fb244b6d52d1283a78d948c1aad654659820 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/BreakDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$Call___init___exposer.class b/src/main/resources/org/python/antlr/ast/Call$Call___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3d371429bc73fdfabe4b47941314ac654a82fabd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$Call___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$PyExposer.class b/src/main/resources/org/python/antlr/ast/Call$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6728ec837bd68957fcf842cb464f74bb6f7b168f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..60537bd320514bfd644dcea299b995a444bfa01e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..68a58103b3f7d0284062fa3766e0de8275b5c504 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$args_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$args_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..947e92f876bd2a70ead8a81088a71e4fc7f39cf3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$args_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5225b3ec1f01d53a96edfa4209ab864afc239ce4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Call$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..8fa35bc7397146be6c7a92d18128294265d30749 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$func_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$func_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a1a99bdc7f844e9f90721c04f514e83a7be71a2a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$func_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$keywords_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$keywords_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e874a1f4be514d8a49e15ad53a32a2cc807f6162 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$keywords_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$kwargs_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$kwargs_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ad481805f7dd8615d2bad89de53df83ac94684e4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$kwargs_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..adee2e02ba30bad8293f9a0c867e004e85d00010 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..29c02a3dc16eb0a03c723e3aa1e84db8f603abbf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call$starargs_descriptor.class b/src/main/resources/org/python/antlr/ast/Call$starargs_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cda726e75ecc8d80c29b4c43269f47aeb9563322 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call$starargs_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Call.class b/src/main/resources/org/python/antlr/ast/Call.class new file mode 100644 index 0000000000000000000000000000000000000000..f51b596fd6e9c9c8e64e2e5afddabe9207c1853d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Call.class differ diff --git a/src/main/resources/org/python/antlr/ast/CallDerived.class b/src/main/resources/org/python/antlr/ast/CallDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..22c432611ef03824776260c209b4f86df8a23b87 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/CallDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$ClassDef___init___exposer.class b/src/main/resources/org/python/antlr/ast/ClassDef$ClassDef___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..64df5bc0060ef318dc02f8d722cc56b2e5fbf09f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$ClassDef___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$PyExposer.class b/src/main/resources/org/python/antlr/ast/ClassDef$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..304d3f7aa3e1b13308d265ed87e49a4e5afe591e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1d74f75b935249ebad76c160859d0633c70a5b21 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..167e8a22b3042a55a78c130fafd791e6de5640dc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$bases_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$bases_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a3fc846db04e316060aeb5fe32be5814f03bce16 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$bases_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$body_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..41af8cc583f16348865b582ab93bb4a4b60b7a93 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ced670777026a0e6c3fd16225cd8a5f0e98ee6f3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$decorator_list_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$decorator_list_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..76edc2393b67032f2d643c43e7b6ea0fdd99e0f4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$decorator_list_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$exposed___new__.class b/src/main/resources/org/python/antlr/ast/ClassDef$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..fd2d8657652299a7e2a6366324bc9250fa049079 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..df6f21e9999d0e89718a10fd5cf82e90011b4c27 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$name_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$name_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8666cbf5bb2e721c1f42869c48a1ad02a56cd0c8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$name_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/ClassDef$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4f31d856a0b895eaa65a731c9b6eb96aa6614060 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDef.class b/src/main/resources/org/python/antlr/ast/ClassDef.class new file mode 100644 index 0000000000000000000000000000000000000000..39ee5bdebc3f5f52b126b34a63f168d0d06c0019 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDef.class differ diff --git a/src/main/resources/org/python/antlr/ast/ClassDefDerived.class b/src/main/resources/org/python/antlr/ast/ClassDefDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..1975151ed9b2528c5f2910d0089ec04c055feaaa Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ClassDefDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$Compare___init___exposer.class b/src/main/resources/org/python/antlr/ast/Compare$Compare___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..00b12d88816b64ac99119cfbc6e7982e78518f68 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$Compare___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$PyExposer.class b/src/main/resources/org/python/antlr/ast/Compare$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ccfaa880361e3494e61c69a69bd2a6d9ccb5de23 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4a278c49a03f73e876409e6b414b1596d1cff698 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..853642075956344819ff8069ffde0d6167fece43 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..10c69a77c69e79f72278c56cbf2ca01b72a68c73 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$comparators_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$comparators_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7298115a12cad09093bcae6ebabea8c607e1a9d5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$comparators_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Compare$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..252947e6d98715c4b25306287571036bb05add7f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$left_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$left_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ec46820ac57f781e32dd4931cd3e0ec4a5a44d86 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$left_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..78b43e9114e212e5dba06676852a781b67c671c7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$ops_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$ops_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fb276af8ada6a439e40af8c7880ec82f5fa24faf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$ops_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Compare$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e81d6c49b83eff85413edfd28945c5a0a22c040c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Compare.class b/src/main/resources/org/python/antlr/ast/Compare.class new file mode 100644 index 0000000000000000000000000000000000000000..de4b3135beb2b31db967af9b118c5a252864944c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Compare.class differ diff --git a/src/main/resources/org/python/antlr/ast/CompareDerived.class b/src/main/resources/org/python/antlr/ast/CompareDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..76aab509e5576b2023c9139ff846f409695e25b7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/CompareDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Context.class b/src/main/resources/org/python/antlr/ast/Context.class new file mode 100644 index 0000000000000000000000000000000000000000..c405defff9988915ac8e2bb92ae7f8eb5952de3c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Context.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$Continue___init___exposer.class b/src/main/resources/org/python/antlr/ast/Continue$Continue___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a38bc183434522034d76c8ce7b0c0994838a0287 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$Continue___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$PyExposer.class b/src/main/resources/org/python/antlr/ast/Continue$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..76bbe8569e5156a18eb05877841bd776f6d618fc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Continue$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1806e05adf0c3269d38d73572e543a66ee3de430 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Continue$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cd8c3cfaee07e21788d9cabeea3729c1c797721b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Continue$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f316a568130169ac03025638ac234d47347a27bc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Continue$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..e005b4f100161d8f37875c12d20434f642528031 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Continue$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..81d7477d561ae8b9012cd4cdf3fdcb57e79d16b9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Continue$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..857ec53bd4808880bb411874a10973edd98018f1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Continue.class b/src/main/resources/org/python/antlr/ast/Continue.class new file mode 100644 index 0000000000000000000000000000000000000000..f445379853b4e0bb599380c34948e1265b6bf3a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Continue.class differ diff --git a/src/main/resources/org/python/antlr/ast/ContinueDerived.class b/src/main/resources/org/python/antlr/ast/ContinueDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..8221576ff00ba6cf69fbfa76c28787690e1731c0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ContinueDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$Delete___init___exposer.class b/src/main/resources/org/python/antlr/ast/Delete$Delete___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cc1886c2dd8045ce4cb0255105df217d88245f5e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$Delete___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$PyExposer.class b/src/main/resources/org/python/antlr/ast/Delete$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b919abf9e57d4e850a248e968e3c38c353ea8e40 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Delete$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cc66c5742a6626aaf4076fafa3c4f57bcc3d2a46 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Delete$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d606cc0e142284d9c482b25bc32a12cbefbdbfd3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Delete$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..893453846b4fe721ec8b6b7570599f66fc76f6b0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Delete$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..a4b47b3482be8ceb14c1875d410c4b1f6c969f24 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Delete$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..45fd2fc22af6f851473c9a3e48cfef469c76588b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Delete$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ac1d7e2c6b2e793a9afb6467557cd68328362384 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete$targets_descriptor.class b/src/main/resources/org/python/antlr/ast/Delete$targets_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5af035a02936d8c971fee4434c25a6d3f4e7c5dd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete$targets_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Delete.class b/src/main/resources/org/python/antlr/ast/Delete.class new file mode 100644 index 0000000000000000000000000000000000000000..f8b69d296adbed043206fdbb1190cf475e8883ee Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Delete.class differ diff --git a/src/main/resources/org/python/antlr/ast/DeleteDerived.class b/src/main/resources/org/python/antlr/ast/DeleteDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..b97b11be2ba93385748e68d30274dfcb73c33ebd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/DeleteDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$Dict___init___exposer.class b/src/main/resources/org/python/antlr/ast/Dict$Dict___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fc14d15ff41763e7c044f3223397c2d02f1c38dd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$Dict___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$PyExposer.class b/src/main/resources/org/python/antlr/ast/Dict$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3d491e18c3efa75a41f4a4e5b0e032aa8fdd0d8d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Dict$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7df02910e31d07ad302631cba731d88ac4bc86a0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Dict$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2895ce30d1b64124677ed465a556324b7dcdcac4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Dict$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..83547449ec066f507fc931eea95df29c3ab03462 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Dict$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..0069542b030f518e4962dfbc6f5ea82e85e45200 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$keys_descriptor.class b/src/main/resources/org/python/antlr/ast/Dict$keys_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..635ffe04f12719f50a2a36e985e9f4dd8e89cf1a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$keys_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Dict$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e5c65d957b4f179ee18f4090b39178ccf950b0a3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Dict$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..dcb83e3738fe28e290d75fe22e47f64fcd7eed08 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict$values_descriptor.class b/src/main/resources/org/python/antlr/ast/Dict$values_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..94af236ea5174533d8e2eff66cf052bb2dde0764 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict$values_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Dict.class b/src/main/resources/org/python/antlr/ast/Dict.class new file mode 100644 index 0000000000000000000000000000000000000000..5098894a43b5da61e88da7e7ab49fd47ca5809a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Dict.class differ diff --git a/src/main/resources/org/python/antlr/ast/DictComp.class b/src/main/resources/org/python/antlr/ast/DictComp.class new file mode 100644 index 0000000000000000000000000000000000000000..c11890f9da37bc5987f2260c2d441de5f47be033 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/DictComp.class differ diff --git a/src/main/resources/org/python/antlr/ast/DictDerived.class b/src/main/resources/org/python/antlr/ast/DictDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..9c23270d5034d2cb1c06dabe0ab5a2818bcf10b3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/DictDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Ellipsis$Ellipsis___init___exposer.class b/src/main/resources/org/python/antlr/ast/Ellipsis$Ellipsis___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..016feb4c6eb67bfa4160ed21d33229fca2b3bcd3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Ellipsis$Ellipsis___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Ellipsis$PyExposer.class b/src/main/resources/org/python/antlr/ast/Ellipsis$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ec34e68e8d2993f034f255c20aaedbd0769e23a1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Ellipsis$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Ellipsis$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Ellipsis$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6a860a6560eff3c44137968d89cc21ec7be5739f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Ellipsis$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Ellipsis$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Ellipsis$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..951f31a3955b1105cb1b6cf925e345bab1f792e7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Ellipsis$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Ellipsis$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Ellipsis$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..661a0fb802da1bee542f2b28fffb0e36aa1e8c71 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Ellipsis$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Ellipsis$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Ellipsis$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5333ef5e6e20985db19f36f1887153ac5d249852 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Ellipsis$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Ellipsis.class b/src/main/resources/org/python/antlr/ast/Ellipsis.class new file mode 100644 index 0000000000000000000000000000000000000000..d51a2231709d1a17aee308d5f1edd5ba48078eb8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Ellipsis.class differ diff --git a/src/main/resources/org/python/antlr/ast/EllipsisDerived.class b/src/main/resources/org/python/antlr/ast/EllipsisDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..b5de9b82bfb10b4916b058cad9b32fe432e9e125 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/EllipsisDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/ErrorExpr.class b/src/main/resources/org/python/antlr/ast/ErrorExpr.class new file mode 100644 index 0000000000000000000000000000000000000000..a6a700dfe42e36218c6f86b56705b5b3574db824 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ErrorExpr.class differ diff --git a/src/main/resources/org/python/antlr/ast/ErrorMod.class b/src/main/resources/org/python/antlr/ast/ErrorMod.class new file mode 100644 index 0000000000000000000000000000000000000000..25dd5268a801150083c3e4001bbdbe1424b297cd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ErrorMod.class differ diff --git a/src/main/resources/org/python/antlr/ast/ErrorSlice.class b/src/main/resources/org/python/antlr/ast/ErrorSlice.class new file mode 100644 index 0000000000000000000000000000000000000000..c46aac1c22229f0792462b7d65827f7fa79292fa Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ErrorSlice.class differ diff --git a/src/main/resources/org/python/antlr/ast/ErrorStmt.class b/src/main/resources/org/python/antlr/ast/ErrorStmt.class new file mode 100644 index 0000000000000000000000000000000000000000..70992b4ac7277d1aa4b8e6e5a9562714c081f7a8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ErrorStmt.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$ExceptHandler___init___exposer.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$ExceptHandler___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f29b37ac24c2e7a66a155f7d6a74e6ab4bab1d01 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$ExceptHandler___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$PyExposer.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..772f56e7638d1de5d07a53141df38527c1213da3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e7e054acb39457dae1bc846ebe58aa888636eb4a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cdb9fec74fe445790e6a2ac702594909c465ff76 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$body_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..96be26d5c15e5217cce43f5ede765a0d4bd853a5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f5e45e99427a4245b591f28055b9ac5f2501d7da Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$exposed___new__.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..182351227747b5eaee6d9d4a050e25535bd9b770 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d6727c9cee010c7cf1c3f18f46303a29733c8ceb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$name_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$name_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..db26c9ed5c07f652c5efe9b8cfce2dee376ab4e6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$name_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4c837cbf6f05b5e84649fc1b1068cdc5b62f0908 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler$type_descriptor.class b/src/main/resources/org/python/antlr/ast/ExceptHandler$type_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8e8a605dbde4f387a7ad3b91638c1e1466ddea38 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler$type_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandler.class b/src/main/resources/org/python/antlr/ast/ExceptHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..68d58559b0a50c4608e2739c3ac8fa85a2b398d4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandler.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExceptHandlerDerived.class b/src/main/resources/org/python/antlr/ast/ExceptHandlerDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..02a9e8d516aa66848625fb3b7196251bb1decdc9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExceptHandlerDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$Exec___init___exposer.class b/src/main/resources/org/python/antlr/ast/Exec$Exec___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2f776dae65c0b733bb567174904cf769cdeb1a3a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$Exec___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$PyExposer.class b/src/main/resources/org/python/antlr/ast/Exec$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..723809b60033d8458e23a3b6463448c5dd438d55 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ca456d820c5a23b9a3ca9a19a53f3fca4479b58c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0df0c3572c081d34a2be2b2c3f19ec60782e2d2d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$body_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7b48b1eeb30e020f397288c46b0fe12118b239f3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1df88cc2dac771642512aa52c7254ec8e7cedd3e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Exec$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b9cf1edaa3655de1dcaae6041e4fb5010dc19713 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$globals_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$globals_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..45bd233e8182f804521ea9516d3c64e1b5cf462b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$globals_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9a6fd63e9f961c8b858ff51c20e70937bb46304d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$locals_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$locals_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..95a3b22df7d115deaade0dde603894b45b8c0707 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$locals_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Exec$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c6d610382e965b33da6b32d36014a95894cfd782 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Exec.class b/src/main/resources/org/python/antlr/ast/Exec.class new file mode 100644 index 0000000000000000000000000000000000000000..c3448e218fb9b777b50fd31651457d4a02b80998 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Exec.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExecDerived.class b/src/main/resources/org/python/antlr/ast/ExecDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..2ad68b282f877d676c7d65cdac44a8da07af28ca Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExecDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$Expr___init___exposer.class b/src/main/resources/org/python/antlr/ast/Expr$Expr___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a6021e47766299368f311214aa78cbbbb6cc8cfb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$Expr___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$PyExposer.class b/src/main/resources/org/python/antlr/ast/Expr$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1d81d6117bbddc28bb87d294ef9783d4e781466e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Expr$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d40ddaa2b09ed220f9d7f844cbe49fdf1f2207b3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Expr$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0a6b964d9d1435d7a878419b974e069ae6263e45 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Expr$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d07ffc38aa59699723c935ef912e2b7aa14b5786 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Expr$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..08bd132480161e6d0ba12f12ab5a8b1b2e3f8d5f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Expr$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..079d0e22e427df9422fda17c368e3c7ee5baf121 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Expr$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bac01323c4e8d1f63aab5424172c6e139a50c43a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Expr$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0cc9384075347ff97496ab62810909ca056089eb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expr.class b/src/main/resources/org/python/antlr/ast/Expr.class new file mode 100644 index 0000000000000000000000000000000000000000..2fa15526f6fc0af5c8127e02c0ce5917149a73c7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expr.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExprDerived.class b/src/main/resources/org/python/antlr/ast/ExprDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..af4d6774d68343ed40d08db25ae80e433c3bc283 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExprDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression$Expression___init___exposer.class b/src/main/resources/org/python/antlr/ast/Expression$Expression___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bf5d09f3152d3f7054fceb7f8610f5e8944f3c4f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression$Expression___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression$PyExposer.class b/src/main/resources/org/python/antlr/ast/Expression$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d35222d40c4e5b40b6f06c6f035a84612db9648d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Expression$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..947fb8ca6171cf5618cbb6a0cef07dc21563aa8b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Expression$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2923385b311a6d9492bff665f09469f1b32caeea Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression$body_descriptor.class b/src/main/resources/org/python/antlr/ast/Expression$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ab520d2881f4c11a09037580adf00aa506bfdb13 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Expression$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..9ff1c759b5cb44ce8fbb4bdba47339d3ad470f05 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Expression$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a843b384e9ee1adecfbb68a92800fbb0063de117 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Expression.class b/src/main/resources/org/python/antlr/ast/Expression.class new file mode 100644 index 0000000000000000000000000000000000000000..9feb7615f4b06c66ccfd13b285f4da64c4646975 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Expression.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExpressionDerived.class b/src/main/resources/org/python/antlr/ast/ExpressionDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..da56b978286fb9457119d843c176ec2a38ee5042 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExpressionDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice$ExtSlice___init___exposer.class b/src/main/resources/org/python/antlr/ast/ExtSlice$ExtSlice___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c6a399edbc818020be8990b753853bc8ddc184e6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice$ExtSlice___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice$PyExposer.class b/src/main/resources/org/python/antlr/ast/ExtSlice$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8d10ebe9d7a609176f36e04d22d4e02e7dc49a77 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/ExtSlice$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7711064b822d83180d58062a88c97cfdcb6a23e9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/ExtSlice$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..818fc7b93de496871dca939a02a0d3fb0e2a4545 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice$dims_descriptor.class b/src/main/resources/org/python/antlr/ast/ExtSlice$dims_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..809f9700c05ab85bfff738b5847d300186f80860 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice$dims_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice$exposed___new__.class b/src/main/resources/org/python/antlr/ast/ExtSlice$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b98416ffae055fcde5aecf635565ce2f91a97b8a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/ExtSlice$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5644fad40e656676e579ac0f7bbb2b9ea6f2eada Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSlice.class b/src/main/resources/org/python/antlr/ast/ExtSlice.class new file mode 100644 index 0000000000000000000000000000000000000000..891234fe34c5b143033da6981149708db3385195 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSlice.class differ diff --git a/src/main/resources/org/python/antlr/ast/ExtSliceDerived.class b/src/main/resources/org/python/antlr/ast/ExtSliceDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..5ef40e30f75a34c054da2fcd816b896525882dcf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ExtSliceDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$For___init___exposer.class b/src/main/resources/org/python/antlr/ast/For$For___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1bccee6cb2024a4b70b215578d78b809bdbe21d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$For___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$PyExposer.class b/src/main/resources/org/python/antlr/ast/For$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1bf41a522cd696ff2e5d7bb0e0b95681d82c0d1f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/For$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..83d03e666040e8642289752638d386f6e5c147e9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/For$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e5d0172f4a589835c8f0aac82f3534836189e3ed Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$body_descriptor.class b/src/main/resources/org/python/antlr/ast/For$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e59a33f584eb21979658ca7bf80b8988dc4728e1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/For$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b5a3c85b6c49be0fe934bd2a0164fb5468951af6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$exposed___new__.class b/src/main/resources/org/python/antlr/ast/For$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..8807b91b1fdce48ba33deb377adb441305d4b456 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$iter_descriptor.class b/src/main/resources/org/python/antlr/ast/For$iter_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..56b5f6593866bf0bfe23a583daa8ff24b49792c3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$iter_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/For$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9b93fe312b3ee3596018d5b3450ad8f1ff503c94 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$orelse_descriptor.class b/src/main/resources/org/python/antlr/ast/For$orelse_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..378b38ed6cf361843679cb17ca623ba30cffe70f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$orelse_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/For$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f0c0b29eefaa641b1412958ee37e44a5fa82003d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For$target_descriptor.class b/src/main/resources/org/python/antlr/ast/For$target_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f8dbbe44a7d3eaf8304009a8d6634c819ef9d90a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For$target_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/For.class b/src/main/resources/org/python/antlr/ast/For.class new file mode 100644 index 0000000000000000000000000000000000000000..86d91ed01d2ba3427c047ee3feeae82a2b6565a4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/For.class differ diff --git a/src/main/resources/org/python/antlr/ast/ForDerived.class b/src/main/resources/org/python/antlr/ast/ForDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..0d55fef8c4b86b74de29944d18eff0c58a9bcb43 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ForDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$FunctionDef___init___exposer.class b/src/main/resources/org/python/antlr/ast/FunctionDef$FunctionDef___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fe3d5811da92c50a6617c145dc6953f50bd1c00f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$FunctionDef___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$PyExposer.class b/src/main/resources/org/python/antlr/ast/FunctionDef$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e4321c13fb02459938c7a5971213ebddda8d2d32 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..11a357bd9789f4114c9e964f7912cc8a312ffa01 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..57af326a574bd52dede692bc348df448ae9ad084 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$args_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$args_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..08f396bbb072b48b708ecd9ca9d259de4bc9257c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$args_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$body_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6807a691fffa5beb70d3459a96bfde2ce403f4a5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3db634bc74a357a559a43fa3be150a15aa9e3fc2 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$decorator_list_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$decorator_list_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e849670577d22cd2b891912db44a34adce44e4d2 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$decorator_list_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$exposed___new__.class b/src/main/resources/org/python/antlr/ast/FunctionDef$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b1898a66a3d16098090b28b621443a2b489e308e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d02c9be3fc217507e10c032b7295bc64131f59af Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$name_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$name_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..576b4c41b1e75e50edc936021ca4c0422c3c5ff5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$name_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/FunctionDef$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e6755d84689fa7efe29f0293c4947f5f77492e84 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDef.class b/src/main/resources/org/python/antlr/ast/FunctionDef.class new file mode 100644 index 0000000000000000000000000000000000000000..1d8cff5d4d774369ff9352811afd974d4c86f067 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDef.class differ diff --git a/src/main/resources/org/python/antlr/ast/FunctionDefDerived.class b/src/main/resources/org/python/antlr/ast/FunctionDefDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..e27b2434fbbe9a65f390419529fd2d6109961e8b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/FunctionDefDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$GeneratorExp___init___exposer.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$GeneratorExp___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a65fa905e17b54503ef31868af5160b4b0cd7c8e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$GeneratorExp___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$PyExposer.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4ca792b7a7bd6df755fc7f69ad74cf85e89f203d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..580ffa721508dbd9a526e33bf80e8cffd3a4115b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f0e6e4e2562bd358481c187c06e6b3bf1685855f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6835ff94000105028acd0e16b56997005cdfb8c5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$elt_descriptor.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$elt_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..417f304740243516558ad41aee2d1ce861ab43ff Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$elt_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$exposed___new__.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..206a996058d85e4c4ffcfb44a5423ca420caacde Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$generators_descriptor.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$generators_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..91dc893a608e975f224e21cb472d5e265c27c885 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$generators_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ca9f7d2138c55d1761c846bdadc9b29d2b534d85 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/GeneratorExp$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..47069f86d98c13fa97def0cc203d35ca18877122 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExp.class b/src/main/resources/org/python/antlr/ast/GeneratorExp.class new file mode 100644 index 0000000000000000000000000000000000000000..415e76e7322a8b1146b62150ee902e1081003ce5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExp.class differ diff --git a/src/main/resources/org/python/antlr/ast/GeneratorExpDerived.class b/src/main/resources/org/python/antlr/ast/GeneratorExpDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..f7177f1f89205d01ac0a761c5b80eeb7f6a5b6b4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GeneratorExpDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$Global___init___exposer.class b/src/main/resources/org/python/antlr/ast/Global$Global___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ebafa15a28d60e48b243bf5fea9861bbc86e7a86 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$Global___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$PyExposer.class b/src/main/resources/org/python/antlr/ast/Global$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fd54cf780e5e49f6f99ec1ba7a1a76992f109b19 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Global$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..25c5e772feaf819059438e4df9e8ccb11e1956bb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Global$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..997a68b3998a34ad7ef8af3a1820dbcd4552e750 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Global$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8df939917eea822de8ebfee948d617c9f624d91c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Global$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..89292e7bdc4c35bbb533d1a46f0ee4ab2a0a3b77 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Global$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9548bffafa2953b613c40af54fcf0d20173d2c9f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$names_descriptor.class b/src/main/resources/org/python/antlr/ast/Global$names_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2d8633bf108a7b35b209fc8cc48d3bc36afd8c23 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$names_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Global$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0b64ccfaa209aab2d1c70bca02831a0bc20cc6f5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Global.class b/src/main/resources/org/python/antlr/ast/Global.class new file mode 100644 index 0000000000000000000000000000000000000000..1ef1fa9270b844a04140326165fe9b97bba874e3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Global.class differ diff --git a/src/main/resources/org/python/antlr/ast/GlobalDerived.class b/src/main/resources/org/python/antlr/ast/GlobalDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..da19d744c2689d1fad8288bf16d1436f1b8f20d6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/GlobalDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$If___init___exposer.class b/src/main/resources/org/python/antlr/ast/If$If___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9a127d727e0b9cf6d1a591653773ed6dab24a4bd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$If___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$PyExposer.class b/src/main/resources/org/python/antlr/ast/If$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5722521e5d37949ce8a44dcfae6c40f8314864e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/If$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0253d094060bffefd1435cd6d6065890e69bf3a1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/If$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6abd51030d21d717ce36bd5e282d2eab6254ba4f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$body_descriptor.class b/src/main/resources/org/python/antlr/ast/If$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ace314a98ed9431f4bfac55dadf951568a87d7b8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/If$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4a85ba4cdca951b6f9c8c52424e18af946154355 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$exposed___new__.class b/src/main/resources/org/python/antlr/ast/If$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..a967dfc058cc619ce9fcb8aadbfc4c964b68d9f5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/If$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..76d5271a902c9cd1eda1b7919036f8d6738e2f3c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$orelse_descriptor.class b/src/main/resources/org/python/antlr/ast/If$orelse_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4f18ae0fd0bcb6b0eb4dcdc3bbaaa09999027be0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$orelse_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/If$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aa86ef672111174d8d37cc25692077f6713bf7fd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If$test_descriptor.class b/src/main/resources/org/python/antlr/ast/If$test_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aaab7b0bf2079f8b16350aabd43dc690299d22f6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If$test_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/If.class b/src/main/resources/org/python/antlr/ast/If.class new file mode 100644 index 0000000000000000000000000000000000000000..3a18f1c3d92eba28d2d2aba730c53e1ac8345533 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/If.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfDerived.class b/src/main/resources/org/python/antlr/ast/IfDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..00186af43bf66c8b40deda78b1851ee16936d090 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$IfExp___init___exposer.class b/src/main/resources/org/python/antlr/ast/IfExp$IfExp___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..775d681011c87a768f72b8ae6daed494fde8d98f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$IfExp___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$PyExposer.class b/src/main/resources/org/python/antlr/ast/IfExp$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..441f15c74d256f84c3ad6149cf115221319375c0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..242de2b4004039d76ff1701ef24a34b183b8ee69 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d3582ad6a225a7b3e826a47237d236db597114a0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$body_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7aea7d8a0d0d832e927237289c7d60a1087c494f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..30dcc2adef221011db7870dcadb05b1e26d05393 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$exposed___new__.class b/src/main/resources/org/python/antlr/ast/IfExp$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..d8e79036653a031c0987ae8cca71b1cbacce6528 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f835b10ce71d6b6a018e50366efaca93fd5fb10b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$orelse_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$orelse_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..68f77c774f1491808c3641a5b9b596f9195b77ce Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$orelse_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ea37d4af2f6b73e7931f22f1f2f53283641e3a83 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp$test_descriptor.class b/src/main/resources/org/python/antlr/ast/IfExp$test_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aee4aab8a79c0f3270a68a1cfe4c4311801e9046 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp$test_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExp.class b/src/main/resources/org/python/antlr/ast/IfExp.class new file mode 100644 index 0000000000000000000000000000000000000000..c2162370948bd5ff335148c533f006aae3040742 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExp.class differ diff --git a/src/main/resources/org/python/antlr/ast/IfExpDerived.class b/src/main/resources/org/python/antlr/ast/IfExpDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..161f0164406df72f46653d86e02f2d1b906269f1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IfExpDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$Import___init___exposer.class b/src/main/resources/org/python/antlr/ast/Import$Import___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..915149ba7997e5719125770f8f7cc033fb049ecd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$Import___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$PyExposer.class b/src/main/resources/org/python/antlr/ast/Import$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4a19ffe680f1f9e4242df84f6bf40230d2cb0e5b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Import$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..303d1e1046aea6f020aae33762c7dbbfa2696e47 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Import$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4f16ac153ab2e83b0dd3b929c08b6474ff3af9c4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Import$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d3793477cc42fcaa975c0b84d2c673bf8e68e4f8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Import$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..1e288224398b759d4cfa305c590ea22a3a9f35c1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Import$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b8d7d151e7f6afc6a73ed01ad424fa4953f62c08 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$names_descriptor.class b/src/main/resources/org/python/antlr/ast/Import$names_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..02886e3c80729528ca6942369022d8967ac80fd0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$names_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Import$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3f9c67ad9c3a919e5926b3f527f847bf4337a346 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Import.class b/src/main/resources/org/python/antlr/ast/Import.class new file mode 100644 index 0000000000000000000000000000000000000000..0dfa0779eb1fdbab10534b22ffa3bbe133401804 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Import.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportDerived.class b/src/main/resources/org/python/antlr/ast/ImportDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..608c6ee26d05c003f58d5e622e9f2eb2a382e38c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$ImportFrom___init___exposer.class b/src/main/resources/org/python/antlr/ast/ImportFrom$ImportFrom___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f488d517bae9efde9d8809ea87612ecbb5649aeb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$ImportFrom___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$PyExposer.class b/src/main/resources/org/python/antlr/ast/ImportFrom$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..14ecf784779a1b1fe158f305e64e9d35fac3c917 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0910751a546dad252233c59c6ae6c078292759a7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8e5440c12509b8c34b5519d2c9995f14034168a1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..44812c97a0c9edbf3820bc540a73a7f59374b361 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$exposed___new__.class b/src/main/resources/org/python/antlr/ast/ImportFrom$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..9bb555687f783bef98a3e71a581a39e99223ceed Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$level_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$level_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6b36ff3fb7e8ea872e24e27a23e33fdc9f9e0d27 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$level_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6b6dfa8c8b7d14079fa67eab98648ba50a2a46c7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$module_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$module_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aa5f268483da8edf9cb279d3bff7630e2dacd571 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$module_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$names_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$names_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..423c03b6b6a554c3e1822ad5bfe95dc4c382c3d9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$names_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/ImportFrom$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..571ba92d5876125ea6ef24575c175841b5245ab6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFrom.class b/src/main/resources/org/python/antlr/ast/ImportFrom.class new file mode 100644 index 0000000000000000000000000000000000000000..59096de0eb0f2b234fbf9132b5651704a0e148fd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFrom.class differ diff --git a/src/main/resources/org/python/antlr/ast/ImportFromDerived.class b/src/main/resources/org/python/antlr/ast/ImportFromDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..b8d687c09f8616a6c65dd4862e76057776390c58 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ImportFromDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index$Index___init___exposer.class b/src/main/resources/org/python/antlr/ast/Index$Index___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5a29c0364b8b69b8589a2b2f031fb957f496871b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index$Index___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index$PyExposer.class b/src/main/resources/org/python/antlr/ast/Index$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a874160b9c993d46d124a73ad9b872b3f8883601 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Index$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..40939302a7a6cc81cf6c28a046967772731d2641 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Index$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2c91ac43e68567fe19fe3cbb215dc451ff0fd6e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Index$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..a262b602e36e6a5938e43cce529e74af09ef4d37 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Index$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..16f6d67bb36549104e67b60ba7cdc68a23dc8b6d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Index$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6ad84abc59164612522abff3076f0d0e0c220504 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Index.class b/src/main/resources/org/python/antlr/ast/Index.class new file mode 100644 index 0000000000000000000000000000000000000000..7827c08dd4379356bd41280417ecd8169fd857d2 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Index.class differ diff --git a/src/main/resources/org/python/antlr/ast/IndexDerived.class b/src/main/resources/org/python/antlr/ast/IndexDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..b7698fda93bb49cdf9e70a205afce03738a6f0b3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/IndexDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive$Interactive___init___exposer.class b/src/main/resources/org/python/antlr/ast/Interactive$Interactive___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f058dc271913675812992cd4fc92cafd6e560da3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive$Interactive___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive$PyExposer.class b/src/main/resources/org/python/antlr/ast/Interactive$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c2dbcf62bc1a2de28b024fae7d27283ff37dbcb6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Interactive$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7797cafbf4b8c67186efb7256c1d1bda5c95a27d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Interactive$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3bece51455d3e739b56c729d6a7d838feefaf97f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive$body_descriptor.class b/src/main/resources/org/python/antlr/ast/Interactive$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e6c81f90434232a69524d9de46a5474921c68630 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Interactive$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..3d318add0521d667aaa4ea329cf14223698ff494 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Interactive$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..10da7625769dffa0917e8820e7108abdac045ccd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Interactive.class b/src/main/resources/org/python/antlr/ast/Interactive.class new file mode 100644 index 0000000000000000000000000000000000000000..9010fa47c6b99272f40b30f4e1972711a0c8a33b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Interactive.class differ diff --git a/src/main/resources/org/python/antlr/ast/InteractiveDerived.class b/src/main/resources/org/python/antlr/ast/InteractiveDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..a8978ea25af42a486cc0fdb072779b45970916c8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/InteractiveDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$Lambda___init___exposer.class b/src/main/resources/org/python/antlr/ast/Lambda$Lambda___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..81ba4689c6e406cd72b7bf64e32acd0f7caea31e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$Lambda___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$PyExposer.class b/src/main/resources/org/python/antlr/ast/Lambda$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..62146b03d2f1124eae214c9c57e197e6c2f1912b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Lambda$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..564aad78b704e2656e9a9edfd227008ee09f24e7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Lambda$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..059509fae360261391d057d562c2007655768430 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$args_descriptor.class b/src/main/resources/org/python/antlr/ast/Lambda$args_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ca1ca579ee1ed134ea160695173b4f71bb38bfa6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$args_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$body_descriptor.class b/src/main/resources/org/python/antlr/ast/Lambda$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2a8fdba5d31c112da73322785b338ed355ea42f7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Lambda$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1df223a40c02252a71a584f49ab0bb5dcb802361 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Lambda$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..27181016f0dcb6a1b855e2334a4919ff019408f9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Lambda$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f49ab64a77a3fe9c372014a548373a3e939ccad5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Lambda$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1d1f565932479c3d9a4ee1d3205ff148dfb1b749 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Lambda.class b/src/main/resources/org/python/antlr/ast/Lambda.class new file mode 100644 index 0000000000000000000000000000000000000000..25250ed12f7a109bab234aef0e467e3f7346c2c7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Lambda.class differ diff --git a/src/main/resources/org/python/antlr/ast/LambdaDerived.class b/src/main/resources/org/python/antlr/ast/LambdaDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3c238c4262b10db1a068980b75a3d316c4fab990 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/LambdaDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$List___init___exposer.class b/src/main/resources/org/python/antlr/ast/List$List___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..01650b6a48679c6d02a0a9560b237591f54c9014 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$List___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$PyExposer.class b/src/main/resources/org/python/antlr/ast/List$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d93b4c9030acf9c47a488a62f7a7226de4cf5d93 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/List$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b18bd404606e527d232b7119f92a716ac938a7bb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/List$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3149339160ab77e8e6509565751c025f4ddf7c7b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/List$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f27ff74113957497f294fe7937a48169003baa45 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$ctx_descriptor.class b/src/main/resources/org/python/antlr/ast/List$ctx_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5c2ab37e5e90540e5cbd9327e72a699127581c67 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$ctx_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$elts_descriptor.class b/src/main/resources/org/python/antlr/ast/List$elts_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4b02399fadc631c05a37c6503bf76f2766180b1c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$elts_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$exposed___new__.class b/src/main/resources/org/python/antlr/ast/List$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..2d65ae4e42cbf01e28d60146857c175338593985 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/List$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0c9c83f524b050086ee4820a0eb942cfeeaa3d86 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/List$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/List$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fad700c0e625102efc0807c3cc9364c11663a4e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/List.class b/src/main/resources/org/python/antlr/ast/List.class new file mode 100644 index 0000000000000000000000000000000000000000..688718af2320ca7b81f9ab421f936860dbb755c0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/List.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$ListComp___init___exposer.class b/src/main/resources/org/python/antlr/ast/ListComp$ListComp___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e13e29deb37dbac426fa68fd6b3148974b82320b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$ListComp___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$PyExposer.class b/src/main/resources/org/python/antlr/ast/ListComp$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..40a5fa4f8a2911bf8e674610addbbc761d6794bf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/ListComp$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0a362feabf64e0a5058ca9c56667cae00c00f946 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/ListComp$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5bd268cd8d9d38bf03f7d81aef7466a6f9d63dce Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/ListComp$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c32473d653a1ef0b80aec8f2c601b6f60cac2868 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$elt_descriptor.class b/src/main/resources/org/python/antlr/ast/ListComp$elt_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1a84a98ca556697bd7587dfe4d1d80de558c7da8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$elt_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$exposed___new__.class b/src/main/resources/org/python/antlr/ast/ListComp$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..32baa3aad3ce2c9b89a0c384f4401449bc1436aa Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$generators_descriptor.class b/src/main/resources/org/python/antlr/ast/ListComp$generators_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d8f286698a241761ad0c3b8e0b3addaf76dcc0b9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$generators_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/ListComp$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9052233a56e6d28b8a1a03a67c0e7706cd90dd67 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/ListComp$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fb7a84556b382fde567eaab1d5e7b81449655cb9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListComp.class b/src/main/resources/org/python/antlr/ast/ListComp.class new file mode 100644 index 0000000000000000000000000000000000000000..d47cf13e21156561b675f0d64c4a118d8d540f3e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListComp.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListCompDerived.class b/src/main/resources/org/python/antlr/ast/ListCompDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..99b0c2379c50234aa82adfa9581001d77d9e5467 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListCompDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/ListDerived.class b/src/main/resources/org/python/antlr/ast/ListDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..9da896209a7bbd9181e132654c0350bdddac12f1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ListDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module$Module___init___exposer.class b/src/main/resources/org/python/antlr/ast/Module$Module___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6eb3d4739885163092945940e4eef1c20cfa0ae4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module$Module___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module$PyExposer.class b/src/main/resources/org/python/antlr/ast/Module$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c03196852cbb2f8239a1adfd62bd3e76387a37c8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Module$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b2ce27d534bcbcda708e4b0282ddf6051b5b5d6e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Module$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1312399da9b74f99e2ca3df2cc05dfa3c5a7e280 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module$body_descriptor.class b/src/main/resources/org/python/antlr/ast/Module$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..58a456653eca4c6d6c7042a34d748fcbf2710f8b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Module$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..acf0e24a7ddd36588ae3f675f40f001c03ce39a7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Module$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a4240ff754b0f0ee06d604720b16a1e15fbc53fc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Module.class b/src/main/resources/org/python/antlr/ast/Module.class new file mode 100644 index 0000000000000000000000000000000000000000..137668a43985e7db16fdbad153cbff1172a0c878 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Module.class differ diff --git a/src/main/resources/org/python/antlr/ast/ModuleDerived.class b/src/main/resources/org/python/antlr/ast/ModuleDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..a2c73a56f6efec6bd11de72f6771a16dfd4de8ac Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ModuleDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$Name___init___exposer.class b/src/main/resources/org/python/antlr/ast/Name$Name___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..379a50e8fa8099e7b764975b39bd80a02c5e1e39 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$Name___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$PyExposer.class b/src/main/resources/org/python/antlr/ast/Name$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1ccc18a0c214d5e1c34a72d2f25794848aeef5a3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Name$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2d2f9950a491c7a73cafe02b47ebd97ae5a70c63 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Name$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bc4e31d4a5f0b80bac453167338997af99fe1772 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Name$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0d0e9d85d5e3c67c83195a07d579a208aae4bf8c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$ctx_descriptor.class b/src/main/resources/org/python/antlr/ast/Name$ctx_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..096426897559318c252238a5b3883e6d0c72d37d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$ctx_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Name$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..df9218d2daa61566e5b41c238f12289b36900dc7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$id_descriptor.class b/src/main/resources/org/python/antlr/ast/Name$id_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..91f28d834a498deea60d985b429a1acf04476962 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$id_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Name$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aee5e5123865bb6998d5d1eaf5058f61055f00f4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Name$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6e3ed1b10772a4860c0a8fbdd58001304079711e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Name.class b/src/main/resources/org/python/antlr/ast/Name.class new file mode 100644 index 0000000000000000000000000000000000000000..b1e7e7d9f9fb914753617ca6cd5ca8b3eebe36b0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Name.class differ diff --git a/src/main/resources/org/python/antlr/ast/NameDerived.class b/src/main/resources/org/python/antlr/ast/NameDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..d6945819800a639792cc644e71ce5b64dccdbfa5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/NameDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$Num___init___exposer.class b/src/main/resources/org/python/antlr/ast/Num$Num___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5e95fce3053521c4df1aede3988e22d73e51a998 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$Num___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$PyExposer.class b/src/main/resources/org/python/antlr/ast/Num$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e6dadbf8bf34fa206e85a27195e17ae319e264a1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Num$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6ad9f600dccc5b0d7bf80d9afd816039fad45214 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Num$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f98c271cbfc0857d358930bb5562737a107e8ad3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Num$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3bd8665d48d6471915e949259ecf0ff2f5a6f935 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Num$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..e8da5e58f33899f06c663a27a8c75bfdb78685a0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Num$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b31ca8a5b48e6af97d9fb8ccb14a86d714b102b8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$n_descriptor.class b/src/main/resources/org/python/antlr/ast/Num$n_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ae433709dda61bc3d73ece975eb9573e39402356 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$n_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Num$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9203dfcd24d9060f82cb15cc453e6a3daa5c8c82 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Num.class b/src/main/resources/org/python/antlr/ast/Num.class new file mode 100644 index 0000000000000000000000000000000000000000..5146385b78fb12b58d0ac2509866e20de3b965ab Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Num.class differ diff --git a/src/main/resources/org/python/antlr/ast/NumDerived.class b/src/main/resources/org/python/antlr/ast/NumDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..22394dff8c192f8106f62d90855e14e0f79e2c5b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/NumDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$Pass___init___exposer.class b/src/main/resources/org/python/antlr/ast/Pass$Pass___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..121c379dfccc01f7ab2e87b96131dbe866fbc168 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$Pass___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$PyExposer.class b/src/main/resources/org/python/antlr/ast/Pass$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..18331a5451d029315fba26a9f486134dfd254ec4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Pass$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..acfcc4c0f81c0c943dd35adb0a28cde7841aea55 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Pass$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..998d139aeabd91833edbb1b8797718774c314f34 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Pass$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..156b94325cb119a7ee7c63d4ff06d465b5a123f8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Pass$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..e869bc515c7768eff2a2b4be3acc88994d6c3298 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Pass$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..db03d0db3a60eec34517e7a9d2a3d40aaaa3e155 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Pass$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..356ddb65bd49bb42572f3e8c89bb3d0b88ec29f3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Pass.class b/src/main/resources/org/python/antlr/ast/Pass.class new file mode 100644 index 0000000000000000000000000000000000000000..e2daff1c20621db5d94b83277c7aa2e446cfa548 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Pass.class differ diff --git a/src/main/resources/org/python/antlr/ast/PassDerived.class b/src/main/resources/org/python/antlr/ast/PassDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..7d5a734aa9614a65c63b8aaca61239a172de4e40 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/PassDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$Print___init___exposer.class b/src/main/resources/org/python/antlr/ast/Print$Print___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b05423f21f6058f864455e186be889deb4fab11f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$Print___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$PyExposer.class b/src/main/resources/org/python/antlr/ast/Print$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2f0edc529a2a8750f0a10bb2b6f8308f387c259f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..97df58ef5296c76c10b5e5f7004fc0c71d94eb9a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..28ea957ba8fe3d9fd2af649340e919ad4b611484 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..922541c14c9b8bbc558f44c23c22e82a35d94669 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$dest_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$dest_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b1085432d1757df39b0684fd0a09c09fa5772ea5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$dest_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Print$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..66f4efbe22862a76601fd5eab22d73ea88882952 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c61eb4367c2bea7e858d247790c0841211034ad3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$nl_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$nl_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5f7bf3969d1b23e7086a2b5f7e17573da0a55eaa Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$nl_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..72d4bec848e902f472a136f84da05ca5705033fa Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print$values_descriptor.class b/src/main/resources/org/python/antlr/ast/Print$values_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ea30eb15d38fc257f8f0dde37ee57fc45ef97c13 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print$values_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Print.class b/src/main/resources/org/python/antlr/ast/Print.class new file mode 100644 index 0000000000000000000000000000000000000000..50dee016d2f5d9dc12ad03a511bc38b1d4bf8df7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Print.class differ diff --git a/src/main/resources/org/python/antlr/ast/PrintDerived.class b/src/main/resources/org/python/antlr/ast/PrintDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..c560abd17e9543d22eaccdded7d30636b50d8c21 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/PrintDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$PyExposer.class b/src/main/resources/org/python/antlr/ast/Raise$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b813c957f166761a05c567b0bb847b543ac52255 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$Raise___init___exposer.class b/src/main/resources/org/python/antlr/ast/Raise$Raise___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..be937cab2dcba5b5043560a78e1220c19dbc9dd7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$Raise___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5dbc3ffb227810bcb4a8f31063feaf76840b9cdd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1a184a7b222def8980b6fce80f9772e32da40158 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c7e17195aacd4a2cfbd3da387f26e0818be5b128 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Raise$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..ea36a94b81694093883d14eeac3d75c4cb2fdf86 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$inst_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$inst_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3e7c1e4f6a080fefd0a3512312f4c703ef45a42b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$inst_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8927e2a157a623002072ef18202ca72dcbc0db5f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9d4c55336d9ebe113a32e291a279ba2704ad17ff Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$tback_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$tback_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..32f678a0d72f0c1db8a776714b6692569a5b94bc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$tback_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise$type_descriptor.class b/src/main/resources/org/python/antlr/ast/Raise$type_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b336ade1128014b9ca2dd66befd64bd1725b4d07 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise$type_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Raise.class b/src/main/resources/org/python/antlr/ast/Raise.class new file mode 100644 index 0000000000000000000000000000000000000000..8a01131c14ad76ffda47f1e78d000250511d7fb2 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Raise.class differ diff --git a/src/main/resources/org/python/antlr/ast/RaiseDerived.class b/src/main/resources/org/python/antlr/ast/RaiseDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..208344fe1a8894b3fcd00aa996e2e00ee3884c3b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/RaiseDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$PyExposer.class b/src/main/resources/org/python/antlr/ast/Repr$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f29d43956ce07dc43dab17825cac43e7e7d2ca8e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$Repr___init___exposer.class b/src/main/resources/org/python/antlr/ast/Repr$Repr___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a0f938be8127451e0a49779c3b601af0286f4318 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$Repr___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Repr$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b3b440d074b66932b181174d68dfcc1994fe98c7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Repr$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9562194ea31a5510e82b4a65cf19677fb2a928a6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Repr$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..eb68bbe360c3b10aea724e0164e2ba81a782cc1d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Repr$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..85204413c24b1a30bdc281228b35c7722907949d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Repr$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d1135ad25c1db7adcad2cd0a7cc6bcd95099dac8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Repr$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2f07db44e33ea5832f277db0aa1cf1ae4ac40421 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Repr$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b8fbee9189349720f080131abcaee118b92c7d3a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Repr.class b/src/main/resources/org/python/antlr/ast/Repr.class new file mode 100644 index 0000000000000000000000000000000000000000..585f0980f9d2bd37e072a03a0121ae84e5b03447 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Repr.class differ diff --git a/src/main/resources/org/python/antlr/ast/ReprDerived.class b/src/main/resources/org/python/antlr/ast/ReprDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..60329c4b7f125975434c6242afd4bcadf6d89175 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ReprDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$PyExposer.class b/src/main/resources/org/python/antlr/ast/Return$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..50e7acc282d57724bf2b6e1efb5fd38055bdcd0a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$Return___init___exposer.class b/src/main/resources/org/python/antlr/ast/Return$Return___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a8892fcfef77402bf57e84d5ccefcd84ee869759 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$Return___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Return$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7f0adf628b5c507d7859f31cf8c3a29831f1749c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Return$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9061bcbb686ec6a42dcf9cbc68d284df8ab81729 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Return$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..74e6b1e3339713b57cc799612ebbeda64b2a86e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Return$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..bc7dcaa7ae92831598a3ad1e049cf1346989930a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Return$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2f8b661ac4b9bcaba69889e39210ae129e51cf5b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Return$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..13911da9a3032a75fd17260e33ed33d591b32597 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Return$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..964b84278f94365ba47e3b021b72381af8a820b9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Return.class b/src/main/resources/org/python/antlr/ast/Return.class new file mode 100644 index 0000000000000000000000000000000000000000..24546105a101e31be1f98435381eaa419142a425 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Return.class differ diff --git a/src/main/resources/org/python/antlr/ast/ReturnDerived.class b/src/main/resources/org/python/antlr/ast/ReturnDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..9908e279813c798e363c4bf080ca67217bf6a730 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/ReturnDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Set.class b/src/main/resources/org/python/antlr/ast/Set.class new file mode 100644 index 0000000000000000000000000000000000000000..7fb2a44cda0138de3cdefdaa058ee65347bcf447 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Set.class differ diff --git a/src/main/resources/org/python/antlr/ast/SetComp.class b/src/main/resources/org/python/antlr/ast/SetComp.class new file mode 100644 index 0000000000000000000000000000000000000000..5e4115a8d7cfe9e06aab3e41cd9aaecd1344f4f8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/SetComp.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$PyExposer.class b/src/main/resources/org/python/antlr/ast/Slice$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ab600e37befdcb21281385cc0c15a0a2cb6678c5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$Slice___init___exposer.class b/src/main/resources/org/python/antlr/ast/Slice$Slice___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6e4fefae65049d4cdc8ec206de19ef2a9283d1a4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$Slice___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Slice$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..03b8ae7782ee194744bd5cb2d14da7fc42049424 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Slice$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a349fd501b692b7a1c944305d2991e73f66c1d4e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Slice$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..c2daa914ade29c616ec2cc333c5c147bfd7161ad Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$lower_descriptor.class b/src/main/resources/org/python/antlr/ast/Slice$lower_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c16557ebb2472b73da9ad4f0ad4c811dbb8023c8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$lower_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Slice$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e3723bbef913040aab80be94c70f312ada228d7c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$step_descriptor.class b/src/main/resources/org/python/antlr/ast/Slice$step_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e2396b19dac477805096190100432b072076a75e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$step_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice$upper_descriptor.class b/src/main/resources/org/python/antlr/ast/Slice$upper_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..355105fff319755c69da7ee2983cd7753480f509 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice$upper_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Slice.class b/src/main/resources/org/python/antlr/ast/Slice.class new file mode 100644 index 0000000000000000000000000000000000000000..94520a04ce067d38b6a711d7f61f520fcc6ca48f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Slice.class differ diff --git a/src/main/resources/org/python/antlr/ast/SliceDerived.class b/src/main/resources/org/python/antlr/ast/SliceDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..132a232e1f2022e19cb6414a97245296097f4aa4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/SliceDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$PyExposer.class b/src/main/resources/org/python/antlr/ast/Str$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ad8c1eac90236d2523b829653f8cae4bdc5a5153 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$Str___init___exposer.class b/src/main/resources/org/python/antlr/ast/Str$Str___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3b3d7cb3339be737a30c363ae4e5e9f81a0ebefe Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$Str___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Str$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..569ca5e1dad9c7ee5fa7b40b50c7a5ec72956544 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Str$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..79c19f5009e3651b252e96579602bed54522fa0d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Str$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5dfa965baec7d56e4f8e2e2caf039d3b95d8c995 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Str$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..4368a53030a57a64071bc6a7ece6a57c1ae3f00d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Str$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b4654fe699c8c1ba1ebb8fa2fe3eb38cc0623189 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Str$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e2e8b900d91f9cce24bca8605f81bcc1129eac68 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str$s_descriptor.class b/src/main/resources/org/python/antlr/ast/Str$s_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..296dc803bea3c2f5c54a6cfa27be770b56a09ccc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str$s_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Str.class b/src/main/resources/org/python/antlr/ast/Str.class new file mode 100644 index 0000000000000000000000000000000000000000..c59df2695f1aee1190514a6d7eb890d57027e1a7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Str.class differ diff --git a/src/main/resources/org/python/antlr/ast/StrDerived.class b/src/main/resources/org/python/antlr/ast/StrDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..f20ae428cf213cff298a1cc8fb50daa869553b70 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/StrDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$PyExposer.class b/src/main/resources/org/python/antlr/ast/Subscript$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f7e525f8a1f49870c46aeeb2bde088ac96881219 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$Subscript___init___exposer.class b/src/main/resources/org/python/antlr/ast/Subscript$Subscript___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..95eb968bb61ea943fd1a2e0ea529f85752ee9246 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$Subscript___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5b8a2136bc804d94bbd09491161549f153026958 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7c4f145e68d011654677c9618918361f21adcbef Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..649ccc08378ce7d4e09348a0965e13aff07b9037 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$ctx_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$ctx_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..28c75b5110773a8195dde117356d9f61e32914d9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$ctx_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Subscript$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..27b2e31c3d7d951579c59a77658b21da99f43a26 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..eaa3470b9a24701aface82d169bfc2359fc6ea69 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b5612db21683846cc71bc44f1a788326eae4c6a4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$slice_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$slice_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b2525e012ef0da39aaed46a893897e0b61721f2f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$slice_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Subscript$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ed6079f5918bb27c80aae72642abe2ee73d16f52 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Subscript.class b/src/main/resources/org/python/antlr/ast/Subscript.class new file mode 100644 index 0000000000000000000000000000000000000000..63e169c4904d959a9660cab6cc202a3dd6acc68d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Subscript.class differ diff --git a/src/main/resources/org/python/antlr/ast/SubscriptDerived.class b/src/main/resources/org/python/antlr/ast/SubscriptDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..7276046940176de0ef0ee7893ad4a6a83ec847ac Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/SubscriptDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite$PyExposer.class b/src/main/resources/org/python/antlr/ast/Suite$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e6677108fe9fcb5d69402302c078305a7940967c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite$Suite___init___exposer.class b/src/main/resources/org/python/antlr/ast/Suite$Suite___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1aaa7d367201053cffa7864ad6143b5d956c7193 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite$Suite___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Suite$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bcf307ecbd42d2069c67b8e6ff458f31a305e816 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Suite$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f1a85fd6d4fd115992e1cb70e2a95cbd4cbea40d Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite$body_descriptor.class b/src/main/resources/org/python/antlr/ast/Suite$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e3b8beb9a658283e58e2dfe3e309296a4a49f62e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Suite$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..eb0825ec5d22592933499aaef1afb61887787869 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Suite$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..611bcaa8a37bbccf9ce310aa6c9b5e95a60af34f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Suite.class b/src/main/resources/org/python/antlr/ast/Suite.class new file mode 100644 index 0000000000000000000000000000000000000000..ff7d88e5249d73fa1f781f4a25fa175e5c14e8bc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Suite.class differ diff --git a/src/main/resources/org/python/antlr/ast/SuiteDerived.class b/src/main/resources/org/python/antlr/ast/SuiteDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..2c3c344d901df61f4bdb91551d358ae22378c63f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/SuiteDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$PyExposer.class b/src/main/resources/org/python/antlr/ast/TryExcept$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1ddd407aa80ea224f7118fee59e1b840605cda7f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$TryExcept___init___exposer.class b/src/main/resources/org/python/antlr/ast/TryExcept$TryExcept___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..befbc082241b066c1b5e8cfe911c29d22706bad2 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$TryExcept___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..be66124dab000af06035227ab5632255cc728e06 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4e782093bca13c0bf679aaea67b6950c88a6ae65 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$body_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..39636add861775361bec00e34de72cb2c5d61741 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d2136996771dbab939d3bf9b03b8d0c60691a9b3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$exposed___new__.class b/src/main/resources/org/python/antlr/ast/TryExcept$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..fa6b560470985c20461e657afe438113c2e091aa Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$handlers_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$handlers_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..45210c1df290e608bd91c7ec299a59a55b19baab Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$handlers_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fdffe0e7f4bca4c78b53c6c1a70f20d9212f3f8c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$orelse_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$orelse_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..389b575a109b8cda1a8aeca7264d2baf6aae24c9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$orelse_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/TryExcept$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a28fc81836cac04ad1a4677312c16de94e3d131e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExcept.class b/src/main/resources/org/python/antlr/ast/TryExcept.class new file mode 100644 index 0000000000000000000000000000000000000000..f76fd811763dbe982576c0ca4e20ce14d3b92adf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExcept.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryExceptDerived.class b/src/main/resources/org/python/antlr/ast/TryExceptDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..5fef64f49f95d5d7acb6ea3ba5c07a6d45df2df4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryExceptDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$PyExposer.class b/src/main/resources/org/python/antlr/ast/TryFinally$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..41b548e47c6befb7eef53d249309f1e2d217af36 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$TryFinally___init___exposer.class b/src/main/resources/org/python/antlr/ast/TryFinally$TryFinally___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3241721a7d9694655c928edb165cd4bdc3bbe000 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$TryFinally___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/TryFinally$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5786e4c426bf0e5a29f2e78198899f267f8d1fff Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/TryFinally$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b4a0bde613b7163887f640e42c4193e4b2ae39eb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$body_descriptor.class b/src/main/resources/org/python/antlr/ast/TryFinally$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1186c912e9fff373fc8f3a01f851b97c942bec33 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/TryFinally$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7395a59cfb83b08449d91adcadaec4ae8549b5e5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$exposed___new__.class b/src/main/resources/org/python/antlr/ast/TryFinally$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..35e39cce948c4d19cb2561a2c9718b4921ead7ae Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$finalbody_descriptor.class b/src/main/resources/org/python/antlr/ast/TryFinally$finalbody_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5ad23c475f6dda01dcc45b15a970e0ae51051fc3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$finalbody_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/TryFinally$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9066a67e5ac1d349e91415835b073219f3c44111 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/TryFinally$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..28a16d4670eac2ffd0ec5ce81f2d3798fb9c77f3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinally.class b/src/main/resources/org/python/antlr/ast/TryFinally.class new file mode 100644 index 0000000000000000000000000000000000000000..9deca9ccaed3026112de6209667af568874de0e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinally.class differ diff --git a/src/main/resources/org/python/antlr/ast/TryFinallyDerived.class b/src/main/resources/org/python/antlr/ast/TryFinallyDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..b196118f693ad17023122c1beaecba0abf870a15 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TryFinallyDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$PyExposer.class b/src/main/resources/org/python/antlr/ast/Tuple$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..32ee493856bb00afbe3eaac2354f60f602b70c54 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$Tuple___init___exposer.class b/src/main/resources/org/python/antlr/ast/Tuple$Tuple___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a006dfc38f49c0ebf84e48233c164fa8e494d71c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$Tuple___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Tuple$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..036aeea54ca677f3c5f6e7feefc3aba3cb1e01de Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Tuple$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..47021c1a36f996bf18b545fff8d7388d410e3af6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Tuple$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..daea0ff02007f663421c8b0c90aa4b7e4642cb15 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$ctx_descriptor.class b/src/main/resources/org/python/antlr/ast/Tuple$ctx_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0ef600b4dbe6d4a4831349c378368c4abb5e3ebb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$ctx_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$elts_descriptor.class b/src/main/resources/org/python/antlr/ast/Tuple$elts_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..669ca51981927f28de30789c085af7bb66ff95ad Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$elts_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Tuple$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..893df8bfe59f4463cab84569be75c1edaf4be097 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Tuple$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a1384214c7f4ee3a18c4045fbfdb41a9dc4cb176 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Tuple$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..65200562ac604dce92f5e6153dd0413f0cdc1dd5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Tuple.class b/src/main/resources/org/python/antlr/ast/Tuple.class new file mode 100644 index 0000000000000000000000000000000000000000..42b36e60f5527847609d7d941790229e5012b347 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Tuple.class differ diff --git a/src/main/resources/org/python/antlr/ast/TupleDerived.class b/src/main/resources/org/python/antlr/ast/TupleDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..a3a2692ed4ca805e0eb82e59fbfff8ccc4cd24a7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/TupleDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$PyExposer.class b/src/main/resources/org/python/antlr/ast/UnaryOp$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..182e352d395fb626509ba3c7a5e9514643357e7e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$UnaryOp___init___exposer.class b/src/main/resources/org/python/antlr/ast/UnaryOp$UnaryOp___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6f6fed8bf03a7dfd00a4c04c99471034fc00b7e3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$UnaryOp___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/UnaryOp$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aa52631195d82cf0f7c49c60b9fc65ee2098d7d9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/UnaryOp$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..916826f8503964e8be46e2a85fcd63cc8c4152a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/UnaryOp$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1a854fa16507262c1257cc4c4a3ac87d7e6d251c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$exposed___new__.class b/src/main/resources/org/python/antlr/ast/UnaryOp$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..83df0333e641a2c5f7852acd378ab467629f4032 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/UnaryOp$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d782888fbe99e04e3fa576533148d10a8bf5acc3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$op_descriptor.class b/src/main/resources/org/python/antlr/ast/UnaryOp$op_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..659ffac96f56dcebc8bed3e852f07c73ffd0e4fc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$op_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$operand_descriptor.class b/src/main/resources/org/python/antlr/ast/UnaryOp$operand_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4de67934c35ee3580feb5dd1240f246b63fce293 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$operand_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/UnaryOp$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..572232f687d1eef45e11cfe61cdf49e4eb1892ea Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOp.class b/src/main/resources/org/python/antlr/ast/UnaryOp.class new file mode 100644 index 0000000000000000000000000000000000000000..20667f982ea7e48e9d5b3e6734ebbd9abd188e74 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOp.class differ diff --git a/src/main/resources/org/python/antlr/ast/UnaryOpDerived.class b/src/main/resources/org/python/antlr/ast/UnaryOpDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..534229c782ccb85a4708e5363905f99ae70bcf27 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/UnaryOpDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/VisitorBase.class b/src/main/resources/org/python/antlr/ast/VisitorBase.class new file mode 100644 index 0000000000000000000000000000000000000000..c6f61a823eeea458ff1c96d2eef6dd993838ea3e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/VisitorBase.class differ diff --git a/src/main/resources/org/python/antlr/ast/VisitorIF.class b/src/main/resources/org/python/antlr/ast/VisitorIF.class new file mode 100644 index 0000000000000000000000000000000000000000..f0fc09ca0c979fe5fb5263e6af262ab325675034 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/VisitorIF.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$PyExposer.class b/src/main/resources/org/python/antlr/ast/While$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2bf59744546a6e1285c61530324c7c51beb8528a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$While___init___exposer.class b/src/main/resources/org/python/antlr/ast/While$While___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a6371cce451810bc59eb6af51da1d5294a36700b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$While___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/While$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cfe4dfab82ad2788923a65b1968c53c40d2eac82 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/While$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..42b79bc1d5ef680ae680630c9c4b8b84f0a559ce Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$body_descriptor.class b/src/main/resources/org/python/antlr/ast/While$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2eeb5f2806f931d521ceab2a7d11f4e8868ab811 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/While$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0784dc0ec58fc93aec6ea90ec11367fac0d7c743 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$exposed___new__.class b/src/main/resources/org/python/antlr/ast/While$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..5d1399b0a8a77759105050642d5507d1451c8a58 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/While$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8929ef92bcbeb788b374933543be5b4fc86bae03 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$orelse_descriptor.class b/src/main/resources/org/python/antlr/ast/While$orelse_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a61b4cc8abdb7525026fb74e239f1d2bd54d82ca Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$orelse_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/While$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b2b273bebe742cc2d54ac284154643611aaaf7e3 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While$test_descriptor.class b/src/main/resources/org/python/antlr/ast/While$test_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..53e606a8779e963068f68d6f36234077a08e5989 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While$test_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/While.class b/src/main/resources/org/python/antlr/ast/While.class new file mode 100644 index 0000000000000000000000000000000000000000..2d30fb301deacc018cffa0ec47f4a19b7fa5f038 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/While.class differ diff --git a/src/main/resources/org/python/antlr/ast/WhileDerived.class b/src/main/resources/org/python/antlr/ast/WhileDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..812817ddf834b6f2848fca537b4bea10756630a4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/WhileDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$PyExposer.class b/src/main/resources/org/python/antlr/ast/With$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fe3537775dbdeaebdc13ae3a4ad4bac7364154ee Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$With___init___exposer.class b/src/main/resources/org/python/antlr/ast/With$With___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..48c3a81c5d22a7d493fadcbd925f07fd8bc2c33c Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$With___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/With$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b75ac7224233990021c36c225ff5a40755321aed Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/With$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..05e02d62daba04b500ea0edec7201f325a971d7a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$body_descriptor.class b/src/main/resources/org/python/antlr/ast/With$body_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d61de0b44c08968cf367481d11c83c61a19e46ae Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$body_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/With$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..889fe5467bb7502560a0197fd6c16a84d6aa2bb8 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$context_expr_descriptor.class b/src/main/resources/org/python/antlr/ast/With$context_expr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7a12f4d35aaa22d763a930495f9b5e2945f1b513 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$context_expr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$exposed___new__.class b/src/main/resources/org/python/antlr/ast/With$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..5dc9110436db53e58ce05faebf1b9f4a289216d7 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/With$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bb6ae18cb08eaa0b61412798208068d90c4a2e32 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$optional_vars_descriptor.class b/src/main/resources/org/python/antlr/ast/With$optional_vars_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..38e40cd39baa9219522663ff18bd0ca0d633d67f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$optional_vars_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/With$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bf7529b854a91f9c6d405ca6ee7d49be4814baf9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/With.class b/src/main/resources/org/python/antlr/ast/With.class new file mode 100644 index 0000000000000000000000000000000000000000..c4dd7757de0f154e6b823bbd9726c694c1997053 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/With.class differ diff --git a/src/main/resources/org/python/antlr/ast/WithDerived.class b/src/main/resources/org/python/antlr/ast/WithDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..0c41f927c32f836720ec804236db5ec2cf8b6ee5 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/WithDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$PyExposer.class b/src/main/resources/org/python/antlr/ast/Yield$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f71aed10de2668d0c10cad1eac3ed0de8c59ce83 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$Yield___init___exposer.class b/src/main/resources/org/python/antlr/ast/Yield$Yield___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d8f89dea936059696509fbdc10233bb14762bdc0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$Yield___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/Yield$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c6026c2eb9162fa2c1acc7f33569478c3d7406d0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/Yield$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c4a26a75009df0c9adfa712c88cd3a9151099d67 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$col_offset_descriptor.class b/src/main/resources/org/python/antlr/ast/Yield$col_offset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5ddee61f89157bc6afa19cb69ff1e18f750f72cc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$col_offset_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$exposed___new__.class b/src/main/resources/org/python/antlr/ast/Yield$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..d6d510eec6c3b23a640019decf6cd92402ccf553 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$lineno_descriptor.class b/src/main/resources/org/python/antlr/ast/Yield$lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cc5892f0533df67c10e14529934ebeb70bc200c9 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$lineno_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/Yield$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7b733cd49ec2698d6fbc8cec0341b24ff7484aff Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield$value_descriptor.class b/src/main/resources/org/python/antlr/ast/Yield$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fae3a96a887c517f64f60710449820aad1c7a11e Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/Yield.class b/src/main/resources/org/python/antlr/ast/Yield.class new file mode 100644 index 0000000000000000000000000000000000000000..fce5900ca9c00c6b1ddb2361950e60a4a2c85aeb Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/Yield.class differ diff --git a/src/main/resources/org/python/antlr/ast/YieldDerived.class b/src/main/resources/org/python/antlr/ast/YieldDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..d390751434afe7c73c61916ca8439b4e8bfaea73 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/YieldDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$PyExposer.class b/src/main/resources/org/python/antlr/ast/alias$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6076a0b980a888278c2f995385702031b9b4190f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/alias$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cc42003f5f74d627e25127124f6fc28713bfe874 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/alias$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..616fb7a91e651ae863dcb1d1457cf2cefb9c90c1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$alias___init___exposer.class b/src/main/resources/org/python/antlr/ast/alias$alias___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bc2c3bb1de06c0d17b532ad51bb8b58a0cbfbdbf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$alias___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$asname_descriptor.class b/src/main/resources/org/python/antlr/ast/alias$asname_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8ab2039a8dc0a2d0c55ba064a55ac796aedc3cbf Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$asname_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$exposed___new__.class b/src/main/resources/org/python/antlr/ast/alias$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..86ce359a5578364cec4b9a0f27939592db9a2f17 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$name_descriptor.class b/src/main/resources/org/python/antlr/ast/alias$name_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e1dd67bbb10da0af646d8639d849999e22796b48 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$name_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/alias$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..731938f7b3fc4dc08c83c9f0592235910b87a35a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/alias.class b/src/main/resources/org/python/antlr/ast/alias.class new file mode 100644 index 0000000000000000000000000000000000000000..b3be599364061daff8778e971c3403c7f8fdc732 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/alias.class differ diff --git a/src/main/resources/org/python/antlr/ast/aliasDerived.class b/src/main/resources/org/python/antlr/ast/aliasDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..7c0888d5cfd9766a37a9349973d5dffece57b659 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/aliasDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$PyExposer.class b/src/main/resources/org/python/antlr/ast/arguments$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b391968f7588f8ea75422091f7efe52499b4a27b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/arguments$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a2d59ebb7f49f5613067ede0800c8c77a8a73191 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/arguments$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f6cccbbcc6199bb735a463f4a11023d0913c9ba0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$args_descriptor.class b/src/main/resources/org/python/antlr/ast/arguments$args_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6e45d93e5f64e1dd4a8bd297c8fcdf5ddadf13f0 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$args_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$arguments___init___exposer.class b/src/main/resources/org/python/antlr/ast/arguments$arguments___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..aa12dc8f9abb16782df564e4481d696bd3b7b48a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$arguments___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$defaults_descriptor.class b/src/main/resources/org/python/antlr/ast/arguments$defaults_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8fd5af7b44f9155f082592666ef92e4f0bda592f Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$defaults_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$exposed___new__.class b/src/main/resources/org/python/antlr/ast/arguments$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..af59fdec289fecd18e1db29e75ce292718edef83 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$kwarg_descriptor.class b/src/main/resources/org/python/antlr/ast/arguments$kwarg_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a6df9d7656d97e30249dd0c18d161ee79289b4ba Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$kwarg_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/arguments$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..35bf192eabe80c3a6b4d337172213e747aa12c24 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments$vararg_descriptor.class b/src/main/resources/org/python/antlr/ast/arguments$vararg_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..15d80e21cde46abd390bd30baccbe793d95f3317 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments$vararg_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/arguments.class b/src/main/resources/org/python/antlr/ast/arguments.class new file mode 100644 index 0000000000000000000000000000000000000000..2d49a93169fc4fe4bb9a2d9e3c642d9d9edef50b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/arguments.class differ diff --git a/src/main/resources/org/python/antlr/ast/argumentsDerived.class b/src/main/resources/org/python/antlr/ast/argumentsDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3d6ff89401d1829172497833c5faeb403b3e2cd6 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/argumentsDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/boolopType.class b/src/main/resources/org/python/antlr/ast/boolopType.class new file mode 100644 index 0000000000000000000000000000000000000000..252c8c0062e62663cd3d202787f0422f1c11292a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/boolopType.class differ diff --git a/src/main/resources/org/python/antlr/ast/cmpopType.class b/src/main/resources/org/python/antlr/ast/cmpopType.class new file mode 100644 index 0000000000000000000000000000000000000000..87522d2be78e6c6b2999a5a06d76fbdc58c5e922 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/cmpopType.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$PyExposer.class b/src/main/resources/org/python/antlr/ast/comprehension$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..671021358f2626e52c026c75b556525de1b3db44 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/comprehension$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fd2e0713ff0dd61f07a97c2cd360a777de35e6a4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/comprehension$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d2f82b6597b7de12aab4c0e6248fecdcfdf18b92 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$comprehension___init___exposer.class b/src/main/resources/org/python/antlr/ast/comprehension$comprehension___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f290309d00bf363de336f61920a9ef33a300b562 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$comprehension___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$exposed___new__.class b/src/main/resources/org/python/antlr/ast/comprehension$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..5f292bd96515ad36dd9781376dc4ef65f10a64fc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$ifs_descriptor.class b/src/main/resources/org/python/antlr/ast/comprehension$ifs_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f7e988aa79aa3862137f60cb80935487c9530541 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$ifs_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$iter_descriptor.class b/src/main/resources/org/python/antlr/ast/comprehension$iter_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..13731d7ab7926203ca470a1b4eba046b85be42e4 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$iter_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/comprehension$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5484cfa3682232b25bea80bbd99eda0107bd28ac Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension$target_descriptor.class b/src/main/resources/org/python/antlr/ast/comprehension$target_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5cca7713a568f296beac52e64f9553da3fd560dc Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension$target_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehension.class b/src/main/resources/org/python/antlr/ast/comprehension.class new file mode 100644 index 0000000000000000000000000000000000000000..0159347de6a8e7be57159f982febee1c0aece727 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehension.class differ diff --git a/src/main/resources/org/python/antlr/ast/comprehensionDerived.class b/src/main/resources/org/python/antlr/ast/comprehensionDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..9413f1e0fd547797eeb190192851044466460223 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/comprehensionDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/expr_contextType.class b/src/main/resources/org/python/antlr/ast/expr_contextType.class new file mode 100644 index 0000000000000000000000000000000000000000..be4734f6ceb9658b3f3f93e49c9cdf02798b5e49 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/expr_contextType.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$PyExposer.class b/src/main/resources/org/python/antlr/ast/keyword$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..09871bf14fa2dbf44d271a14eb841b9aa52237ce Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$_attributes_descriptor.class b/src/main/resources/org/python/antlr/ast/keyword$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9cf1f1c82891fc04005d3297dffb3b66845c41ec Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$_fields_descriptor.class b/src/main/resources/org/python/antlr/ast/keyword$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b33a4f346ff92251d43ae52ca2ec311df9afba35 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$arg_descriptor.class b/src/main/resources/org/python/antlr/ast/keyword$arg_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a76bac10f8d6f9d289c6c9b88f55b5829543e3f1 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$arg_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$exposed___new__.class b/src/main/resources/org/python/antlr/ast/keyword$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..9f9092bbe6bbf18f02a88d606845ee4970a6c356 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$keyword___init___exposer.class b/src/main/resources/org/python/antlr/ast/keyword$keyword___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8bf27d22ec4c8cdbc5ca681161a0cd74c636f1ba Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$keyword___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$repr_descriptor.class b/src/main/resources/org/python/antlr/ast/keyword$repr_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e24543d5d15c6d6a00ce7c25c2dc2e0b9b5e3c5a Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$repr_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword$value_descriptor.class b/src/main/resources/org/python/antlr/ast/keyword$value_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d874f9a456fc7cb0e44eed0dacffe335332b8775 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword$value_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/ast/keyword.class b/src/main/resources/org/python/antlr/ast/keyword.class new file mode 100644 index 0000000000000000000000000000000000000000..2a7aaaa4f5817a32c8a949fc65fbde2abe0ebb5b Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keyword.class differ diff --git a/src/main/resources/org/python/antlr/ast/keywordDerived.class b/src/main/resources/org/python/antlr/ast/keywordDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3977fa3d1ac53acc850f0aa2ef918fa889b8efdd Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/keywordDerived.class differ diff --git a/src/main/resources/org/python/antlr/ast/operatorType.class b/src/main/resources/org/python/antlr/ast/operatorType.class new file mode 100644 index 0000000000000000000000000000000000000000..ef3100051b6b032f07bea4069272f697a55fd230 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/operatorType.class differ diff --git a/src/main/resources/org/python/antlr/ast/unaryopType.class b/src/main/resources/org/python/antlr/ast/unaryopType.class new file mode 100644 index 0000000000000000000000000000000000000000..3a4287d4e44e35f4d7f375b10fd4b92492b0dd62 Binary files /dev/null and b/src/main/resources/org/python/antlr/ast/unaryopType.class differ diff --git a/src/main/resources/org/python/antlr/base/excepthandler$PyExposer.class b/src/main/resources/org/python/antlr/base/excepthandler$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..853993b1285630e85c65e2a00b2a8a52b6af0ca3 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/excepthandler$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/base/excepthandler$_attributes_descriptor.class b/src/main/resources/org/python/antlr/base/excepthandler$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2d2ed5b1e496aa66ecb98518af2a808563e6c285 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/excepthandler$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/excepthandler$_fields_descriptor.class b/src/main/resources/org/python/antlr/base/excepthandler$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c962c04296ecb57825d8cd74971af5b8d66de880 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/excepthandler$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/excepthandler.class b/src/main/resources/org/python/antlr/base/excepthandler.class new file mode 100644 index 0000000000000000000000000000000000000000..58177d836641c77af4fa5a167a1dd2b0c95f021e Binary files /dev/null and b/src/main/resources/org/python/antlr/base/excepthandler.class differ diff --git a/src/main/resources/org/python/antlr/base/expr$PyExposer.class b/src/main/resources/org/python/antlr/base/expr$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..104628942c9cddcbd0ea52694b01ef65073f75e2 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/expr$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/base/expr$_attributes_descriptor.class b/src/main/resources/org/python/antlr/base/expr$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..942afc21dcb903a80804003b91a9fddee229fbf6 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/expr$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/expr$_fields_descriptor.class b/src/main/resources/org/python/antlr/base/expr$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..11217243f40ca8a29b7e5503210223227471177d Binary files /dev/null and b/src/main/resources/org/python/antlr/base/expr$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/expr.class b/src/main/resources/org/python/antlr/base/expr.class new file mode 100644 index 0000000000000000000000000000000000000000..451644d6ac8f8a8da12249eb825c091c0f91798e Binary files /dev/null and b/src/main/resources/org/python/antlr/base/expr.class differ diff --git a/src/main/resources/org/python/antlr/base/mod$PyExposer.class b/src/main/resources/org/python/antlr/base/mod$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..efd540f123e558a30383d3428d7a8564e98720e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/mod$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/base/mod$_attributes_descriptor.class b/src/main/resources/org/python/antlr/base/mod$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5cc80308de723b0fad3bffd2e139146a7738d2dd Binary files /dev/null and b/src/main/resources/org/python/antlr/base/mod$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/mod$_fields_descriptor.class b/src/main/resources/org/python/antlr/base/mod$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bdb09fa739dfca593a706fcd96370f930e3e035e Binary files /dev/null and b/src/main/resources/org/python/antlr/base/mod$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/mod.class b/src/main/resources/org/python/antlr/base/mod.class new file mode 100644 index 0000000000000000000000000000000000000000..fef3dc62c770eac4a991c4c0a17dc00155f3722d Binary files /dev/null and b/src/main/resources/org/python/antlr/base/mod.class differ diff --git a/src/main/resources/org/python/antlr/base/slice$PyExposer.class b/src/main/resources/org/python/antlr/base/slice$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..83c1c4796b3a542e32fc74126d1cc0a45d590ef5 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/slice$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/base/slice$_attributes_descriptor.class b/src/main/resources/org/python/antlr/base/slice$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3b748da3952720a935e3ac8f2b8533d4ad9c53a3 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/slice$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/slice$_fields_descriptor.class b/src/main/resources/org/python/antlr/base/slice$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1dc6018279f099e59512577c0f83e7a4df1bdf5e Binary files /dev/null and b/src/main/resources/org/python/antlr/base/slice$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/slice.class b/src/main/resources/org/python/antlr/base/slice.class new file mode 100644 index 0000000000000000000000000000000000000000..eac323ae15401a60882df3a64565ad223eee69c0 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/slice.class differ diff --git a/src/main/resources/org/python/antlr/base/stmt$PyExposer.class b/src/main/resources/org/python/antlr/base/stmt$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..05ebc49f69e85f6651f2a8f4781cc712f4e13562 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/stmt$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/base/stmt$_attributes_descriptor.class b/src/main/resources/org/python/antlr/base/stmt$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..456caeb3f96b2103b38bd03b72fb5c24f89ca73c Binary files /dev/null and b/src/main/resources/org/python/antlr/base/stmt$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/stmt$_fields_descriptor.class b/src/main/resources/org/python/antlr/base/stmt$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7f9a8930d792e9f47f87134e61bbe23192c403d6 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/stmt$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/base/stmt.class b/src/main/resources/org/python/antlr/base/stmt.class new file mode 100644 index 0000000000000000000000000000000000000000..a65dfd3a5382a39dd6736c80322af7dd7d012f03 Binary files /dev/null and b/src/main/resources/org/python/antlr/base/stmt.class differ diff --git a/src/main/resources/org/python/antlr/op/Add$Add___init___exposer.class b/src/main/resources/org/python/antlr/op/Add$Add___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1827b6a1af3d0c328de261d9736db976a3607166 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Add$Add___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Add$PyExposer.class b/src/main/resources/org/python/antlr/op/Add$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d6d9047c08c31d0298a30a5ea4ca59ad64b9425c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Add$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Add$__int___exposer.class b/src/main/resources/org/python/antlr/op/Add$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b7aeb21e7a33107621bb63de0b254e4dd045dfb7 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Add$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Add$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Add$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3d077a1eca995d61a8df56c8b4f95bf37d3efef6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Add$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Add$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Add$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e5ec558ffea2a6ca3896890d25bba5ed1835cc14 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Add$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Add$exposed___new__.class b/src/main/resources/org/python/antlr/op/Add$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..7a4937c20ead03f7c69bc1b1e58267a08086687c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Add$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Add.class b/src/main/resources/org/python/antlr/op/Add.class new file mode 100644 index 0000000000000000000000000000000000000000..b9f71048d35129f6559e8ed4a76949b39a1326b0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Add.class differ diff --git a/src/main/resources/org/python/antlr/op/AddDerived.class b/src/main/resources/org/python/antlr/op/AddDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..7ef2d559d3ad7e0d66341900ce1b5c2f9da4fb6c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AddDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/And$And___init___exposer.class b/src/main/resources/org/python/antlr/op/And$And___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..398d8a857291c448b254cb9a5fe3a07e23486f59 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/And$And___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/And$PyExposer.class b/src/main/resources/org/python/antlr/op/And$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1e8a8bd05f404edb1ca793c32a39d1d977227c37 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/And$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/And$__int___exposer.class b/src/main/resources/org/python/antlr/op/And$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9fc1afc71d771d350a307079a227afcef113ffb5 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/And$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/And$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/And$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..89508da209091cc94ab2617f2e17f007d2505b08 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/And$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/And$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/And$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5e6249925cb3c52241af1d4a783491912dc2a342 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/And$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/And$exposed___new__.class b/src/main/resources/org/python/antlr/op/And$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..87c58a81e0eac411d71c98277a623cf772d15530 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/And$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/And.class b/src/main/resources/org/python/antlr/op/And.class new file mode 100644 index 0000000000000000000000000000000000000000..7bd9c22ddb8ffec77e04813bae0efa150a74e755 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/And.class differ diff --git a/src/main/resources/org/python/antlr/op/AndDerived.class b/src/main/resources/org/python/antlr/op/AndDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3744450ab4db82932dd8f10b380c311942c63b6f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AndDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoad$AugLoad___init___exposer.class b/src/main/resources/org/python/antlr/op/AugLoad$AugLoad___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0f9b394b1c5cb2f668f977d4fd4e09787507f8fa Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoad$AugLoad___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoad$PyExposer.class b/src/main/resources/org/python/antlr/op/AugLoad$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..572eadcc301c495765ab00741de41a06e782fab2 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoad$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoad$__int___exposer.class b/src/main/resources/org/python/antlr/op/AugLoad$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..438cf3c1d56f1a4c114bcadb1241240cdebdb3ce Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoad$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoad$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/AugLoad$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f2affb47a07ff6c7a900c3ca5a39202f545dffb9 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoad$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoad$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/AugLoad$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b98b26201e1096d7f910aaa0f041b3c52bdb804c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoad$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoad$exposed___new__.class b/src/main/resources/org/python/antlr/op/AugLoad$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..469bdee057af0e41450bf673ec5d240902fff5aa Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoad$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoad.class b/src/main/resources/org/python/antlr/op/AugLoad.class new file mode 100644 index 0000000000000000000000000000000000000000..6b188bd247e3e28b0454dfd2b1a0618df063bf13 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoad.class differ diff --git a/src/main/resources/org/python/antlr/op/AugLoadDerived.class b/src/main/resources/org/python/antlr/op/AugLoadDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..d28be80a676c0c2b14559543fded6c5c27144168 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugLoadDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStore$AugStore___init___exposer.class b/src/main/resources/org/python/antlr/op/AugStore$AugStore___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ae28437f17646ff3e933cf46688087b319a77232 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStore$AugStore___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStore$PyExposer.class b/src/main/resources/org/python/antlr/op/AugStore$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3f41db85e2b6a239d43153418ec701986dfca0aa Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStore$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStore$__int___exposer.class b/src/main/resources/org/python/antlr/op/AugStore$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..93db9ca23fb71b7b80c82007bb27d93525ad95d0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStore$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStore$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/AugStore$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c5ee96ac06c49961419102744d9b84629bac1205 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStore$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStore$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/AugStore$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2a9e2ed063772def76ef9789811f01226f109992 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStore$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStore$exposed___new__.class b/src/main/resources/org/python/antlr/op/AugStore$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..4c82c526bf7539048551decf63c47f4fde60be8b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStore$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStore.class b/src/main/resources/org/python/antlr/op/AugStore.class new file mode 100644 index 0000000000000000000000000000000000000000..02dbcd404a4d017d5a6958998cabb89767d22652 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStore.class differ diff --git a/src/main/resources/org/python/antlr/op/AugStoreDerived.class b/src/main/resources/org/python/antlr/op/AugStoreDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..4b7b9831df56badc98eb3bb62c7bfd9833c1c4a3 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/AugStoreDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAnd$BitAnd___init___exposer.class b/src/main/resources/org/python/antlr/op/BitAnd$BitAnd___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f12f19624ff61ea1bff97cbbb4a227622f12a53d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAnd$BitAnd___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAnd$PyExposer.class b/src/main/resources/org/python/antlr/op/BitAnd$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..60c0100428f7d98d3380b95c5512059a6e234345 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAnd$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAnd$__int___exposer.class b/src/main/resources/org/python/antlr/op/BitAnd$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..49f6f6a846c95e69d12ea43535913148a8747dac Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAnd$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAnd$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/BitAnd$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fb9aafad092491e49282d5dd6d0d9484c0e37c63 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAnd$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAnd$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/BitAnd$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..136502ff980f56e9d9d6eda4ea84b77d9d383266 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAnd$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAnd$exposed___new__.class b/src/main/resources/org/python/antlr/op/BitAnd$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..99add42e429c2709588ded1abe5f7d28348dc8d6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAnd$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAnd.class b/src/main/resources/org/python/antlr/op/BitAnd.class new file mode 100644 index 0000000000000000000000000000000000000000..e080202df06ec3258338efb96ad5423039aa3b17 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAnd.class differ diff --git a/src/main/resources/org/python/antlr/op/BitAndDerived.class b/src/main/resources/org/python/antlr/op/BitAndDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..b8a6f96703124f9b33d97d61d5db1f8cf3a68015 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitAndDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOr$BitOr___init___exposer.class b/src/main/resources/org/python/antlr/op/BitOr$BitOr___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d369ce6065602ba0554f18d7e3144f41b6fddb62 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOr$BitOr___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOr$PyExposer.class b/src/main/resources/org/python/antlr/op/BitOr$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d4a9961da98448f9f2175cc5eacfcaaeab327cc6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOr$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOr$__int___exposer.class b/src/main/resources/org/python/antlr/op/BitOr$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7549f7c9259b29c9f60ea3d926cfb9abb32b6d0b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOr$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOr$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/BitOr$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..370642b8eb3da6b2732339dc41e7a7e0b400a498 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOr$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOr$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/BitOr$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2bb7d5c935d862ce3c0636e30a15133405767c62 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOr$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOr$exposed___new__.class b/src/main/resources/org/python/antlr/op/BitOr$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..58340841c7d246efbc44456ae2b7b343d6eee014 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOr$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOr.class b/src/main/resources/org/python/antlr/op/BitOr.class new file mode 100644 index 0000000000000000000000000000000000000000..885986cbf30e24d0269a4aa9e7c2e0577463497c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOr.class differ diff --git a/src/main/resources/org/python/antlr/op/BitOrDerived.class b/src/main/resources/org/python/antlr/op/BitOrDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..a511fcdd43175b71786dc7c82504b7e448d4c035 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitOrDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXor$BitXor___init___exposer.class b/src/main/resources/org/python/antlr/op/BitXor$BitXor___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4cf4029567eea910c29cd67ab101d691f0838d81 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXor$BitXor___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXor$PyExposer.class b/src/main/resources/org/python/antlr/op/BitXor$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8f4e6e74916e3dedec9b4b72e603c9c43150b292 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXor$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXor$__int___exposer.class b/src/main/resources/org/python/antlr/op/BitXor$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dfdf5f662751440a4645441c85245eec9966df1e Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXor$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXor$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/BitXor$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a0124d80d5e26f8882690a9f3c32c35d345f3af5 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXor$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXor$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/BitXor$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..168240504b1df65c3f0e2284d2c2bac1b6301e51 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXor$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXor$exposed___new__.class b/src/main/resources/org/python/antlr/op/BitXor$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..46a758823e61ffdc5a3962a541fe0b79f0fe7601 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXor$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXor.class b/src/main/resources/org/python/antlr/op/BitXor.class new file mode 100644 index 0000000000000000000000000000000000000000..97f5787adfe42cdddfa807b37c00922279baaf1d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXor.class differ diff --git a/src/main/resources/org/python/antlr/op/BitXorDerived.class b/src/main/resources/org/python/antlr/op/BitXorDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..af25ccc87f8aa7d578ab86e3ef6d36c3682484ee Binary files /dev/null and b/src/main/resources/org/python/antlr/op/BitXorDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Del$Del___init___exposer.class b/src/main/resources/org/python/antlr/op/Del$Del___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..469370ded8128ead139f05bb1f0bbe0d39828a4b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Del$Del___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Del$PyExposer.class b/src/main/resources/org/python/antlr/op/Del$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c95ecbb883aebf82b67247dd3aa354ec2bb126f2 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Del$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Del$__int___exposer.class b/src/main/resources/org/python/antlr/op/Del$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4e2b54cb88e63404df53826ff0524cda062ab30f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Del$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Del$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Del$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6663a3d4a17e2b580cb43982d34527f61bc8930d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Del$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Del$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Del$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..dfd315a0bf802576103ce3bd125caec56465343f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Del$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Del$exposed___new__.class b/src/main/resources/org/python/antlr/op/Del$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..1504c14fbc700ba18ed4dd14203ab17da0a53be0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Del$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Del.class b/src/main/resources/org/python/antlr/op/Del.class new file mode 100644 index 0000000000000000000000000000000000000000..7d5554f004b5dc783c6f9d9b6ee1bd012ec8cfa3 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Del.class differ diff --git a/src/main/resources/org/python/antlr/op/DelDerived.class b/src/main/resources/org/python/antlr/op/DelDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3e06666f4f65ac83d39a522b2d64aafa762b8708 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/DelDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Div$Div___init___exposer.class b/src/main/resources/org/python/antlr/op/Div$Div___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ab0ac3d6a4e74bc206411a60c69b7ca34fd8dc67 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Div$Div___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Div$PyExposer.class b/src/main/resources/org/python/antlr/op/Div$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3bec73c60318304b10ca12b8c75d0144a2a36750 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Div$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Div$__int___exposer.class b/src/main/resources/org/python/antlr/op/Div$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a19efe861f543e88adddb32862d4be1bd3aa8f52 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Div$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Div$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Div$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..33d7dc1dfa45bfb4f229868b946524ea60dab74a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Div$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Div$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Div$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..08cdf73da7f826eda09000609c61191725b76b4c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Div$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Div$exposed___new__.class b/src/main/resources/org/python/antlr/op/Div$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..fc635122d743aefd71e04661092923ae8f12c8d1 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Div$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Div.class b/src/main/resources/org/python/antlr/op/Div.class new file mode 100644 index 0000000000000000000000000000000000000000..05d28755a7df99fa423e58409241d9f973f41471 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Div.class differ diff --git a/src/main/resources/org/python/antlr/op/DivDerived.class b/src/main/resources/org/python/antlr/op/DivDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..28d9d2760be448dfe46f7bff276ecb102666759d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/DivDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Eq$Eq___init___exposer.class b/src/main/resources/org/python/antlr/op/Eq$Eq___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..48a2809871987aa51310c73753f95f7e07fdeadd Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Eq$Eq___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Eq$PyExposer.class b/src/main/resources/org/python/antlr/op/Eq$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..438b6a8ee1794d9ce83eceaf72162dd3b9be6084 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Eq$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Eq$__int___exposer.class b/src/main/resources/org/python/antlr/op/Eq$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9561f388137f0111dca71175dec53f4e15117235 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Eq$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Eq$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Eq$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3eceded759363efcaf13dc5ecdbe0c3828af00e1 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Eq$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Eq$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Eq$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..41161efb33b3d4bd34f49abc39854a8d7a322bab Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Eq$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Eq$exposed___new__.class b/src/main/resources/org/python/antlr/op/Eq$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b475ad823e2c7478d009d453f45af8e2e63b79b0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Eq$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Eq.class b/src/main/resources/org/python/antlr/op/Eq.class new file mode 100644 index 0000000000000000000000000000000000000000..081231847c031230ff658df93161584212ac4c54 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Eq.class differ diff --git a/src/main/resources/org/python/antlr/op/EqDerived.class b/src/main/resources/org/python/antlr/op/EqDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..993b2279ef2c9726157e89612f46046326d1a39b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/EqDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDiv$FloorDiv___init___exposer.class b/src/main/resources/org/python/antlr/op/FloorDiv$FloorDiv___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b1522ec215e245deb82eff3743966ddaefb8625a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDiv$FloorDiv___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDiv$PyExposer.class b/src/main/resources/org/python/antlr/op/FloorDiv$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..edcd61d0d80aa51b05fa210a9abc2f34fbfcf309 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDiv$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDiv$__int___exposer.class b/src/main/resources/org/python/antlr/op/FloorDiv$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8699462abcf0663da96060ec21186a15c79b422b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDiv$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDiv$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/FloorDiv$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f1927dac4e5dad8172cf9117a30553a46014438a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDiv$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDiv$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/FloorDiv$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..22722bc602028086c9b5671d9b46b1b1ea03933f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDiv$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDiv$exposed___new__.class b/src/main/resources/org/python/antlr/op/FloorDiv$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..775a2a6570aa760c9f5691ed51a33756927985e7 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDiv$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDiv.class b/src/main/resources/org/python/antlr/op/FloorDiv.class new file mode 100644 index 0000000000000000000000000000000000000000..ccc58161d436aa774aebc69221ceaabe0dbdc459 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDiv.class differ diff --git a/src/main/resources/org/python/antlr/op/FloorDivDerived.class b/src/main/resources/org/python/antlr/op/FloorDivDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..41f5ca62c9c1c7c0fd8dee3599e019a33d81eb4a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/FloorDivDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Gt$Gt___init___exposer.class b/src/main/resources/org/python/antlr/op/Gt$Gt___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f0ce5908f69be65d54131b3f27655ab1e8e61a77 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Gt$Gt___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Gt$PyExposer.class b/src/main/resources/org/python/antlr/op/Gt$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f0c2c148d59009f8350e7f0369c12e95b6c70ff4 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Gt$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Gt$__int___exposer.class b/src/main/resources/org/python/antlr/op/Gt$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e16f47cf213c7ae2044974bbe01a172289277375 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Gt$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Gt$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Gt$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b1614bd972b5e5a22b55a4e85a4c46128e41c2c3 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Gt$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Gt$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Gt$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8b2119d5929dfe79ae8d0e05424ccb476ae4ab78 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Gt$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Gt$exposed___new__.class b/src/main/resources/org/python/antlr/op/Gt$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..277f8fbbf75b6717ace3a89b2429d8d64697716c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Gt$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Gt.class b/src/main/resources/org/python/antlr/op/Gt.class new file mode 100644 index 0000000000000000000000000000000000000000..8d1920038e6446043f95abe9530819454b11a099 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Gt.class differ diff --git a/src/main/resources/org/python/antlr/op/GtDerived.class b/src/main/resources/org/python/antlr/op/GtDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..d420552094d394b77fd76ce58e3ca65d5c4ffb33 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/GtE$GtE___init___exposer.class b/src/main/resources/org/python/antlr/op/GtE$GtE___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..40a4b30fedf128fcc509e7780d7e482bf393acfe Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtE$GtE___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/GtE$PyExposer.class b/src/main/resources/org/python/antlr/op/GtE$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3f7b9b9b8cb3b8df0c37004287d2b9c7e73a5d95 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtE$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/GtE$__int___exposer.class b/src/main/resources/org/python/antlr/op/GtE$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..674bf8298538a2489460a06932c038c60fd1eb65 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtE$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/GtE$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/GtE$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..976317a82606877edb8a280e3bb6fdafcac98bf2 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtE$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/GtE$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/GtE$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2a51d7e1fc6d91f0e4c8edd5e19190f728c6031b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtE$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/GtE$exposed___new__.class b/src/main/resources/org/python/antlr/op/GtE$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..868d50c8a3385b38f901ed4c2b8b4e95298fe445 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtE$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/GtE.class b/src/main/resources/org/python/antlr/op/GtE.class new file mode 100644 index 0000000000000000000000000000000000000000..010af8ed95bce78441411582df8221ae3d281806 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtE.class differ diff --git a/src/main/resources/org/python/antlr/op/GtEDerived.class b/src/main/resources/org/python/antlr/op/GtEDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..7ea200493b1f873cac22504465093a9e6537c7bd Binary files /dev/null and b/src/main/resources/org/python/antlr/op/GtEDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/In$In___init___exposer.class b/src/main/resources/org/python/antlr/op/In$In___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2f95149ad433eb7a5888b187f9f54046d4d12a96 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/In$In___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/In$PyExposer.class b/src/main/resources/org/python/antlr/op/In$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a6c7574bd84801ab9a506b858b68ff08d7d49e07 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/In$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/In$__int___exposer.class b/src/main/resources/org/python/antlr/op/In$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f66e366ea9827fb633530b09fcf133ea34b91c9c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/In$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/In$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/In$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f1b44bb876d9181cfb210b278e70fef162d1054a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/In$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/In$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/In$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..42454a1b72c21dd4d22c50d022b12575745568d0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/In$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/In$exposed___new__.class b/src/main/resources/org/python/antlr/op/In$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..ffb7e5c816f4509685e4dc7b9d9bd01530cac427 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/In$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/In.class b/src/main/resources/org/python/antlr/op/In.class new file mode 100644 index 0000000000000000000000000000000000000000..fcd580478be722031623c87ae1c374b18fc724a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/In.class differ diff --git a/src/main/resources/org/python/antlr/op/InDerived.class b/src/main/resources/org/python/antlr/op/InDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..84e718fc4f115b6f29d38d1afd92213a480b4395 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/InDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Invert$Invert___init___exposer.class b/src/main/resources/org/python/antlr/op/Invert$Invert___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d5a6f096aa4b83308ae49f30bcdf4bf85ca08b1d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Invert$Invert___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Invert$PyExposer.class b/src/main/resources/org/python/antlr/op/Invert$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6053beacf412565437834cffe53deac9adda9907 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Invert$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Invert$__int___exposer.class b/src/main/resources/org/python/antlr/op/Invert$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f9b8b8cd47add66ed5e4327ddc1649e22a3bd7fe Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Invert$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Invert$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Invert$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e791dd033965fb72b6f4f3e88ce27d7a260bba08 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Invert$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Invert$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Invert$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a8b03482f9e123d18d051904c65816ba7bcd8372 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Invert$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Invert$exposed___new__.class b/src/main/resources/org/python/antlr/op/Invert$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..51c2bb88aa098d078222db443eeade0d3b884ffc Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Invert$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Invert.class b/src/main/resources/org/python/antlr/op/Invert.class new file mode 100644 index 0000000000000000000000000000000000000000..ae8e225c693431719d5566235d7a48d1a88c4a04 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Invert.class differ diff --git a/src/main/resources/org/python/antlr/op/InvertDerived.class b/src/main/resources/org/python/antlr/op/InvertDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..060ae0fc8934f0c25aa76aaefb4ca1b46567f766 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/InvertDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Is$Is___init___exposer.class b/src/main/resources/org/python/antlr/op/Is$Is___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2ba2f7612a230771dce53ac04b8627fe10063b71 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Is$Is___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Is$PyExposer.class b/src/main/resources/org/python/antlr/op/Is$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f43c0a7e68a385f9c06bdd397e66f27276d77662 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Is$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Is$__int___exposer.class b/src/main/resources/org/python/antlr/op/Is$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..43702e177f164770b28dfb0cddc8390a25c53bf6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Is$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Is$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Is$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..524b91629954356106e522e95e841894ecc71e29 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Is$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Is$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Is$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8892749aec8299cffb49997dd4161afd2536757c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Is$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Is$exposed___new__.class b/src/main/resources/org/python/antlr/op/Is$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..ba56a55bffc9b2e9ce9a43699301dc468d8676df Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Is$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Is.class b/src/main/resources/org/python/antlr/op/Is.class new file mode 100644 index 0000000000000000000000000000000000000000..525b9682e5d2eb1c93a7c1947d5e1ca6a6de825e Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Is.class differ diff --git a/src/main/resources/org/python/antlr/op/IsDerived.class b/src/main/resources/org/python/antlr/op/IsDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..6b81805923e4de862bc96a4ef52b3c4f144309e9 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNot$IsNot___init___exposer.class b/src/main/resources/org/python/antlr/op/IsNot$IsNot___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ce9148f565c08a97e55d8042ec2f19a474caeb62 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNot$IsNot___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNot$PyExposer.class b/src/main/resources/org/python/antlr/op/IsNot$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f76030d22edca69de2d0e7473400527680b54bd6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNot$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNot$__int___exposer.class b/src/main/resources/org/python/antlr/op/IsNot$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d9b8a24ece53ca6f06d46bcff97281e0354f96d0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNot$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNot$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/IsNot$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ad25233773e4eed1935622661c6d9caa7c0c5f5d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNot$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNot$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/IsNot$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..db46188e52624627a9f49f48d53a006e4f737bea Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNot$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNot$exposed___new__.class b/src/main/resources/org/python/antlr/op/IsNot$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..6bc8d5dcf69eb4bbfd50e2e74320ada6c6a9b61f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNot$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNot.class b/src/main/resources/org/python/antlr/op/IsNot.class new file mode 100644 index 0000000000000000000000000000000000000000..e9629e665169bcd3e0b4e92e81b58b4ba15d190c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNot.class differ diff --git a/src/main/resources/org/python/antlr/op/IsNotDerived.class b/src/main/resources/org/python/antlr/op/IsNotDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..0255eaa5a98cb14508eea1484aa446cc04978a67 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/IsNotDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/LShift$LShift___init___exposer.class b/src/main/resources/org/python/antlr/op/LShift$LShift___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1da5393f80c97a228950d89ff7bbd130cf13fd2e Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShift$LShift___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/LShift$PyExposer.class b/src/main/resources/org/python/antlr/op/LShift$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7fdcafa2e3312638e777766ff0bc6a4cda2f8eaf Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShift$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/LShift$__int___exposer.class b/src/main/resources/org/python/antlr/op/LShift$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb9b787d4080d9ff83d116938f60be3cadca6998 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShift$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/LShift$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/LShift$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..82d776985fe81d5f688137971695546fa258fd46 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShift$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/LShift$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/LShift$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c8e77aaee151b7be4bf1c9c8a1a7f7fa11210c9b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShift$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/LShift$exposed___new__.class b/src/main/resources/org/python/antlr/op/LShift$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..80e5baa89b6492707e3f0dcf9ac0f6e174e2fdc7 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShift$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/LShift.class b/src/main/resources/org/python/antlr/op/LShift.class new file mode 100644 index 0000000000000000000000000000000000000000..c7ac971d5bee822a0ae21cf68a4acbdbbebc40a4 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShift.class differ diff --git a/src/main/resources/org/python/antlr/op/LShiftDerived.class b/src/main/resources/org/python/antlr/op/LShiftDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..c97873cee0ead9bd9706322f1dc643d4e5017832 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LShiftDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Load$Load___init___exposer.class b/src/main/resources/org/python/antlr/op/Load$Load___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a96dfa9b932ef3ff452c2a09e4b59e39476ceea4 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Load$Load___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Load$PyExposer.class b/src/main/resources/org/python/antlr/op/Load$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..aa62cca561f1d727d78738f8ecabc8bbd25bdb62 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Load$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Load$__int___exposer.class b/src/main/resources/org/python/antlr/op/Load$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..85b9a6acd72ae5905a663f599053e3698ee98ebb Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Load$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Load$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Load$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cccbc152eacf4cbfb4e48d819bd5ab8a33f1ab25 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Load$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Load$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Load$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9332d2b87f81658fb601f2ed3000e5d30fb7e15a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Load$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Load$exposed___new__.class b/src/main/resources/org/python/antlr/op/Load$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..7578aefe3d74fe7f317e4da4ef3a23e4a406f0ce Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Load$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Load.class b/src/main/resources/org/python/antlr/op/Load.class new file mode 100644 index 0000000000000000000000000000000000000000..896d1730ed9cb63dffd0dcfef29010e2726dcfc3 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Load.class differ diff --git a/src/main/resources/org/python/antlr/op/LoadDerived.class b/src/main/resources/org/python/antlr/op/LoadDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3eab0cff9b5def4796bb7ca61f5b4109127f66b8 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LoadDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Lt$Lt___init___exposer.class b/src/main/resources/org/python/antlr/op/Lt$Lt___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..662df46d40e3bd59be2c10bed85450122ddaa82a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Lt$Lt___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Lt$PyExposer.class b/src/main/resources/org/python/antlr/op/Lt$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a6ce55a7c7cdc8b419413aeb033a79faf30b1af6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Lt$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Lt$__int___exposer.class b/src/main/resources/org/python/antlr/op/Lt$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4254edc48a3b14ace8e337056e4a31dbeab5709b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Lt$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Lt$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Lt$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..979da477a58c1abfd5c22a0f267088267716d0cc Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Lt$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Lt$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Lt$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..278be54460710f5d6e690f3d42c011274e1c45fd Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Lt$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Lt$exposed___new__.class b/src/main/resources/org/python/antlr/op/Lt$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..193a81d7c62c94538d2f283976279e1300368022 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Lt$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Lt.class b/src/main/resources/org/python/antlr/op/Lt.class new file mode 100644 index 0000000000000000000000000000000000000000..b9ee2f5b022c26da7295d8dd4927eae461c30da6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Lt.class differ diff --git a/src/main/resources/org/python/antlr/op/LtDerived.class b/src/main/resources/org/python/antlr/op/LtDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..cf449ab2f79ba4bd6819c3de323dc81b5e5f1fb4 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/LtE$LtE___init___exposer.class b/src/main/resources/org/python/antlr/op/LtE$LtE___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7e058272dc60705c1125534b24f334d1af7232eb Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtE$LtE___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/LtE$PyExposer.class b/src/main/resources/org/python/antlr/op/LtE$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f8c26d0ea9f71da3d44e697a2632690362c8f8ba Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtE$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/LtE$__int___exposer.class b/src/main/resources/org/python/antlr/op/LtE$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6a11ef18c383f726756a84af7fb9ff35ae83cb64 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtE$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/LtE$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/LtE$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bd396b97953804454d2563e674f9e2c85d855269 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtE$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/LtE$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/LtE$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..98d42d70053a9f3fafb7f5ddcfe7c5f660a981e4 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtE$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/LtE$exposed___new__.class b/src/main/resources/org/python/antlr/op/LtE$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..2db3f6575af3aa1c9d782638e62d664bbabbc44d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtE$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/LtE.class b/src/main/resources/org/python/antlr/op/LtE.class new file mode 100644 index 0000000000000000000000000000000000000000..2bd457b1d9c9bf14c2db7631310fa333b023416f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtE.class differ diff --git a/src/main/resources/org/python/antlr/op/LtEDerived.class b/src/main/resources/org/python/antlr/op/LtEDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..593d2eec19f016de7e693ed3964f29798c7e0b41 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/LtEDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Mod$Mod___init___exposer.class b/src/main/resources/org/python/antlr/op/Mod$Mod___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..637d93286ca31e0a4b1e4c6ebc36ba37603362a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mod$Mod___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Mod$PyExposer.class b/src/main/resources/org/python/antlr/op/Mod$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5409db702719593b8e3bc7efd1c9e9cd01644bce Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mod$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Mod$__int___exposer.class b/src/main/resources/org/python/antlr/op/Mod$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..70bbbb4eb6bdcd31bb5700247a0e3633ca09fa67 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mod$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Mod$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Mod$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..041e6acabf498b23ee2d3dce3e21e716aefc63ff Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mod$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Mod$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Mod$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2cb9b996c09ad35a7a340fef5ed50dd582f05eaf Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mod$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Mod$exposed___new__.class b/src/main/resources/org/python/antlr/op/Mod$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..716892f0de56b0563d4597a24c8fe19012fae9ae Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mod$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Mod.class b/src/main/resources/org/python/antlr/op/Mod.class new file mode 100644 index 0000000000000000000000000000000000000000..e2a0fef961686e1a67ab1b790b8d544a1ed2448e Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mod.class differ diff --git a/src/main/resources/org/python/antlr/op/ModDerived.class b/src/main/resources/org/python/antlr/op/ModDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..75a8b2834928e7be03e199109da16ba249c19d4c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/ModDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Mult$Mult___init___exposer.class b/src/main/resources/org/python/antlr/op/Mult$Mult___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7f54f8f59f619001ff8eb9f0004a7590c011831b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mult$Mult___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Mult$PyExposer.class b/src/main/resources/org/python/antlr/op/Mult$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1bdfb8348f95e6201c56f71364f900ad27eafd8 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mult$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Mult$__int___exposer.class b/src/main/resources/org/python/antlr/op/Mult$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e3c2909bc140e535a65ed78b8de2a454f159bff1 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mult$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Mult$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Mult$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5b107a142e8ea954ad69c8f6706d7100c77514a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mult$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Mult$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Mult$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bfc8c45f2593c74ebc9845d6e244476c4c4e209d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mult$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Mult$exposed___new__.class b/src/main/resources/org/python/antlr/op/Mult$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..2dd98ed0365e323dfceaeab25d9fc7c982ff0fd3 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mult$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Mult.class b/src/main/resources/org/python/antlr/op/Mult.class new file mode 100644 index 0000000000000000000000000000000000000000..aaca848b74af575389a4e3b9f31b8c54586b884d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Mult.class differ diff --git a/src/main/resources/org/python/antlr/op/MultDerived.class b/src/main/resources/org/python/antlr/op/MultDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..f3889699c80205e26f1f6ecd32071f1df439adde Binary files /dev/null and b/src/main/resources/org/python/antlr/op/MultDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Not$Not___init___exposer.class b/src/main/resources/org/python/antlr/op/Not$Not___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8116893c450f598c4d8fc9be4404e89f17beaa94 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Not$Not___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Not$PyExposer.class b/src/main/resources/org/python/antlr/op/Not$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..08552ab85ca14e7da2c46b8bb43b18e11ee60b7a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Not$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Not$__int___exposer.class b/src/main/resources/org/python/antlr/op/Not$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b2b16edf7ec9a61489c2eac6256b09188233a585 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Not$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Not$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Not$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cecd3798a39f5a9ab49eef797b19480692b29d53 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Not$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Not$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Not$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aae2bc4c5235d523f1e18169e72521dc8e599328 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Not$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Not$exposed___new__.class b/src/main/resources/org/python/antlr/op/Not$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..2806e26ff0ac4ad98b4ad306ec4eb134050e443b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Not$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Not.class b/src/main/resources/org/python/antlr/op/Not.class new file mode 100644 index 0000000000000000000000000000000000000000..ad5c643391601e3d593e981d501aef134a9d2da1 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Not.class differ diff --git a/src/main/resources/org/python/antlr/op/NotDerived.class b/src/main/resources/org/python/antlr/op/NotDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..54574cf983da48006f73525037fc6be94b402e8b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEq$NotEq___init___exposer.class b/src/main/resources/org/python/antlr/op/NotEq$NotEq___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c14bd2255ec2e02cc4e92bcebe53d6dbb03edb06 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEq$NotEq___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEq$PyExposer.class b/src/main/resources/org/python/antlr/op/NotEq$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..97ea5a17c1051d2760ca87de0b9db0249e3267c8 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEq$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEq$__int___exposer.class b/src/main/resources/org/python/antlr/op/NotEq$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fc6698480ee17a6448ae89bd7d39001696b7ceb3 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEq$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEq$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/NotEq$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8761bcda8dd2eb09e33710c19acf1f91fd99d00f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEq$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEq$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/NotEq$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0c8fe59fa5b1e240b4f25c959ba50623d755ea0d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEq$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEq$exposed___new__.class b/src/main/resources/org/python/antlr/op/NotEq$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..2c45dc255d2947b4457e062e8a2c9e425e94c827 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEq$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEq.class b/src/main/resources/org/python/antlr/op/NotEq.class new file mode 100644 index 0000000000000000000000000000000000000000..00adff07ef5c5ea3047340c69c7a256619ae8b27 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEq.class differ diff --git a/src/main/resources/org/python/antlr/op/NotEqDerived.class b/src/main/resources/org/python/antlr/op/NotEqDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..919c09f8bf14034cb3a1355869cb81c6955e9fba Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotEqDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/NotIn$NotIn___init___exposer.class b/src/main/resources/org/python/antlr/op/NotIn$NotIn___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7df918c27c7f743b09540fbea871473ef26330ab Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotIn$NotIn___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/NotIn$PyExposer.class b/src/main/resources/org/python/antlr/op/NotIn$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bcca2b3a06fb3a89ba741149b86d3913787691a3 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotIn$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/NotIn$__int___exposer.class b/src/main/resources/org/python/antlr/op/NotIn$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a579044689909cb94a223675db50dc1631f5965d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotIn$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/NotIn$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/NotIn$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7b9016d47611ab6f412dd6eea08cc469839006e5 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotIn$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/NotIn$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/NotIn$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8e07ace956100bdd3d72d015b296e76e653f1f0f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotIn$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/NotIn$exposed___new__.class b/src/main/resources/org/python/antlr/op/NotIn$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..3f6ca8f5224b8dc2d5817e34313652a47f221687 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotIn$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/NotIn.class b/src/main/resources/org/python/antlr/op/NotIn.class new file mode 100644 index 0000000000000000000000000000000000000000..ea2e33e075cc3b49cb3746e1dcdcd599476b0d10 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotIn.class differ diff --git a/src/main/resources/org/python/antlr/op/NotInDerived.class b/src/main/resources/org/python/antlr/op/NotInDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..805430f8bb43e1af0e48082dca4376b60ecab06e Binary files /dev/null and b/src/main/resources/org/python/antlr/op/NotInDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Or$Or___init___exposer.class b/src/main/resources/org/python/antlr/op/Or$Or___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3fea912a5c0ebb06f99e51e90c93c66c35f8afff Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Or$Or___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Or$PyExposer.class b/src/main/resources/org/python/antlr/op/Or$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8891512efe0b9f65b35b8aa04cf81b7c104d0e67 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Or$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Or$__int___exposer.class b/src/main/resources/org/python/antlr/op/Or$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..08578fb18e3a0842dc308f180a0fae749011f1fa Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Or$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Or$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Or$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c9e323675c7cf22c3b119eb0b8a7a2e29487bfc7 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Or$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Or$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Or$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8dbc855909647f7ec3aeb3ad66c55b32402341f0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Or$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Or$exposed___new__.class b/src/main/resources/org/python/antlr/op/Or$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..51731077bd64800e4be57e22294567f287c64b27 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Or$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Or.class b/src/main/resources/org/python/antlr/op/Or.class new file mode 100644 index 0000000000000000000000000000000000000000..aeb810afc8d13550df3e9697fca74a30c5c3d063 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Or.class differ diff --git a/src/main/resources/org/python/antlr/op/OrDerived.class b/src/main/resources/org/python/antlr/op/OrDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..7c5fe45ba529f6452477c9586d2e1050ab7d00d0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/OrDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Param$Param___init___exposer.class b/src/main/resources/org/python/antlr/op/Param$Param___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3161b58f74e018e00ff17e1498817efd629c1e8d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Param$Param___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Param$PyExposer.class b/src/main/resources/org/python/antlr/op/Param$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..550111b8901b3a8b7bd40b20e3e360d16eeff156 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Param$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Param$__int___exposer.class b/src/main/resources/org/python/antlr/op/Param$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..571ef55d8a1cee6d32a88f1680b1588f5d5d9f6f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Param$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Param$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Param$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8f91885b8f7cde262601da1088aa824b4f4bf972 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Param$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Param$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Param$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..73461b0ed0a540faa131df69b3f217193a3ccccc Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Param$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Param$exposed___new__.class b/src/main/resources/org/python/antlr/op/Param$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..a9066238ad1a39755163d45b9885c7cfda7aff78 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Param$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Param.class b/src/main/resources/org/python/antlr/op/Param.class new file mode 100644 index 0000000000000000000000000000000000000000..4494849f134fdc193c0d4d5d3141a8d5f4c6b45c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Param.class differ diff --git a/src/main/resources/org/python/antlr/op/ParamDerived.class b/src/main/resources/org/python/antlr/op/ParamDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..ab5b6d83ff2fb8abae02b6030ac1fda6526dfd4d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/ParamDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Pow$Pow___init___exposer.class b/src/main/resources/org/python/antlr/op/Pow$Pow___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3549dfcb8c40d1bb26a9e78dc1ab71789ba3988a Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Pow$Pow___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Pow$PyExposer.class b/src/main/resources/org/python/antlr/op/Pow$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8260008388dc9201314699d4f71073a72e70e5d8 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Pow$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Pow$__int___exposer.class b/src/main/resources/org/python/antlr/op/Pow$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5f4eacafe647c093e560a2205c1ef717542a82da Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Pow$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Pow$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Pow$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7164c3dbdb476a1b12da7a320ba2432e7d29f58f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Pow$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Pow$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Pow$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..df45bc9ec269eb81eb25347300f528cc428c8bd8 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Pow$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Pow$exposed___new__.class b/src/main/resources/org/python/antlr/op/Pow$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..456d419c137275ad7d0b827501ed0bf1238b760f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Pow$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Pow.class b/src/main/resources/org/python/antlr/op/Pow.class new file mode 100644 index 0000000000000000000000000000000000000000..efc29dd2fa0fc827898f91bf0528773e01e8c063 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Pow.class differ diff --git a/src/main/resources/org/python/antlr/op/PowDerived.class b/src/main/resources/org/python/antlr/op/PowDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..eb2acebfb464a679f503a4a2a83cb1a54b585335 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/PowDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/RShift$PyExposer.class b/src/main/resources/org/python/antlr/op/RShift$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4c7cc543cea240f668a91e52b67845dc1f9b6e52 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShift$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/RShift$RShift___init___exposer.class b/src/main/resources/org/python/antlr/op/RShift$RShift___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c5e2880558ac5400d8914feab672343b57c29b46 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShift$RShift___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/RShift$__int___exposer.class b/src/main/resources/org/python/antlr/op/RShift$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e8fd5c87e13931f99f308b75419340fbcbacaf24 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShift$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/RShift$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/RShift$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d86b58930ec96d62855150d03321e24df986558f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShift$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/RShift$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/RShift$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e8cb306ccda5e94374f7e216d076119d458efde1 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShift$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/RShift$exposed___new__.class b/src/main/resources/org/python/antlr/op/RShift$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..8f212a8c6941c6a9e1e59abe8ec24af16af146e0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShift$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/RShift.class b/src/main/resources/org/python/antlr/op/RShift.class new file mode 100644 index 0000000000000000000000000000000000000000..fba6d844c6aacbac429df49cda7d6506009461ae Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShift.class differ diff --git a/src/main/resources/org/python/antlr/op/RShiftDerived.class b/src/main/resources/org/python/antlr/op/RShiftDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..91b835f82e52e37374a9fc484c1c751c5adc1c2c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/RShiftDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Store$PyExposer.class b/src/main/resources/org/python/antlr/op/Store$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..597088aedc9dcc9561409c46eb2a2a37ab176976 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Store$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Store$Store___init___exposer.class b/src/main/resources/org/python/antlr/op/Store$Store___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d7d36f01ef3e4a6677fcf55c60164e8fab55e695 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Store$Store___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Store$__int___exposer.class b/src/main/resources/org/python/antlr/op/Store$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..57dbe9e9af959caf4da8bd338e55fb42b0259350 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Store$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Store$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Store$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..35ccd6dfe6d79180df2d9ec45916b17810e225ae Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Store$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Store$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Store$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..adba447c3c7ef7f4b3cbfc465924432b6d1562d0 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Store$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Store$exposed___new__.class b/src/main/resources/org/python/antlr/op/Store$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..fa722b0fbb60f06c774704d5ddf86cca17aa5bec Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Store$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Store.class b/src/main/resources/org/python/antlr/op/Store.class new file mode 100644 index 0000000000000000000000000000000000000000..2ef0247667e657057c3196a42bfff7bfd2019c55 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Store.class differ diff --git a/src/main/resources/org/python/antlr/op/StoreDerived.class b/src/main/resources/org/python/antlr/op/StoreDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..ba10e526d99046caf2328fc4b666649944382246 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/StoreDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/Sub$PyExposer.class b/src/main/resources/org/python/antlr/op/Sub$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..28d6095a1cb2918903873bfc7ec94e99f549d70b Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Sub$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Sub$Sub___init___exposer.class b/src/main/resources/org/python/antlr/op/Sub$Sub___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a9f5d9d8f675b34920ebddd077bca29391636a04 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Sub$Sub___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Sub$__int___exposer.class b/src/main/resources/org/python/antlr/op/Sub$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cce996e486c32c036368c7ea3ea9216be34c7166 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Sub$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/Sub$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/Sub$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d3037df443398fb2b49743152a24a0c536ae2350 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Sub$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Sub$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/Sub$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2770b5f5e401b83c7654a7668969a30173e234de Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Sub$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/Sub$exposed___new__.class b/src/main/resources/org/python/antlr/op/Sub$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..a8b0c03bea7db2576518c0511a60d19e444809da Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Sub$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/Sub.class b/src/main/resources/org/python/antlr/op/Sub.class new file mode 100644 index 0000000000000000000000000000000000000000..3e826d10f22e1015ec0ad28017cc8ea171c0adf1 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/Sub.class differ diff --git a/src/main/resources/org/python/antlr/op/SubDerived.class b/src/main/resources/org/python/antlr/op/SubDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3736947de160728fe0d2e66b6b925484b11eeda6 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/SubDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/UAdd$PyExposer.class b/src/main/resources/org/python/antlr/op/UAdd$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7ba8c2d3b71560a78c949abc1a5b58d526d4c6dd Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAdd$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/UAdd$UAdd___init___exposer.class b/src/main/resources/org/python/antlr/op/UAdd$UAdd___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9fcb1932784faf72288fea7df6937744257b1518 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAdd$UAdd___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/UAdd$__int___exposer.class b/src/main/resources/org/python/antlr/op/UAdd$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..837ffc0ecf409491e608026ebef6db0ba8e1d8bb Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAdd$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/UAdd$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/UAdd$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aa02b5777724b1754b5d3edd716af8c8ffa6b47f Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAdd$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/UAdd$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/UAdd$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..118bef989cc19a93898125ec4190117fdd7c19ae Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAdd$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/UAdd$exposed___new__.class b/src/main/resources/org/python/antlr/op/UAdd$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..f4846a926de156ce8ca60d56f4a361cc065820ce Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAdd$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/UAdd.class b/src/main/resources/org/python/antlr/op/UAdd.class new file mode 100644 index 0000000000000000000000000000000000000000..cecf3edb49ec21c69a0e394ddb405a67b7b5e61d Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAdd.class differ diff --git a/src/main/resources/org/python/antlr/op/UAddDerived.class b/src/main/resources/org/python/antlr/op/UAddDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..75ecf47a7d04a2f1f12eebc362d765af6159f800 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/UAddDerived.class differ diff --git a/src/main/resources/org/python/antlr/op/USub$PyExposer.class b/src/main/resources/org/python/antlr/op/USub$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7e5c9098bb45b93256d957c4081f6f52259b817c Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USub$PyExposer.class differ diff --git a/src/main/resources/org/python/antlr/op/USub$USub___init___exposer.class b/src/main/resources/org/python/antlr/op/USub$USub___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..888dc13cae0a08dd75eebf4b6212dda767d962c5 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USub$USub___init___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/USub$__int___exposer.class b/src/main/resources/org/python/antlr/op/USub$__int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9afa7e528598fac83795c8cd9130886a820a9e40 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USub$__int___exposer.class differ diff --git a/src/main/resources/org/python/antlr/op/USub$_attributes_descriptor.class b/src/main/resources/org/python/antlr/op/USub$_attributes_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f171bcc2b3c1dd337f89d06021e28fcbe2eeb3cd Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USub$_attributes_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/USub$_fields_descriptor.class b/src/main/resources/org/python/antlr/op/USub$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6605ea8cb329b0b527f11412951e2a6edc087103 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USub$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/antlr/op/USub$exposed___new__.class b/src/main/resources/org/python/antlr/op/USub$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..710f4f932cc60ff111d00c02501925dfaaf6e2d9 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USub$exposed___new__.class differ diff --git a/src/main/resources/org/python/antlr/op/USub.class b/src/main/resources/org/python/antlr/op/USub.class new file mode 100644 index 0000000000000000000000000000000000000000..6a08f3ad942eb88a90d3ed125f1b1bd63359aac1 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USub.class differ diff --git a/src/main/resources/org/python/antlr/op/USubDerived.class b/src/main/resources/org/python/antlr/op/USubDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..9931c142623c27b5e485ca93770f88a21069fd20 Binary files /dev/null and b/src/main/resources/org/python/antlr/op/USubDerived.class differ diff --git a/src/main/resources/org/python/antlr/runtime/ANTLRFileStream.class b/src/main/resources/org/python/antlr/runtime/ANTLRFileStream.class new file mode 100644 index 0000000000000000000000000000000000000000..c869445b09d559a4c4f7ca2d6bca476687a4ed6d Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/ANTLRFileStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/ANTLRInputStream.class b/src/main/resources/org/python/antlr/runtime/ANTLRInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..039035ec3255f2b3bc8b3bf2bda9f739ef71b1c1 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/ANTLRInputStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/ANTLRReaderStream.class b/src/main/resources/org/python/antlr/runtime/ANTLRReaderStream.class new file mode 100644 index 0000000000000000000000000000000000000000..592e464aa342921bec2331d1ae8e4a28bea37d89 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/ANTLRReaderStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/ANTLRStringStream.class b/src/main/resources/org/python/antlr/runtime/ANTLRStringStream.class new file mode 100644 index 0000000000000000000000000000000000000000..18332ab985ffced6e9aa2d2dc5164fa4e5bec2be Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/ANTLRStringStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/BaseRecognizer.class b/src/main/resources/org/python/antlr/runtime/BaseRecognizer.class new file mode 100644 index 0000000000000000000000000000000000000000..0d245126f543a23405c824e9cd416f8c6b8d4381 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/BaseRecognizer.class differ diff --git a/src/main/resources/org/python/antlr/runtime/BitSet.class b/src/main/resources/org/python/antlr/runtime/BitSet.class new file mode 100644 index 0000000000000000000000000000000000000000..c5f9f1ee883098bb05538bb3826e6a272250d9a9 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/BitSet.class differ diff --git a/src/main/resources/org/python/antlr/runtime/CharStream.class b/src/main/resources/org/python/antlr/runtime/CharStream.class new file mode 100644 index 0000000000000000000000000000000000000000..450e77089e0ea84110ae6c11cf03bbc074e221d1 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/CharStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/CharStreamState.class b/src/main/resources/org/python/antlr/runtime/CharStreamState.class new file mode 100644 index 0000000000000000000000000000000000000000..1122748e5a4effc97c7dc9467b5bff5f55f68315 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/CharStreamState.class differ diff --git a/src/main/resources/org/python/antlr/runtime/ClassicToken.class b/src/main/resources/org/python/antlr/runtime/ClassicToken.class new file mode 100644 index 0000000000000000000000000000000000000000..02f16eabc64d349fb96297dc9a52d97d96e5282e Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/ClassicToken.class differ diff --git a/src/main/resources/org/python/antlr/runtime/CommonToken.class b/src/main/resources/org/python/antlr/runtime/CommonToken.class new file mode 100644 index 0000000000000000000000000000000000000000..8eeb33e65e43ebecbddd13c311e49ce28dee500f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/CommonToken.class differ diff --git a/src/main/resources/org/python/antlr/runtime/CommonTokenStream.class b/src/main/resources/org/python/antlr/runtime/CommonTokenStream.class new file mode 100644 index 0000000000000000000000000000000000000000..e8cecb659e2c48d2f3aeebe88763eab3f5775d08 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/CommonTokenStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/DFA.class b/src/main/resources/org/python/antlr/runtime/DFA.class new file mode 100644 index 0000000000000000000000000000000000000000..badd87d6cdb744a464858a2ff1bea56b79cd8fb4 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/DFA.class differ diff --git a/src/main/resources/org/python/antlr/runtime/EarlyExitException.class b/src/main/resources/org/python/antlr/runtime/EarlyExitException.class new file mode 100644 index 0000000000000000000000000000000000000000..294b28554b24392eb80a7a5ac5786fad0f26a4b0 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/EarlyExitException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/FailedPredicateException.class b/src/main/resources/org/python/antlr/runtime/FailedPredicateException.class new file mode 100644 index 0000000000000000000000000000000000000000..34da00677960f26feab7d316b4f3fbbdc0950181 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/FailedPredicateException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/IntStream.class b/src/main/resources/org/python/antlr/runtime/IntStream.class new file mode 100644 index 0000000000000000000000000000000000000000..6eb69808f28088044d12771aaf1338849eed7fac Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/IntStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/Lexer.class b/src/main/resources/org/python/antlr/runtime/Lexer.class new file mode 100644 index 0000000000000000000000000000000000000000..ddd0883f8992e4d7c126af3192d1385a0ebf3bef Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/Lexer.class differ diff --git a/src/main/resources/org/python/antlr/runtime/MismatchedNotSetException.class b/src/main/resources/org/python/antlr/runtime/MismatchedNotSetException.class new file mode 100644 index 0000000000000000000000000000000000000000..131c6355f59c4846ea653a16620daf2d54b5ef02 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/MismatchedNotSetException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/MismatchedRangeException.class b/src/main/resources/org/python/antlr/runtime/MismatchedRangeException.class new file mode 100644 index 0000000000000000000000000000000000000000..65a7af8dcb7725321a368a0dd8b3f71846a8393a Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/MismatchedRangeException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/MismatchedSetException.class b/src/main/resources/org/python/antlr/runtime/MismatchedSetException.class new file mode 100644 index 0000000000000000000000000000000000000000..faa5e0ebce836c32e06d77aca96d527ae99933b4 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/MismatchedSetException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/MismatchedTokenException.class b/src/main/resources/org/python/antlr/runtime/MismatchedTokenException.class new file mode 100644 index 0000000000000000000000000000000000000000..7b8dd9a50c77f992def0120bd43f44c926387f3d Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/MismatchedTokenException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/MismatchedTreeNodeException.class b/src/main/resources/org/python/antlr/runtime/MismatchedTreeNodeException.class new file mode 100644 index 0000000000000000000000000000000000000000..e2e2f184722b5caaf61e65d849cb9820f18d2dc9 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/MismatchedTreeNodeException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/MissingTokenException.class b/src/main/resources/org/python/antlr/runtime/MissingTokenException.class new file mode 100644 index 0000000000000000000000000000000000000000..e8d4e98de6edef3b6eaad1fdfd47e3f383fcf85c Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/MissingTokenException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/NoViableAltException.class b/src/main/resources/org/python/antlr/runtime/NoViableAltException.class new file mode 100644 index 0000000000000000000000000000000000000000..146fd95b48257b6159b7fed5be2173340988facb Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/NoViableAltException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/Parser.class b/src/main/resources/org/python/antlr/runtime/Parser.class new file mode 100644 index 0000000000000000000000000000000000000000..b2987c822487e02e65001a4559a684506581ece9 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/Parser.class differ diff --git a/src/main/resources/org/python/antlr/runtime/ParserRuleReturnScope.class b/src/main/resources/org/python/antlr/runtime/ParserRuleReturnScope.class new file mode 100644 index 0000000000000000000000000000000000000000..29be4d9d6fa004cf1cfab662a1f95f36a046214a Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/ParserRuleReturnScope.class differ diff --git a/src/main/resources/org/python/antlr/runtime/RecognitionException.class b/src/main/resources/org/python/antlr/runtime/RecognitionException.class new file mode 100644 index 0000000000000000000000000000000000000000..7ee0d9bbdaf49657173c0c077243471bb69821bf Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/RecognitionException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/RecognizerSharedState.class b/src/main/resources/org/python/antlr/runtime/RecognizerSharedState.class new file mode 100644 index 0000000000000000000000000000000000000000..6e16e77208f3a01c853b5f3e1d14705395fffd02 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/RecognizerSharedState.class differ diff --git a/src/main/resources/org/python/antlr/runtime/RuleReturnScope.class b/src/main/resources/org/python/antlr/runtime/RuleReturnScope.class new file mode 100644 index 0000000000000000000000000000000000000000..e026422676e2fc7d9bbecf332c3b44e64d44aa98 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/RuleReturnScope.class differ diff --git a/src/main/resources/org/python/antlr/runtime/SerializedGrammar$Block.class b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$Block.class new file mode 100644 index 0000000000000000000000000000000000000000..a926a9f20f17e885eae6170c10c653a1814f1415 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$Block.class differ diff --git a/src/main/resources/org/python/antlr/runtime/SerializedGrammar$Rule.class b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$Rule.class new file mode 100644 index 0000000000000000000000000000000000000000..2d767e556c64bc8d35a01c080acaac9c356e8fff Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$Rule.class differ diff --git a/src/main/resources/org/python/antlr/runtime/SerializedGrammar$RuleRef.class b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$RuleRef.class new file mode 100644 index 0000000000000000000000000000000000000000..220efc1a77b29965272da6a9224b3467b260ba60 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$RuleRef.class differ diff --git a/src/main/resources/org/python/antlr/runtime/SerializedGrammar$TokenRef.class b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$TokenRef.class new file mode 100644 index 0000000000000000000000000000000000000000..3af06172211e673820d6e6f9ebf88e0ebe08f78b Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/SerializedGrammar$TokenRef.class differ diff --git a/src/main/resources/org/python/antlr/runtime/SerializedGrammar.class b/src/main/resources/org/python/antlr/runtime/SerializedGrammar.class new file mode 100644 index 0000000000000000000000000000000000000000..ba0a2ea26bd6f768e22a03aedaeae7c0a1adb52f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/SerializedGrammar.class differ diff --git a/src/main/resources/org/python/antlr/runtime/Token.class b/src/main/resources/org/python/antlr/runtime/Token.class new file mode 100644 index 0000000000000000000000000000000000000000..5339ba2603e17fb2cbd8a45ce706df6ed6bd70e1 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/Token.class differ diff --git a/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$DeleteOp.class b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$DeleteOp.class new file mode 100644 index 0000000000000000000000000000000000000000..95e3136f26fbe6af5d50b802d7f8d57fe84fdd19 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$DeleteOp.class differ diff --git a/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$InsertBeforeOp.class b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$InsertBeforeOp.class new file mode 100644 index 0000000000000000000000000000000000000000..bf8f24a7a3717f1e4fa1c374519a08c829dfa938 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$InsertBeforeOp.class differ diff --git a/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$ReplaceOp.class b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$ReplaceOp.class new file mode 100644 index 0000000000000000000000000000000000000000..5a2e543518484718332d1e6df0bffb6c46fdc17a Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$ReplaceOp.class differ diff --git a/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$RewriteOperation.class b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$RewriteOperation.class new file mode 100644 index 0000000000000000000000000000000000000000..3cfc9c874bdf6723d50186f56c07cbe09b357fed Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream$RewriteOperation.class differ diff --git a/src/main/resources/org/python/antlr/runtime/TokenRewriteStream.class b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream.class new file mode 100644 index 0000000000000000000000000000000000000000..3cb2c3b6b217bae2e9428c560018e0388c43f69f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/TokenRewriteStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/TokenSource.class b/src/main/resources/org/python/antlr/runtime/TokenSource.class new file mode 100644 index 0000000000000000000000000000000000000000..0ae21f5bd3a588e3e265823eb07a0cacb9ed9f66 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/TokenSource.class differ diff --git a/src/main/resources/org/python/antlr/runtime/TokenStream.class b/src/main/resources/org/python/antlr/runtime/TokenStream.class new file mode 100644 index 0000000000000000000000000000000000000000..3816c3b46b8442f7ebf64d5133742a170f4b85e9 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/TokenStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/UnwantedTokenException.class b/src/main/resources/org/python/antlr/runtime/UnwantedTokenException.class new file mode 100644 index 0000000000000000000000000000000000000000..4588562bc5cf32bf914496c258c8e29bc274b661 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/UnwantedTokenException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/BlankDebugEventListener.class b/src/main/resources/org/python/antlr/runtime/debug/BlankDebugEventListener.class new file mode 100644 index 0000000000000000000000000000000000000000..4364c5c96af1b872ca8bfc32a80ba5cc8af525f4 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/BlankDebugEventListener.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugEventHub.class b/src/main/resources/org/python/antlr/runtime/debug/DebugEventHub.class new file mode 100644 index 0000000000000000000000000000000000000000..3d27499edc7e430f3cc8e7616829e2f667b38e06 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugEventHub.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugEventListener.class b/src/main/resources/org/python/antlr/runtime/debug/DebugEventListener.class new file mode 100644 index 0000000000000000000000000000000000000000..c93610153c526560028608729cb671161b6aa2c8 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugEventListener.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugEventRepeater.class b/src/main/resources/org/python/antlr/runtime/debug/DebugEventRepeater.class new file mode 100644 index 0000000000000000000000000000000000000000..8e311723c66f814b1de6d6733106da9bc5c403ab Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugEventRepeater.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugEventSocketProxy.class b/src/main/resources/org/python/antlr/runtime/debug/DebugEventSocketProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..b77596217a1deea158bff9cc8614e3b38a542b8f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugEventSocketProxy.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugParser.class b/src/main/resources/org/python/antlr/runtime/debug/DebugParser.class new file mode 100644 index 0000000000000000000000000000000000000000..28393b654131f1bfc20682c04faf88f39f13f736 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugParser.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugTokenStream.class b/src/main/resources/org/python/antlr/runtime/debug/DebugTokenStream.class new file mode 100644 index 0000000000000000000000000000000000000000..1c853b2bb5f6211c23ad72de9228b80100b20444 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugTokenStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugTreeAdaptor.class b/src/main/resources/org/python/antlr/runtime/debug/DebugTreeAdaptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6b4b19090fb97ccc4cff0a744aab119636eb937e Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugTreeAdaptor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugTreeNodeStream.class b/src/main/resources/org/python/antlr/runtime/debug/DebugTreeNodeStream.class new file mode 100644 index 0000000000000000000000000000000000000000..4aacaa5933f02970d725d738998d5efcdd9d9031 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugTreeNodeStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/DebugTreeParser.class b/src/main/resources/org/python/antlr/runtime/debug/DebugTreeParser.class new file mode 100644 index 0000000000000000000000000000000000000000..a419ec3e1c042243993df01bc934dc700061993a Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/DebugTreeParser.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/ParseTreeBuilder.class b/src/main/resources/org/python/antlr/runtime/debug/ParseTreeBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..920c3c037e74c32a61e6daba94f92d10f2d66b58 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/ParseTreeBuilder.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/Profiler.class b/src/main/resources/org/python/antlr/runtime/debug/Profiler.class new file mode 100644 index 0000000000000000000000000000000000000000..e9156eccaeb27a72371fc8b270e71a3024057bd9 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/Profiler.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener$ProxyToken.class b/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener$ProxyToken.class new file mode 100644 index 0000000000000000000000000000000000000000..dbcbbb58ae85de5e50529138e7bda5850f7bc051 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener$ProxyToken.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener$ProxyTree.class b/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener$ProxyTree.class new file mode 100644 index 0000000000000000000000000000000000000000..049ffc140d7c05be90f94289326e8d777c79100c Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener$ProxyTree.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener.class b/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener.class new file mode 100644 index 0000000000000000000000000000000000000000..093e98ed7a3aba27ef71188014d7390c8c572a13 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/RemoteDebugEventSocketListener.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/TraceDebugEventListener.class b/src/main/resources/org/python/antlr/runtime/debug/TraceDebugEventListener.class new file mode 100644 index 0000000000000000000000000000000000000000..69848594fa3264c42a029296b050e8dccd37e9a1 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/TraceDebugEventListener.class differ diff --git a/src/main/resources/org/python/antlr/runtime/debug/Tracer.class b/src/main/resources/org/python/antlr/runtime/debug/Tracer.class new file mode 100644 index 0000000000000000000000000000000000000000..937149705dda8fc24540d34df324a5b6b454b2fc Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/debug/Tracer.class differ diff --git a/src/main/resources/org/python/antlr/runtime/misc/FastQueue.class b/src/main/resources/org/python/antlr/runtime/misc/FastQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..8450231406ff44f7382cf60e6aa20408d6326d8f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/misc/FastQueue.class differ diff --git a/src/main/resources/org/python/antlr/runtime/misc/IntArray.class b/src/main/resources/org/python/antlr/runtime/misc/IntArray.class new file mode 100644 index 0000000000000000000000000000000000000000..f462f70f7fa109e056a2af7b668f421d3d0a8497 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/misc/IntArray.class differ diff --git a/src/main/resources/org/python/antlr/runtime/misc/LookaheadStream.class b/src/main/resources/org/python/antlr/runtime/misc/LookaheadStream.class new file mode 100644 index 0000000000000000000000000000000000000000..39647d3ab698306d0ded2eade5bffaa0fdc3b8bc Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/misc/LookaheadStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/misc/Stats.class b/src/main/resources/org/python/antlr/runtime/misc/Stats.class new file mode 100644 index 0000000000000000000000000000000000000000..0ee0eefddca259ef04f79a0bc8f6ebd8541c0b80 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/misc/Stats.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/BaseTree.class b/src/main/resources/org/python/antlr/runtime/tree/BaseTree.class new file mode 100644 index 0000000000000000000000000000000000000000..352a6ce8e1b1f8d9a2d7c12a34d76e307b3bfc81 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/BaseTree.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/BaseTreeAdaptor.class b/src/main/resources/org/python/antlr/runtime/tree/BaseTreeAdaptor.class new file mode 100644 index 0000000000000000000000000000000000000000..535ca0df0991452d375232beecb64414af8f6447 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/BaseTreeAdaptor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/BufferedTreeNodeStream$StreamIterator.class b/src/main/resources/org/python/antlr/runtime/tree/BufferedTreeNodeStream$StreamIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..2db93e38611132fa8c6a3e20bcddd7d0ab1dc9e1 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/BufferedTreeNodeStream$StreamIterator.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/BufferedTreeNodeStream.class b/src/main/resources/org/python/antlr/runtime/tree/BufferedTreeNodeStream.class new file mode 100644 index 0000000000000000000000000000000000000000..15e2c469ff6e6946491ae27655eb09f617771c81 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/BufferedTreeNodeStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/CommonErrorNode.class b/src/main/resources/org/python/antlr/runtime/tree/CommonErrorNode.class new file mode 100644 index 0000000000000000000000000000000000000000..eaa777268dc4650b9fbede9920234c6fdceba00f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/CommonErrorNode.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/CommonTree.class b/src/main/resources/org/python/antlr/runtime/tree/CommonTree.class new file mode 100644 index 0000000000000000000000000000000000000000..4ffd491af385804459ccbb8287e6cab7ed524fab Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/CommonTree.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/CommonTreeAdaptor.class b/src/main/resources/org/python/antlr/runtime/tree/CommonTreeAdaptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a581bb442c0c2d33be1b4457054f9835e687335a Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/CommonTreeAdaptor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/CommonTreeNodeStream.class b/src/main/resources/org/python/antlr/runtime/tree/CommonTreeNodeStream.class new file mode 100644 index 0000000000000000000000000000000000000000..90fdb2f5281f4eadb8bc73a3f1fa6056c7466b79 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/CommonTreeNodeStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/DOTTreeGenerator.class b/src/main/resources/org/python/antlr/runtime/tree/DOTTreeGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..c4ab28ca7fe37cfd60689ac17b238ad2a9729999 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/DOTTreeGenerator.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/ParseTree.class b/src/main/resources/org/python/antlr/runtime/tree/ParseTree.class new file mode 100644 index 0000000000000000000000000000000000000000..c7e9ababca970cf939dd298a3621d0747311f1d6 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/ParseTree.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/RewriteCardinalityException.class b/src/main/resources/org/python/antlr/runtime/tree/RewriteCardinalityException.class new file mode 100644 index 0000000000000000000000000000000000000000..d9f2d92c805d003ed1838210462c0df9ded435e8 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/RewriteCardinalityException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/RewriteEarlyExitException.class b/src/main/resources/org/python/antlr/runtime/tree/RewriteEarlyExitException.class new file mode 100644 index 0000000000000000000000000000000000000000..5a5c0b361477f9f1a9dd005a35b341b37034c3f4 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/RewriteEarlyExitException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/RewriteEmptyStreamException.class b/src/main/resources/org/python/antlr/runtime/tree/RewriteEmptyStreamException.class new file mode 100644 index 0000000000000000000000000000000000000000..42406f1a2a393e7841b018057e3daf697b099571 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/RewriteEmptyStreamException.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleElementStream.class b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleElementStream.class new file mode 100644 index 0000000000000000000000000000000000000000..bda7fa4c8aa5c7b788411177c00c045fcfbdf700 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleElementStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleNodeStream.class b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleNodeStream.class new file mode 100644 index 0000000000000000000000000000000000000000..7581e688ca1b501c59033dcfa33bc287f2c40a0d Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleNodeStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleSubtreeStream.class b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleSubtreeStream.class new file mode 100644 index 0000000000000000000000000000000000000000..9f7d63a810b19fc98cf237e899901068253d6d0f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleSubtreeStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleTokenStream.class b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleTokenStream.class new file mode 100644 index 0000000000000000000000000000000000000000..72601963e4f6acab113c9258e8c304f301f574a6 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/RewriteRuleTokenStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/Tree.class b/src/main/resources/org/python/antlr/runtime/tree/Tree.class new file mode 100644 index 0000000000000000000000000000000000000000..9fdb885e40ae8db10a9b12a27680192f36226d83 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/Tree.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeAdaptor.class b/src/main/resources/org/python/antlr/runtime/tree/TreeAdaptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d2deba643928bc143bac8802e14cbd8b1b6ed257 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeAdaptor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$1.class b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c10a0a268c5dc6cc33ede7124fa0fefc4158806b Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$1.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$2.class b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$2.class new file mode 100644 index 0000000000000000000000000000000000000000..47c928789a27de91ab6330df651db425e796e2fe Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$2.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$3.class b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$3.class new file mode 100644 index 0000000000000000000000000000000000000000..a5871d4ca7fc84fb4b0f8563cace3d48de58efbe Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$3.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$fptr.class b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$fptr.class new file mode 100644 index 0000000000000000000000000000000000000000..6dbcb5511ce0a5875d16e5b68825aaec2c8ed60d Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter$fptr.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeFilter.class b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..3e4b39e32210d1f9af2952752bdd5bd54f52291c Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeFilter.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeIterator.class b/src/main/resources/org/python/antlr/runtime/tree/TreeIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..7214fc821097cef6ba959397999e75765ed1c1da Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeIterator.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeNodeStream.class b/src/main/resources/org/python/antlr/runtime/tree/TreeNodeStream.class new file mode 100644 index 0000000000000000000000000000000000000000..662cd3e5f9207a4e0a5d3f216dd051e90fc799db Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeNodeStream.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeParser.class b/src/main/resources/org/python/antlr/runtime/tree/TreeParser.class new file mode 100644 index 0000000000000000000000000000000000000000..6886fe4507a8767dcc1a851696d9a0676588b800 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeParser.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreePatternLexer.class b/src/main/resources/org/python/antlr/runtime/tree/TreePatternLexer.class new file mode 100644 index 0000000000000000000000000000000000000000..2000daa4fe44fbff20524998bb7b28ad627a900a Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreePatternLexer.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreePatternParser.class b/src/main/resources/org/python/antlr/runtime/tree/TreePatternParser.class new file mode 100644 index 0000000000000000000000000000000000000000..2318f87eb8c11097d504daec39524737274bf9ee Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreePatternParser.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$1.class b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5fc8bbd7b725458feea33217623044fc48416e92 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$1.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$2.class b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$2.class new file mode 100644 index 0000000000000000000000000000000000000000..b06b194d5e25dbf8f950dc03642618ecd86f76be Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$2.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$3.class b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$3.class new file mode 100644 index 0000000000000000000000000000000000000000..fd1844d7203e54612877c2043a8a902ba5b59b93 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$3.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$fptr.class b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$fptr.class new file mode 100644 index 0000000000000000000000000000000000000000..837d5393274c3640b73ba316b535599e6aba0203 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter$fptr.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter.class b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter.class new file mode 100644 index 0000000000000000000000000000000000000000..1acab89e1aac121c198ccf458d419665f506566f Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeRewriter.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeRuleReturnScope.class b/src/main/resources/org/python/antlr/runtime/tree/TreeRuleReturnScope.class new file mode 100644 index 0000000000000000000000000000000000000000..1fe077b3f6cd229f1abd44d287f0d4bd6e040437 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeRuleReturnScope.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeVisitor.class b/src/main/resources/org/python/antlr/runtime/tree/TreeVisitor.class new file mode 100644 index 0000000000000000000000000000000000000000..515f056d722aadee2e92fb804f4692ea2970dab7 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeVisitor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeVisitorAction.class b/src/main/resources/org/python/antlr/runtime/tree/TreeVisitorAction.class new file mode 100644 index 0000000000000000000000000000000000000000..85909ce156bfc64963db8fb026b532b5fedecf41 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeVisitorAction.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$1.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$1.class new file mode 100644 index 0000000000000000000000000000000000000000..31b8fec53cfe6fb8776c5f4096dafbccfd7f425d Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$1.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$2.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c3996cacbd659d922b824c39523d3b61cf616fd5 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$2.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$3.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$3.class new file mode 100644 index 0000000000000000000000000000000000000000..55e334d10df2b259522a50f5474c65c8955392e1 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$3.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$ContextVisitor.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$ContextVisitor.class new file mode 100644 index 0000000000000000000000000000000000000000..009547e2d3a7299bb3badca0e8b83e5b8c41a1a4 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$ContextVisitor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$TreePattern.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$TreePattern.class new file mode 100644 index 0000000000000000000000000000000000000000..60ab28555aebfd34f273e9d785781ab80a5b92f6 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$TreePattern.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$TreePatternTreeAdaptor.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$TreePatternTreeAdaptor.class new file mode 100644 index 0000000000000000000000000000000000000000..566695364e71c53f241c76c4cb712dd75eca565e Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$TreePatternTreeAdaptor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$Visitor.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$Visitor.class new file mode 100644 index 0000000000000000000000000000000000000000..f1fc8d8bc9242141eaee3a49e5d15259cae08771 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$Visitor.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$WildcardTreePattern.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$WildcardTreePattern.class new file mode 100644 index 0000000000000000000000000000000000000000..4acd2683df466a88be7ca0213aa24ef7e079c0d2 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard$WildcardTreePattern.class differ diff --git a/src/main/resources/org/python/antlr/runtime/tree/TreeWizard.class b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard.class new file mode 100644 index 0000000000000000000000000000000000000000..859d360ea6f657f65ad8968db65bfd988b023c54 Binary files /dev/null and b/src/main/resources/org/python/antlr/runtime/tree/TreeWizard.class differ diff --git a/src/main/resources/org/python/apache/html/dom/CollectionIndex.class b/src/main/resources/org/python/apache/html/dom/CollectionIndex.class new file mode 100644 index 0000000000000000000000000000000000000000..986ab7ca9b2690b073ae8b6a47e4f4a359d15dcd Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/CollectionIndex.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLAnchorElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLAnchorElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..72747b2d651da4d16463e52db352518fd7d2adf8 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLAnchorElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLAppletElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLAppletElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5bf02fb0ce9b9922b0092619298a73763b7128b6 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLAppletElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLAreaElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLAreaElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..32a4d97e8d5786c1f92914dac1c2cb6458720166 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLAreaElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLBRElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLBRElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..44da9f8d1e2f87472d0bb76ab5e37d535eac2550 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLBRElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLBaseElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLBaseElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..4faabced7d6bf5e303679452a5332add5bc2d63e Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLBaseElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLBaseFontElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLBaseFontElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..18ac5599b994571d1e89a58c1b95ae52826456be Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLBaseFontElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLBodyElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLBodyElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..495f78d66435ae379bada29731bb4bc4a7810628 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLBodyElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLBuilder.class b/src/main/resources/org/python/apache/html/dom/HTMLBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..70e8c0c384fa265a463508d1942f3b9dcf14e3a8 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLBuilder.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLButtonElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLButtonElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..cd0beeca7dd86324aeb099d30eb74c0f941d5c1e Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLButtonElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLCollectionImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLCollectionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..71ae7f250b818c8be0905d2dca8afbda10a0ea21 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLCollectionImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLDListElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLDListElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..f456367f834e74ca0203dccbf8134b8ddd0fc0cd Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLDListElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLDOMImplementationImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLDOMImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..06ae81e619e7a8043717185a192f7d38d9573c40 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLDOMImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLDirectoryElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLDirectoryElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..13710343b39fb2c73ac2de7278c94a9a1a8062ad Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLDirectoryElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLDivElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLDivElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..995b8384d6cbc70e31d32aaf889cb03d21df8c34 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLDivElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLDocumentImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLDocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..346cbeedf1fba37aee2680b358b3b44924d41fb7 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLDocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..f637991aa16033f24781d3e083018993467b916f Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLFieldSetElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLFieldSetElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2087049c2ae95720c5813b49c1c26b17d90b67f5 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLFieldSetElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLFontElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLFontElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..94183e48033a2312ff292ce78c3610b5ee70762b Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLFontElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLFormControl.class b/src/main/resources/org/python/apache/html/dom/HTMLFormControl.class new file mode 100644 index 0000000000000000000000000000000000000000..6a71b7fb69c5b91c6c67ccabcb44c942f04d690a Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLFormControl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLFormElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLFormElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5c66c7a41b088aff397db698f6d3b9bd36a57725 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLFormElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLFrameElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLFrameElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..ba9d8bb1ace7e9fb282d21d2ac178d502dd02576 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLFrameElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLFrameSetElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLFrameSetElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..cfafb1c141a897e60e756edfdc122d4f1bc234c1 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLFrameSetElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLHRElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLHRElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d7bf14ad24deddb66899c05968e54219f76b751c Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLHRElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLHeadElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLHeadElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a44051e6ecd3527d2b733cc4c92636b30a83527e Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLHeadElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLHeadingElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLHeadingElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3fb77d68e3e72238ac1f8dfbd91f064a2f141283 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLHeadingElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLHtmlElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLHtmlElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..dc9a5a7a6865f89cc0601f3330fdcd94bd633015 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLHtmlElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLIFrameElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLIFrameElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..03278e12c2fbbea6250704a0678296d04eb52f04 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLIFrameElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLImageElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLImageElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b60e94640ee4dfc8a7f021282da2100c0ce8d172 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLImageElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLInputElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLInputElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..285bd89ec85d0219e20a09e4e9cd905d8a610e7a Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLInputElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLIsIndexElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLIsIndexElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..baaffdbd671504a87d718d0c5b7846e6ad48efde Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLIsIndexElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLLIElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLLIElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..6a938942ab744d98c3b3e1fd9ea0d6ce56ebdf12 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLLIElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLLabelElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLLabelElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..fae5544e8e20f4464e96bdc024cf072d525df074 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLLabelElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLLegendElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLLegendElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d45c59f1ad017e88edda5938c8e29e7b6df4acd3 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLLegendElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLLinkElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLLinkElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7872419ddd58269328f0ac861093a7759ca35655 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLLinkElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLMapElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLMapElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8af6860376bb2210a1d00b51fd5a2fea4a4cba37 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLMapElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLMenuElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLMenuElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..aa31e26307ad581037548d456f3317e6c336ca45 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLMenuElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLMetaElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLMetaElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..c4c8b56f03a0d876bc12ccf14db2e38206186af6 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLMetaElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLModElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLModElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..07901e426436e5c7be522755c46051e7b6e604b5 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLModElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLOListElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLOListElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9d3c8692f9ea73c73487c31f92e45b67cb882627 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLOListElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLObjectElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLObjectElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..4918765f969fbbef1e0ef864704c24088acb9f1f Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLObjectElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLOptGroupElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLOptGroupElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..50c7aa727e923a36a64bcdcd9c0945a23980cd4d Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLOptGroupElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLOptionElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLOptionElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2e32c120658c0a550945d7c15cd1d7662868c911 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLOptionElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLParagraphElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLParagraphElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..15c5424257e8fd4efd8c17d3bb040a8a0ea81dd8 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLParagraphElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLParamElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLParamElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..faad5c6d996b041dd741efb43ee5ea27ac4290b4 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLParamElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLPreElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLPreElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..60ad68ebb84d88f2cff97bb129a0924eac4939c6 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLPreElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLQuoteElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLQuoteElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1b046ffef3aa188e4aa68bc6532f78788660d65f Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLQuoteElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLScriptElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLScriptElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..149680dd04dc4146cb5c1e53388729d48858783b Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLScriptElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLSelectElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLSelectElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..91ebede56bf3a81aac85ab42b4bb3377cfe8bec2 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLSelectElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLStyleElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLStyleElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..76e4ac1644a522785248875af87abccbaaf18266 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLStyleElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTableCaptionElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTableCaptionElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8f5ced9fe2db781267b200fa5d018153d472fbf9 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTableCaptionElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTableCellElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTableCellElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9016ce3fa7f06cbd835fc9fc7c741054d6dc524a Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTableCellElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTableColElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTableColElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..868311909c66757a1104293ec949aa418a759b2f Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTableColElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTableElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTableElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..39d7af9a6793d767336196f75e4e6f82792b5746 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTableElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTableRowElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTableRowElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..f1a067582e81752d24b73d2cf24ccb37c0d161bb Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTableRowElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTableSectionElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTableSectionElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..c2650250e6cafea04e8b9ec91166af1440a455c9 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTableSectionElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTextAreaElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTextAreaElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..26f8a26b1b0d3cf6616f4911f67daff007ef4071 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTextAreaElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLTitleElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLTitleElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..030b57f4fb906a64af93541083573fc0288882f1 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLTitleElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/HTMLUListElementImpl.class b/src/main/resources/org/python/apache/html/dom/HTMLUListElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9a4f2d4a8d8032ffb1fea4094143451bee6d46d7 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/HTMLUListElementImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/NameNodeListImpl.class b/src/main/resources/org/python/apache/html/dom/NameNodeListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b82c002c9337ab3435b9a19405eea5644f7abb0e Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/NameNodeListImpl.class differ diff --git a/src/main/resources/org/python/apache/html/dom/ObjectFactory$ConfigurationError.class b/src/main/resources/org/python/apache/html/dom/ObjectFactory$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..ad21b581082f4b5aa31ba3b22cd59126f4a416a2 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/ObjectFactory$ConfigurationError.class differ diff --git a/src/main/resources/org/python/apache/html/dom/ObjectFactory.class b/src/main/resources/org/python/apache/html/dom/ObjectFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..458e2ee54114c7b836ed953e1e2eee37ad9705aa Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/ObjectFactory.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$1.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..067822274679056d4a4dc70b95df163b0591ddd1 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$1.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$2.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..b7de98b1be72a9ae6c97af179234043cf1ed8bee Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$2.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$3.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..fa44a4ee1b58a18230ebefc7a1a8a87c98747010 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$3.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$4.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..9ef8a59adf1f73755b73ac6d6832326cbac34fef Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$4.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$5.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..2036c9ca8fa310962f64183f43f1b5b8b109efdf Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$5.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$6.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..f2a740838129cc6108d284cf8b6d3f562e9b211a Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$6.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$7.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..9e181b37e4a4004c1748e5b9147b07aba232be82 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$7.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport$8.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..cca2fcc2779e873fe3ef6b8ccc76ed4e6ca857a4 Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport$8.class differ diff --git a/src/main/resources/org/python/apache/html/dom/SecuritySupport.class b/src/main/resources/org/python/apache/html/dom/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..7569976ab70ddc26ec33c568289f35fe0ad4f49b Binary files /dev/null and b/src/main/resources/org/python/apache/html/dom/SecuritySupport.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLAElement.class b/src/main/resources/org/python/apache/wml/WMLAElement.class new file mode 100644 index 0000000000000000000000000000000000000000..c4cf759f9dbee87231450d53fa058ad10214a885 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLAElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLAccessElement.class b/src/main/resources/org/python/apache/wml/WMLAccessElement.class new file mode 100644 index 0000000000000000000000000000000000000000..6fd3f881ab3027af8884ec39f9e6a3f5ff869dc7 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLAccessElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLAnchorElement.class b/src/main/resources/org/python/apache/wml/WMLAnchorElement.class new file mode 100644 index 0000000000000000000000000000000000000000..39a9f1e4fcd0556b7af4f64f6c9b6a6d7c5e14f1 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLAnchorElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLBElement.class b/src/main/resources/org/python/apache/wml/WMLBElement.class new file mode 100644 index 0000000000000000000000000000000000000000..0f98ceb12c4ee9a9d6eb682cc7d2251c7270956a Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLBElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLBigElement.class b/src/main/resources/org/python/apache/wml/WMLBigElement.class new file mode 100644 index 0000000000000000000000000000000000000000..417ba1be0eb2e7a27360d236a6579494ead7bd94 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLBigElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLBrElement.class b/src/main/resources/org/python/apache/wml/WMLBrElement.class new file mode 100644 index 0000000000000000000000000000000000000000..61031dfd1d99543d6ec05063498d998d122ff687 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLBrElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLCardElement.class b/src/main/resources/org/python/apache/wml/WMLCardElement.class new file mode 100644 index 0000000000000000000000000000000000000000..bbb16e15061b4330dc69d086062dd8fcd48fb42a Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLCardElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLDOMImplementation.class b/src/main/resources/org/python/apache/wml/WMLDOMImplementation.class new file mode 100644 index 0000000000000000000000000000000000000000..0844bc4a87a15caab0ecfddcc2e6b72859afd6ea Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLDOMImplementation.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLDoElement.class b/src/main/resources/org/python/apache/wml/WMLDoElement.class new file mode 100644 index 0000000000000000000000000000000000000000..3bc46e3b9fc8d8bf87c9876a0e1be0e3da86fd6c Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLDoElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLDocument.class b/src/main/resources/org/python/apache/wml/WMLDocument.class new file mode 100644 index 0000000000000000000000000000000000000000..cf6260b0efaf24b1767069701a8bdd9a30afa3ce Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLDocument.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLElement.class b/src/main/resources/org/python/apache/wml/WMLElement.class new file mode 100644 index 0000000000000000000000000000000000000000..5afec0c7f5914d763facc9a2f734bf7ef6be9d7f Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLEmElement.class b/src/main/resources/org/python/apache/wml/WMLEmElement.class new file mode 100644 index 0000000000000000000000000000000000000000..25729d0c7ac95dd3c895508b28330bf8ed287dd3 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLEmElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLFieldsetElement.class b/src/main/resources/org/python/apache/wml/WMLFieldsetElement.class new file mode 100644 index 0000000000000000000000000000000000000000..fb40ef8458064deaddd366414da20821e77b5d0f Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLFieldsetElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLGoElement.class b/src/main/resources/org/python/apache/wml/WMLGoElement.class new file mode 100644 index 0000000000000000000000000000000000000000..d6d774266854f293929ea86e3072a1b1e03d66d1 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLGoElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLHeadElement.class b/src/main/resources/org/python/apache/wml/WMLHeadElement.class new file mode 100644 index 0000000000000000000000000000000000000000..a6de32fcd67943eab893b1509ebea29a8c5ccea5 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLHeadElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLIElement.class b/src/main/resources/org/python/apache/wml/WMLIElement.class new file mode 100644 index 0000000000000000000000000000000000000000..1d29bdaa1223a78acc6b945f7a9aaeedb80ca7cd Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLIElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLImgElement.class b/src/main/resources/org/python/apache/wml/WMLImgElement.class new file mode 100644 index 0000000000000000000000000000000000000000..e126ed41552ca9e81e80b5191dc3ade55b9c18b7 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLImgElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLInputElement.class b/src/main/resources/org/python/apache/wml/WMLInputElement.class new file mode 100644 index 0000000000000000000000000000000000000000..52f6b0bb0bc0e8e3b4fc1613210cfa58c9f84bf7 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLInputElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLMetaElement.class b/src/main/resources/org/python/apache/wml/WMLMetaElement.class new file mode 100644 index 0000000000000000000000000000000000000000..c593103c43b9e045da10591bd50a6aa5c0cba725 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLMetaElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLNoopElement.class b/src/main/resources/org/python/apache/wml/WMLNoopElement.class new file mode 100644 index 0000000000000000000000000000000000000000..9f461fa06f426a6dc43fb55451b6a02f02700da6 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLNoopElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLOneventElement.class b/src/main/resources/org/python/apache/wml/WMLOneventElement.class new file mode 100644 index 0000000000000000000000000000000000000000..6a0be6ffbf3dac0184d71886a4c4ba1bdba9611b Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLOneventElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLOptgroupElement.class b/src/main/resources/org/python/apache/wml/WMLOptgroupElement.class new file mode 100644 index 0000000000000000000000000000000000000000..567a2ff47c2dda8da62479b50013713dae77af90 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLOptgroupElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLOptionElement.class b/src/main/resources/org/python/apache/wml/WMLOptionElement.class new file mode 100644 index 0000000000000000000000000000000000000000..f9f89ff1a3b565a0da1072cd19e09d7a78b1f331 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLOptionElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLPElement.class b/src/main/resources/org/python/apache/wml/WMLPElement.class new file mode 100644 index 0000000000000000000000000000000000000000..db887f54822fdab1708bec54bfe9eb6d11f0c4b0 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLPElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLPostfieldElement.class b/src/main/resources/org/python/apache/wml/WMLPostfieldElement.class new file mode 100644 index 0000000000000000000000000000000000000000..fcfe40d0ed1cab4e22f3a53e967bf6ea4b5eed9f Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLPostfieldElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLPrevElement.class b/src/main/resources/org/python/apache/wml/WMLPrevElement.class new file mode 100644 index 0000000000000000000000000000000000000000..262e0820b07763e8320f63029fa78d5eb7670497 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLPrevElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLRefreshElement.class b/src/main/resources/org/python/apache/wml/WMLRefreshElement.class new file mode 100644 index 0000000000000000000000000000000000000000..caaf05751ed68f366b6e17825cc607bb6b1ab17d Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLRefreshElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLSelectElement.class b/src/main/resources/org/python/apache/wml/WMLSelectElement.class new file mode 100644 index 0000000000000000000000000000000000000000..5a1ecaa0b0cb5ae83ad2fdfcc49ad844e2f14150 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLSelectElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLSetvarElement.class b/src/main/resources/org/python/apache/wml/WMLSetvarElement.class new file mode 100644 index 0000000000000000000000000000000000000000..f15dba24d65b1a88ea1f3755ada8444d6993ced3 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLSetvarElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLSmallElement.class b/src/main/resources/org/python/apache/wml/WMLSmallElement.class new file mode 100644 index 0000000000000000000000000000000000000000..9a466c1564dc1c616390731a283a1f576b2cc3e2 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLSmallElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLStrongElement.class b/src/main/resources/org/python/apache/wml/WMLStrongElement.class new file mode 100644 index 0000000000000000000000000000000000000000..6d63ace108c24cb40c7e8f7a465d05f498a09d25 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLStrongElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLTableElement.class b/src/main/resources/org/python/apache/wml/WMLTableElement.class new file mode 100644 index 0000000000000000000000000000000000000000..57c2af9c17c387a5afe5f121676ff109df8a3cec Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLTableElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLTdElement.class b/src/main/resources/org/python/apache/wml/WMLTdElement.class new file mode 100644 index 0000000000000000000000000000000000000000..90d91b242618060abd51ebe9f89060431a291502 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLTdElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLTemplateElement.class b/src/main/resources/org/python/apache/wml/WMLTemplateElement.class new file mode 100644 index 0000000000000000000000000000000000000000..ff17d390ec6d1ae7d2d139343434c367d8669143 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLTemplateElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLTimerElement.class b/src/main/resources/org/python/apache/wml/WMLTimerElement.class new file mode 100644 index 0000000000000000000000000000000000000000..f3544249e1acaf530e353148870577d4096c4bad Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLTimerElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLTrElement.class b/src/main/resources/org/python/apache/wml/WMLTrElement.class new file mode 100644 index 0000000000000000000000000000000000000000..d8ef3237164511c968964b5948ed493170eb85fc Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLTrElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLUElement.class b/src/main/resources/org/python/apache/wml/WMLUElement.class new file mode 100644 index 0000000000000000000000000000000000000000..58a20e05847721744092d3ca43719246f22f0a6d Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLUElement.class differ diff --git a/src/main/resources/org/python/apache/wml/WMLWmlElement.class b/src/main/resources/org/python/apache/wml/WMLWmlElement.class new file mode 100644 index 0000000000000000000000000000000000000000..ae9cda1a676a7393100d72411b1be5e24880bb59 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/WMLWmlElement.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLAElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLAElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..023bea774740b91a28010bd9285f736c483217cb Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLAElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLAccessElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLAccessElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d598567f0ce1e6f3f53bbea4915e6044d07e5aad Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLAccessElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLAnchorElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLAnchorElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..4cfd3d2354924ef3f7b2c9408c55b8afbd693d82 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLAnchorElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLBElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLBElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d8adc5f069124a9942aef0932866213e063a37ce Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLBElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLBigElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLBigElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..95ab12f5cbfa4609fe8cc049658cdea5e3d58dad Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLBigElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLBrElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLBrElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..fec737f7c5ce8904d23bca71333fa0344549614a Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLBrElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLCardElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLCardElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2a9a512044490ff0184d1f9c1b30a99c87e8cf50 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLCardElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLDOMImplementationImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLDOMImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d493bd6a8c6793bfbfdb98772509ab9b757a61dc Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLDOMImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLDoElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLDoElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1f444638a8822991befaaf1d610bf89daed31a9e Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLDoElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLDocumentImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLDocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..36a5f9652050823d00a4b9387ebbc00e773c3566 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLDocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2ebc53ebe299b08c2325ad6a311549e3bef625dc Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLEmElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLEmElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..482f61d28309c28822a8af846e1032f035355dba Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLEmElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLFieldsetElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLFieldsetElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..65ac60b53a7a07ac5f24122517f896f755e73cd1 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLFieldsetElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLGoElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLGoElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..16b3dfebc3aac31732552a440acebcfbb3a4c48e Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLGoElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLHeadElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLHeadElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..200217927dcdbd369f4e5d53925e788c221dfe95 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLHeadElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLIElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLIElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..ed79c7ca9a2e06973e29c5e092d1ef3df6e8103a Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLIElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLImgElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLImgElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..6490189491828d40758c74b39d52859de8bca607 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLImgElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLInputElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLInputElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7225f842c4cefb4cb36c905597f79591dab3819f Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLInputElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLMetaElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLMetaElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..bb591cf6bb7a876ebf4d9063817662613cce6dfc Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLMetaElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLNoopElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLNoopElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b3223a55bac690ad17fa56807a424a853162f020 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLNoopElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLOneventElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLOneventElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..c10694c384eaa5cda6a91548097d81f3a66d3979 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLOneventElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLOptgroupElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLOptgroupElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7da1206fd70506417644e36554cd673f7f3825d9 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLOptgroupElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLOptionElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLOptionElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a6a9555a241160aec96e8065cc012729a3d1a12e Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLOptionElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLPElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLPElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..0de286e445e90115c6f0b5c35f871e2dd3bc3308 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLPElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLPostfieldElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLPostfieldElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7629580b02290a470bc4ba2a9511ee19590c15de Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLPostfieldElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLPrevElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLPrevElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..85ac3f88686a13f783003b211151182cac40ed3f Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLPrevElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLRefreshElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLRefreshElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..af81ce28bda0394f21b4583b2602385c9b90ef96 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLRefreshElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLSelectElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLSelectElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5c18ed425f401cd71e36dc808c595b610d504835 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLSelectElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLSetvarElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLSetvarElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3cbca7bddfe4f97a996b2a0b37be7f1f2aee6e34 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLSetvarElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLSmallElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLSmallElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a16a44e0ee326ee87d284bd1ed9bb138330d4648 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLSmallElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLStrongElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLStrongElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..218d972eba975719b9da4a1fe5620b2d86ff4418 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLStrongElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLTableElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLTableElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8c87f7454384f3d367445a3cb6151fc1a08d9df2 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLTableElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLTdElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLTdElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..95bce453aba74543c7592b53e174512a1fd7638f Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLTdElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLTemplateElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLTemplateElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..fd35a6c883ff0e92121c81de68c1046481af06f1 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLTemplateElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLTimerElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLTimerElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..61776f70439b1198b9e5c63bca1e4938bfb47d51 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLTimerElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLTrElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLTrElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..092346bfc3cf941a1e0d758acf5e48591719e214 Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLTrElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLUElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLUElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7bd430232adc150eed7bad0c7733f73db57ad00e Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLUElementImpl.class differ diff --git a/src/main/resources/org/python/apache/wml/dom/WMLWmlElementImpl.class b/src/main/resources/org/python/apache/wml/dom/WMLWmlElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9d587339d279c12facb7b08a7f16a5bc4411eccb Binary files /dev/null and b/src/main/resources/org/python/apache/wml/dom/WMLWmlElementImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ASDOMImplementationImpl.class b/src/main/resources/org/python/apache/xerces/dom/ASDOMImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..46df6c9438069c1829e6510d954af7b465f48152 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ASDOMImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ASModelImpl.class b/src/main/resources/org/python/apache/xerces/dom/ASModelImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..91aa45bdd32490904acf3e397649263ec4873683 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ASModelImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/AttrImpl.class b/src/main/resources/org/python/apache/xerces/dom/AttrImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..30bef1ddbe5c7f7441a2ce435556e3dd2c36cda0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/AttrImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/AttrNSImpl.class b/src/main/resources/org/python/apache/xerces/dom/AttrNSImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..32e9086d3fd43606f3711f0a8442e3d1199476dc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/AttrNSImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/AttributeMap.class b/src/main/resources/org/python/apache/xerces/dom/AttributeMap.class new file mode 100644 index 0000000000000000000000000000000000000000..f30fb647ead60d48876e991c90d34b544bb7eff1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/AttributeMap.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CDATASectionImpl.class b/src/main/resources/org/python/apache/xerces/dom/CDATASectionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..eb555042ec3ba46dcdff5e4e73fb64c456796eec Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CDATASectionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CharacterDataImpl$1.class b/src/main/resources/org/python/apache/xerces/dom/CharacterDataImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..7b31958eac15348abbb39109c71ed1db2fbb2b06 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CharacterDataImpl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CharacterDataImpl.class b/src/main/resources/org/python/apache/xerces/dom/CharacterDataImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..68bc7626c8b7b1fb9f0c01f2094b849f862bce04 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CharacterDataImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ChildNode.class b/src/main/resources/org/python/apache/xerces/dom/ChildNode.class new file mode 100644 index 0000000000000000000000000000000000000000..7446e50e948194385ed8abff23801a974c4f6183 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ChildNode.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CommentImpl.class b/src/main/resources/org/python/apache/xerces/dom/CommentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e645b5d7c31777c7f5ed33027f9ba73d9156fe8e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CommentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl$RevalidationHandlerHolder.class b/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl$RevalidationHandlerHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..97ec65eaeba04c160f835bfaa602fc6810b3f81f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl$RevalidationHandlerHolder.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl$XMLDTDLoaderHolder.class b/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl$XMLDTDLoaderHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..e5a6966aaa32bb6fa926c9d7651ee0cf4a2f1276 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl$XMLDTDLoaderHolder.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl.class b/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..f8fbe412876232ce811f98785b24df18c7753f56 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CoreDOMImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/CoreDocumentImpl.class b/src/main/resources/org/python/apache/xerces/dom/CoreDocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2dbaa8bf07bb26fc2306a60cfb0f8609fac1cb5d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/CoreDocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMConfigurationImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMConfigurationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..acc4063d8961091c7a76812f49d516d329c6eed8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMConfigurationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMErrorImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMErrorImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..25ab2a33e7607576b16d8e8fede7ee8e3c5a44c9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMErrorImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMImplementationImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..42b840d28de542b1b1abef71d5cf712dbceb79d9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMImplementationListImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMImplementationListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..34dd0b6f3c5d0d529133b213eacc8f0f0c5afcf3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMImplementationListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMImplementationSourceImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMImplementationSourceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8d2875323e9189ca0c9d212f0ce1760f0ab0d8fd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMImplementationSourceImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMInputImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMInputImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..37f8a599293ebb5800216fd9a1b269df29ba0d79 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMInputImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMLocatorImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMLocatorImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d202a9b3750707695b5cddcc784a05a005277faf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMLocatorImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMMessageFormatter.class b/src/main/resources/org/python/apache/xerces/dom/DOMMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..38be8fc15f455bc8fcb5911347e569ccec061ebd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMNormalizer$XMLAttributesProxy.class b/src/main/resources/org/python/apache/xerces/dom/DOMNormalizer$XMLAttributesProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..4bc27aaf03752da63dd59eda00ac708bd3a19d6c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMNormalizer$XMLAttributesProxy.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMNormalizer.class b/src/main/resources/org/python/apache/xerces/dom/DOMNormalizer.class new file mode 100644 index 0000000000000000000000000000000000000000..fa35188b5e8c11fa7b40403772dafa4c546203f1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMNormalizer.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMOutputImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMOutputImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1ac51275cacd1da174afc7a7b77811ed3c48858f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMOutputImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMStringListImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMStringListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..69a8768a91753ad433ab17f0fac6102f57fafa9d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMStringListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DOMXSImplementationSourceImpl.class b/src/main/resources/org/python/apache/xerces/dom/DOMXSImplementationSourceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..abc6403081dcc64ed6cb3441bb3cc176c61e63de Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DOMXSImplementationSourceImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeepNodeListImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeepNodeListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3562df292a836013a88dc89642630cf73164866e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeepNodeListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredAttrImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredAttrImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1acb80e9bc9cbbf537c1902e6d43fc5ce7575ff6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredAttrImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredAttrNSImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredAttrNSImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9f34d111013734c909a04e29ba446c881478615b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredAttrNSImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredCDATASectionImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredCDATASectionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..70e54f337f720798cac1fa990e7bda3d57decac7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredCDATASectionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredCommentImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredCommentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d67a54deba5f21729d084d82dd6d717f4ade6723 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredCommentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredDOMImplementationImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredDOMImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..0053dfa854e0d0ad172bc0674fcff0f830aeeab3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredDOMImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl$IntVector.class b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl$IntVector.class new file mode 100644 index 0000000000000000000000000000000000000000..36d8d41f6ff7c676a7ec713de7390793ba8acc97 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl$IntVector.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl$RefCount.class b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl$RefCount.class new file mode 100644 index 0000000000000000000000000000000000000000..3704bc5b3b456ab0a491c34d86867fd1e6f30942 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl$RefCount.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2e4d7163071783a8b39e61b7405d51a982084c0e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentTypeImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentTypeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..0c96911d9df4cb83f49d15398f832ad43c99ab9e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredDocumentTypeImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredElementDefinitionImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredElementDefinitionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1d9f004a9da40e9036d55a710fc5fac92ad5ab1c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredElementDefinitionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredElementImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..94c986e89e0fd313b4f1bb761b98c87aeea10e1b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredElementImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredElementNSImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredElementNSImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a4a0d7a0a923518b188eb2bdf85b700565b21d76 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredElementNSImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredEntityImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredEntityImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..734f295a27d64dc91fbcefbcb3227790c1de2afe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredEntityImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredEntityReferenceImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredEntityReferenceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..0e81fe94ac3e9c91fc8a9b09b6e1339e4ce4e9a2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredEntityReferenceImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredNode.class b/src/main/resources/org/python/apache/xerces/dom/DeferredNode.class new file mode 100644 index 0000000000000000000000000000000000000000..949fc0dedfbb18064df962f8c359f7245e2fb3ad Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredNode.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredNotationImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredNotationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b95f0ae9e0fda5f9fbed5a90cf5621ab2f8c0fd4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredNotationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredProcessingInstructionImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredProcessingInstructionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d8efe45719bcaadd15e598065e46980f646179bc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredProcessingInstructionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DeferredTextImpl.class b/src/main/resources/org/python/apache/xerces/dom/DeferredTextImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2f0bc455595e76e1767673d8c5d79122c6764aab Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DeferredTextImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DocumentFragmentImpl.class b/src/main/resources/org/python/apache/xerces/dom/DocumentFragmentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..ac69c3b7aa67350edbea20fbbf6539aac60869c4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DocumentFragmentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DocumentImpl$EnclosingAttr.class b/src/main/resources/org/python/apache/xerces/dom/DocumentImpl$EnclosingAttr.class new file mode 100644 index 0000000000000000000000000000000000000000..06b03ef7741d6c158be4b7ac359bba59052597f7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DocumentImpl$EnclosingAttr.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DocumentImpl$LEntry.class b/src/main/resources/org/python/apache/xerces/dom/DocumentImpl$LEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..ef302084c06536dd37e35a71f6bf6b2c3043e761 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DocumentImpl$LEntry.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DocumentImpl.class b/src/main/resources/org/python/apache/xerces/dom/DocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..be921a81b56d61807df4ec47e37d837fe95c8755 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/DocumentTypeImpl.class b/src/main/resources/org/python/apache/xerces/dom/DocumentTypeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8ddf4f87ff52654c7110fb076f13ddfb9939a392 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/DocumentTypeImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ElementDefinitionImpl.class b/src/main/resources/org/python/apache/xerces/dom/ElementDefinitionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..03642f2f7efd0e9e6c8c0fab32878efef3748fee Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ElementDefinitionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ElementImpl.class b/src/main/resources/org/python/apache/xerces/dom/ElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b1868125967327249967daa18ffa5251aa1a622f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ElementImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ElementNSImpl.class b/src/main/resources/org/python/apache/xerces/dom/ElementNSImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8ff29f0ea5db78f85f0c7371cba84a88fe32cff2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ElementNSImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/EntityImpl.class b/src/main/resources/org/python/apache/xerces/dom/EntityImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..cf8eed28c5d23be2fc21d303234ad15862e85f30 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/EntityImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/EntityReferenceImpl.class b/src/main/resources/org/python/apache/xerces/dom/EntityReferenceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5084b271b7f16293f85b79e2790b3f5904b46138 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/EntityReferenceImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/LCount.class b/src/main/resources/org/python/apache/xerces/dom/LCount.class new file mode 100644 index 0000000000000000000000000000000000000000..bea4e38ee27a4cf0ce1a5fe9a99a4c0f1c1ce967 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/LCount.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/NamedNodeMapImpl.class b/src/main/resources/org/python/apache/xerces/dom/NamedNodeMapImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..376eceea9a5a0c057c93ef590eeabba099decb72 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/NamedNodeMapImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/NodeImpl.class b/src/main/resources/org/python/apache/xerces/dom/NodeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8be4e94cb5ee016a6ccea3501008614af2176c43 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/NodeImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/NodeIteratorImpl.class b/src/main/resources/org/python/apache/xerces/dom/NodeIteratorImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..4509809d7cd50fb70fe3789822da38106f598dbe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/NodeIteratorImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/NodeListCache.class b/src/main/resources/org/python/apache/xerces/dom/NodeListCache.class new file mode 100644 index 0000000000000000000000000000000000000000..bfaa8c3ef6e9d87639410e517ca612f6486e69eb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/NodeListCache.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/NotationImpl.class b/src/main/resources/org/python/apache/xerces/dom/NotationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..ad292f551f0fcf03000d1b6f79fe97e7c1ed364f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/NotationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ObjectFactory$ConfigurationError.class b/src/main/resources/org/python/apache/xerces/dom/ObjectFactory$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..6bdd68972baaeff66ba09e66af42bcaec59c44cf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ObjectFactory$ConfigurationError.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ObjectFactory.class b/src/main/resources/org/python/apache/xerces/dom/ObjectFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..fcac89f72f57c2b8761bfceb12305c3e4a5a6b44 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ObjectFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/PSVIAttrNSImpl.class b/src/main/resources/org/python/apache/xerces/dom/PSVIAttrNSImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3ea813d2ae2870d6d18046bc2e71ee2eed335a1d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/PSVIAttrNSImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/PSVIDOMImplementationImpl.class b/src/main/resources/org/python/apache/xerces/dom/PSVIDOMImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d3ea1838f0ac84131e450e06bd59426d19e7a40b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/PSVIDOMImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/PSVIDocumentImpl.class b/src/main/resources/org/python/apache/xerces/dom/PSVIDocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..c32c4564a05f6b66bef54a6bfaea9e4a600f53d8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/PSVIDocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/PSVIElementNSImpl.class b/src/main/resources/org/python/apache/xerces/dom/PSVIElementNSImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..20245ebfccc047ea61f767ff8d47bd0ebb470624 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/PSVIElementNSImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ParentNode$1.class b/src/main/resources/org/python/apache/xerces/dom/ParentNode$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3b1ab35e83d27a059530078b0f1968801973f5ef Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ParentNode$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ParentNode$UserDataRecord.class b/src/main/resources/org/python/apache/xerces/dom/ParentNode$UserDataRecord.class new file mode 100644 index 0000000000000000000000000000000000000000..e7a44c9186ae337d25ef34c88bffdd6e8186938e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ParentNode$UserDataRecord.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ParentNode.class b/src/main/resources/org/python/apache/xerces/dom/ParentNode.class new file mode 100644 index 0000000000000000000000000000000000000000..2c0876d86090618f334dbf37cab1a1aa9f28bb1a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ParentNode.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/ProcessingInstructionImpl.class b/src/main/resources/org/python/apache/xerces/dom/ProcessingInstructionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2dfae4d0c5b572dbe36ab8827bf0dd5987a262c9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/ProcessingInstructionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/RangeExceptionImpl.class b/src/main/resources/org/python/apache/xerces/dom/RangeExceptionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1d13e8735530d0a8e9a5158a065bf1649b66320b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/RangeExceptionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/RangeImpl.class b/src/main/resources/org/python/apache/xerces/dom/RangeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..91ce35bd6061bb2a2fb46db6ffaa5838c282d0ab Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/RangeImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$1.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..024e50cca38d173ac7acaee192032ff28be5cbd7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$2.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..0dd364bdc4828e009fa7626fd42f7567953d70de Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$3.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..8f7777b1252c22f2a3ca9a1df8572485645cd0dd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$3.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$4.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..b337e3286205a042b434a4902b088983b9813df6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$4.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$5.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..51e5edc37a5d38a22e0e834fa3c4c88e81feaefe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$5.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$6.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..4d49f0ee55bab8e3a09c91048f08d8ae69b1bdfd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$6.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$7.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..7d6f2060bfdc902bc5a63203dee37c5e9aebe55b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$7.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$8.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..e9edbed350e1c16ad452d92d8884dfe7e999b770 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport$8.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/SecuritySupport.class b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..a85af0b91b8139faffbe2e09560801a39435142c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/SecuritySupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/TextImpl.class b/src/main/resources/org/python/apache/xerces/dom/TextImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8c8db49db381631ba431953157a25d69706807b7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/TextImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/TreeWalkerImpl.class b/src/main/resources/org/python/apache/xerces/dom/TreeWalkerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2e3e92810c08eafe6adddfe9a0a76e1d912b1a62 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/TreeWalkerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/events/EventImpl.class b/src/main/resources/org/python/apache/xerces/dom/events/EventImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2706c5064ff6a73c7d79a58a25349337b98124ab Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/events/EventImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/events/MouseEventImpl.class b/src/main/resources/org/python/apache/xerces/dom/events/MouseEventImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a4aff044a65fa6c57ad11ec218d82ea5e6ca3b60 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/events/MouseEventImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/events/MutationEventImpl.class b/src/main/resources/org/python/apache/xerces/dom/events/MutationEventImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e73ac76137a8af5799cb118a5487368d3273dc66 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/events/MutationEventImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom/events/UIEventImpl.class b/src/main/resources/org/python/apache/xerces/dom/events/UIEventImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e866d26c84b9da883de679170fa5ccd837283a3c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom/events/UIEventImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASAttributeDeclaration.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASAttributeDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..ac6af795dccd77de64b627ddb8b95cec5524ceac Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASAttributeDeclaration.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASContentModel.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASContentModel.class new file mode 100644 index 0000000000000000000000000000000000000000..196321684a2054547a6a124ecab66eb33dfaa19c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASContentModel.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASDataType.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASDataType.class new file mode 100644 index 0000000000000000000000000000000000000000..420fc7adc9d2907de6278bc899eed693d9397d2e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASDataType.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASElementDeclaration.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASElementDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..e7a11561d303c5b11eea71d5d5fdeea10174f16c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASElementDeclaration.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASEntityDeclaration.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASEntityDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..17af00ee4935ca10fb7d13ece56aaf35c216e708 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASEntityDeclaration.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASModel.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASModel.class new file mode 100644 index 0000000000000000000000000000000000000000..fb81dc77038ea88ff3bc66fa3031030d2e9e965c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASModel.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASNamedObjectMap.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASNamedObjectMap.class new file mode 100644 index 0000000000000000000000000000000000000000..a6e1cf6a1a56d050e57654ac7e282adfe3d58c38 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASNamedObjectMap.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASNotationDeclaration.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASNotationDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..f893aaa01908a6effde27d163023e99a3cb18d43 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASNotationDeclaration.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASObject.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASObject.class new file mode 100644 index 0000000000000000000000000000000000000000..16ab69ee927986caccdfa862d436514c5ee31375 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASObject.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ASObjectList.class b/src/main/resources/org/python/apache/xerces/dom3/as/ASObjectList.class new file mode 100644 index 0000000000000000000000000000000000000000..1b30ba76073c5f2602365f5c08f1209f10247bf8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ASObjectList.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/CharacterDataEditAS.class b/src/main/resources/org/python/apache/xerces/dom3/as/CharacterDataEditAS.class new file mode 100644 index 0000000000000000000000000000000000000000..8ee12755160c2b687e5049c27a4ad81076e754b2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/CharacterDataEditAS.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/DOMASBuilder.class b/src/main/resources/org/python/apache/xerces/dom3/as/DOMASBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..c1cc5e7a6afb2f2f99c167349469d62f21db690f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/DOMASBuilder.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/DOMASException.class b/src/main/resources/org/python/apache/xerces/dom3/as/DOMASException.class new file mode 100644 index 0000000000000000000000000000000000000000..08c3845f98f499992a4a56575b9a5eb47c0514db Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/DOMASException.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/DOMASWriter.class b/src/main/resources/org/python/apache/xerces/dom3/as/DOMASWriter.class new file mode 100644 index 0000000000000000000000000000000000000000..10acc5b0e9c5495726470a55ebee8de5fabb1fe7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/DOMASWriter.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/DOMImplementationAS.class b/src/main/resources/org/python/apache/xerces/dom3/as/DOMImplementationAS.class new file mode 100644 index 0000000000000000000000000000000000000000..8e7ac46e47dd7afe70f61d4c5fe912b9891fbe41 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/DOMImplementationAS.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/DocumentAS.class b/src/main/resources/org/python/apache/xerces/dom3/as/DocumentAS.class new file mode 100644 index 0000000000000000000000000000000000000000..0b00c0b93377a74492e8053efdb48b35d728c76f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/DocumentAS.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/DocumentEditAS.class b/src/main/resources/org/python/apache/xerces/dom3/as/DocumentEditAS.class new file mode 100644 index 0000000000000000000000000000000000000000..4b2cff05380520dfa01be82eb4ffdebf027fa83c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/DocumentEditAS.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/ElementEditAS.class b/src/main/resources/org/python/apache/xerces/dom3/as/ElementEditAS.class new file mode 100644 index 0000000000000000000000000000000000000000..063632ee1acf1358e0b32b780dc41c736eb9603c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/ElementEditAS.class differ diff --git a/src/main/resources/org/python/apache/xerces/dom3/as/NodeEditAS.class b/src/main/resources/org/python/apache/xerces/dom3/as/NodeEditAS.class new file mode 100644 index 0000000000000000000000000000000000000000..f99ef084048d869db821c6368b0c8c50f6a8c84d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/dom3/as/NodeEditAS.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/Constants$ArrayEnumeration.class b/src/main/resources/org/python/apache/xerces/impl/Constants$ArrayEnumeration.class new file mode 100644 index 0000000000000000000000000000000000000000..95709c2410b4a4be7f22f5d577fdb7ccb696e432 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/Constants$ArrayEnumeration.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/Constants.class b/src/main/resources/org/python/apache/xerces/impl/Constants.class new file mode 100644 index 0000000000000000000000000000000000000000..aadbac3badf7ca4d0f08718c3cf069633ac3f7ed Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/Constants.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/ExternalSubsetResolver.class b/src/main/resources/org/python/apache/xerces/impl/ExternalSubsetResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..8385e939dabbcb289aa41e3c2bcdf7cf088fe4c5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/ExternalSubsetResolver.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/RevalidationHandler.class b/src/main/resources/org/python/apache/xerces/impl/RevalidationHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..0f6e7f45d22530f452f99d9cef24151ef33e2636 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/RevalidationHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/Version.class b/src/main/resources/org/python/apache/xerces/impl/Version.class new file mode 100644 index 0000000000000000000000000000000000000000..313ad10f603ffebdca61680146004276625acd1a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/Version.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XML11DTDScannerImpl.class b/src/main/resources/org/python/apache/xerces/impl/XML11DTDScannerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..19e9b07a2c0789e941c1a909c6923a9278a08b9a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XML11DTDScannerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XML11DocumentScannerImpl.class b/src/main/resources/org/python/apache/xerces/impl/XML11DocumentScannerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..303f45d8d9719baf3ba42376d75c4ff6f95050c7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XML11DocumentScannerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XML11EntityScanner.class b/src/main/resources/org/python/apache/xerces/impl/XML11EntityScanner.class new file mode 100644 index 0000000000000000000000000000000000000000..bf86a19d76772fb34ae8a74677d4587bea75f16b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XML11EntityScanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XML11NSDocumentScannerImpl$NS11ContentDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XML11NSDocumentScannerImpl$NS11ContentDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..fff90bd786ca176a7ef0c5800aaa5c48fe1d03c0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XML11NSDocumentScannerImpl$NS11ContentDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XML11NSDocumentScannerImpl.class b/src/main/resources/org/python/apache/xerces/impl/XML11NSDocumentScannerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1d87193d4c499ef00beeb0bf9365ad4614e4f679 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XML11NSDocumentScannerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XML11NamespaceBinder.class b/src/main/resources/org/python/apache/xerces/impl/XML11NamespaceBinder.class new file mode 100644 index 0000000000000000000000000000000000000000..aedf29c86319c81c7493ab6af1f52101104f3f28 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XML11NamespaceBinder.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDTDScannerImpl.class b/src/main/resources/org/python/apache/xerces/impl/XMLDTDScannerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3a41cff519d298eea620f42c6f9c6be84d222804 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDTDScannerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$Dispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$Dispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..1ce605475731e7843e2dc5043e246852fef3367f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$Dispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$ElementStack.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$ElementStack.class new file mode 100644 index 0000000000000000000000000000000000000000..2d6b3e590c1eb03e420d57ef680c5f2210141c1e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$ElementStack.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..554c593d4e78399bf53e55b0dc228b565e2350b3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..6f3a8fc6067248f5e36489ffa31d0679551ce629 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentFragmentScannerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$ContentDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$ContentDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..cca539b4c0f6962144c4d2be487646f0f7793155 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$ContentDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$DTDDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$DTDDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..78c3a29d5ae41b6a4f0647eecf0a2af0a0c7e531 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$DTDDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$PrologDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$PrologDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..306c8d878c3c8d3ec565ede905a771514ef22cfa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$PrologDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$TrailingMiscDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$TrailingMiscDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..250b979b3dbed008afa22ddfa59eb645a898ef23 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$TrailingMiscDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$XMLDeclDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$XMLDeclDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..3525f16121862e7126b9d0bacdb235affa5a6ef1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl$XMLDeclDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl.class b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..0feeb53feb6e546795e0ecd37ea5570844add4f1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLDocumentScannerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityDescription.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityDescription.class new file mode 100644 index 0000000000000000000000000000000000000000..02fc1cc9e095269ecb43e0052edc33e3c5fcfec6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityDescription.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityHandler.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..96d0883f321475de11b8374b8a6cfc0d7fef9b3f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$1.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$1.class new file mode 100644 index 0000000000000000000000000000000000000000..785286f82873ddb934efc89b607143918e845501 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ByteBufferPool.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ByteBufferPool.class new file mode 100644 index 0000000000000000000000000000000000000000..fff15392903e304ad1cca606ce0f8a4ffb62f33f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ByteBufferPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$CharacterBuffer.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$CharacterBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..93499518089ba9bea6f396871d515ea40cc11178 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$CharacterBuffer.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$CharacterBufferPool.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$CharacterBufferPool.class new file mode 100644 index 0000000000000000000000000000000000000000..1b6a06a9d7825bdd91aeb8acacfcd8fe00c96bed Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$CharacterBufferPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$EncodingInfo.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$EncodingInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..b7c5464d4e23e7915d3f17443e32ee97964beca8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$EncodingInfo.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$Entity.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$Entity.class new file mode 100644 index 0000000000000000000000000000000000000000..651c11b10c334c16e021a01b0dcd40a69a20bce0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$Entity.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ExternalEntity.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ExternalEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..d77550a62442a26856c511932bdc20f0645ed6a0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ExternalEntity.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$InternalEntity.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$InternalEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..1694e6e24322aeb6aaca3be8d2481b1c6c845189 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$InternalEntity.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$RewindableInputStream.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$RewindableInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..cac3822b928075a241f67f3e814227035bb733b5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$RewindableInputStream.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ScannedEntity.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ScannedEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..6c9d10cf3aaa9fa723cda7e0a0528f554ad1d9c4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager$ScannedEntity.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager.class new file mode 100644 index 0000000000000000000000000000000000000000..cc11c3f9697dfe206f4119563ef5932a3528c525 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityManager.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityScanner$1.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityScanner$1.class new file mode 100644 index 0000000000000000000000000000000000000000..bf4e4bbd23bf124eaf0d818da47a81237fbaec68 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityScanner$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLEntityScanner.class b/src/main/resources/org/python/apache/xerces/impl/XMLEntityScanner.class new file mode 100644 index 0000000000000000000000000000000000000000..90893be08fac6e1d66031e17d71501ff930d92eb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLEntityScanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLErrorReporter$1.class b/src/main/resources/org/python/apache/xerces/impl/XMLErrorReporter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ac38d910f8e47ec0a3dac553eb5449e853d0565f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLErrorReporter$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLErrorReporter.class b/src/main/resources/org/python/apache/xerces/impl/XMLErrorReporter.class new file mode 100644 index 0000000000000000000000000000000000000000..c653c0cb84a58f146c85d67b8db6cc97fb9c2f60 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLErrorReporter.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLNSDocumentScannerImpl$NSContentDispatcher.class b/src/main/resources/org/python/apache/xerces/impl/XMLNSDocumentScannerImpl$NSContentDispatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..988015aa1b79c70ed5263379332c048efda70064 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLNSDocumentScannerImpl$NSContentDispatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLNSDocumentScannerImpl.class b/src/main/resources/org/python/apache/xerces/impl/XMLNSDocumentScannerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..721da0668cbf22004fdfb4a564b8b1b0ecb191ce Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLNSDocumentScannerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLNamespaceBinder.class b/src/main/resources/org/python/apache/xerces/impl/XMLNamespaceBinder.class new file mode 100644 index 0000000000000000000000000000000000000000..944167e4713a1667ab1000c9b502ef4bad57e043 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLNamespaceBinder.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLScanner.class b/src/main/resources/org/python/apache/xerces/impl/XMLScanner.class new file mode 100644 index 0000000000000000000000000000000000000000..57517f3fe2a7d88fea79def3b86513fc68fecd5c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLScanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/XMLVersionDetector.class b/src/main/resources/org/python/apache/xerces/impl/XMLVersionDetector.class new file mode 100644 index 0000000000000000000000000000000000000000..bdcdd6da92b039c03213af1862d1c19f8dbd4575 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/XMLVersionDetector.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/BalancedDTDGrammar.class b/src/main/resources/org/python/apache/xerces/impl/dtd/BalancedDTDGrammar.class new file mode 100644 index 0000000000000000000000000000000000000000..df38f70b8d52f99f3e1a568dd262018824efbc2a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/BalancedDTDGrammar.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar$ChildrenList.class b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar$ChildrenList.class new file mode 100644 index 0000000000000000000000000000000000000000..ddd1636903a0280126f04a660584758cbe609d63 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar$ChildrenList.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar$QNameHashtable.class b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar$QNameHashtable.class new file mode 100644 index 0000000000000000000000000000000000000000..90ee959b009f7f3e5534165d6ea10084ecf97df5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar$QNameHashtable.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar.class b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar.class new file mode 100644 index 0000000000000000000000000000000000000000..e56c961e196f4d3eadb0b1d20d7beabeb1c3f953 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammar.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammarBucket.class b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammarBucket.class new file mode 100644 index 0000000000000000000000000000000000000000..23658ccb0fc1de3902948815c744aedc66b965ae Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/DTDGrammarBucket.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XML11DTDProcessor.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XML11DTDProcessor.class new file mode 100644 index 0000000000000000000000000000000000000000..a95a02184984065665dd51745597d32fe583492c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XML11DTDProcessor.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XML11DTDValidator.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XML11DTDValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..c51451f5164d0977eed26be30aa6ddacc4b8c606 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XML11DTDValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XML11NSDTDValidator.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XML11NSDTDValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..b874dfd5c638e84bc38830bbc0fbb213061c88e9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XML11NSDTDValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLAttributeDecl.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLAttributeDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..34ddaa7585bb8ab1bfdd002c22e43f18d3a9b134 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLAttributeDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLContentSpec$Provider.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLContentSpec$Provider.class new file mode 100644 index 0000000000000000000000000000000000000000..dbaa9f87fa48a9faafcb79185abc88ffa4d3c76c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLContentSpec$Provider.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLContentSpec.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLContentSpec.class new file mode 100644 index 0000000000000000000000000000000000000000..ed2615bc1d7c88e6eadc5622be41aa7444294728 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLContentSpec.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDDescription.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDDescription.class new file mode 100644 index 0000000000000000000000000000000000000000..b32edb0073a0ed86e4f7c7d93bd89d5d67df3b76 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDDescription.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDLoader.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..39b381ca7fa448880386c06a124bb8ecdc32eef0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDLoader.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDProcessor.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDProcessor.class new file mode 100644 index 0000000000000000000000000000000000000000..84db0d79bde8164d2215195ed6e8c26c85737843 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDProcessor.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDValidator.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..98f6606acdf73b2311fc3a2c421daa0ae82bc9dc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDValidatorFilter.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDValidatorFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..c3eb7b54aa27385820c3b137bc8df11ff3b99642 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLDTDValidatorFilter.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLElementDecl.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLElementDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..dad3d08c277a14317b6b079698afbad2c8e78ad5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLElementDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLEntityDecl.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLEntityDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..15c94e7c9b5c94a5245c85ca4fda34dcd32162bf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLEntityDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLNSDTDValidator.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLNSDTDValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..4f735c00e066ebab7e16534f505d5709f05bbbd8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLNSDTDValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLNotationDecl.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLNotationDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..1f1b3766abf49991ad05bcbfb190ed866dab9e37 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLNotationDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/XMLSimpleType.class b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLSimpleType.class new file mode 100644 index 0000000000000000000000000000000000000000..022b8a75003d455c14178c6f957be745c7e2de07 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/XMLSimpleType.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMAny.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMAny.class new file mode 100644 index 0000000000000000000000000000000000000000..7b765c65b4c5f3d679a91bb77d4dc0ef1441bf40 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMAny.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMBinOp.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMBinOp.class new file mode 100644 index 0000000000000000000000000000000000000000..4658e1524018060e640955298e83e690a22fc0a8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMBinOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMLeaf.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMLeaf.class new file mode 100644 index 0000000000000000000000000000000000000000..66b1bbc8076e608d6dae5e014128b17ac7ce609c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMLeaf.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMNode.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMNode.class new file mode 100644 index 0000000000000000000000000000000000000000..b4b8ea92c66f4ad3321227a7a5c043b17ff3447f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMNode.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMStateSet.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMStateSet.class new file mode 100644 index 0000000000000000000000000000000000000000..e802aa581e407ed4a85ad3e379573b9251c6f3fe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMStateSet.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMUniOp.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMUniOp.class new file mode 100644 index 0000000000000000000000000000000000000000..b3c6cc8153c6c028ea6e056f4084d362b28fac52 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/CMUniOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/ContentModelValidator.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/ContentModelValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..426d3975645d3204bead0cef1a1411f350e95040 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/ContentModelValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/DFAContentModel.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/DFAContentModel.class new file mode 100644 index 0000000000000000000000000000000000000000..c404a2337187e445eb3f5025ca0b6b9f46a441c9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/DFAContentModel.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/MixedContentModel.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/MixedContentModel.class new file mode 100644 index 0000000000000000000000000000000000000000..36722b71c9eccc86c2bdc2f8d6576bd6884aff61 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/MixedContentModel.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dtd/models/SimpleContentModel.class b/src/main/resources/org/python/apache/xerces/impl/dtd/models/SimpleContentModel.class new file mode 100644 index 0000000000000000000000000000000000000000..c5ee9d86b7426b5ee075796c48cf47e3d4a49b14 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dtd/models/SimpleContentModel.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/DTDDVFactory.class b/src/main/resources/org/python/apache/xerces/impl/dv/DTDDVFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..cd70d01ea37602fdc4d640990eb938709351c4c6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/DTDDVFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/DVFactoryException.class b/src/main/resources/org/python/apache/xerces/impl/dv/DVFactoryException.class new file mode 100644 index 0000000000000000000000000000000000000000..8778a560c33bfd44231b760dfa31ab575bcb1895 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/DVFactoryException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/DatatypeException.class b/src/main/resources/org/python/apache/xerces/impl/dv/DatatypeException.class new file mode 100644 index 0000000000000000000000000000000000000000..118a25588977d1d77c9ecce4b82f188d835f84c0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/DatatypeException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/DatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/DatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..ffa746ed7065bcfd75b4bcdb3001642cf4d67445 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/DatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/InvalidDatatypeFacetException.class b/src/main/resources/org/python/apache/xerces/impl/dv/InvalidDatatypeFacetException.class new file mode 100644 index 0000000000000000000000000000000000000000..f3f1a5e18a70a8689e2b6392fd9bebabe7979203 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/InvalidDatatypeFacetException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/InvalidDatatypeValueException.class b/src/main/resources/org/python/apache/xerces/impl/dv/InvalidDatatypeValueException.class new file mode 100644 index 0000000000000000000000000000000000000000..3c01a338b5da0522a44e9ada283625eacb9a2f84 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/InvalidDatatypeValueException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/ObjectFactory$ConfigurationError.class b/src/main/resources/org/python/apache/xerces/impl/dv/ObjectFactory$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..af2f623952a5ae20a6381dda70b62d2fa6c9de48 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/ObjectFactory$ConfigurationError.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/ObjectFactory.class b/src/main/resources/org/python/apache/xerces/impl/dv/ObjectFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..953b94c363c81a8003a180901c6fa5843cf266b0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/ObjectFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SchemaDVFactory.class b/src/main/resources/org/python/apache/xerces/impl/dv/SchemaDVFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..f9690fba7d930abb86fed427adb357a149264ae5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SchemaDVFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$1.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..850c45ba1be2dda00220f0fa972bf42b42564fc2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$2.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..f80b6837cf0a3c35626ced3f9594c15515e239f0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$3.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..7e21955291357693a14b3ed14aa8cb8e88f82f6c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$3.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$4.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..655e2d6f73f9370648cf81c448b0a43d8415b6e8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$4.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$5.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..f1a519c3a4b2a3425f11983610146ce34e09999a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$5.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$6.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..967c992ec026e9a69a1bb5a3960ec172681b6a43 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$6.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$7.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..74bf8643e50788e6e6c8b57890e7cbe037744cb4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$7.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$8.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..c3f0b8703bd576a7ff1aa14be39968c7faf9bee1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport$8.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport.class b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..a96101a5f4eebfe094abd38360f7c3a00a6da610 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/SecuritySupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/ValidatedInfo.class b/src/main/resources/org/python/apache/xerces/impl/dv/ValidatedInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..b4ed19285d34459fd36a81f6d0225aae06105907 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/ValidatedInfo.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/ValidationContext.class b/src/main/resources/org/python/apache/xerces/impl/dv/ValidationContext.class new file mode 100644 index 0000000000000000000000000000000000000000..8bd1d444d9b854843775f8b59bf779add306fdc9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/ValidationContext.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/XSFacets.class b/src/main/resources/org/python/apache/xerces/impl/dv/XSFacets.class new file mode 100644 index 0000000000000000000000000000000000000000..d13d6b22c2c78a4598137b7675b8b15dbbd53cbe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/XSFacets.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/XSSimpleType.class b/src/main/resources/org/python/apache/xerces/impl/dv/XSSimpleType.class new file mode 100644 index 0000000000000000000000000000000000000000..9d9cf88e93f5e65a53fa361d74226494c8d1b39b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/XSSimpleType.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/DTDDVFactoryImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/DTDDVFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3ebecf095a4154dc8d12f403bbaf376ab226378c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/DTDDVFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/ENTITYDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/ENTITYDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..6b074efe77b2cc5b2aaa9fb24493672dad5d6f00 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/ENTITYDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/IDDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/IDDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..fd24f5bd101bb4e0f729b30f159fb43ff8f3319e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/IDDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/IDREFDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/IDREFDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..dc435027a146092c577582cb9e81982dd741b190 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/IDREFDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/ListDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/ListDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..6709c0908e49ea5029de51e80e53261adf673981 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/ListDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/NMTOKENDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/NMTOKENDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..0897103ff4cd41a0a2c1ae04e339ea0925d6365f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/NMTOKENDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/NOTATIONDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/NOTATIONDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..15d3587f478a254c41a72858e6ecf056d3f8ee3d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/NOTATIONDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/StringDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/StringDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..8eb5be5074b6714a385baceec9da0c89d67d8868 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/StringDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11DTDDVFactoryImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11DTDDVFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..14447db205b051c058fa2dee842c11b7bff9d096 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11DTDDVFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11IDDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11IDDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..115bfc4c4f40009bdc8a23fa3200ede55ea994fb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11IDDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11IDREFDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11IDREFDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..d76dc75a274debd18ede699ea155b7add848de1a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11IDREFDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11NMTOKENDatatypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11NMTOKENDatatypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..bcf8b030a2260d58d49abf1af74ad257021e2f33 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/dtd/XML11NMTOKENDatatypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/util/Base64.class b/src/main/resources/org/python/apache/xerces/impl/dv/util/Base64.class new file mode 100644 index 0000000000000000000000000000000000000000..c001123295a69687fbbeecf88fca322f87e4bedc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/util/Base64.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/util/ByteListImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/util/ByteListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b7f10df56ed9ed08a75939f1c175587c4ab70d6c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/util/ByteListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/util/HexBin.class b/src/main/resources/org/python/apache/xerces/impl/dv/util/HexBin.class new file mode 100644 index 0000000000000000000000000000000000000000..85c13996db1b32c39c9cbe17d8896c3cfc3e5b54 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/util/HexBin.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/AbstractDateTimeDV$DateTimeData.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AbstractDateTimeDV$DateTimeData.class new file mode 100644 index 0000000000000000000000000000000000000000..a27c346e61a8c0402e9b96b5041df6bd7d977be0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AbstractDateTimeDV$DateTimeData.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/AbstractDateTimeDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AbstractDateTimeDV.class new file mode 100644 index 0000000000000000000000000000000000000000..8cfc39e501c1745e5d20147c0c9f90f617b21e9e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AbstractDateTimeDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnyAtomicDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnyAtomicDV.class new file mode 100644 index 0000000000000000000000000000000000000000..b85efa9bcf6373fd2519bd0628fa2591bf1357ef Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnyAtomicDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnySimpleDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnySimpleDV.class new file mode 100644 index 0000000000000000000000000000000000000000..c1bbe2a010b19d28147e0e950f0820c8e142ef88 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnySimpleDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnyURIDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnyURIDV.class new file mode 100644 index 0000000000000000000000000000000000000000..dcdcd3f43336ac1b74bb5086ae563e4fc18729a3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/AnyURIDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/Base64BinaryDV$XBase64.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/Base64BinaryDV$XBase64.class new file mode 100644 index 0000000000000000000000000000000000000000..1b7156e1287a4ff6d9db6d7a292582fa4bacfa72 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/Base64BinaryDV$XBase64.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/Base64BinaryDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/Base64BinaryDV.class new file mode 100644 index 0000000000000000000000000000000000000000..c1fd7d68fbfe6df8051809c296c7eab737c4a3a2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/Base64BinaryDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/BaseDVFactory.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/BaseDVFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..4b8827ba92c42372ea239343bc481cb663a62028 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/BaseDVFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/BaseSchemaDVFactory.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/BaseSchemaDVFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..c78b148b074d096f74955efce10bbff8d47f1c93 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/BaseSchemaDVFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/BooleanDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/BooleanDV.class new file mode 100644 index 0000000000000000000000000000000000000000..bdce74b72248093d5acdb0cf5c6d9811f24198cd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/BooleanDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DateDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DateDV.class new file mode 100644 index 0000000000000000000000000000000000000000..d1135e46ffc55d5d34e2c699ec4848ac336d00fd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DateDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DateTimeDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DateTimeDV.class new file mode 100644 index 0000000000000000000000000000000000000000..55d5202445977eda24b898c7bcb9cdb3aecabc1a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DateTimeDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DayDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DayDV.class new file mode 100644 index 0000000000000000000000000000000000000000..e6b43eb1660dfbd3f6054de1d1b014a363d337c6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DayDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DayTimeDurationDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DayTimeDurationDV.class new file mode 100644 index 0000000000000000000000000000000000000000..b63c36cc1ecf476124b6a5a62e3026eb2ed22a2c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DayTimeDurationDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DecimalDV$XDecimal.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DecimalDV$XDecimal.class new file mode 100644 index 0000000000000000000000000000000000000000..90231b3b2b8b90b87e10b82de1ca448b11a2d2d0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DecimalDV$XDecimal.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DecimalDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DecimalDV.class new file mode 100644 index 0000000000000000000000000000000000000000..357e48259a3f04f3a90baa840280a73c4f2a12b5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DecimalDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DoubleDV$XDouble.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DoubleDV$XDouble.class new file mode 100644 index 0000000000000000000000000000000000000000..fa42f9549cd3ac0d15de704f310b58f5dc6a1953 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DoubleDV$XDouble.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DoubleDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DoubleDV.class new file mode 100644 index 0000000000000000000000000000000000000000..9c60b4b5416909f67bc55780e2fe9bf5e671c186 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DoubleDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/DurationDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DurationDV.class new file mode 100644 index 0000000000000000000000000000000000000000..09e28a1ce3bab52e09fdb3253bd3e087259febf7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/DurationDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/EntityDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/EntityDV.class new file mode 100644 index 0000000000000000000000000000000000000000..f1707c3548297d7e7786b97d62a0a40758367ca0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/EntityDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/ExtendedSchemaDVFactoryImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/ExtendedSchemaDVFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5ed8240a4b52da8c607a12e1e4b0d37006087772 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/ExtendedSchemaDVFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/FloatDV$XFloat.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/FloatDV$XFloat.class new file mode 100644 index 0000000000000000000000000000000000000000..1f1e5a425a7f285233068e601613eec3a144f3ca Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/FloatDV$XFloat.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/FloatDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/FloatDV.class new file mode 100644 index 0000000000000000000000000000000000000000..d5d53db8cdaec0675ce79188b874ed65012b8bd5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/FloatDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/FullDVFactory.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/FullDVFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..fa7a01681ec93a124ca51572e454a5063b74cd88 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/FullDVFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/HexBinaryDV$XHex.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/HexBinaryDV$XHex.class new file mode 100644 index 0000000000000000000000000000000000000000..936186b9863680ddb69ac251657575ffed8d060b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/HexBinaryDV$XHex.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/HexBinaryDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/HexBinaryDV.class new file mode 100644 index 0000000000000000000000000000000000000000..33f89a9d613ecca3c8ec41c8926ec3fe12ca27c7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/HexBinaryDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/IDDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/IDDV.class new file mode 100644 index 0000000000000000000000000000000000000000..14a5b404bffec4dc0811fb22dff2430877baa7b3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/IDDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/IDREFDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/IDREFDV.class new file mode 100644 index 0000000000000000000000000000000000000000..395dc06628f343450e774af8d68677461a356504 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/IDREFDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/IntegerDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/IntegerDV.class new file mode 100644 index 0000000000000000000000000000000000000000..004ce252f04c933401f1968477c5b128b959afb9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/IntegerDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/ListDV$ListData.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/ListDV$ListData.class new file mode 100644 index 0000000000000000000000000000000000000000..a3577629f3934a19082070a438abb8487391c776 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/ListDV$ListData.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/ListDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/ListDV.class new file mode 100644 index 0000000000000000000000000000000000000000..4419ad85b072cff4a2944d4b92dd779267be677f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/ListDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/MonthDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/MonthDV.class new file mode 100644 index 0000000000000000000000000000000000000000..38f37de39e3d2830455d66244f14b3a883ad2157 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/MonthDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/MonthDayDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/MonthDayDV.class new file mode 100644 index 0000000000000000000000000000000000000000..73890e51508960b253f1f90cd2e4558ae5c91ddc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/MonthDayDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/PrecisionDecimalDV$XPrecisionDecimal.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/PrecisionDecimalDV$XPrecisionDecimal.class new file mode 100644 index 0000000000000000000000000000000000000000..8279080a4bde8d7cedc87e04f04ecf89065aeede Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/PrecisionDecimalDV$XPrecisionDecimal.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/PrecisionDecimalDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/PrecisionDecimalDV.class new file mode 100644 index 0000000000000000000000000000000000000000..8567ee222ce5b50431285718e20e6594ce07f23e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/PrecisionDecimalDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/QNameDV$XQName.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/QNameDV$XQName.class new file mode 100644 index 0000000000000000000000000000000000000000..4c5b7b0057a7dee1d3a0568bde12308222eb7112 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/QNameDV$XQName.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/QNameDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/QNameDV.class new file mode 100644 index 0000000000000000000000000000000000000000..3aaa3f46d5f8d8b7f28aaec7f47a6cab4f50f446 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/QNameDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/SchemaDVFactoryImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/SchemaDVFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..da74a38a50b0ccd8781c187c9c3bb630118e062d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/SchemaDVFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/SchemaDateTimeException.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/SchemaDateTimeException.class new file mode 100644 index 0000000000000000000000000000000000000000..e164710fab62d48ed2ea716d80e4c7a6a1e146ab Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/SchemaDateTimeException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/StringDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/StringDV.class new file mode 100644 index 0000000000000000000000000000000000000000..7585d367a7839d5c16da37cc443da774b089b024 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/StringDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/TimeDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/TimeDV.class new file mode 100644 index 0000000000000000000000000000000000000000..5c40d0c141434f3fbbbf96d49306a5ac50909dbf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/TimeDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/TypeValidator.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/TypeValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..050f941ae8a12f3cd423593bf771fe2044d6596a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/TypeValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/UnionDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/UnionDV.class new file mode 100644 index 0000000000000000000000000000000000000000..3ac62f55311bf300107cdbdb8682fb1a0432044a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/UnionDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$1.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c1c9f3ce57fe62de814189759fe14dd102709ea1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$2.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$2.class new file mode 100644 index 0000000000000000000000000000000000000000..08ab3d6717b31d0d797b73d10f1c3bca62dce16b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$3.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$3.class new file mode 100644 index 0000000000000000000000000000000000000000..370ad5dd9587d9ed8a03cafbaa23033fe0b0ab80 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$3.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$4.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$4.class new file mode 100644 index 0000000000000000000000000000000000000000..739f92bea3593a80caf872fb1ac735a91f5dff80 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$4.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$AbstractObjectList.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$AbstractObjectList.class new file mode 100644 index 0000000000000000000000000000000000000000..ba5555c3b21724011a4284ae989451b16f6c9daa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$AbstractObjectList.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$ValidationContextImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$ValidationContextImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..ad34121f04277e81121f876d4e39bc9051a37279 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$ValidationContextImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$XSFacetImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$XSFacetImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b839d532da8fb2680110ff5bd6a9dff66c6fd1fe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$XSFacetImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$XSMVFacetImpl.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$XSMVFacetImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8d770fae06b83d5d20bc0f255fab9d5133d667f4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl$XSMVFacetImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..e3313fd37be9653d6806e85f899c11037dcf8abe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDelegate.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..346863ef084bdcaefc7c9f9b0ca1fb18e940e938 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/XSSimpleTypeDelegate.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearDV.class new file mode 100644 index 0000000000000000000000000000000000000000..f7094456780b67a2a1b7334d6514c5028d7a7be9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearMonthDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearMonthDV.class new file mode 100644 index 0000000000000000000000000000000000000000..5efbf36cf9380ade4371b9abd590285b8695c223 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearMonthDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearMonthDurationDV.class b/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearMonthDurationDV.class new file mode 100644 index 0000000000000000000000000000000000000000..4155600ffa104f9a87f1cbcdd22ee3bf42b228bc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/dv/xs/YearMonthDurationDV.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/io/ASCIIReader.class b/src/main/resources/org/python/apache/xerces/impl/io/ASCIIReader.class new file mode 100644 index 0000000000000000000000000000000000000000..4f72614246eedad9c78d3c838c8fad3691356bbb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/io/ASCIIReader.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/io/Latin1Reader.class b/src/main/resources/org/python/apache/xerces/impl/io/Latin1Reader.class new file mode 100644 index 0000000000000000000000000000000000000000..8777142845ff82b25a8f2feb986eaa4c0faba14d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/io/Latin1Reader.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/io/MalformedByteSequenceException.class b/src/main/resources/org/python/apache/xerces/impl/io/MalformedByteSequenceException.class new file mode 100644 index 0000000000000000000000000000000000000000..2c1793dc1260b85a9c5e679e7a8ed13618dc169e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/io/MalformedByteSequenceException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/io/UCSReader.class b/src/main/resources/org/python/apache/xerces/impl/io/UCSReader.class new file mode 100644 index 0000000000000000000000000000000000000000..38830c1fdffbe319e764482e77348ca54005125c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/io/UCSReader.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/io/UTF16Reader.class b/src/main/resources/org/python/apache/xerces/impl/io/UTF16Reader.class new file mode 100644 index 0000000000000000000000000000000000000000..f587d7afaa83aa1a2af9b3d3c423c25171684657 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/io/UTF16Reader.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/io/UTF8Reader.class b/src/main/resources/org/python/apache/xerces/impl/io/UTF8Reader.class new file mode 100644 index 0000000000000000000000000000000000000000..776615693c122775d0da13655035707cd2072d81 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/io/UTF8Reader.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/DOMMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/DOMMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..dd2745543f382571f0f2b13721067ff89ec35fcb --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/DOMMessages.properties @@ -0,0 +1,84 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces +# DOM implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: DOMMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + +# DOM Core + +# exception codes +DOMSTRING_SIZE_ERR = The specified range of text does not fit into a DOMString. +HIERARCHY_REQUEST_ERR = An attempt was made to insert a node where it is not permitted. +INDEX_SIZE_ERR = The index or size is negative, or greater than the allowed value. +INUSE_ATTRIBUTE_ERR = An attempt is made to add an attribute that is already in use elsewhere. +INVALID_ACCESS_ERR = A parameter or an operation is not supported by the underlying object. +INVALID_CHARACTER_ERR = An invalid or illegal XML character is specified. +INVALID_MODIFICATION_ERR = An attempt is made to modify the type of the underlying object. +INVALID_STATE_ERR = An attempt is made to use an object that is not, or is no longer, usable. +NAMESPACE_ERR = An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. +NOT_FOUND_ERR = An attempt is made to reference a node in a context where it does not exist. +NOT_SUPPORTED_ERR = The implementation does not support the requested type of object or operation. +NO_DATA_ALLOWED_ERR = Data is specified for a node which does not support data. +NO_MODIFICATION_ALLOWED_ERR = An attempt is made to modify an object where modifications are not allowed. +SYNTAX_ERR = An invalid or illegal string is specified. +VALIDATION_ERR = A call to a method such as insertBefore or removeChild would make the Node invalid with respect to document grammar. +WRONG_DOCUMENT_ERR = A node is used in a different document than the one that created it. +TYPE_MISMATCH_ERR = The value type for this parameter name is incompatible with the expected value type. + +#error messages or exceptions +FEATURE_NOT_SUPPORTED = The parameter {0} is recognized but the requested value cannot be set. +FEATURE_NOT_FOUND = The parameter {0} is not recognized. +STRING_TOO_LONG = The resulting string is too long to fit in a DOMString: ''{0}''. + +#DOM Level 3 DOMError codes +wf-invalid-character = The text {0} of the {1} node contains invalid XML characters. +wf-invalid-character-in-node-name = The {0} node named {1} contains invalid XML characters. +cdata-sections-splitted = CDATA sections containing the CDATA section termination marker \"]]>\" +doctype-not-allowed = DOCTYPE declaration is not allowed. +unsupported-encoding = The encoding {0} is not supported. + +#Error codes used in DOM Normalizer +InvalidXMLCharInDOM = An invalid XML character (Unicode: 0x{0}) was found in the DOM during normalization. +UndeclaredEntRefInAttrValue = The attribute \"{0}\" value \"{1}\" referenced an entity that was not declared. +NullLocalElementName = A null local name was encountered during namespace normalization of element {0}. +NullLocalAttrName = A null local name was encountered during namespace normalization of attribute {0}. + +#Error codes used in DOMParser +InvalidDocumentClassName = The class name of the document factory \"{0}\" used to construct the DOM tree is not of type org.w3c.dom.Document. +MissingDocumentClassName = The class name of the document factory \"{0}\" used to construct the DOM tree could not be found. +CannotCreateDocumentClass = The class named \"{0}\" could not be constructed as a org.w3c.dom.Document. +CannotQueryDeferredNode = Current element node cannot be queried when node expansion is deferred. + +# Error codes used by JAXP DocumentBuilder +jaxp-order-not-supported = Property ''{0}'' must be set before setting property ''{1}''. +jaxp-null-input-source = The source specified cannot be null. + +#Ranges +BAD_BOUNDARYPOINTS_ERR = The boundary-points of a Range do not meet specific requirements. +INVALID_NODE_TYPE_ERR = The container of a boundary-point of a Range is being set to either a node of an invalid type or a node with an ancestor of an invalid type. + + +#Events +UNSPECIFIED_EVENT_TYPE_ERR = The Event's type was not specified by initializing the event before the method was called. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/DOMMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/DOMMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..dd2745543f382571f0f2b13721067ff89ec35fcb --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/DOMMessages_en.properties @@ -0,0 +1,84 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces +# DOM implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: DOMMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + +# DOM Core + +# exception codes +DOMSTRING_SIZE_ERR = The specified range of text does not fit into a DOMString. +HIERARCHY_REQUEST_ERR = An attempt was made to insert a node where it is not permitted. +INDEX_SIZE_ERR = The index or size is negative, or greater than the allowed value. +INUSE_ATTRIBUTE_ERR = An attempt is made to add an attribute that is already in use elsewhere. +INVALID_ACCESS_ERR = A parameter or an operation is not supported by the underlying object. +INVALID_CHARACTER_ERR = An invalid or illegal XML character is specified. +INVALID_MODIFICATION_ERR = An attempt is made to modify the type of the underlying object. +INVALID_STATE_ERR = An attempt is made to use an object that is not, or is no longer, usable. +NAMESPACE_ERR = An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. +NOT_FOUND_ERR = An attempt is made to reference a node in a context where it does not exist. +NOT_SUPPORTED_ERR = The implementation does not support the requested type of object or operation. +NO_DATA_ALLOWED_ERR = Data is specified for a node which does not support data. +NO_MODIFICATION_ALLOWED_ERR = An attempt is made to modify an object where modifications are not allowed. +SYNTAX_ERR = An invalid or illegal string is specified. +VALIDATION_ERR = A call to a method such as insertBefore or removeChild would make the Node invalid with respect to document grammar. +WRONG_DOCUMENT_ERR = A node is used in a different document than the one that created it. +TYPE_MISMATCH_ERR = The value type for this parameter name is incompatible with the expected value type. + +#error messages or exceptions +FEATURE_NOT_SUPPORTED = The parameter {0} is recognized but the requested value cannot be set. +FEATURE_NOT_FOUND = The parameter {0} is not recognized. +STRING_TOO_LONG = The resulting string is too long to fit in a DOMString: ''{0}''. + +#DOM Level 3 DOMError codes +wf-invalid-character = The text {0} of the {1} node contains invalid XML characters. +wf-invalid-character-in-node-name = The {0} node named {1} contains invalid XML characters. +cdata-sections-splitted = CDATA sections containing the CDATA section termination marker \"]]>\" +doctype-not-allowed = DOCTYPE declaration is not allowed. +unsupported-encoding = The encoding {0} is not supported. + +#Error codes used in DOM Normalizer +InvalidXMLCharInDOM = An invalid XML character (Unicode: 0x{0}) was found in the DOM during normalization. +UndeclaredEntRefInAttrValue = The attribute \"{0}\" value \"{1}\" referenced an entity that was not declared. +NullLocalElementName = A null local name was encountered during namespace normalization of element {0}. +NullLocalAttrName = A null local name was encountered during namespace normalization of attribute {0}. + +#Error codes used in DOMParser +InvalidDocumentClassName = The class name of the document factory \"{0}\" used to construct the DOM tree is not of type org.w3c.dom.Document. +MissingDocumentClassName = The class name of the document factory \"{0}\" used to construct the DOM tree could not be found. +CannotCreateDocumentClass = The class named \"{0}\" could not be constructed as a org.w3c.dom.Document. +CannotQueryDeferredNode = Current element node cannot be queried when node expansion is deferred. + +# Error codes used by JAXP DocumentBuilder +jaxp-order-not-supported = Property ''{0}'' must be set before setting property ''{1}''. +jaxp-null-input-source = The source specified cannot be null. + +#Ranges +BAD_BOUNDARYPOINTS_ERR = The boundary-points of a Range do not meet specific requirements. +INVALID_NODE_TYPE_ERR = The container of a boundary-point of a Range is being set to either a node of an invalid type or a node with an ancestor of an invalid type. + + +#Events +UNSPECIFIED_EVENT_TYPE_ERR = The Event's type was not specified by initializing the event before the method was called. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/DatatypeMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/DatatypeMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..f1739e7abdb03fe4289c026287ea6365cf69381e --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/DatatypeMessages.properties @@ -0,0 +1,47 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces JAXP Datatype API implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: DatatypeMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +FieldCannotBeNull={0} cannot be called with 'null' parameter. +UnknownField={0} called with an unknown field\:{1} +#There are two similar keys 'InvalidXMLGreogorianCalendarValue' . Suffix (year, month) has been added and are used as per the context. +InvalidXGCValue-milli=Year \= {0}, Month \= {1}, Day \= {2}, Hour \= {3}, Minute \= {4}, Second \= {5}, fractionalSecond \= {6}, Timezone \= {7} , is not a valid representation of an XML Gregorian Calendar value. +#There are two similar keys 'InvalidXMLGreogorianCalendarValue' . Suffix (year, month) has been added and are used as per the context. +InvalidXGCValue-fractional=Year \= {0}, Month \= {1}, Day \= {2}, Hour \= {3}, Minute \= {4}, Second \= {5}, fractionalSecond \= {6}, Timezone \= {7} , is not a valid representation of an XML Gregorian Calendar value. + +InvalidXGCFields=Invalid set of fields set for XMLGregorianCalendar + +InvalidFractional=Invalid value {0} for fractional second. + +#XGC stands for XML Gregorian Calendar +InvalidXGCRepresentation="{0}" is not a valid representation of an XML Gregorian Calendar value. + +InvalidFieldValue=Invalid value {0} for {1} field. + +NegativeField= {0} field is negative + +AllFieldsNull=All the fields (javax.xml.datatype.DatatypeConstants.Field) are null. + +TooLarge={0} value "{1}" too large to be supported by this implementation diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/DatatypeMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/DatatypeMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..f1739e7abdb03fe4289c026287ea6365cf69381e --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/DatatypeMessages_en.properties @@ -0,0 +1,47 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces JAXP Datatype API implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: DatatypeMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +FieldCannotBeNull={0} cannot be called with 'null' parameter. +UnknownField={0} called with an unknown field\:{1} +#There are two similar keys 'InvalidXMLGreogorianCalendarValue' . Suffix (year, month) has been added and are used as per the context. +InvalidXGCValue-milli=Year \= {0}, Month \= {1}, Day \= {2}, Hour \= {3}, Minute \= {4}, Second \= {5}, fractionalSecond \= {6}, Timezone \= {7} , is not a valid representation of an XML Gregorian Calendar value. +#There are two similar keys 'InvalidXMLGreogorianCalendarValue' . Suffix (year, month) has been added and are used as per the context. +InvalidXGCValue-fractional=Year \= {0}, Month \= {1}, Day \= {2}, Hour \= {3}, Minute \= {4}, Second \= {5}, fractionalSecond \= {6}, Timezone \= {7} , is not a valid representation of an XML Gregorian Calendar value. + +InvalidXGCFields=Invalid set of fields set for XMLGregorianCalendar + +InvalidFractional=Invalid value {0} for fractional second. + +#XGC stands for XML Gregorian Calendar +InvalidXGCRepresentation="{0}" is not a valid representation of an XML Gregorian Calendar value. + +InvalidFieldValue=Invalid value {0} for {1} field. + +NegativeField= {0} field is negative + +AllFieldsNull=All the fields (javax.xml.datatype.DatatypeConstants.Field) are null. + +TooLarge={0} value "{1}" too large to be supported by this implementation diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/JAXPValidationMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/JAXPValidationMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..6a31cad569cbd0052a3b0cd15205b45668b420e2 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/JAXPValidationMessages.properties @@ -0,0 +1,50 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces JAXP Validation API implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: JAXPValidationMessages.properties 683837 2008-08-08 04:12:37Z mrglavas $ + +# Messages for message reporting +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# SchemaFactory error messages +SchemaLanguageNull = The schema language specified cannot be null. +SchemaLanguageLengthZero = The schema language specified cannot have a length of zero characters. +SchemaSourceArrayNull = The Source array parameter cannot be null. +SchemaSourceArrayMemberNull = The Source array parameter cannot contain any items that are null. +SchemaFactorySourceUnrecognized = Source parameter of type ''{0}'' is not recognized by this SchemaFactory. +SAXSourceNullInputSource = The SAXSource specified contains no InputSource. + +# Validator error messages +SourceParameterNull = Source parameter cannot be null. +SourceNotAccepted = Source parameter of type ''{0}'' is not accepted by this validator. +SourceResultMismatch = Source parameter of type ''{0}'' is not compatible with result parameter of type ''{1}''. +StAXIllegalInitialState = Expecting the initial state to be start document or start element. +StreamResultNotInitialized = The StreamResult contains no OutputStream, Writer, or system ID. + +# TypeInfoProvider error messages +TypeInfoProviderIllegalStateElement = Element type information cannot be queried from a TypeInfoProvider outside of a startElement or endElement callback. +TypeInfoProviderIllegalStateAttribute = Attribute type information cannot be queried from a TypeInfoProvider outside of a startElement callback. + +# General error messages +FeatureNameNull = The feature name cannot be null. +ProperyNameNull = The property name cannot be null. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/JAXPValidationMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/JAXPValidationMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..6a31cad569cbd0052a3b0cd15205b45668b420e2 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/JAXPValidationMessages_en.properties @@ -0,0 +1,50 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces JAXP Validation API implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: JAXPValidationMessages.properties 683837 2008-08-08 04:12:37Z mrglavas $ + +# Messages for message reporting +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# SchemaFactory error messages +SchemaLanguageNull = The schema language specified cannot be null. +SchemaLanguageLengthZero = The schema language specified cannot have a length of zero characters. +SchemaSourceArrayNull = The Source array parameter cannot be null. +SchemaSourceArrayMemberNull = The Source array parameter cannot contain any items that are null. +SchemaFactorySourceUnrecognized = Source parameter of type ''{0}'' is not recognized by this SchemaFactory. +SAXSourceNullInputSource = The SAXSource specified contains no InputSource. + +# Validator error messages +SourceParameterNull = Source parameter cannot be null. +SourceNotAccepted = Source parameter of type ''{0}'' is not accepted by this validator. +SourceResultMismatch = Source parameter of type ''{0}'' is not compatible with result parameter of type ''{1}''. +StAXIllegalInitialState = Expecting the initial state to be start document or start element. +StreamResultNotInitialized = The StreamResult contains no OutputStream, Writer, or system ID. + +# TypeInfoProvider error messages +TypeInfoProviderIllegalStateElement = Element type information cannot be queried from a TypeInfoProvider outside of a startElement or endElement callback. +TypeInfoProviderIllegalStateAttribute = Attribute type information cannot be queried from a TypeInfoProvider outside of a startElement callback. + +# General error messages +FeatureNameNull = The feature name cannot be null. +ProperyNameNull = The property name cannot be null. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/SAXMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/SAXMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..ae65a962b081d61b8257557537d8df7bf412c546 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/SAXMessages.properties @@ -0,0 +1,46 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces +# SAX implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: SAXMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# JAXP messages +schema-not-supported = The specified schema language is not supported. +jaxp-order-not-supported = Property ''{0}'' must be set before setting property ''{1}''. +schema-already-specified = Property ''{0}'' cannot be set when a non-null Schema object has already been specified. + +# feature messages +feature-not-supported = Feature ''{0}'' is not supported. +feature-not-recognized = Feature ''{0}'' is not recognized. +true-not-supported = True state for feature ''{0}'' is not supported. +false-not-supported = False state for feature ''{0}'' is not supported. +feature-read-only = Feature ''{0}'' is read only. + +# property messages +property-not-supported = Property ''{0}'' is not supported. +property-not-recognized = Property ''{0}'' is not recognized. +property-read-only = Property ''{0}'' is read only. +property-not-parsing-supported = Property ''{0}'' is not supported while parsing. +dom-node-read-not-supported = Cannot read DOM node property. No DOM tree exists. +incompatible-class = The value specified for property ''{0}'' cannot be casted to {1}. diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/SAXMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/SAXMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..ae65a962b081d61b8257557537d8df7bf412c546 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/SAXMessages_en.properties @@ -0,0 +1,46 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces +# SAX implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: SAXMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# JAXP messages +schema-not-supported = The specified schema language is not supported. +jaxp-order-not-supported = Property ''{0}'' must be set before setting property ''{1}''. +schema-already-specified = Property ''{0}'' cannot be set when a non-null Schema object has already been specified. + +# feature messages +feature-not-supported = Feature ''{0}'' is not supported. +feature-not-recognized = Feature ''{0}'' is not recognized. +true-not-supported = True state for feature ''{0}'' is not supported. +false-not-supported = False state for feature ''{0}'' is not supported. +feature-read-only = Feature ''{0}'' is read only. + +# property messages +property-not-supported = Property ''{0}'' is not supported. +property-not-recognized = Property ''{0}'' is not recognized. +property-read-only = Property ''{0}'' is read only. +property-not-parsing-supported = Property ''{0}'' is not supported while parsing. +dom-node-read-not-supported = Cannot read DOM node property. No DOM tree exists. +incompatible-class = The value specified for property ''{0}'' cannot be casted to {1}. diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XIncludeMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XIncludeMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..01e82ea2fe745b2529b324c0b9edf680165c4e0f --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XIncludeMessages.properties @@ -0,0 +1,56 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces XInclude implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XIncludeMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +# Messages for message reporting +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# Messages for erroneous input +NoFallback = An 'include' failed, and no 'fallback' element was found. +MultipleFallbacks = The [children] of an 'include' element cannot contain more than one 'fallback' element. +FallbackParent = A 'fallback' element was found that did not have 'include' as the parent. +IncludeChild = Elements from namespace ''http://www.w3.org/2001/XInclude'', other than ''fallback'', are not allowed to be children of ''include'' elements. However, ''{0}'' was found. +FallbackChild = Elements from namespace ''http://www.w3.org/2001/XInclude'', other than ''include'', are not allowed to be children of ''fallback'' elements. However, ''{0}'' was found. +HrefMissing = The 'href' attribute of an 'include' element is missing. +RecursiveInclude = Recursive include detected. Document ''{0}'' was already processed. +InvalidParseValue = Invalid value for ''parse'' attribute on ''include'' element: ''{0}''. +XMLParseError = Error attempting to parse XML file (href=''{0}''). +XMLResourceError = Include operation failed, reverting to fallback. Resource error reading file as XML (href=''{0}''). Reason: {1} +TextResourceError = Include operation failed, reverting to fallback. Resource error reading file as text (href=''{0}''). Reason: {1} +NonDuplicateNotation = Multiple notations were used which had the name ''{0}'', but which were not determined to be duplicates. +NonDuplicateUnparsedEntity = Multiple unparsed entities were used which had the name ''{0}'', but which were not determined to be duplicates. +XpointerMissing = xpointer attribute must be present when href attribute is absent. +AcceptMalformed = Characters outside the range #x20 through #x7E are not allowed in the value of the 'accept' attribute of an 'include' element. +AcceptLanguageMalformed = Characters outside the range #x20 through #x7E are not allowed in the value of the 'accept-language' attribute of an 'include' element. +RootElementRequired = A well-formed document requires a root element. +MultipleRootElements = A well-formed document must not contain multiple root elements. +ContentIllegalAtTopLevel = The replacement of an 'include' element appearing as the document element in the top-level source infoset cannot contain characters. +UnexpandedEntityReferenceIllegal = The replacement of an 'include' element appearing as the document element in the top-level source infoset cannot contain unexpanded entity references. +HrefFragmentIdentifierIllegal = Fragment identifiers must not be used. The ''href'' attribute value ''{0}'' is not permitted. +HrefSyntacticallyInvalid = ''href'' attribute value ''{0}'' is syntactically invalid. After applying escaping rules the value is neither a syntactically correct URI or IRI. +XPointerStreamability = An xpointer was specified that points to a location in the source infoset. This location cannot be accessed due to the streaming nature of the processor. +XPointerResolutionUnsuccessful = XPointer resolution unsuccessful. + +# Messages from erroneous set-up +IncompatibleNamespaceContext = The type of the NamespaceContext is incompatible with using XInclude; it must be an instance of XIncludeNamespaceSupport +ExpandedSystemId = Could not expand system id of included resource diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XIncludeMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XIncludeMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..01e82ea2fe745b2529b324c0b9edf680165c4e0f --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XIncludeMessages_en.properties @@ -0,0 +1,56 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces XInclude implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XIncludeMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +# Messages for message reporting +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# Messages for erroneous input +NoFallback = An 'include' failed, and no 'fallback' element was found. +MultipleFallbacks = The [children] of an 'include' element cannot contain more than one 'fallback' element. +FallbackParent = A 'fallback' element was found that did not have 'include' as the parent. +IncludeChild = Elements from namespace ''http://www.w3.org/2001/XInclude'', other than ''fallback'', are not allowed to be children of ''include'' elements. However, ''{0}'' was found. +FallbackChild = Elements from namespace ''http://www.w3.org/2001/XInclude'', other than ''include'', are not allowed to be children of ''fallback'' elements. However, ''{0}'' was found. +HrefMissing = The 'href' attribute of an 'include' element is missing. +RecursiveInclude = Recursive include detected. Document ''{0}'' was already processed. +InvalidParseValue = Invalid value for ''parse'' attribute on ''include'' element: ''{0}''. +XMLParseError = Error attempting to parse XML file (href=''{0}''). +XMLResourceError = Include operation failed, reverting to fallback. Resource error reading file as XML (href=''{0}''). Reason: {1} +TextResourceError = Include operation failed, reverting to fallback. Resource error reading file as text (href=''{0}''). Reason: {1} +NonDuplicateNotation = Multiple notations were used which had the name ''{0}'', but which were not determined to be duplicates. +NonDuplicateUnparsedEntity = Multiple unparsed entities were used which had the name ''{0}'', but which were not determined to be duplicates. +XpointerMissing = xpointer attribute must be present when href attribute is absent. +AcceptMalformed = Characters outside the range #x20 through #x7E are not allowed in the value of the 'accept' attribute of an 'include' element. +AcceptLanguageMalformed = Characters outside the range #x20 through #x7E are not allowed in the value of the 'accept-language' attribute of an 'include' element. +RootElementRequired = A well-formed document requires a root element. +MultipleRootElements = A well-formed document must not contain multiple root elements. +ContentIllegalAtTopLevel = The replacement of an 'include' element appearing as the document element in the top-level source infoset cannot contain characters. +UnexpandedEntityReferenceIllegal = The replacement of an 'include' element appearing as the document element in the top-level source infoset cannot contain unexpanded entity references. +HrefFragmentIdentifierIllegal = Fragment identifiers must not be used. The ''href'' attribute value ''{0}'' is not permitted. +HrefSyntacticallyInvalid = ''href'' attribute value ''{0}'' is syntactically invalid. After applying escaping rules the value is neither a syntactically correct URI or IRI. +XPointerStreamability = An xpointer was specified that points to a location in the source infoset. This location cannot be accessed due to the streaming nature of the processor. +XPointerResolutionUnsuccessful = XPointer resolution unsuccessful. + +# Messages from erroneous set-up +IncompatibleNamespaceContext = The type of the NamespaceContext is incompatible with using XInclude; it must be an instance of XIncludeNamespaceSupport +ExpandedSystemId = Could not expand system id of included resource diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessageFormatter.class b/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..a266effa07b4c9146cf9f60d71f970daa81b0a27 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..47e42141a2c5cc7038dde7fd28697454eb71ebfa --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessages.properties @@ -0,0 +1,309 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file contains error and warning messages related to XML +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XMLMessages.properties 595214 2007-11-15 05:32:38Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + +# Document messages + PrematureEOF=Premature end of file. +# 2.1 Well-Formed XML Documents + RootElementRequired = The root element is required in a well-formed document. +# 2.2 Characters + InvalidCharInCDSect = An invalid XML character (Unicode: 0x{0}) was found in the CDATA section. + InvalidCharInContent = An invalid XML character (Unicode: 0x{0}) was found in the element content of the document. + TwoColonsInQName = An invalid second ':' was found in the element type or attribute name. + ColonNotLegalWithNS = A colon is not allowed in the name ''{0}'' when namespaces are enabled. + InvalidCharInMisc = An invalid XML character (Unicode: 0x{0}) was found in markup after the end of the element content. + InvalidCharInProlog = An invalid XML character (Unicode: 0x{0}) was found in the prolog of the document. + InvalidCharInXMLDecl = An invalid XML character (Unicode: 0x{0}) was found in the XML declaration. +# 2.4 Character Data and Markup + CDEndInContent = The character sequence \"]]>\" must not appear in content unless used to mark the end of a CDATA section. +# 2.7 CDATA Sections + CDSectUnterminated = The CDATA section must end with \"]]>\". +# 2.8 Prolog and Document Type Declaration + XMLDeclMustBeFirst = The XML declaration may only appear at the very beginning of the document. + EqRequiredInXMLDecl = The '' = '' character must follow \"{0}\" in the XML declaration. + QuoteRequiredInXMLDecl = The value following \"{0}\" in the XML declaration must be a quoted string. + XMLDeclUnterminated = The XML declaration must end with \"?>\". + VersionInfoRequired = The version is required in the XML declaration. + SpaceRequiredBeforeVersionInXMLDecl = White space is required before the version pseudo attribute in the XML declaration. + SpaceRequiredBeforeEncodingInXMLDecl = White space is required before the encoding pseudo attribute in the XML declaration. + SpaceRequiredBeforeStandalone = White space is required before the encoding pseudo attribute in the XML declaration. + MarkupNotRecognizedInProlog = The markup in the document preceding the root element must be well-formed. + MarkupNotRecognizedInMisc = The markup in the document following the root element must be well-formed. + AlreadySeenDoctype = Already seen doctype. + DoctypeNotAllowed = DOCTYPE is disallowed when the feature "http://apache.org/xml/features/disallow-doctype-decl" set to true. + ContentIllegalInProlog = Content is not allowed in prolog. + ReferenceIllegalInProlog = Reference is not allowed in prolog. +# Trailing Misc + ContentIllegalInTrailingMisc=Content is not allowed in trailing section. + ReferenceIllegalInTrailingMisc=Reference is not allowed in trailing section. + +# 2.9 Standalone Document Declaration + SDDeclInvalid = The standalone document declaration value must be \"yes\" or \"no\", not \"{0}\". +# 2.12 Language Identification + XMLLangInvalid = The xml:lang attribute value \"{0}\" is an invalid language identifier. +# 3. Logical Structures + ETagRequired = The element type \"{0}\" must be terminated by the matching end-tag \"</{0}>\". +# 3.1 Start-Tags, End-Tags, and Empty-Element Tags + ElementUnterminated = Element type \"{0}\" must be followed by either attribute specifications, \">\" or \"/>\". + EqRequiredInAttribute = Attribute name \"{1}\" associated with an element type \"{0}\" must be followed by the '' = '' character. + OpenQuoteExpected = Open quote is expected for attribute \"{1}\" associated with an element type \"{0}\". + CloseQuoteExpected = Close quote is expected for attribute \"{1}\" associated with an element type \"{0}\". + AttributeNotUnique = Attribute \"{1}\" was already specified for element \"{0}\". + AttributeNSNotUnique = Attribute \"{1}\" bound to namespace \"{2}\" was already specified for element \"{0}\". + ETagUnterminated = The end-tag for element type \"{0}\" must end with a ''>'' delimiter. + MarkupNotRecognizedInContent = The content of elements must consist of well-formed character data or markup. + DoctypeIllegalInContent = A DOCTYPE is not allowed in content. +# 4.1 Character and Entity References + ReferenceUnterminated = The reference must be terminated by a ';' delimiter. +# 4.3.2 Well-Formed Parsed Entities + ReferenceNotInOneEntity = The reference must be entirely contained within the same parsed entity. + ElementEntityMismatch = The element \"{0}\" must start and end within the same entity. + MarkupEntityMismatch=XML document structures must start and end within the same entity. + +# Messages common to Document and DTD +# 2.2 Characters + InvalidCharInAttValue = An invalid XML character (Unicode: 0x{2}) was found in the value of attribute \"{1}\" and element is \"{0}\". + InvalidCharInComment = An invalid XML character (Unicode: 0x{0}) was found in the comment. + InvalidCharInPI = An invalid XML character (Unicode: 0x{0}) was found in the processing instruction. + InvalidCharInInternalSubset = An invalid XML character (Unicode: 0x{0}) was found in the internal subset of the DTD. + InvalidCharInTextDecl = An invalid XML character (Unicode: 0x{0}) was found in the text declaration. +# 2.3 Common Syntactic Constructs + QuoteRequiredInAttValue = The value of attribute \"{1}\" must begin with either a single or double quote character. + LessthanInAttValue = The value of attribute \"{1}\" associated with an element type \"{0}\" must not contain the ''<'' character. + AttributeValueUnterminated = The value for attribute \"{1}\" must end with the matching quote character. +# 2.5 Comments + InvalidCommentStart = Comment must start with \"<!--\". + DashDashInComment = The string \"--\" is not permitted within comments. + CommentUnterminated = The comment must end with \"-->\". + COMMENT_NOT_IN_ONE_ENTITY = The comment is not enclosed in the same entity. +# 2.6 Processing Instructions + PITargetRequired = The processing instruction must begin with the name of the target. + SpaceRequiredInPI = White space is required between the processing instruction target and data. + PIUnterminated = The processing instruction must end with \"?>\". + ReservedPITarget = The processing instruction target matching \"[xX][mM][lL]\" is not allowed. + PI_NOT_IN_ONE_ENTITY = The processing instruction is not enclosed in the same entity. +# 2.8 Prolog and Document Type Declaration + VersionInfoInvalid = Invalid version \"{0}\". + VersionNotSupported = XML version \"{0}\" is not supported, only XML 1.0 is supported. + VersionNotSupported11 = XML version \"{0}\" is not supported, only XML 1.0 and XML 1.1 are supported. +# 4.1 Character and Entity References + DigitRequiredInCharRef = A decimal representation must immediately follow the \"&#\" in a character reference. + HexdigitRequiredInCharRef = A hexadecimal representation must immediately follow the \"&#x\" in a character reference. + SemicolonRequiredInCharRef = The character reference must end with the ';' delimiter. + InvalidCharRef = Character reference \"&#{0}\" is an invalid XML character. + NameRequiredInReference = The entity name must immediately follow the '&' in the entity reference. + SemicolonRequiredInReference = The reference to entity \"{0}\" must end with the '';'' delimiter. +# 4.3.1 The Text Declaration + TextDeclMustBeFirst = The text declaration may only appear at the very beginning of the external parsed entity. + EqRequiredInTextDecl = The '' = '' character must follow \"{0}\" in the text declaration. + QuoteRequiredInTextDecl = The value following \"{0}\" in the text declaration must be a quoted string. + CloseQuoteMissingInTextDecl = closing quote in the value following \"{0}\" in the text declaration is missing. + SpaceRequiredBeforeVersionInTextDecl = White space is required before the version pseudo attribute in the text declaration. + SpaceRequiredBeforeEncodingInTextDecl = White space is required before the encoding pseudo attribute in the text declaration. + TextDeclUnterminated = The text declaration must end with \"?>\". + EncodingDeclRequired = The encoding declaration is required in the text declaration. + NoMorePseudoAttributes = No more pseudo attributes are allowed. + MorePseudoAttributes = More pseudo attributes are expected. + PseudoAttrNameExpected = A pseudo attribute name is expected. +# 4.3.2 Well-Formed Parsed Entities + CommentNotInOneEntity = The comment must be entirely contained within the same parsed entity. + PINotInOneEntity = The processing instruction must be entirely contained within the same parsed entity. +# 4.3.3 Character Encoding in Entities + EncodingDeclInvalid = Invalid encoding name \"{0}\". + EncodingByteOrderUnsupported = Given byte order for encoding \"{0}\" is not supported. + InvalidByte = Invalid byte {0} of {1}-byte UTF-8 sequence. + ExpectedByte = Expected byte {0} of {1}-byte UTF-8 sequence. + InvalidHighSurrogate = High surrogate bits in UTF-8 sequence must not exceed 0x10 but found 0x{0}. + OperationNotSupported = Operation \"{0}\" not supported by {1} reader. + InvalidASCII = Byte \"{0}\" is not a member of the (7-bit) ASCII character set. + CharConversionFailure = An entity determined to be in a certain encoding must not contain sequences illegal in that encoding. + +# DTD Messages +# 2.2 Characters + InvalidCharInEntityValue = An invalid XML character (Unicode: 0x{0}) was found in the literal entity value. + InvalidCharInExternalSubset = An invalid XML character (Unicode: 0x{0}) was found in the external subset of the DTD. + InvalidCharInIgnoreSect = An invalid XML character (Unicode: 0x{0}) was found in the excluded conditional section. + InvalidCharInPublicID = An invalid XML character (Unicode: 0x{0}) was found in the public identifier. + InvalidCharInSystemID = An invalid XML character (Unicode: 0x{0}) was found in the system identifier. +# 2.3 Common Syntactic Constructs + SpaceRequiredAfterSYSTEM = White space is required after keyword SYSTEM in DOCTYPE decl. + QuoteRequiredInSystemID = The system identifier must begin with either a single or double quote character. + SystemIDUnterminated = The system identifier must end with the matching quote character. + SpaceRequiredAfterPUBLIC = White spaces are required after keyword PUBLIC in DOCTYPE decl. + QuoteRequiredInPublicID = The public identifier must begin with either a single or double quote character. + PublicIDUnterminated = The public identifier must end with the matching quote character. + PubidCharIllegal = The character (Unicode: 0x{0}) is not permitted in the public identifier. + SpaceRequiredBetweenPublicAndSystem = White spaces are required between publicId and systemId. +# 2.8 Prolog and Document Type Declaration + MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = White space is required after \"<!DOCTYPE\" in the document type declaration. + MSG_ROOT_ELEMENT_TYPE_REQUIRED = The root element type must appear after \"<!DOCTYPE\" in the document type declaration. + DoctypedeclUnterminated = The document type declaration for root element type \"{0}\" must end with ''>''. + PEReferenceWithinMarkup = The parameter entity reference \"%{0};\" cannot occur within markup in the internal subset of the DTD. + MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = The markup declarations contained or pointed to by the document type declaration must be well-formed. +# 2.10 White Space Handling + MSG_XML_SPACE_DECLARATION_ILLEGAL = The attribute declaration for \"xml:space\" must be given as an enumerated type whose only possible values are \"default\" and \"preserve\". +# 3.2 Element Type Declarations + MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL = White space is required after \"<!ELEMENT\" in the element type declaration. + MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL = The element type is required in the element type declaration. + MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL = White space is required after the element type \"{0}\" in the element type declaration. + MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL = The constraint is required after the element type \"{0}\" in the element type declaration. + ElementDeclUnterminated = The declaration for element type \"{0}\" must end with ''>''. +# 3.2.1 Element Content + MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN = A ''('' character or an element type is required in the declaration of element type \"{0}\". + MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN = A '')'' is required in the declaration of element type \"{0}\". +# 3.2.2 Mixed Content + MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT = An element type is required in the declaration of element type \"{0}\". + MSG_CLOSE_PAREN_REQUIRED_IN_MIXED = A '')'' is required in the declaration of element type \"{0}\". + MixedContentUnterminated = The mixed content model \"{0}\" must end with \")*\" when the types of child elements are constrained. +# 3.3 Attribute-List Declarations + MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL = White space is required after \"<!ATTLIST\" in the attribute-list declaration. + MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL = The element type is required in the attribute-list declaration. + MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF = White space is required before the attribute name in the attribute-list declaration for element \"{0}\". + AttNameRequiredInAttDef = The attribute name must be specified in the attribute-list declaration for element \"{0}\". + MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF = White space is required before the attribute type in the declaration of attribute \"{1}\" for element \"{0}\". + AttTypeRequiredInAttDef = The attribute type is required in the declaration of attribute \"{1}\" for element \"{0}\". + MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF = White space is required before the attribute default in the declaration of attribute \"{1}\" for element \"{0}\". + MSG_DUPLICATE_ATTRIBUTE_DEFINITION = More than one attribute definition is provided for the same attribute \"{1}\" of a given element \"{0}\". +# 3.3.1 Attribute Types + MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE = White space must appear after \"NOTATION\" in the \"{1}\" attribute declaration. + MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE = The ''('' character must follow \"NOTATION\" in the \"{1}\" attribute declaration. + MSG_NAME_REQUIRED_IN_NOTATIONTYPE = The notation name is required in the notation type list for the \"{1}\" attribute declaration. + NotationTypeUnterminated = The notation type list must end with '')'' in the \"{1}\" attribute declaration. + MSG_NMTOKEN_REQUIRED_IN_ENUMERATION = The name token is required in the enumerated type list for the \"{1}\" attribute declaration. + EnumerationUnterminated = The enumerated type list must end with '')'' in the \"{1}\" attribute declaration. + MSG_DISTINCT_TOKENS_IN_ENUMERATION = The enumeration value \"{1}\" was specified more than once in the declaration of attribute \"{2}\" for element \"{0}\". The NMTOKENS in a single Enumeration attribute declaration must all be distinct. + MSG_DISTINCT_NOTATION_IN_ENUMERATION = The enumeration value \"{1}\" was specified more than once in the declaration of attribute \"{2}\" for element \"{0}\". The NOTATION names in a single NotationType attribute declaration must all be distinct. +# 3.3.2 Attribute Defaults + MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL = White space must appear after \"FIXED\" in the \"{1}\" attribute declaration. +# 3.4 Conditional Sections + IncludeSectUnterminated = The included conditional section must end with \"]]>\". + IgnoreSectUnterminated = The excluded conditional section must end with \"]]>\". +# 4.1 Character and Entity References + NameRequiredInPEReference = The entity name must immediately follow the '%' in the parameter entity reference. + SemicolonRequiredInPEReference = The parameter entity reference \"%{0};\" must end with the '';'' delimiter. +# 4.2 Entity Declarations + MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL = White space is required after \"<!ENTITY\" in the entity declaration. + MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL = White space is required between \"<!ENTITY\" and the '%' character in the parameter entity declaration. + MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL = White space is required between the '%' and the entity name in the parameter entity declaration. + MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL = The name of the entity is required in the entity declaration. + MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL = White space is required between the entity name \"{0}\" and the definition in the entity declaration. + MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL = White space is required between \"NDATA\" and the notation name in the declaration for the entity \"{0}\". + MSG_SPACE_REQUIRED_BEFORE_NDATA_IN_UNPARSED_ENTITYDECL = White space is required before \"NDATA\" in the declaration for the entity \"{0}\". + MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL = The notation name is required after \"NDATA\" in the declaration for the entity \"{0}\". + EntityDeclUnterminated = The declaration for the entity \"{0}\" must end with ''>''. + MSG_DUPLICATE_ENTITY_DEFINITION = Entity \"{0}\" is declared more than once. +# 4.2.2 External Entities + ExternalIDRequired = The external entity declaration must begin with either \"SYSTEM\" or \"PUBLIC\". + MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID = White space is required between \"PUBLIC\" and the public identifier. + MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID = White space is required between the public identifier and the system identifier. + MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID = White space is required between \"SYSTEM\" and the system identifier. + MSG_URI_FRAGMENT_IN_SYSTEMID = The fragment identifier should not be specified as part of the system identifier \"{0}\". +# 4.7 Notation Declarations + MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL = White space is required after \"<!NOTATION\" in the notation declaration. + MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL = The name of the notation is required in the notation declaration. + MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL = White space is required after the notation name \"{0}\" in the notation declaration. + ExternalIDorPublicIDRequired = The declaration for the notation \"{0}\" must include a system or public identifier. + NotationDeclUnterminated = The declaration for the notation \"{0}\" must end with ''>''. + +# Validation messages + DuplicateTypeInMixedContent = The element type \"{1}\" was already specified in the content model of the element decl \"{0}\". + ENTITIESInvalid = Attribute value \"{1}\" of type ENTITIES must be the names of one or more unparsed entities. + ENTITYInvalid = Attribute value \"{1}\" of type ENTITY must be the name of an unparsed entity. + IDDefaultTypeInvalid = The ID attribute \"{0}\" must have a declared default of \"#IMPLIED\" or \"#REQUIRED\". + IDInvalid = Attribute value \"{0}\" of type ID must be a name. + IDInvalidWithNamespaces = Attribute value \"{0}\" of type ID must be an NCName when namespaces are enabled. + IDNotUnique = Attribute value \"{0}\" of type ID must be unique within the document. + IDREFInvalid = Attribute value \"{0}\" of type IDREF must be a name. + IDREFInvalidWithNamespaces = Attribute value \"{0}\" of type IDREF must be an NCName when namespaces are enabled. + IDREFSInvalid = Attribute value \"{0}\" of type IDREFS must be one or more names. + ILL_FORMED_PARAMETER_ENTITY_WHEN_USED_IN_DECL = The replacement text of parameter entity \"{0}\" must include properly nested declarations when the entity reference is used as a complete declaration. + ImproperDeclarationNesting = The replacement text of parameter entity \"{0}\" must include properly nested declarations. + ImproperGroupNesting = The replacement text of parameter entity \"{0}\" must include properly nested pairs of parentheses. + INVALID_PE_IN_CONDITIONAL = The replacement text of parameter entity \"{0}\" must include the entire conditional section or just INCLUDE or IGNORE. + MSG_ATTRIBUTE_NOT_DECLARED = Attribute \"{1}\" must be declared for element type \"{0}\". + MSG_ATTRIBUTE_VALUE_NOT_IN_LIST = Attribute \"{0}\" with value \"{1}\" must have a value from the list \"{2}\". + MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE = The value \"{1}\" of attribute \"{0}\" must not be changed by normalization (to \"{2}\") in a standalone document. + MSG_CONTENT_INCOMPLETE = The content of element type \"{0}\" is incomplete, it must match \"{1}\". + MSG_CONTENT_INVALID = The content of element type \"{0}\" must match \"{1}\". + MSG_CONTENT_INVALID_SPECIFIED = The content of element type \"{0}\" must match \"{1}\". Children of type \"{2}\" are not allowed. + MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED = Attribute \"{1}\" for element type \"{0}\" has a default value and must be specified in a standalone document. + MSG_DUPLICATE_ATTDEF = Attribute \"{1}\" is already declared for element type \"{0}\". + MSG_ELEMENT_ALREADY_DECLARED = Element type \"{0}\" must not be declared more than once. + MSG_ELEMENT_NOT_DECLARED = Element type \"{0}\" must be declared. + MSG_GRAMMAR_NOT_FOUND = Document is invalid: no grammar found. + MSG_ELEMENT_WITH_ID_REQUIRED = An element with the identifier \"{0}\" must appear in the document. + MSG_EXTERNAL_ENTITY_NOT_PERMITTED = The reference to external entity \"{0}\" is not permitted in a standalone document. + MSG_FIXED_ATTVALUE_INVALID = Attribute \"{1}\" with value \"{2}\" must have a value of \"{3}\". + MSG_MORE_THAN_ONE_ID_ATTRIBUTE = Element type \"{0}\" already has attribute \"{1}\" of type ID, a second attribute \"{2}\" of type ID is not permitted. + MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE = Element type \"{0}\" already has attribute \"{1}\" of type NOTATION, a second attribute \"{2}\" of type NOTATION is not permitted. + MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE = The notation \"{1}\" must be declared when referenced in the notation type list for attribute \"{0}\". + MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL = The notation \"{1}\" must be declared when referenced in the unparsed entity declaration for \"{0}\". + MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE = The reference to entity \"{0}\" declared in the external subset of the DTD or in a parameter entity is not permitted in a standalone document. + MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED = Attribute \"{1}\" is required and must be specified for element type \"{0}\". + MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE = In a standalone document white space must not occur between elements with element content which are declared in the external subset of the DTD or in a parameter entity. + NMTOKENInvalid = Attribute value \"{0}\" of type NMTOKEN must be a name token. + NMTOKENSInvalid = Attribute value \"{0}\" of type NMTOKENS must be one or more name tokens. + NoNotationOnEmptyElement = Element type \"{0}\" which was declared EMPTY cannot declare attribute \"{1}\" of type NOTATION. + RootElementTypeMustMatchDoctypedecl = Document root element \"{1}\", must match DOCTYPE root \"{0}\". + UndeclaredElementInContentSpec = The content model of element \"{0}\" refers to the undeclared element \"{1}\". + UniqueNotationName = The declaration for the notation \"{0}\" is not unique. A given Name must not be declared in more than one notation declaration. + ENTITYFailedInitializeGrammar = ENTITYDatatype Validator: Failed Need to call initialize method with a valid Grammar reference. + ENTITYNotUnparsed = ENTITY \"{0}\" is not unparsed. + ENTITYNotValid = ENTITY \"{0}\" is not valid. + EmptyList = Value of type ENTITIES, IDREFS, and NMTOKENS cannot be empty list. + +# Entity related messages +# 3.1 Start-Tags, End-Tags, and Empty-Element Tags + ReferenceToExternalEntity = The external entity reference \"&{0};\" is not permitted in an attribute value. +# 4.1 Character and Entity References + EntityNotDeclared = The entity \"{0}\" was referenced, but not declared. + ReferenceToUnparsedEntity = The unparsed entity reference \"&{0};\" is not permitted. + RecursiveReference = Recursive entity reference \"{0}\". (Reference path: {1}), + RecursiveGeneralReference = Recursive general entity reference \"&{0};\". (Reference path: {1}), + RecursivePEReference = Recursive parameter entity reference \"%{0};\". (Reference path: {1}), +# 4.3.3 Character Encoding in Entities + EncodingNotSupported = The encoding \"{0}\" is not supported. + EncodingRequired = A parsed entity not encoded in either UTF-8 or UTF-16 must contain an encoding declaration. + +# Namespaces support +# 4. Using Qualified Names + IllegalQName = Element or attribute do not match QName production: QName::=(NCName':')?NCName. + ElementXMLNSPrefix = Element \"{0}\" cannot have \"xmlns\" as its prefix. + ElementPrefixUnbound = The prefix \"{0}\" for element \"{1}\" is not bound. + AttributePrefixUnbound = The prefix \"{2}\" for attribute \"{1}\" associated with an element type \"{0}\" is not bound. + EmptyPrefixedAttName = The value of the attribute \"{0}\" is invalid. Prefixed namespace bindings may not be empty. + PrefixDeclared = The namespace prefix \"{0}\" was not declared. + CantBindXMLNS = The prefix "xmlns" cannot be bound to any namespace explicitly; neither can the namespace for "xmlns" be bound to any prefix explicitly. + CantBindXML = The prefix "xml" cannot be bound to any namespace other than its usual namespace; neither can the namespace for "xml" be bound to any prefix other than "xml". + MSG_ATT_DEFAULT_INVALID = The defaultValue \"{1}\" of attribute \"{0}\" is not legal as for the lexical constraints of this attribute type. + +# REVISIT: These need messages + MSG_SPACE_REQUIRED_AFTER_SYSTEMLITERAL_IN_EXTERNALID=MSG_SPACE_REQUIRED_AFTER_SYSTEMLITERAL_IN_EXTERNALID + OpenQuoteMissingInDecl=OpenQuoteMissingInDecl + InvalidCharInLiteral=InvalidCharInLiteral + + +#Application can set the limit of number of entities that should be expanded by the parser. +EntityExpansionLimitExceeded=The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the application. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..47e42141a2c5cc7038dde7fd28697454eb71ebfa --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XMLMessages_en.properties @@ -0,0 +1,309 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file contains error and warning messages related to XML +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XMLMessages.properties 595214 2007-11-15 05:32:38Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + +# Document messages + PrematureEOF=Premature end of file. +# 2.1 Well-Formed XML Documents + RootElementRequired = The root element is required in a well-formed document. +# 2.2 Characters + InvalidCharInCDSect = An invalid XML character (Unicode: 0x{0}) was found in the CDATA section. + InvalidCharInContent = An invalid XML character (Unicode: 0x{0}) was found in the element content of the document. + TwoColonsInQName = An invalid second ':' was found in the element type or attribute name. + ColonNotLegalWithNS = A colon is not allowed in the name ''{0}'' when namespaces are enabled. + InvalidCharInMisc = An invalid XML character (Unicode: 0x{0}) was found in markup after the end of the element content. + InvalidCharInProlog = An invalid XML character (Unicode: 0x{0}) was found in the prolog of the document. + InvalidCharInXMLDecl = An invalid XML character (Unicode: 0x{0}) was found in the XML declaration. +# 2.4 Character Data and Markup + CDEndInContent = The character sequence \"]]>\" must not appear in content unless used to mark the end of a CDATA section. +# 2.7 CDATA Sections + CDSectUnterminated = The CDATA section must end with \"]]>\". +# 2.8 Prolog and Document Type Declaration + XMLDeclMustBeFirst = The XML declaration may only appear at the very beginning of the document. + EqRequiredInXMLDecl = The '' = '' character must follow \"{0}\" in the XML declaration. + QuoteRequiredInXMLDecl = The value following \"{0}\" in the XML declaration must be a quoted string. + XMLDeclUnterminated = The XML declaration must end with \"?>\". + VersionInfoRequired = The version is required in the XML declaration. + SpaceRequiredBeforeVersionInXMLDecl = White space is required before the version pseudo attribute in the XML declaration. + SpaceRequiredBeforeEncodingInXMLDecl = White space is required before the encoding pseudo attribute in the XML declaration. + SpaceRequiredBeforeStandalone = White space is required before the encoding pseudo attribute in the XML declaration. + MarkupNotRecognizedInProlog = The markup in the document preceding the root element must be well-formed. + MarkupNotRecognizedInMisc = The markup in the document following the root element must be well-formed. + AlreadySeenDoctype = Already seen doctype. + DoctypeNotAllowed = DOCTYPE is disallowed when the feature "http://apache.org/xml/features/disallow-doctype-decl" set to true. + ContentIllegalInProlog = Content is not allowed in prolog. + ReferenceIllegalInProlog = Reference is not allowed in prolog. +# Trailing Misc + ContentIllegalInTrailingMisc=Content is not allowed in trailing section. + ReferenceIllegalInTrailingMisc=Reference is not allowed in trailing section. + +# 2.9 Standalone Document Declaration + SDDeclInvalid = The standalone document declaration value must be \"yes\" or \"no\", not \"{0}\". +# 2.12 Language Identification + XMLLangInvalid = The xml:lang attribute value \"{0}\" is an invalid language identifier. +# 3. Logical Structures + ETagRequired = The element type \"{0}\" must be terminated by the matching end-tag \"</{0}>\". +# 3.1 Start-Tags, End-Tags, and Empty-Element Tags + ElementUnterminated = Element type \"{0}\" must be followed by either attribute specifications, \">\" or \"/>\". + EqRequiredInAttribute = Attribute name \"{1}\" associated with an element type \"{0}\" must be followed by the '' = '' character. + OpenQuoteExpected = Open quote is expected for attribute \"{1}\" associated with an element type \"{0}\". + CloseQuoteExpected = Close quote is expected for attribute \"{1}\" associated with an element type \"{0}\". + AttributeNotUnique = Attribute \"{1}\" was already specified for element \"{0}\". + AttributeNSNotUnique = Attribute \"{1}\" bound to namespace \"{2}\" was already specified for element \"{0}\". + ETagUnterminated = The end-tag for element type \"{0}\" must end with a ''>'' delimiter. + MarkupNotRecognizedInContent = The content of elements must consist of well-formed character data or markup. + DoctypeIllegalInContent = A DOCTYPE is not allowed in content. +# 4.1 Character and Entity References + ReferenceUnterminated = The reference must be terminated by a ';' delimiter. +# 4.3.2 Well-Formed Parsed Entities + ReferenceNotInOneEntity = The reference must be entirely contained within the same parsed entity. + ElementEntityMismatch = The element \"{0}\" must start and end within the same entity. + MarkupEntityMismatch=XML document structures must start and end within the same entity. + +# Messages common to Document and DTD +# 2.2 Characters + InvalidCharInAttValue = An invalid XML character (Unicode: 0x{2}) was found in the value of attribute \"{1}\" and element is \"{0}\". + InvalidCharInComment = An invalid XML character (Unicode: 0x{0}) was found in the comment. + InvalidCharInPI = An invalid XML character (Unicode: 0x{0}) was found in the processing instruction. + InvalidCharInInternalSubset = An invalid XML character (Unicode: 0x{0}) was found in the internal subset of the DTD. + InvalidCharInTextDecl = An invalid XML character (Unicode: 0x{0}) was found in the text declaration. +# 2.3 Common Syntactic Constructs + QuoteRequiredInAttValue = The value of attribute \"{1}\" must begin with either a single or double quote character. + LessthanInAttValue = The value of attribute \"{1}\" associated with an element type \"{0}\" must not contain the ''<'' character. + AttributeValueUnterminated = The value for attribute \"{1}\" must end with the matching quote character. +# 2.5 Comments + InvalidCommentStart = Comment must start with \"<!--\". + DashDashInComment = The string \"--\" is not permitted within comments. + CommentUnterminated = The comment must end with \"-->\". + COMMENT_NOT_IN_ONE_ENTITY = The comment is not enclosed in the same entity. +# 2.6 Processing Instructions + PITargetRequired = The processing instruction must begin with the name of the target. + SpaceRequiredInPI = White space is required between the processing instruction target and data. + PIUnterminated = The processing instruction must end with \"?>\". + ReservedPITarget = The processing instruction target matching \"[xX][mM][lL]\" is not allowed. + PI_NOT_IN_ONE_ENTITY = The processing instruction is not enclosed in the same entity. +# 2.8 Prolog and Document Type Declaration + VersionInfoInvalid = Invalid version \"{0}\". + VersionNotSupported = XML version \"{0}\" is not supported, only XML 1.0 is supported. + VersionNotSupported11 = XML version \"{0}\" is not supported, only XML 1.0 and XML 1.1 are supported. +# 4.1 Character and Entity References + DigitRequiredInCharRef = A decimal representation must immediately follow the \"&#\" in a character reference. + HexdigitRequiredInCharRef = A hexadecimal representation must immediately follow the \"&#x\" in a character reference. + SemicolonRequiredInCharRef = The character reference must end with the ';' delimiter. + InvalidCharRef = Character reference \"&#{0}\" is an invalid XML character. + NameRequiredInReference = The entity name must immediately follow the '&' in the entity reference. + SemicolonRequiredInReference = The reference to entity \"{0}\" must end with the '';'' delimiter. +# 4.3.1 The Text Declaration + TextDeclMustBeFirst = The text declaration may only appear at the very beginning of the external parsed entity. + EqRequiredInTextDecl = The '' = '' character must follow \"{0}\" in the text declaration. + QuoteRequiredInTextDecl = The value following \"{0}\" in the text declaration must be a quoted string. + CloseQuoteMissingInTextDecl = closing quote in the value following \"{0}\" in the text declaration is missing. + SpaceRequiredBeforeVersionInTextDecl = White space is required before the version pseudo attribute in the text declaration. + SpaceRequiredBeforeEncodingInTextDecl = White space is required before the encoding pseudo attribute in the text declaration. + TextDeclUnterminated = The text declaration must end with \"?>\". + EncodingDeclRequired = The encoding declaration is required in the text declaration. + NoMorePseudoAttributes = No more pseudo attributes are allowed. + MorePseudoAttributes = More pseudo attributes are expected. + PseudoAttrNameExpected = A pseudo attribute name is expected. +# 4.3.2 Well-Formed Parsed Entities + CommentNotInOneEntity = The comment must be entirely contained within the same parsed entity. + PINotInOneEntity = The processing instruction must be entirely contained within the same parsed entity. +# 4.3.3 Character Encoding in Entities + EncodingDeclInvalid = Invalid encoding name \"{0}\". + EncodingByteOrderUnsupported = Given byte order for encoding \"{0}\" is not supported. + InvalidByte = Invalid byte {0} of {1}-byte UTF-8 sequence. + ExpectedByte = Expected byte {0} of {1}-byte UTF-8 sequence. + InvalidHighSurrogate = High surrogate bits in UTF-8 sequence must not exceed 0x10 but found 0x{0}. + OperationNotSupported = Operation \"{0}\" not supported by {1} reader. + InvalidASCII = Byte \"{0}\" is not a member of the (7-bit) ASCII character set. + CharConversionFailure = An entity determined to be in a certain encoding must not contain sequences illegal in that encoding. + +# DTD Messages +# 2.2 Characters + InvalidCharInEntityValue = An invalid XML character (Unicode: 0x{0}) was found in the literal entity value. + InvalidCharInExternalSubset = An invalid XML character (Unicode: 0x{0}) was found in the external subset of the DTD. + InvalidCharInIgnoreSect = An invalid XML character (Unicode: 0x{0}) was found in the excluded conditional section. + InvalidCharInPublicID = An invalid XML character (Unicode: 0x{0}) was found in the public identifier. + InvalidCharInSystemID = An invalid XML character (Unicode: 0x{0}) was found in the system identifier. +# 2.3 Common Syntactic Constructs + SpaceRequiredAfterSYSTEM = White space is required after keyword SYSTEM in DOCTYPE decl. + QuoteRequiredInSystemID = The system identifier must begin with either a single or double quote character. + SystemIDUnterminated = The system identifier must end with the matching quote character. + SpaceRequiredAfterPUBLIC = White spaces are required after keyword PUBLIC in DOCTYPE decl. + QuoteRequiredInPublicID = The public identifier must begin with either a single or double quote character. + PublicIDUnterminated = The public identifier must end with the matching quote character. + PubidCharIllegal = The character (Unicode: 0x{0}) is not permitted in the public identifier. + SpaceRequiredBetweenPublicAndSystem = White spaces are required between publicId and systemId. +# 2.8 Prolog and Document Type Declaration + MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL = White space is required after \"<!DOCTYPE\" in the document type declaration. + MSG_ROOT_ELEMENT_TYPE_REQUIRED = The root element type must appear after \"<!DOCTYPE\" in the document type declaration. + DoctypedeclUnterminated = The document type declaration for root element type \"{0}\" must end with ''>''. + PEReferenceWithinMarkup = The parameter entity reference \"%{0};\" cannot occur within markup in the internal subset of the DTD. + MSG_MARKUP_NOT_RECOGNIZED_IN_DTD = The markup declarations contained or pointed to by the document type declaration must be well-formed. +# 2.10 White Space Handling + MSG_XML_SPACE_DECLARATION_ILLEGAL = The attribute declaration for \"xml:space\" must be given as an enumerated type whose only possible values are \"default\" and \"preserve\". +# 3.2 Element Type Declarations + MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL = White space is required after \"<!ELEMENT\" in the element type declaration. + MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL = The element type is required in the element type declaration. + MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL = White space is required after the element type \"{0}\" in the element type declaration. + MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL = The constraint is required after the element type \"{0}\" in the element type declaration. + ElementDeclUnterminated = The declaration for element type \"{0}\" must end with ''>''. +# 3.2.1 Element Content + MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN = A ''('' character or an element type is required in the declaration of element type \"{0}\". + MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN = A '')'' is required in the declaration of element type \"{0}\". +# 3.2.2 Mixed Content + MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT = An element type is required in the declaration of element type \"{0}\". + MSG_CLOSE_PAREN_REQUIRED_IN_MIXED = A '')'' is required in the declaration of element type \"{0}\". + MixedContentUnterminated = The mixed content model \"{0}\" must end with \")*\" when the types of child elements are constrained. +# 3.3 Attribute-List Declarations + MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL = White space is required after \"<!ATTLIST\" in the attribute-list declaration. + MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL = The element type is required in the attribute-list declaration. + MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF = White space is required before the attribute name in the attribute-list declaration for element \"{0}\". + AttNameRequiredInAttDef = The attribute name must be specified in the attribute-list declaration for element \"{0}\". + MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF = White space is required before the attribute type in the declaration of attribute \"{1}\" for element \"{0}\". + AttTypeRequiredInAttDef = The attribute type is required in the declaration of attribute \"{1}\" for element \"{0}\". + MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF = White space is required before the attribute default in the declaration of attribute \"{1}\" for element \"{0}\". + MSG_DUPLICATE_ATTRIBUTE_DEFINITION = More than one attribute definition is provided for the same attribute \"{1}\" of a given element \"{0}\". +# 3.3.1 Attribute Types + MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE = White space must appear after \"NOTATION\" in the \"{1}\" attribute declaration. + MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE = The ''('' character must follow \"NOTATION\" in the \"{1}\" attribute declaration. + MSG_NAME_REQUIRED_IN_NOTATIONTYPE = The notation name is required in the notation type list for the \"{1}\" attribute declaration. + NotationTypeUnterminated = The notation type list must end with '')'' in the \"{1}\" attribute declaration. + MSG_NMTOKEN_REQUIRED_IN_ENUMERATION = The name token is required in the enumerated type list for the \"{1}\" attribute declaration. + EnumerationUnterminated = The enumerated type list must end with '')'' in the \"{1}\" attribute declaration. + MSG_DISTINCT_TOKENS_IN_ENUMERATION = The enumeration value \"{1}\" was specified more than once in the declaration of attribute \"{2}\" for element \"{0}\". The NMTOKENS in a single Enumeration attribute declaration must all be distinct. + MSG_DISTINCT_NOTATION_IN_ENUMERATION = The enumeration value \"{1}\" was specified more than once in the declaration of attribute \"{2}\" for element \"{0}\". The NOTATION names in a single NotationType attribute declaration must all be distinct. +# 3.3.2 Attribute Defaults + MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL = White space must appear after \"FIXED\" in the \"{1}\" attribute declaration. +# 3.4 Conditional Sections + IncludeSectUnterminated = The included conditional section must end with \"]]>\". + IgnoreSectUnterminated = The excluded conditional section must end with \"]]>\". +# 4.1 Character and Entity References + NameRequiredInPEReference = The entity name must immediately follow the '%' in the parameter entity reference. + SemicolonRequiredInPEReference = The parameter entity reference \"%{0};\" must end with the '';'' delimiter. +# 4.2 Entity Declarations + MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL = White space is required after \"<!ENTITY\" in the entity declaration. + MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL = White space is required between \"<!ENTITY\" and the '%' character in the parameter entity declaration. + MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL = White space is required between the '%' and the entity name in the parameter entity declaration. + MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL = The name of the entity is required in the entity declaration. + MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL = White space is required between the entity name \"{0}\" and the definition in the entity declaration. + MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL = White space is required between \"NDATA\" and the notation name in the declaration for the entity \"{0}\". + MSG_SPACE_REQUIRED_BEFORE_NDATA_IN_UNPARSED_ENTITYDECL = White space is required before \"NDATA\" in the declaration for the entity \"{0}\". + MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL = The notation name is required after \"NDATA\" in the declaration for the entity \"{0}\". + EntityDeclUnterminated = The declaration for the entity \"{0}\" must end with ''>''. + MSG_DUPLICATE_ENTITY_DEFINITION = Entity \"{0}\" is declared more than once. +# 4.2.2 External Entities + ExternalIDRequired = The external entity declaration must begin with either \"SYSTEM\" or \"PUBLIC\". + MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID = White space is required between \"PUBLIC\" and the public identifier. + MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID = White space is required between the public identifier and the system identifier. + MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID = White space is required between \"SYSTEM\" and the system identifier. + MSG_URI_FRAGMENT_IN_SYSTEMID = The fragment identifier should not be specified as part of the system identifier \"{0}\". +# 4.7 Notation Declarations + MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL = White space is required after \"<!NOTATION\" in the notation declaration. + MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL = The name of the notation is required in the notation declaration. + MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL = White space is required after the notation name \"{0}\" in the notation declaration. + ExternalIDorPublicIDRequired = The declaration for the notation \"{0}\" must include a system or public identifier. + NotationDeclUnterminated = The declaration for the notation \"{0}\" must end with ''>''. + +# Validation messages + DuplicateTypeInMixedContent = The element type \"{1}\" was already specified in the content model of the element decl \"{0}\". + ENTITIESInvalid = Attribute value \"{1}\" of type ENTITIES must be the names of one or more unparsed entities. + ENTITYInvalid = Attribute value \"{1}\" of type ENTITY must be the name of an unparsed entity. + IDDefaultTypeInvalid = The ID attribute \"{0}\" must have a declared default of \"#IMPLIED\" or \"#REQUIRED\". + IDInvalid = Attribute value \"{0}\" of type ID must be a name. + IDInvalidWithNamespaces = Attribute value \"{0}\" of type ID must be an NCName when namespaces are enabled. + IDNotUnique = Attribute value \"{0}\" of type ID must be unique within the document. + IDREFInvalid = Attribute value \"{0}\" of type IDREF must be a name. + IDREFInvalidWithNamespaces = Attribute value \"{0}\" of type IDREF must be an NCName when namespaces are enabled. + IDREFSInvalid = Attribute value \"{0}\" of type IDREFS must be one or more names. + ILL_FORMED_PARAMETER_ENTITY_WHEN_USED_IN_DECL = The replacement text of parameter entity \"{0}\" must include properly nested declarations when the entity reference is used as a complete declaration. + ImproperDeclarationNesting = The replacement text of parameter entity \"{0}\" must include properly nested declarations. + ImproperGroupNesting = The replacement text of parameter entity \"{0}\" must include properly nested pairs of parentheses. + INVALID_PE_IN_CONDITIONAL = The replacement text of parameter entity \"{0}\" must include the entire conditional section or just INCLUDE or IGNORE. + MSG_ATTRIBUTE_NOT_DECLARED = Attribute \"{1}\" must be declared for element type \"{0}\". + MSG_ATTRIBUTE_VALUE_NOT_IN_LIST = Attribute \"{0}\" with value \"{1}\" must have a value from the list \"{2}\". + MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE = The value \"{1}\" of attribute \"{0}\" must not be changed by normalization (to \"{2}\") in a standalone document. + MSG_CONTENT_INCOMPLETE = The content of element type \"{0}\" is incomplete, it must match \"{1}\". + MSG_CONTENT_INVALID = The content of element type \"{0}\" must match \"{1}\". + MSG_CONTENT_INVALID_SPECIFIED = The content of element type \"{0}\" must match \"{1}\". Children of type \"{2}\" are not allowed. + MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED = Attribute \"{1}\" for element type \"{0}\" has a default value and must be specified in a standalone document. + MSG_DUPLICATE_ATTDEF = Attribute \"{1}\" is already declared for element type \"{0}\". + MSG_ELEMENT_ALREADY_DECLARED = Element type \"{0}\" must not be declared more than once. + MSG_ELEMENT_NOT_DECLARED = Element type \"{0}\" must be declared. + MSG_GRAMMAR_NOT_FOUND = Document is invalid: no grammar found. + MSG_ELEMENT_WITH_ID_REQUIRED = An element with the identifier \"{0}\" must appear in the document. + MSG_EXTERNAL_ENTITY_NOT_PERMITTED = The reference to external entity \"{0}\" is not permitted in a standalone document. + MSG_FIXED_ATTVALUE_INVALID = Attribute \"{1}\" with value \"{2}\" must have a value of \"{3}\". + MSG_MORE_THAN_ONE_ID_ATTRIBUTE = Element type \"{0}\" already has attribute \"{1}\" of type ID, a second attribute \"{2}\" of type ID is not permitted. + MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE = Element type \"{0}\" already has attribute \"{1}\" of type NOTATION, a second attribute \"{2}\" of type NOTATION is not permitted. + MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE = The notation \"{1}\" must be declared when referenced in the notation type list for attribute \"{0}\". + MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL = The notation \"{1}\" must be declared when referenced in the unparsed entity declaration for \"{0}\". + MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE = The reference to entity \"{0}\" declared in the external subset of the DTD or in a parameter entity is not permitted in a standalone document. + MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED = Attribute \"{1}\" is required and must be specified for element type \"{0}\". + MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE = In a standalone document white space must not occur between elements with element content which are declared in the external subset of the DTD or in a parameter entity. + NMTOKENInvalid = Attribute value \"{0}\" of type NMTOKEN must be a name token. + NMTOKENSInvalid = Attribute value \"{0}\" of type NMTOKENS must be one or more name tokens. + NoNotationOnEmptyElement = Element type \"{0}\" which was declared EMPTY cannot declare attribute \"{1}\" of type NOTATION. + RootElementTypeMustMatchDoctypedecl = Document root element \"{1}\", must match DOCTYPE root \"{0}\". + UndeclaredElementInContentSpec = The content model of element \"{0}\" refers to the undeclared element \"{1}\". + UniqueNotationName = The declaration for the notation \"{0}\" is not unique. A given Name must not be declared in more than one notation declaration. + ENTITYFailedInitializeGrammar = ENTITYDatatype Validator: Failed Need to call initialize method with a valid Grammar reference. + ENTITYNotUnparsed = ENTITY \"{0}\" is not unparsed. + ENTITYNotValid = ENTITY \"{0}\" is not valid. + EmptyList = Value of type ENTITIES, IDREFS, and NMTOKENS cannot be empty list. + +# Entity related messages +# 3.1 Start-Tags, End-Tags, and Empty-Element Tags + ReferenceToExternalEntity = The external entity reference \"&{0};\" is not permitted in an attribute value. +# 4.1 Character and Entity References + EntityNotDeclared = The entity \"{0}\" was referenced, but not declared. + ReferenceToUnparsedEntity = The unparsed entity reference \"&{0};\" is not permitted. + RecursiveReference = Recursive entity reference \"{0}\". (Reference path: {1}), + RecursiveGeneralReference = Recursive general entity reference \"&{0};\". (Reference path: {1}), + RecursivePEReference = Recursive parameter entity reference \"%{0};\". (Reference path: {1}), +# 4.3.3 Character Encoding in Entities + EncodingNotSupported = The encoding \"{0}\" is not supported. + EncodingRequired = A parsed entity not encoded in either UTF-8 or UTF-16 must contain an encoding declaration. + +# Namespaces support +# 4. Using Qualified Names + IllegalQName = Element or attribute do not match QName production: QName::=(NCName':')?NCName. + ElementXMLNSPrefix = Element \"{0}\" cannot have \"xmlns\" as its prefix. + ElementPrefixUnbound = The prefix \"{0}\" for element \"{1}\" is not bound. + AttributePrefixUnbound = The prefix \"{2}\" for attribute \"{1}\" associated with an element type \"{0}\" is not bound. + EmptyPrefixedAttName = The value of the attribute \"{0}\" is invalid. Prefixed namespace bindings may not be empty. + PrefixDeclared = The namespace prefix \"{0}\" was not declared. + CantBindXMLNS = The prefix "xmlns" cannot be bound to any namespace explicitly; neither can the namespace for "xmlns" be bound to any prefix explicitly. + CantBindXML = The prefix "xml" cannot be bound to any namespace other than its usual namespace; neither can the namespace for "xml" be bound to any prefix other than "xml". + MSG_ATT_DEFAULT_INVALID = The defaultValue \"{1}\" of attribute \"{0}\" is not legal as for the lexical constraints of this attribute type. + +# REVISIT: These need messages + MSG_SPACE_REQUIRED_AFTER_SYSTEMLITERAL_IN_EXTERNALID=MSG_SPACE_REQUIRED_AFTER_SYSTEMLITERAL_IN_EXTERNALID + OpenQuoteMissingInDecl=OpenQuoteMissingInDecl + InvalidCharInLiteral=InvalidCharInLiteral + + +#Application can set the limit of number of entities that should be expanded by the parser. +EntityExpansionLimitExceeded=The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the application. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XMLSchemaMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSchemaMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..cd8765da056a52ba84301800ba5c031d3797c239 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSchemaMessages.properties @@ -0,0 +1,320 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file contains error and warning messages related to XML Schema +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XMLSchemaMessages.properties 806363 2009-08-20 21:18:48Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + +# For internal use + + Internal-Error = Internal error: {0}. + dt-whitespace = Whitespace facet value is not available for the union simpleType ''{0}'' + GrammarConflict = One of the grammar(s) returned from the user's grammar pool is in conflict with another grammar. + +# Identity constraints + + AbsentKeyValue = cvc-identity-constraint.4.2.1.a: Element \"{0}\" has no value for the key \"{1}\". + DuplicateField = Duplicate match in scope for field \"{0}\". + DuplicateKey = cvc-identity-constraint.4.2.2: Duplicate key value [{0}] declared for identity constraint \"{2}\" of element \"{1}\". + DuplicateUnique = cvc-identity-constraint.4.1: Duplicate unique value [{0}] declared for identity constraint \"{2}\" of element \"{1}\". + FieldMultipleMatch = cvc-identity-constraint.3: Field \"{0}\" of identity constraint \"{1}\" matches more than one value within the scope of its selector; fields must match unique values. + FixedDiffersFromActual = The content of this element is not equivalent to the value of the \"fixed\" attribute in the element's declaration in the schema. + KeyMatchesNillable = cvc-identity-constraint.4.2.3: Element \"{0}\" has the key \"{1}\" which matches an element which has nillable set to true. + KeyNotEnoughValues = cvc-identity-constraint.4.2.1.b: Not enough values specified for <key name=\"{1}\"> identity constraint specified for element \"{0}\". + KeyNotFound = cvc-identity-constraint.4.3: Key ''{0}'' with value ''{1}'' not found for identity constraint of element ''{2}''. + KeyRefOutOfScope = Identity Constraint error: identity constraint \"{0}\" has a keyref which refers to a key or unique that is out of scope. + KeyRefReferNotFound = Key reference declaration \"{0}\" refers to unknown key with name \"{1}\". + UnknownField = Internal identity constraint error; unknown field \"{0}\" for identity constraint \"{2}\" specified for element \"{1}\". + +# Ideally, we should only use the following error keys, not the ones under +# "Identity constraints". And we should cover all of the following errors. + +#validation (3.X.4) + + cvc-attribute.3 = cvc-attribute.3: The value ''{2}'' of attribute ''{1}'' on element ''{0}'' is not valid with respect to its type, ''{3}''. + cvc-attribute.4 = cvc-attribute.4: The value ''{2}'' of attribute ''{1}'' on element ''{0}'' is not valid with respect to its fixed '{'value constraint'}'. The attribute must have a value of ''{3}''. + cvc-complex-type.2.1 = cvc-complex-type.2.1: Element ''{0}'' must have no character or element information item [children], because the type''s content type is empty. + cvc-complex-type.2.2 = cvc-complex-type.2.2: Element ''{0}'' must have no element [children], and the value must be valid. + cvc-complex-type.2.3 = cvc-complex-type.2.3: Element ''{0}'' cannot have character [children], because the type''s content type is element-only. + cvc-complex-type.2.4.a = cvc-complex-type.2.4.a: Invalid content was found starting with element ''{0}''. One of ''{1}'' is expected. + cvc-complex-type.2.4.b = cvc-complex-type.2.4.b: The content of element ''{0}'' is not complete. One of ''{1}'' is expected. + cvc-complex-type.2.4.c = cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ''{0}''. + cvc-complex-type.2.4.d = cvc-complex-type.2.4.d: Invalid content was found starting with element ''{0}''. No child element is expected at this point. + cvc-complex-type.2.4.e = cvc-complex-type.2.4.e: ''{0}'' can occur a maximum of ''{2}'' times in the current sequence. This limit was exceeded. At this point one of ''{1}'' is expected. + cvc-complex-type.2.4.f = cvc-complex-type.2.4.f: ''{0}'' can occur a maximum of ''{1}'' times in the current sequence. This limit was exceeded. No child element is expected at this point. + cvc-complex-type.2.4.g = cvc-complex-type.2.4.g: Invalid content was found starting with element ''{0}''. ''{1}'' is expected to occur a minimum of ''{2}'' times in the current sequence. One more instance is required to satisfy this constraint. + cvc-complex-type.2.4.h = cvc-complex-type.2.4.h: Invalid content was found starting with element ''{0}''. ''{1}'' is expected to occur a minimum of ''{2}'' times in the current sequence. ''{3}'' more instances are required to satisfy this constraint. + cvc-complex-type.2.4.i = cvc-complex-type.2.4.i: The content of element ''{0}'' is not complete. ''{1}'' is expected to occur a minimum of ''{2}'' times. One more instance is required to satisfy this constraint. + cvc-complex-type.2.4.j = cvc-complex-type.2.4.j: The content of element ''{0}'' is not complete. ''{1}'' is expected to occur a minimum of ''{2}'' times. ''{3}'' more instances are required to satisfy this constraint. + cvc-complex-type.3.1 = cvc-complex-type.3.1: Value ''{2}'' of attribute ''{1}'' of element ''{0}'' is not valid with respect to the corresponding attribute use. Attribute ''{1}'' has a fixed value of ''{3}''. + cvc-complex-type.3.2.1 = cvc-complex-type.3.2.1: Element ''{0}'' does not have an attribute wildcard for attribute ''{1}''. + cvc-complex-type.3.2.2 = cvc-complex-type.3.2.2: Attribute ''{1}'' is not allowed to appear in element ''{0}''. + cvc-complex-type.4 = cvc-complex-type.4: Attribute ''{1}'' must appear on element ''{0}''. + cvc-complex-type.5.1 = cvc-complex-type.5.1: In element ''{0}'', attribute ''{1}'' is a Wild ID. But there is already a Wild ID ''{2}''. There can be only one. + cvc-complex-type.5.2 = cvc-complex-type.5.2: In element ''{0}'', attribute ''{1}'' is a Wild ID. But there is already an attribute ''{2}'' derived from ID among the '{'attribute uses'}'. + cvc-datatype-valid.1.2.1 = cvc-datatype-valid.1.2.1: ''{0}'' is not a valid value for ''{1}''. + cvc-datatype-valid.1.2.2 = cvc-datatype-valid.1.2.2: ''{0}'' is not a valid value of list type ''{1}''. + cvc-datatype-valid.1.2.3 = cvc-datatype-valid.1.2.3: ''{0}'' is not a valid value of union type ''{1}''. + cvc-elt.1.a = cvc-elt.1.a: Cannot find the declaration of element ''{0}''. + cvc-elt.1.b = cvc-elt.1.b: The name of the element does not match the name of the element declaration. Saw ''{0}''. Expected ''{1}''. + cvc-elt.2 = cvc-elt.2: The value of '{'abstract'}' in the element declaration for ''{0}'' must be false. + cvc-elt.3.1 = cvc-elt.3.1: Attribute ''{1}'' must not appear on element ''{0}'', because the '{'nillable'}' property of ''{0}'' is false. + cvc-elt.3.2.1 = cvc-elt.3.2.1: Element ''{0}'' cannot have character or element information [children], because ''{1}'' is specified. + cvc-elt.3.2.2 = cvc-elt.3.2.2: There must be no fixed '{'value constraint'}' for element ''{0}'', because ''{1}'' is specified. + cvc-elt.4.1 = cvc-elt.4.1: The value ''{2}'' of attribute ''{1}'' of element ''{0}'' is not a valid QName. + cvc-elt.4.2 = cvc-elt.4.2: Cannot resolve ''{1}'' to a type definition for element ''{0}''. + cvc-elt.4.3 = cvc-elt.4.3: Type ''{1}'' is not validly derived from the type definition, ''{2}'', of element ''{0}''. + cvc-elt.5.1.1 = cvc-elt.5.1.1: '{'value constraint'}' ''{2}'' of element ''{0}'' is not a valid default value for type ''{1}''. + cvc-elt.5.2.2.1 = cvc-elt.5.2.2.1: Element ''{0}'' must have no element information item [children]. + cvc-elt.5.2.2.2.1 = cvc-elt.5.2.2.2.1: The value ''{1}'' of element ''{0}'' does not match the fixed '{'value constraint'}' value ''{2}''. + cvc-elt.5.2.2.2.2 = cvc-elt.5.2.2.2.2: The value ''{1}'' of element ''{0}'' does not match the '{'value constraint'}' value ''{2}''. + cvc-enumeration-valid = cvc-enumeration-valid: Value ''{0}'' is not facet-valid with respect to enumeration ''{1}''. It must be a value from the enumeration. + cvc-fractionDigits-valid = cvc-fractionDigits-valid: Value ''{0}'' has {1} fraction digits, but the number of fraction digits has been limited to {2}. + cvc-id.1 = cvc-id.1: There is no ID/IDREF binding for IDREF ''{0}''. + cvc-id.2 = cvc-id.2: There are multiple occurrences of ID value ''{0}''. + cvc-id.3 = cvc-id.3: A field of identity constraint ''{0}'' matched element ''{1}'', but this element does not have a simple type. + cvc-length-valid = cvc-length-valid: Value ''{0}'' with length = ''{1}'' is not facet-valid with respect to length ''{2}'' for type ''{3}''. + cvc-maxExclusive-valid = cvc-maxExclusive-valid: Value ''{0}'' is not facet-valid with respect to maxExclusive ''{1}'' for type ''{2}''. + cvc-maxInclusive-valid = cvc-maxInclusive-valid: Value ''{0}'' is not facet-valid with respect to maxInclusive ''{1}'' for type ''{2}''. + cvc-maxLength-valid = cvc-maxLength-valid: Value ''{0}'' with length = ''{1}'' is not facet-valid with respect to maxLength ''{2}'' for type ''{3}''. + cvc-minExclusive-valid = cvc-minExclusive-valid: Value ''{0}'' is not facet-valid with respect to minExclusive ''{1}'' for type ''{2}''. + cvc-minInclusive-valid = cvc-minInclusive-valid: Value ''{0}'' is not facet-valid with respect to minInclusive ''{1}'' for type ''{2}''. + cvc-minLength-valid = cvc-minLength-valid: Value ''{0}'' with length = ''{1}'' is not facet-valid with respect to minLength ''{2}'' for type ''{3}''. + cvc-pattern-valid = cvc-pattern-valid: Value ''{0}'' is not facet-valid with respect to pattern ''{1}'' for type ''{2}''. + cvc-totalDigits-valid = cvc-totalDigits-valid: Value ''{0}'' has {1} total digits, but the number of total digits has been limited to {2}. + cvc-type.1 = cvc-type.1: The type definition ''{0}'' was not found. + cvc-type.2 = cvc-type.2: The type definition cannot be abstract for element {0}. + cvc-type.3.1.1 = cvc-type.3.1.1: Element ''{0}'' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to ''http://www.w3.org/2001/XMLSchema-instance'' and whose [local name] is one of ''type'', ''nil'', ''schemaLocation'' or ''noNamespaceSchemaLocation''. However, the attribute, ''{1}'' was found. + cvc-type.3.1.2 = cvc-type.3.1.2: Element ''{0}'' is a simple type, so it must have no element information item [children]. + cvc-type.3.1.3 = cvc-type.3.1.3: The value ''{1}'' of element ''{0}'' is not valid. + +#schema valid (3.X.3) + + schema_reference.4 = schema_reference.4: Failed to read schema document ''{0}'', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. + src-annotation = src-annotation: <annotation> elements can only contain <appinfo> and <documentation> elements, but ''{0}'' was found. + src-attribute.1 = src-attribute.1: The properties ''default'' and ''fixed'' cannot both be present in attribute declaration ''{0}''. Use only one of them. + src-attribute.2 = src-attribute.2: : The property ''default'' is present in attribute ''{0}'', so the value of ''use'' must be ''optional''. + src-attribute.3.1 = src-attribute.3.1: One of 'ref' or 'name' must be present in a local attribute declaration. + src-attribute.3.2 = src-attribute.3.2: The content must match (annotation?) for the attribute reference ''{0}''. + src-attribute.4 = src-attribute.4: Attribute ''{0}'' has both a ''type'' attribute and an anonymous ''simpleType'' child. Only one of these is allowed for an attribute. + src-attribute_group.2 = src-attribute_group.2: The intersection of wildcards is not expressible for attribute group ''{0}''. + src-attribute_group.3 = src-attribute_group.3: Circular definitions detected for attribute group ''{0}''. Recursively following attribute group references eventually leads back to itself. + src-ct.1 = src-ct.1: Complex Type Definition Representation Error for type ''{0}''. When <complexContent> is used, the base type must be a complexType. ''{1}'' is a simpleType. + src-ct.2.1 = src-ct.2.1: Complex Type Definition Representation Error for type ''{0}''. When <simpleContent> is used, the base type must be a complexType whose content type is simple, or, only if restriction is specified, a complex type with mixed content and emptiable particle, or, only if extension is specified, a simple type. ''{1}'' satisfies none of these conditions. + src-ct.2.2 = src-ct.2.2: Complex Type Definition Representation Error for type ''{0}''. When a complexType with simpleContent restricts a complexType with mixed content and emptiable particle, then there must be a <simpleType> among the children of <restriction>. + src-ct.4 = src-ct.4: Complex Type Definition Representation Error for type ''{0}''. The intersection of wildcards is not expressible. + src-ct.5 = src-ct.5: Complex Type Definition Representation Error for type ''{0}''. The union of wildcards is not expressible. + src-element.1 = src-element.1: The properties ''default'' and ''fixed'' cannot both be present in element declaration ''{0}''. Use only one of them. + src-element.2.1 = src-element.2.1: : One of 'ref' or 'name' must be present in a local element declaration. + src-element.2.2 = src-element.2.2: Since ''{0}'' contains the ''ref'' attribute, its content must match (annotation?). However, ''{1}'' was found. + src-element.3 = src-element.3: Element ''{0}'' has both a ''type'' attribute and a ''anonymous type'' child. Only one of these is allowed for an element. + src-import.1.1 = src-import.1.1: The namespace attribute ''{0}'' of an <import> element information item must not be the same as the targetNamespace of the schema it exists in. + src-import.1.2 = src-import.1.2: If the namespace attribute is not present on an <import> element information item then the enclosing schema must have a targetNamespace. + src-import.2 = src-import.2: The root element of document ''{0}'' has to have the namespace name ''http://www.w3.org/2001/XMLSchema'' and the local name ''schema''. + src-import.3.1 = src-import.3.1: The namespace attribute, ''{0}'', of an <import> element information item must be identical to the targetNamespace attribute, ''{1}'', of the imported document. + src-import.3.2 = src-import.3.2: An <import> element information item that had no namespace attribute was found, so the imported document cannot have a targetNamespace attribute. However, the targetNamespace ''{1}'' was found in the imported document. + src-include.1 = src-include.1: The root element of document ''{0}'' has to have the namespace name ''http://www.w3.org/2001/XMLSchema'' and the local name ''schema''. + src-include.2.1 = src-include.2.1: The targetNamespace of the referenced schema, currently ''{1}'', must be identical to that of the including schema, currently ''{0}''. + src-redefine.2 = src-redefine.2: The root element of document ''{0}'' has to have the namespace name ''http://www.w3.org/2001/XMLSchema'' and the local name ''schema''. + src-redefine.3.1 = src-redefine.3.1: The targetNamespace of the referenced schema, currently ''{1}'', must be identical to that of the redefining schema, currently ''{0}''. + src-redefine.5.a.a = src-redefine.5.a.a: No non-annotation children of <simpleType> were found. <simpleType> children of <redefine> elements must have <restriction> descendants, with 'base' attributes that refer to themselves. + src-redefine.5.a.b = src-redefine.5.a.b: ''{0}'' is not a valid child element. <simpleType> children of <redefine> elements must have <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.5.a.c = src-redefine.5.a.c: ''{0}'' does not have a ''base'' attribute that refers to the redefined element, ''{1}''. <simpleType> children of <redefine> elements must have <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.5.b.a = src-redefine.5.b.a: No non-annotation children of <complexType> were found. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with 'base' attributes that refer to themselves. + src-redefine.5.b.b = src-redefine.5.b.b: No non-annotation grandchildren of <complexType> were found. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with 'base' attributes that refer to themselves. + src-redefine.5.b.c = src-redefine.5.b.c: ''{0}'' is not a valid grandchild element. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.5.b.d = src-redefine.5.b.d: ''{0}'' does not have a ''base'' attribute that refers to the redefined element, ''{1}''. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.6.1.1 = src-redefine.6.1.1: If a group child of a <redefine> element contains a group referring itself, it must have exactly 1; this one has ''{0}''. + src-redefine.6.1.2 = src-redefine.6.1.2: The group ''{0}'', which contains a reference to a group being redefined, must have ''minOccurs'' = ''maxOccurs'' = 1. + src-redefine.6.2.1 = src-redefine.6.2.1: No group in the redefined schema has a name matching ''{0}''. + src-redefine.6.2.2 = src-redefine.6.2.2: Group ''{0}'' does not properly restrict the group it redefines; constraint violated: ''{1}''. + src-redefine.7.1 = src-redefine.7.1: If an attributeGroup child of a <redefine> element contains an attributeGroup referring itself, it must have exactly 1; this one has {0}. + src-redefine.7.2.1 = src-redefine.7.2.1: No attributeGroup in the redefined schema has a name matching ''{0}''. + src-redefine.7.2.2 = src-redefine.7.2.2: AttributeGroup ''{0}'' does not properly restrict the attributeGroup it redefines; constraint violated: ''{1}''. + src-resolve = src-resolve: Cannot resolve the name ''{0}'' to a(n) ''{1}'' component. + src-resolve.4.1 = src-resolve.4.1: Error resolving component ''{2}''. It was detected that ''{2}'' has no namespace, but components with no target namespace are not referenceable from schema document ''{0}''. If ''{2}'' is intended to have a namespace, perhaps a prefix needs to be provided. If it is intended that ''{2}'' has no namespace, then an ''import'' without a "namespace" attribute should be added to ''{0}''. + src-resolve.4.2 = src-resolve.4.2: Error resolving component ''{2}''. It was detected that ''{2}'' is in namespace ''{1}'', but components from this namespace are not referenceable from schema document ''{0}''. If this is the incorrect namespace, perhaps the prefix of ''{2}'' needs to be changed. If this is the correct namespace, then an appropriate ''import'' tag should be added to ''{0}''. + src-simple-type.2.a = src-simple-type.2.a: A <restriction> element was found that has both a base [attribute] and a <simpleType> element among its [children]. Only one is allowed. + src-simple-type.2.b = src-simple-type.2.b: A <restriction> element was found that has neither a base [attribute] nor a <simpleType> element among its [children]. One is required. + src-simple-type.3.a = src-simple-type.3.a: A <list> element was found that has both an itemType [attribute] and a <simpleType> element among its [children]. Only one is allowed. + src-simple-type.3.b = src-simple-type.3.b: A <list> element was found that has neither an itemType [attribute] nor a <simpleType> element among its [children]. One is required. + src-single-facet-value = src-single-facet-value: The facet ''{0}'' is defined more than once. + src-union-memberTypes-or-simpleTypes = src-union-memberTypes-or-simpleTypes: A <union> element must have either a non-empty memberTypes [attribute] or at least one <simpleType> element among its [children]. + +#constraint valid (3.X.6) + + ag-props-correct.2 = ag-props-correct.2: Error for attribute group ''{0}''. Duplicate attribute uses with the same name and target namespace are specified. Name of duplicate attribute use is ''{1}''. + ag-props-correct.3 = ag-props-correct.3: Error for attribute group ''{0}''. Two attribute declarations, ''{1}'' and ''{2}'' have types which are derived from ID. + a-props-correct.2 = a-props-correct.2: Invalid value constraint value ''{1}'' in attribute ''{0}''. + a-props-correct.3 = a-props-correct.3: Attribute ''{0}'' cannot use ''fixed'' or ''default'', because the attribute''s '{'type definition'}' is ID, or is derived from ID. + au-props-correct.2 = au-props-correct.2: In the attribute declaration of ''{0}'', a fixed value of ''{1}'' was specified. So if the attribute use referring to ''{0}'' also has a '{'value constraint'}', it must be fixed and its value must be ''{1}''. + cos-all-limited.1.2 = cos-all-limited.1.2: An 'all' model group must appear in a particle with '{'min occurs'}' = '{'max occurs'}' = 1, and that particle must be part of a pair which constitutes the '{'content type'}' of a complex type definition. + cos-all-limited.2 = cos-all-limited.2: The '{'max occurs'}' of an element in an ''all'' model group must be 0 or 1. The value ''{0}'' for element ''{1}'' is invalid. + cos-applicable-facets = cos-applicable-facets: Facet ''{0}'' is not allowed by type {1}. + cos-ct-extends.1.1 = cos-ct-extends.1.1: Type ''{0}'' was derived by extension from type ''{1}''. However, the ''final'' attribute of ''{1}'' forbids derivation by extension. + cos-ct-extends.1.4.3.2.2.1.a = cos-ct-extends.1.4.3.2.2.1.a: The content type of a derived type and that of its base must both be mixed or both be element-only. Type ''{0}'' is element only, but its base type is not. + cos-ct-extends.1.4.3.2.2.1.b = cos-ct-extends.1.4.3.2.2.1.b: The content type of a derived type and that of its base must both be mixed or both be element-only. Type ''{0}'' is mixed, but its base type is not. + cos-element-consistent = cos-element-consistent: Error for type ''{0}''. Multiple elements with name ''{1}'', with different types, appear in the model group. + cos-list-of-atomic = cos-list-of-atomic: In the definition of list type ''{0}'', type ''{1}'' is an invalid list element type because it is not atomic (''{1}'' is either a list type, or a union type which contains a list). + cos-nonambig = cos-nonambig: {0} and {1} (or elements from their substitution group) violate \"Unique Particle Attribution\". During validation against this schema, ambiguity would be created for those two particles. + cos-particle-restrict.a = cos-particle-restrict.a: Derived particle is empty, and base is not emptiable. + cos-particle-restrict.b = cos-particle-restrict.b: Base particle is empty, but derived particle is not. + cos-particle-restrict.2 = cos-particle-restrict.2: Forbidden particle restriction: ''{0}''. + cos-st-restricts.1.1 = cos-st-restricts.1.1: The type ''{1}'' is atomic, so its '{'base type definition'}', ''{0}'', must be an atomic simple type definition or a built-in primitive datatype. + cos-st-restricts.2.1 = cos-st-restricts.2.1: In the definition of list type ''{0}'', type ''{1}'' is an invalid item type because it is either a list type, or a union type that contains a list. + cos-st-restricts.2.3.1.1 = cos-st-restricts.2.3.1.1: The '{'final'}' component of the '{'item type definition'}', ''{0}'', contains ''list''. This means that ''{0}'' cannot be used as an item type for list type ''{1}''. + cos-st-restricts.3.3.1.1 = cos-st-restricts.3.3.1.1: The '{'final'}' component of the '{'member type definitions'}', ''{0}'', contains ''union''. This means that ''{0}'' cannot be used as an member type for union type ''{1}''. + cos-valid-default.2.1 = cos-valid-default.2.1: Element ''{0}'' has a value constraint and must have a mixed or simple content model. + cos-valid-default.2.2.2 = cos-valid-default.2.2.2: Since element ''{0}'' has a '{'value constraint'}' and its type definition has mixed '{'content type'}', then the particle of the '{'content type'}' must be emptiable. + c-props-correct.2 = c-props-correct.2: Cardinality of Fields for keyref ''{0}'' and key ''{1}'' must match each other. + ct-props-correct.3 = ct-props-correct.3: Circular definitions detected for complex type ''{0}''. This means that ''{0}'' is contained in its own type hierarchy, which is an error. + ct-props-correct.4 = ct-props-correct.4: Error for type ''{0}''. Duplicate attribute uses with the same name and target namespace are specified. Name of duplicate attribute use is ''{1}''. + ct-props-correct.5 = ct-props-correct.5: Error for type ''{0}''. Two attribute declarations, ''{1}'' and ''{2}'' have types which are derived from ID. + derivation-ok-restriction.1 = derivation-ok-restriction.1: Type ''{0}'' was derived by restriction from type ''{1}''. However, ''{1}'' has a '{'final'}' property that forbids derivation by restriction. + derivation-ok-restriction.2.1.1 = derivation-ok-restriction.2.1.1: Error for type ''{0}''. The attribute use ''{1}'' in this type has a ''use'' value of ''{2}'', which is inconsistent with the value of ''required'' in a matching attribute use in the base type. + derivation-ok-restriction.2.1.2 = derivation-ok-restriction.2.1.2: Error for type ''{0}''. The attribute use ''{1}'' in this type has type ''{2}'', which is not validly derived from ''{3}'', the type of the matching attribute use in the base type. + derivation-ok-restriction.2.1.3.a = derivation-ok-restriction.2.1.3.a: Error for type ''{0}''. The attribute use ''{1}'' in this type has an effective value constraint which is not fixed, and the effective value constraint of the matching attribute use in the base type is fixed. + derivation-ok-restriction.2.1.3.b = derivation-ok-restriction.2.1.3.b: Error for type ''{0}''. The attribute use ''{1}'' in this type has an effective value constraint fixed with a value of ''{2}'', which is not consistent with the value of ''{3}'' for the fixed effective value constraint of the matching attribute use in the base type. + derivation-ok-restriction.2.2.a = derivation-ok-restriction.2.2.a: Error for type ''{0}''. The attribute use ''{1}'' in this type does not have a matching attribute use in the base, and the base type does not have a wildcard attribute. + derivation-ok-restriction.2.2.b = derivation-ok-restriction.2.2.b: Error for type ''{0}''. The attribute use ''{1}'' in this type does not have a matching attribute use in the base, and the wildcard in the base type does not allow the namespace ''{2}'' of this attribute use. + derivation-ok-restriction.3 = derivation-ok-restriction.3: Error for type ''{0}''. The attribute use ''{1}'' in the base type has REQUIRED as true, but there is no matching attribute use in the derived type. + derivation-ok-restriction.4.1 = derivation-ok-restriction.4.1: Error for type ''{0}''. The derivation has an attribute wildcard, but the base does not have one. + derivation-ok-restriction.4.2 = derivation-ok-restriction.4.2: Error for type ''{0}''. The wildcard in the derivation is not a valid wildcard subset of the one in the base. + derivation-ok-restriction.4.3 = derivation-ok-restriction.4.3: Error for type ''{0}''. The process contents of the wildcard in the derivation ({1}) is weaker than that in the base ({2}). + derivation-ok-restriction.5.2.2.1 = derivation-ok-restriction.5.2.2.1: Error for type ''{0}''. The simple content type of this type, ''{1}'', is not a valid restriction of the simple content type of the base, ''{2}''. + derivation-ok-restriction.5.3.2 = derivation-ok-restriction.5.3.2: Error for type ''{0}''. The content type of this type is empty, but the content type of the base, ''{1}'', is not empty or emptiable. + derivation-ok-restriction.5.4.1.2 = derivation-ok-restriction.5.4.1.2: Error for type ''{0}''. The content type of this type is mixed, but the content type of the base, ''{1}'', is not. + derivation-ok-restriction.5.4.2 = derivation-ok-restriction.5.4.2: Error for type ''{0}''. The particle of the type is not a valid restriction of the particle of the base. + enumeration-required-notation = enumeration-required-notation: The NOTATION type, ''{0}'' used by {2} ''{1}'', must have an enumeration facet value which specifies the notation elements used by this type. + enumeration-valid-restriction = enumeration-valid-restriction: Enumeration value ''{0}'' is not in the value space of the base type, {1}. + e-props-correct.2 = e-props-correct.2: Invalid value constraint value ''{1}'' in element ''{0}''. + e-props-correct.4 = e-props-correct.4: The '{'type definition'}' of element ''{0}'' is not validly derived from the '{'type definition'}' of the substitutionHead ''{1}'', or the '{'substitution group exclusions'}' property of ''{1}'' does not allow this derivation. + e-props-correct.5 = e-props-correct.5: A '{'value constraint'}' must not be present on element ''{0}'', because the element''s '{'type definition'}' or '{'type definition'}'''s '{'content type'}' is ID, or is derived from ID. + e-props-correct.6 = e-props-correct.6: Circular substitution group detected for element ''{0}''. + fractionDigits-valid-restriction = fractionDigits-valid-restriction: In the definition of {2}, the value ''{0}'' for the facet ''fractionDigits'' is invalid, because it must be <= the value for ''fractionDigits'' which was set to ''{1}'' in one of the ancestor types. + fractionDigits-totalDigits = fractionDigits-totalDigits: In the definition of {2}, the value ''{0}'' for the facet ''fractionDigits'' is invalid, because the value must be <= the value for ''totalDigits'' which is ''{1}''. + length-minLength-maxLength.1.1 = length-minLength-maxLength.1.1: For type {0}, it is an error for the value of length ''{1}'' to be less than the value of minLength ''{2}''. + length-minLength-maxLength.1.2.a = length-minLength-maxLength.1.2.a: For type {0}, it is an error for the base to not have a minLength facet if the current restriction has the minLength facet and the current restriction or base has the length facet. + length-minLength-maxLength.1.2.b = length-minLength-maxLength.1.2.b: For type {0}, it is an error for the current minLength ''{1}'' to not equal the base minLength ''{2}''. + length-minLength-maxLength.2.1 = length-minLength-maxLength.2.1: For type {0}, it is an error for the value of length ''{1}'' to be greater than the value of maxLength ''{2}''. + length-minLength-maxLength.2.2.a = length-minLength-maxLength.2.2.a: For type {0}, it is an error for the base to not have a maxLength facet if the current restriction has the maxLength facet and the current restriction or base has the length facet. + length-minLength-maxLength.2.2.b = length-minLength-maxLength.2.2.b: For type {0}, it is an error for the current maxLength ''{1}'' to not equal the base maxLength ''{2}''. + length-valid-restriction = length-valid-restriction: Error for type ''{2}''. The value of length = ''{0}'' must be = the value of that of the base type ''{1}''. + maxExclusive-valid-restriction.1 = maxExclusive-valid-restriction.1: Error for type ''{2}''. The maxExclusive value =''{0}'' must be <= maxExclusive of the base type ''{1}''. + maxExclusive-valid-restriction.2 = maxExclusive-valid-restriction.2: Error for type ''{2}''. The maxExclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + maxExclusive-valid-restriction.3 = maxExclusive-valid-restriction.3: Error for type ''{2}''. The maxExclusive value =''{0}'' must be > minInclusive of the base type ''{1}''. + maxExclusive-valid-restriction.4 = maxExclusive-valid-restriction.4: Error for type ''{2}''. The maxExclusive value =''{0}'' must be > minExclusive of the base type ''{1}''. + maxInclusive-maxExclusive = maxInclusive-maxExclusive: It is an error for both maxInclusive and maxExclusive to be specified for the same datatype. In {2}, maxInclusive = ''{0}'' and maxExclusive = ''{1}''. + maxInclusive-valid-restriction.1 = maxInclusive-valid-restriction.1: Error for type ''{2}''. The maxInclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + maxInclusive-valid-restriction.2 = maxInclusive-valid-restriction.2: Error for type ''{2}''. The maxInclusive value =''{0}'' must be < maxExclusive of the base type ''{1}''. + maxInclusive-valid-restriction.3 = maxInclusive-valid-restriction.3: Error for type ''{2}''. The maxInclusive value =''{0}'' must be >= minInclusive of the base type ''{1}''. + maxInclusive-valid-restriction.4 = maxInclusive-valid-restriction.4: Error for type ''{2}''. The maxInclusive value =''{0}'' must be > minExclusive of the base type ''{1}''. + maxLength-valid-restriction = maxLength-valid-restriction: In the definition of {2}, maxLength value = ''{0}'' must be <= that of the base type ''{1}''. + mg-props-correct.2 = mg-props-correct.2: Circular definitions detected for group ''{0}''. Recursively following the '{'term'}' values of the particles leads to a particle whose '{'term'}' is the group itself. + minExclusive-less-than-equal-to-maxExclusive = minExclusive-less-than-equal-to-maxExclusive: In the definition of {2}, minExclusive value = ''{0}'' must be <= maxExclusive value = ''{1}''. + minExclusive-less-than-maxInclusive = minExclusive-less-than-maxInclusive: In the definition of {2}, minExclusive value = ''{0}'' must be < maxInclusive value = ''{1}''. + minExclusive-valid-restriction.1 = minExclusive-valid-restriction.1: Error for type ''{2}''. The minExclusive value =''{0}'' must be >= minExclusive of the base type ''{1}''. + minExclusive-valid-restriction.2 = minExclusive-valid-restriction.2: Error for type ''{2}''. The minExclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + minExclusive-valid-restriction.3 = minExclusive-valid-restriction.3: Error for type ''{2}''. The minExclusive value =''{0}'' must be >= minInclusive of the base type ''{1}''. + minExclusive-valid-restriction.4 = minExclusive-valid-restriction.4: Error for type ''{2}''. The minExclusive value =''{0}'' must be < maxExclusive of the base type ''{1}''. + minInclusive-less-than-equal-to-maxInclusive = minInclusive-less-than-equal-to-maxInclusive: In the definition of {2}, minInclusive value = ''{0}'' must be <= maxInclusive value = ''{1}''. + minInclusive-less-than-maxExclusive = minInclusive-less-than-maxExclusive: In the definition of {2}, minInclusive value = ''{0}'' must be < maxExclusive value = ''{1}''. + minInclusive-minExclusive = minInclusive-minExclusive: It is an error for both minInclusive and minExclusive to be specified for the same datatype. In {2}, minInclusive = ''{0}'' and minExclusive = ''{1}''. + minInclusive-valid-restriction.1 = minInclusive-valid-restriction.1: Error for type ''{2}''. The minInclusive value =''{0}'' must be >= minInclusive of the base type ''{1}''. + minInclusive-valid-restriction.2 = minInclusive-valid-restriction.2: Error for type ''{2}''. The minInclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + minInclusive-valid-restriction.3 = minInclusive-valid-restriction.3: Error for type ''{2}''. The minInclusive value =''{0}'' must be > minExclusive of the base type ''{1}''. + minInclusive-valid-restriction.4 = minInclusive-valid-restriction.4: Error for type ''{2}''. The minInclusive value =''{0}'' must be < maxExclusive of the base type ''{1}''. + minLength-less-than-equal-to-maxLength = minLength-less-than-equal-to-maxLength: In the definition of {2}, value of minLength = ''{0}'' must be < value of maxLength = ''{1}''. + minLength-valid-restriction = minLength-valid-restriction: In the definition of {2}, minLength = ''{0}'' must be >= than that of the base type, ''{1}''. + no-xmlns = no-xmlns: The {name} of an attribute declaration must not match 'xmlns'. + no-xsi = no-xsi: The '{'target namespace'}' of an attribute declaration must not match ''{0}''. + p-props-correct.2.1 = p-props-correct.2.1: In the declaration of ''{0}'', the value of ''minOccurs'' is ''{1}'', but it must not be greater than the value of ''maxOccurs'', which is ''{2}''. + rcase-MapAndSum.1 = rcase-MapAndSum.1: There is not a complete functional mapping between the particles. + rcase-MapAndSum.2 = rcase-MapAndSum.2: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-NameAndTypeOK.1 = rcase-NameAndTypeOK.1: Elements have names and target namespaces which are not the same: Element ''{0}'' in namespace ''{1}'' and element ''{2}'' in namespace ''{3}''. + rcase-NameAndTypeOK.2 = rcase-NameAndTypeOK.2: Error for the particle whose '{'term'}' is the element declaration ''{0}''. The element declaration''s '{'nillable'}' is true, but the corresponding particle in the base type has an element declaration whose '{'nillable'}' is false. + rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}), of the corresponding particle in the base type. + rcase-NameAndTypeOK.4.a = rcase-NameAndTypeOK.4.a: Element ''{0}'' is not fixed, but the corresponding element in the base type is fixed with value ''{1}''. + rcase-NameAndTypeOK.4.b = rcase-NameAndTypeOK.4.b: Element ''{0}'' is fixed with value ''{1}'', but the corresponding element in the base type is fixed with value ''{2}''. + rcase-NameAndTypeOK.5 = rcase-NameAndTypeOK.5: Identity constraints for element ''{0}'' are not a subset of those in base. + rcase-NameAndTypeOK.6 = rcase-NameAndTypeOK.6: The disallowed substitutions for element ''{0}'' are not a superset of those in the base. + rcase-NameAndTypeOK.7 = rcase-NameAndTypeOK.7: The type of element ''{0}'', ''{1}'', is not derived from the type of the base element, ''{2}''. + rcase-NSCompat.1 = rcase-NSCompat.1: Element ''{0}'' has a namespace ''{1}'' which is not allowed by the wildcard in the base. + rcase-NSCompat.2 = rcase-NSCompat.2: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}), of the corresponding particle in the base type. + rcase-NSRecurseCheckCardinality.1 = rcase-NSRecurseCheckCardinality.1: There is not a complete functional mapping between the particles. + rcase-NSRecurseCheckCardinality.2 = rcase-NSRecurseCheckCardinality.2: Group''s occurrence range, ({0},{1}), is not a valid restriction of base wildcard''s range, ({2},{3}). + rcase-NSSubset.1 = rcase-NSSubset.1: Wildcard is not a subset of corresponding wildcard in base. + rcase-NSSubset.2 = rcase-NSSubset.2: Wildcard''s occurrence range, ({0},{1}), is not a valid restriction of that in the base, ({2},{3}),. + rcase-NSSubset.3 = rcase-NSSubset.3: Wildcard''s process contents, ''{0}'', is weaker than that in the base, ''{1}''. + rcase-Recurse.1 = rcase-Recurse.1: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-Recurse.2 = rcase-Recurse.2: There is not a complete functional mapping between the particles. + rcase-RecurseLax.1 = rcase-RecurseLax.1: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-RecurseLax.2 = rcase-RecurseLax.2: There is not a complete functional mapping between the particles. + rcase-RecurseUnordered.1 = rcase-RecurseUnordered.1: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-RecurseUnordered.2 = rcase-RecurseUnordered.2: There is not a complete functional mapping between the particles. +# We're using sch-props-correct.2 instead of the old src-redefine.1 +# src-redefine.1 = src-redefine.1: The component ''{0}'' is begin redefined, but its corresponding component isn't in the schema document being redefined (with namespace ''{2}''), but in a different document, with namespace ''{1}''. + sch-props-correct.2 = sch-props-correct.2: A schema cannot contain two global components with the same name; this schema contains two occurrences of ''{0}''. + st-props-correct.2 = st-props-correct.2: Circular definitions have been detected for simple type ''{0}''. This means that ''{0}'' is contained in its own type hierarchy, which is an error. + st-props-correct.3 = st-props-correct.3: Error for type ''{0}''. The value of '{'final'}' of the '{'base type definition'}', ''{1}'', forbids derivation by restriction. + totalDigits-valid-restriction = totalDigits-valid-restriction: In the definition of {2}, the value ''{0}'' for the facet ''totalDigits'' is invalid, because it must be <= the value for ''totalDigits'' which was set to ''{1}'' in one of the ancestor types. + whiteSpace-valid-restriction.1 = whiteSpace-valid-restriction.1: In the definition of {0}, the value ''{1}'' for the facet ''whitespace'' is invalid, because the value for ''whitespace'' has been set to ''collapse'' in one of the ancestor types. + whiteSpace-valid-restriction.2 = whiteSpace-valid-restriction.2: In the definition of {0}, the value ''preserve'' for the facet ''whitespace'' is invalid, because the value for ''whitespace'' has been set to ''replace'' in one of the ancestor types. + +#schema for Schemas + + s4s-att-invalid-value = s4s-att-invalid-value: Invalid attribute value for ''{1}'' in element ''{0}''. Recorded reason: {2} + s4s-att-must-appear = s4s-att-must-appear: Attribute ''{1}'' must appear in element ''{0}''. + s4s-att-not-allowed = s4s-att-not-allowed: Attribute ''{1}'' cannot appear in element ''{0}''. + s4s-elt-invalid = s4s-elt-invalid: Element ''{0}'' is not a valid element in a schema document. + s4s-elt-must-match.1 = s4s-elt-must-match.1: The content of ''{0}'' must match {1}. A problem was found starting at: {2}. + s4s-elt-must-match.2 = s4s-elt-must-match.2: The content of ''{0}'' must match {1}. Not enough elements were found. + # the "invalid-content" messages provide less information than the "must-match" counterparts above. They're used for complex types when providing a "match" would be an information dump + s4s-elt-invalid-content.1 = s4s-elt-invalid-content.1: The content of ''{0}'' is invalid. Element ''{1}'' is invalid, misplaced, or occurs too often. + s4s-elt-invalid-content.2 = s4s-elt-invalid-content.2: The content of ''{0}'' is invalid. Element ''{1}'' cannot be empty. + s4s-elt-invalid-content.3 = s4s-elt-invalid-content.3: Elements of type ''{0}'' cannot appear after declarations as children of a <schema> element. + s4s-elt-schema-ns = s4s-elt-schema-ns: The namespace of element ''{0}'' must be from the schema namespace, ''http://www.w3.org/2001/XMLSchema''. + s4s-elt-character = s4s-elt-character: Non-whitespace characters are not allowed in schema elements other than ''xs:appinfo'' and ''xs:documentation''. Saw ''{0}''. + +# codes not defined by the spec + + c-fields-xpaths = c-fields-xpaths: The field value = ''{0}'' is not valid. + c-general-xpath = c-general-xpath: The expression ''{0}'' is not valid with respect to the XPath subset supported by XML Schema. + c-general-xpath-ns = c-general-xpath-ns: A namespace prefix in XPath expression ''{0}'' was not bound to a namespace. + c-selector-xpath = c-selector-xpath: The selector value = ''{0}'' is not valid; selector xpaths cannot contain attributes. + EmptyTargetNamespace = EmptyTargetNamespace: In schema document ''{0}'', the value of the ''targetNamespace'' attribute cannot be an empty string. + FacetValueFromBase = FacetValueFromBase: In the declaration of type ''{0}'', value ''{1}'' of facet ''{2}'' must be from the value space of the base type, ''{3}''. + FixedFacetValue = FixedFacetValue: In the definition of {3}, the value ''{1}'' for the facet ''{0}'' is invalid, because the value for ''{0}'' has been set to ''{2}'' in one of the ancestor types, and '{'fixed'}' = true. + InvalidRegex = InvalidRegex: Pattern value ''{0}'' is not a valid regular expression. The reported error was: ''{1}''. + maxOccurLimit = Current configuration of the parser doesn''t allow the expansion of a content model for a complex type to contain more than {0} nodes. + PublicSystemOnNotation = PublicSystemOnNotation: At least one of 'public' and 'system' must appear in element 'notation'. + SchemaLocation = SchemaLocation: schemaLocation value = ''{0}'' must have even number of URI''s. + TargetNamespace.1 = TargetNamespace.1: Expecting namespace ''{0}'', but the target namespace of the schema document is ''{1}''. + TargetNamespace.2 = TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of ''{1}''. + UndeclaredEntity = UndeclaredEntity: Entity ''{0}'' is not declared. + UndeclaredPrefix = UndeclaredPrefix: Cannot resolve ''{0}'' as a QName: the prefix ''{1}'' is not declared. + +# JAXP 1.2 schema source property errors + + jaxp12-schema-source-type.1 = The ''http://java.sun.com/xml/jaxp/properties/schemaSource'' property cannot have a value of type ''{0}''. Possible types of the value supported are String, File, InputStream, InputSource or an array of these types. + jaxp12-schema-source-type.2 = The ''http://java.sun.com/xml/jaxp/properties/schemaSource'' property cannot have an array value of type ''{0}''. Possible types of the array supported are Object, String, File, InputStream and InputSource. + jaxp12-schema-source-ns = When using an array of Objects as the value of the 'http://java.sun.com/xml/jaxp/properties/schemaSource' property, it is illegal to have two schemas that share the same target namespace. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XMLSchemaMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSchemaMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..cd8765da056a52ba84301800ba5c031d3797c239 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSchemaMessages_en.properties @@ -0,0 +1,320 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file contains error and warning messages related to XML Schema +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XMLSchemaMessages.properties 806363 2009-08-20 21:18:48Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + +# For internal use + + Internal-Error = Internal error: {0}. + dt-whitespace = Whitespace facet value is not available for the union simpleType ''{0}'' + GrammarConflict = One of the grammar(s) returned from the user's grammar pool is in conflict with another grammar. + +# Identity constraints + + AbsentKeyValue = cvc-identity-constraint.4.2.1.a: Element \"{0}\" has no value for the key \"{1}\". + DuplicateField = Duplicate match in scope for field \"{0}\". + DuplicateKey = cvc-identity-constraint.4.2.2: Duplicate key value [{0}] declared for identity constraint \"{2}\" of element \"{1}\". + DuplicateUnique = cvc-identity-constraint.4.1: Duplicate unique value [{0}] declared for identity constraint \"{2}\" of element \"{1}\". + FieldMultipleMatch = cvc-identity-constraint.3: Field \"{0}\" of identity constraint \"{1}\" matches more than one value within the scope of its selector; fields must match unique values. + FixedDiffersFromActual = The content of this element is not equivalent to the value of the \"fixed\" attribute in the element's declaration in the schema. + KeyMatchesNillable = cvc-identity-constraint.4.2.3: Element \"{0}\" has the key \"{1}\" which matches an element which has nillable set to true. + KeyNotEnoughValues = cvc-identity-constraint.4.2.1.b: Not enough values specified for <key name=\"{1}\"> identity constraint specified for element \"{0}\". + KeyNotFound = cvc-identity-constraint.4.3: Key ''{0}'' with value ''{1}'' not found for identity constraint of element ''{2}''. + KeyRefOutOfScope = Identity Constraint error: identity constraint \"{0}\" has a keyref which refers to a key or unique that is out of scope. + KeyRefReferNotFound = Key reference declaration \"{0}\" refers to unknown key with name \"{1}\". + UnknownField = Internal identity constraint error; unknown field \"{0}\" for identity constraint \"{2}\" specified for element \"{1}\". + +# Ideally, we should only use the following error keys, not the ones under +# "Identity constraints". And we should cover all of the following errors. + +#validation (3.X.4) + + cvc-attribute.3 = cvc-attribute.3: The value ''{2}'' of attribute ''{1}'' on element ''{0}'' is not valid with respect to its type, ''{3}''. + cvc-attribute.4 = cvc-attribute.4: The value ''{2}'' of attribute ''{1}'' on element ''{0}'' is not valid with respect to its fixed '{'value constraint'}'. The attribute must have a value of ''{3}''. + cvc-complex-type.2.1 = cvc-complex-type.2.1: Element ''{0}'' must have no character or element information item [children], because the type''s content type is empty. + cvc-complex-type.2.2 = cvc-complex-type.2.2: Element ''{0}'' must have no element [children], and the value must be valid. + cvc-complex-type.2.3 = cvc-complex-type.2.3: Element ''{0}'' cannot have character [children], because the type''s content type is element-only. + cvc-complex-type.2.4.a = cvc-complex-type.2.4.a: Invalid content was found starting with element ''{0}''. One of ''{1}'' is expected. + cvc-complex-type.2.4.b = cvc-complex-type.2.4.b: The content of element ''{0}'' is not complete. One of ''{1}'' is expected. + cvc-complex-type.2.4.c = cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ''{0}''. + cvc-complex-type.2.4.d = cvc-complex-type.2.4.d: Invalid content was found starting with element ''{0}''. No child element is expected at this point. + cvc-complex-type.2.4.e = cvc-complex-type.2.4.e: ''{0}'' can occur a maximum of ''{2}'' times in the current sequence. This limit was exceeded. At this point one of ''{1}'' is expected. + cvc-complex-type.2.4.f = cvc-complex-type.2.4.f: ''{0}'' can occur a maximum of ''{1}'' times in the current sequence. This limit was exceeded. No child element is expected at this point. + cvc-complex-type.2.4.g = cvc-complex-type.2.4.g: Invalid content was found starting with element ''{0}''. ''{1}'' is expected to occur a minimum of ''{2}'' times in the current sequence. One more instance is required to satisfy this constraint. + cvc-complex-type.2.4.h = cvc-complex-type.2.4.h: Invalid content was found starting with element ''{0}''. ''{1}'' is expected to occur a minimum of ''{2}'' times in the current sequence. ''{3}'' more instances are required to satisfy this constraint. + cvc-complex-type.2.4.i = cvc-complex-type.2.4.i: The content of element ''{0}'' is not complete. ''{1}'' is expected to occur a minimum of ''{2}'' times. One more instance is required to satisfy this constraint. + cvc-complex-type.2.4.j = cvc-complex-type.2.4.j: The content of element ''{0}'' is not complete. ''{1}'' is expected to occur a minimum of ''{2}'' times. ''{3}'' more instances are required to satisfy this constraint. + cvc-complex-type.3.1 = cvc-complex-type.3.1: Value ''{2}'' of attribute ''{1}'' of element ''{0}'' is not valid with respect to the corresponding attribute use. Attribute ''{1}'' has a fixed value of ''{3}''. + cvc-complex-type.3.2.1 = cvc-complex-type.3.2.1: Element ''{0}'' does not have an attribute wildcard for attribute ''{1}''. + cvc-complex-type.3.2.2 = cvc-complex-type.3.2.2: Attribute ''{1}'' is not allowed to appear in element ''{0}''. + cvc-complex-type.4 = cvc-complex-type.4: Attribute ''{1}'' must appear on element ''{0}''. + cvc-complex-type.5.1 = cvc-complex-type.5.1: In element ''{0}'', attribute ''{1}'' is a Wild ID. But there is already a Wild ID ''{2}''. There can be only one. + cvc-complex-type.5.2 = cvc-complex-type.5.2: In element ''{0}'', attribute ''{1}'' is a Wild ID. But there is already an attribute ''{2}'' derived from ID among the '{'attribute uses'}'. + cvc-datatype-valid.1.2.1 = cvc-datatype-valid.1.2.1: ''{0}'' is not a valid value for ''{1}''. + cvc-datatype-valid.1.2.2 = cvc-datatype-valid.1.2.2: ''{0}'' is not a valid value of list type ''{1}''. + cvc-datatype-valid.1.2.3 = cvc-datatype-valid.1.2.3: ''{0}'' is not a valid value of union type ''{1}''. + cvc-elt.1.a = cvc-elt.1.a: Cannot find the declaration of element ''{0}''. + cvc-elt.1.b = cvc-elt.1.b: The name of the element does not match the name of the element declaration. Saw ''{0}''. Expected ''{1}''. + cvc-elt.2 = cvc-elt.2: The value of '{'abstract'}' in the element declaration for ''{0}'' must be false. + cvc-elt.3.1 = cvc-elt.3.1: Attribute ''{1}'' must not appear on element ''{0}'', because the '{'nillable'}' property of ''{0}'' is false. + cvc-elt.3.2.1 = cvc-elt.3.2.1: Element ''{0}'' cannot have character or element information [children], because ''{1}'' is specified. + cvc-elt.3.2.2 = cvc-elt.3.2.2: There must be no fixed '{'value constraint'}' for element ''{0}'', because ''{1}'' is specified. + cvc-elt.4.1 = cvc-elt.4.1: The value ''{2}'' of attribute ''{1}'' of element ''{0}'' is not a valid QName. + cvc-elt.4.2 = cvc-elt.4.2: Cannot resolve ''{1}'' to a type definition for element ''{0}''. + cvc-elt.4.3 = cvc-elt.4.3: Type ''{1}'' is not validly derived from the type definition, ''{2}'', of element ''{0}''. + cvc-elt.5.1.1 = cvc-elt.5.1.1: '{'value constraint'}' ''{2}'' of element ''{0}'' is not a valid default value for type ''{1}''. + cvc-elt.5.2.2.1 = cvc-elt.5.2.2.1: Element ''{0}'' must have no element information item [children]. + cvc-elt.5.2.2.2.1 = cvc-elt.5.2.2.2.1: The value ''{1}'' of element ''{0}'' does not match the fixed '{'value constraint'}' value ''{2}''. + cvc-elt.5.2.2.2.2 = cvc-elt.5.2.2.2.2: The value ''{1}'' of element ''{0}'' does not match the '{'value constraint'}' value ''{2}''. + cvc-enumeration-valid = cvc-enumeration-valid: Value ''{0}'' is not facet-valid with respect to enumeration ''{1}''. It must be a value from the enumeration. + cvc-fractionDigits-valid = cvc-fractionDigits-valid: Value ''{0}'' has {1} fraction digits, but the number of fraction digits has been limited to {2}. + cvc-id.1 = cvc-id.1: There is no ID/IDREF binding for IDREF ''{0}''. + cvc-id.2 = cvc-id.2: There are multiple occurrences of ID value ''{0}''. + cvc-id.3 = cvc-id.3: A field of identity constraint ''{0}'' matched element ''{1}'', but this element does not have a simple type. + cvc-length-valid = cvc-length-valid: Value ''{0}'' with length = ''{1}'' is not facet-valid with respect to length ''{2}'' for type ''{3}''. + cvc-maxExclusive-valid = cvc-maxExclusive-valid: Value ''{0}'' is not facet-valid with respect to maxExclusive ''{1}'' for type ''{2}''. + cvc-maxInclusive-valid = cvc-maxInclusive-valid: Value ''{0}'' is not facet-valid with respect to maxInclusive ''{1}'' for type ''{2}''. + cvc-maxLength-valid = cvc-maxLength-valid: Value ''{0}'' with length = ''{1}'' is not facet-valid with respect to maxLength ''{2}'' for type ''{3}''. + cvc-minExclusive-valid = cvc-minExclusive-valid: Value ''{0}'' is not facet-valid with respect to minExclusive ''{1}'' for type ''{2}''. + cvc-minInclusive-valid = cvc-minInclusive-valid: Value ''{0}'' is not facet-valid with respect to minInclusive ''{1}'' for type ''{2}''. + cvc-minLength-valid = cvc-minLength-valid: Value ''{0}'' with length = ''{1}'' is not facet-valid with respect to minLength ''{2}'' for type ''{3}''. + cvc-pattern-valid = cvc-pattern-valid: Value ''{0}'' is not facet-valid with respect to pattern ''{1}'' for type ''{2}''. + cvc-totalDigits-valid = cvc-totalDigits-valid: Value ''{0}'' has {1} total digits, but the number of total digits has been limited to {2}. + cvc-type.1 = cvc-type.1: The type definition ''{0}'' was not found. + cvc-type.2 = cvc-type.2: The type definition cannot be abstract for element {0}. + cvc-type.3.1.1 = cvc-type.3.1.1: Element ''{0}'' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to ''http://www.w3.org/2001/XMLSchema-instance'' and whose [local name] is one of ''type'', ''nil'', ''schemaLocation'' or ''noNamespaceSchemaLocation''. However, the attribute, ''{1}'' was found. + cvc-type.3.1.2 = cvc-type.3.1.2: Element ''{0}'' is a simple type, so it must have no element information item [children]. + cvc-type.3.1.3 = cvc-type.3.1.3: The value ''{1}'' of element ''{0}'' is not valid. + +#schema valid (3.X.3) + + schema_reference.4 = schema_reference.4: Failed to read schema document ''{0}'', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. + src-annotation = src-annotation: <annotation> elements can only contain <appinfo> and <documentation> elements, but ''{0}'' was found. + src-attribute.1 = src-attribute.1: The properties ''default'' and ''fixed'' cannot both be present in attribute declaration ''{0}''. Use only one of them. + src-attribute.2 = src-attribute.2: : The property ''default'' is present in attribute ''{0}'', so the value of ''use'' must be ''optional''. + src-attribute.3.1 = src-attribute.3.1: One of 'ref' or 'name' must be present in a local attribute declaration. + src-attribute.3.2 = src-attribute.3.2: The content must match (annotation?) for the attribute reference ''{0}''. + src-attribute.4 = src-attribute.4: Attribute ''{0}'' has both a ''type'' attribute and an anonymous ''simpleType'' child. Only one of these is allowed for an attribute. + src-attribute_group.2 = src-attribute_group.2: The intersection of wildcards is not expressible for attribute group ''{0}''. + src-attribute_group.3 = src-attribute_group.3: Circular definitions detected for attribute group ''{0}''. Recursively following attribute group references eventually leads back to itself. + src-ct.1 = src-ct.1: Complex Type Definition Representation Error for type ''{0}''. When <complexContent> is used, the base type must be a complexType. ''{1}'' is a simpleType. + src-ct.2.1 = src-ct.2.1: Complex Type Definition Representation Error for type ''{0}''. When <simpleContent> is used, the base type must be a complexType whose content type is simple, or, only if restriction is specified, a complex type with mixed content and emptiable particle, or, only if extension is specified, a simple type. ''{1}'' satisfies none of these conditions. + src-ct.2.2 = src-ct.2.2: Complex Type Definition Representation Error for type ''{0}''. When a complexType with simpleContent restricts a complexType with mixed content and emptiable particle, then there must be a <simpleType> among the children of <restriction>. + src-ct.4 = src-ct.4: Complex Type Definition Representation Error for type ''{0}''. The intersection of wildcards is not expressible. + src-ct.5 = src-ct.5: Complex Type Definition Representation Error for type ''{0}''. The union of wildcards is not expressible. + src-element.1 = src-element.1: The properties ''default'' and ''fixed'' cannot both be present in element declaration ''{0}''. Use only one of them. + src-element.2.1 = src-element.2.1: : One of 'ref' or 'name' must be present in a local element declaration. + src-element.2.2 = src-element.2.2: Since ''{0}'' contains the ''ref'' attribute, its content must match (annotation?). However, ''{1}'' was found. + src-element.3 = src-element.3: Element ''{0}'' has both a ''type'' attribute and a ''anonymous type'' child. Only one of these is allowed for an element. + src-import.1.1 = src-import.1.1: The namespace attribute ''{0}'' of an <import> element information item must not be the same as the targetNamespace of the schema it exists in. + src-import.1.2 = src-import.1.2: If the namespace attribute is not present on an <import> element information item then the enclosing schema must have a targetNamespace. + src-import.2 = src-import.2: The root element of document ''{0}'' has to have the namespace name ''http://www.w3.org/2001/XMLSchema'' and the local name ''schema''. + src-import.3.1 = src-import.3.1: The namespace attribute, ''{0}'', of an <import> element information item must be identical to the targetNamespace attribute, ''{1}'', of the imported document. + src-import.3.2 = src-import.3.2: An <import> element information item that had no namespace attribute was found, so the imported document cannot have a targetNamespace attribute. However, the targetNamespace ''{1}'' was found in the imported document. + src-include.1 = src-include.1: The root element of document ''{0}'' has to have the namespace name ''http://www.w3.org/2001/XMLSchema'' and the local name ''schema''. + src-include.2.1 = src-include.2.1: The targetNamespace of the referenced schema, currently ''{1}'', must be identical to that of the including schema, currently ''{0}''. + src-redefine.2 = src-redefine.2: The root element of document ''{0}'' has to have the namespace name ''http://www.w3.org/2001/XMLSchema'' and the local name ''schema''. + src-redefine.3.1 = src-redefine.3.1: The targetNamespace of the referenced schema, currently ''{1}'', must be identical to that of the redefining schema, currently ''{0}''. + src-redefine.5.a.a = src-redefine.5.a.a: No non-annotation children of <simpleType> were found. <simpleType> children of <redefine> elements must have <restriction> descendants, with 'base' attributes that refer to themselves. + src-redefine.5.a.b = src-redefine.5.a.b: ''{0}'' is not a valid child element. <simpleType> children of <redefine> elements must have <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.5.a.c = src-redefine.5.a.c: ''{0}'' does not have a ''base'' attribute that refers to the redefined element, ''{1}''. <simpleType> children of <redefine> elements must have <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.5.b.a = src-redefine.5.b.a: No non-annotation children of <complexType> were found. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with 'base' attributes that refer to themselves. + src-redefine.5.b.b = src-redefine.5.b.b: No non-annotation grandchildren of <complexType> were found. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with 'base' attributes that refer to themselves. + src-redefine.5.b.c = src-redefine.5.b.c: ''{0}'' is not a valid grandchild element. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.5.b.d = src-redefine.5.b.d: ''{0}'' does not have a ''base'' attribute that refers to the redefined element, ''{1}''. <complexType> children of <redefine> elements must have <extension> or <restriction> descendants, with ''base'' attributes that refer to themselves. + src-redefine.6.1.1 = src-redefine.6.1.1: If a group child of a <redefine> element contains a group referring itself, it must have exactly 1; this one has ''{0}''. + src-redefine.6.1.2 = src-redefine.6.1.2: The group ''{0}'', which contains a reference to a group being redefined, must have ''minOccurs'' = ''maxOccurs'' = 1. + src-redefine.6.2.1 = src-redefine.6.2.1: No group in the redefined schema has a name matching ''{0}''. + src-redefine.6.2.2 = src-redefine.6.2.2: Group ''{0}'' does not properly restrict the group it redefines; constraint violated: ''{1}''. + src-redefine.7.1 = src-redefine.7.1: If an attributeGroup child of a <redefine> element contains an attributeGroup referring itself, it must have exactly 1; this one has {0}. + src-redefine.7.2.1 = src-redefine.7.2.1: No attributeGroup in the redefined schema has a name matching ''{0}''. + src-redefine.7.2.2 = src-redefine.7.2.2: AttributeGroup ''{0}'' does not properly restrict the attributeGroup it redefines; constraint violated: ''{1}''. + src-resolve = src-resolve: Cannot resolve the name ''{0}'' to a(n) ''{1}'' component. + src-resolve.4.1 = src-resolve.4.1: Error resolving component ''{2}''. It was detected that ''{2}'' has no namespace, but components with no target namespace are not referenceable from schema document ''{0}''. If ''{2}'' is intended to have a namespace, perhaps a prefix needs to be provided. If it is intended that ''{2}'' has no namespace, then an ''import'' without a "namespace" attribute should be added to ''{0}''. + src-resolve.4.2 = src-resolve.4.2: Error resolving component ''{2}''. It was detected that ''{2}'' is in namespace ''{1}'', but components from this namespace are not referenceable from schema document ''{0}''. If this is the incorrect namespace, perhaps the prefix of ''{2}'' needs to be changed. If this is the correct namespace, then an appropriate ''import'' tag should be added to ''{0}''. + src-simple-type.2.a = src-simple-type.2.a: A <restriction> element was found that has both a base [attribute] and a <simpleType> element among its [children]. Only one is allowed. + src-simple-type.2.b = src-simple-type.2.b: A <restriction> element was found that has neither a base [attribute] nor a <simpleType> element among its [children]. One is required. + src-simple-type.3.a = src-simple-type.3.a: A <list> element was found that has both an itemType [attribute] and a <simpleType> element among its [children]. Only one is allowed. + src-simple-type.3.b = src-simple-type.3.b: A <list> element was found that has neither an itemType [attribute] nor a <simpleType> element among its [children]. One is required. + src-single-facet-value = src-single-facet-value: The facet ''{0}'' is defined more than once. + src-union-memberTypes-or-simpleTypes = src-union-memberTypes-or-simpleTypes: A <union> element must have either a non-empty memberTypes [attribute] or at least one <simpleType> element among its [children]. + +#constraint valid (3.X.6) + + ag-props-correct.2 = ag-props-correct.2: Error for attribute group ''{0}''. Duplicate attribute uses with the same name and target namespace are specified. Name of duplicate attribute use is ''{1}''. + ag-props-correct.3 = ag-props-correct.3: Error for attribute group ''{0}''. Two attribute declarations, ''{1}'' and ''{2}'' have types which are derived from ID. + a-props-correct.2 = a-props-correct.2: Invalid value constraint value ''{1}'' in attribute ''{0}''. + a-props-correct.3 = a-props-correct.3: Attribute ''{0}'' cannot use ''fixed'' or ''default'', because the attribute''s '{'type definition'}' is ID, or is derived from ID. + au-props-correct.2 = au-props-correct.2: In the attribute declaration of ''{0}'', a fixed value of ''{1}'' was specified. So if the attribute use referring to ''{0}'' also has a '{'value constraint'}', it must be fixed and its value must be ''{1}''. + cos-all-limited.1.2 = cos-all-limited.1.2: An 'all' model group must appear in a particle with '{'min occurs'}' = '{'max occurs'}' = 1, and that particle must be part of a pair which constitutes the '{'content type'}' of a complex type definition. + cos-all-limited.2 = cos-all-limited.2: The '{'max occurs'}' of an element in an ''all'' model group must be 0 or 1. The value ''{0}'' for element ''{1}'' is invalid. + cos-applicable-facets = cos-applicable-facets: Facet ''{0}'' is not allowed by type {1}. + cos-ct-extends.1.1 = cos-ct-extends.1.1: Type ''{0}'' was derived by extension from type ''{1}''. However, the ''final'' attribute of ''{1}'' forbids derivation by extension. + cos-ct-extends.1.4.3.2.2.1.a = cos-ct-extends.1.4.3.2.2.1.a: The content type of a derived type and that of its base must both be mixed or both be element-only. Type ''{0}'' is element only, but its base type is not. + cos-ct-extends.1.4.3.2.2.1.b = cos-ct-extends.1.4.3.2.2.1.b: The content type of a derived type and that of its base must both be mixed or both be element-only. Type ''{0}'' is mixed, but its base type is not. + cos-element-consistent = cos-element-consistent: Error for type ''{0}''. Multiple elements with name ''{1}'', with different types, appear in the model group. + cos-list-of-atomic = cos-list-of-atomic: In the definition of list type ''{0}'', type ''{1}'' is an invalid list element type because it is not atomic (''{1}'' is either a list type, or a union type which contains a list). + cos-nonambig = cos-nonambig: {0} and {1} (or elements from their substitution group) violate \"Unique Particle Attribution\". During validation against this schema, ambiguity would be created for those two particles. + cos-particle-restrict.a = cos-particle-restrict.a: Derived particle is empty, and base is not emptiable. + cos-particle-restrict.b = cos-particle-restrict.b: Base particle is empty, but derived particle is not. + cos-particle-restrict.2 = cos-particle-restrict.2: Forbidden particle restriction: ''{0}''. + cos-st-restricts.1.1 = cos-st-restricts.1.1: The type ''{1}'' is atomic, so its '{'base type definition'}', ''{0}'', must be an atomic simple type definition or a built-in primitive datatype. + cos-st-restricts.2.1 = cos-st-restricts.2.1: In the definition of list type ''{0}'', type ''{1}'' is an invalid item type because it is either a list type, or a union type that contains a list. + cos-st-restricts.2.3.1.1 = cos-st-restricts.2.3.1.1: The '{'final'}' component of the '{'item type definition'}', ''{0}'', contains ''list''. This means that ''{0}'' cannot be used as an item type for list type ''{1}''. + cos-st-restricts.3.3.1.1 = cos-st-restricts.3.3.1.1: The '{'final'}' component of the '{'member type definitions'}', ''{0}'', contains ''union''. This means that ''{0}'' cannot be used as an member type for union type ''{1}''. + cos-valid-default.2.1 = cos-valid-default.2.1: Element ''{0}'' has a value constraint and must have a mixed or simple content model. + cos-valid-default.2.2.2 = cos-valid-default.2.2.2: Since element ''{0}'' has a '{'value constraint'}' and its type definition has mixed '{'content type'}', then the particle of the '{'content type'}' must be emptiable. + c-props-correct.2 = c-props-correct.2: Cardinality of Fields for keyref ''{0}'' and key ''{1}'' must match each other. + ct-props-correct.3 = ct-props-correct.3: Circular definitions detected for complex type ''{0}''. This means that ''{0}'' is contained in its own type hierarchy, which is an error. + ct-props-correct.4 = ct-props-correct.4: Error for type ''{0}''. Duplicate attribute uses with the same name and target namespace are specified. Name of duplicate attribute use is ''{1}''. + ct-props-correct.5 = ct-props-correct.5: Error for type ''{0}''. Two attribute declarations, ''{1}'' and ''{2}'' have types which are derived from ID. + derivation-ok-restriction.1 = derivation-ok-restriction.1: Type ''{0}'' was derived by restriction from type ''{1}''. However, ''{1}'' has a '{'final'}' property that forbids derivation by restriction. + derivation-ok-restriction.2.1.1 = derivation-ok-restriction.2.1.1: Error for type ''{0}''. The attribute use ''{1}'' in this type has a ''use'' value of ''{2}'', which is inconsistent with the value of ''required'' in a matching attribute use in the base type. + derivation-ok-restriction.2.1.2 = derivation-ok-restriction.2.1.2: Error for type ''{0}''. The attribute use ''{1}'' in this type has type ''{2}'', which is not validly derived from ''{3}'', the type of the matching attribute use in the base type. + derivation-ok-restriction.2.1.3.a = derivation-ok-restriction.2.1.3.a: Error for type ''{0}''. The attribute use ''{1}'' in this type has an effective value constraint which is not fixed, and the effective value constraint of the matching attribute use in the base type is fixed. + derivation-ok-restriction.2.1.3.b = derivation-ok-restriction.2.1.3.b: Error for type ''{0}''. The attribute use ''{1}'' in this type has an effective value constraint fixed with a value of ''{2}'', which is not consistent with the value of ''{3}'' for the fixed effective value constraint of the matching attribute use in the base type. + derivation-ok-restriction.2.2.a = derivation-ok-restriction.2.2.a: Error for type ''{0}''. The attribute use ''{1}'' in this type does not have a matching attribute use in the base, and the base type does not have a wildcard attribute. + derivation-ok-restriction.2.2.b = derivation-ok-restriction.2.2.b: Error for type ''{0}''. The attribute use ''{1}'' in this type does not have a matching attribute use in the base, and the wildcard in the base type does not allow the namespace ''{2}'' of this attribute use. + derivation-ok-restriction.3 = derivation-ok-restriction.3: Error for type ''{0}''. The attribute use ''{1}'' in the base type has REQUIRED as true, but there is no matching attribute use in the derived type. + derivation-ok-restriction.4.1 = derivation-ok-restriction.4.1: Error for type ''{0}''. The derivation has an attribute wildcard, but the base does not have one. + derivation-ok-restriction.4.2 = derivation-ok-restriction.4.2: Error for type ''{0}''. The wildcard in the derivation is not a valid wildcard subset of the one in the base. + derivation-ok-restriction.4.3 = derivation-ok-restriction.4.3: Error for type ''{0}''. The process contents of the wildcard in the derivation ({1}) is weaker than that in the base ({2}). + derivation-ok-restriction.5.2.2.1 = derivation-ok-restriction.5.2.2.1: Error for type ''{0}''. The simple content type of this type, ''{1}'', is not a valid restriction of the simple content type of the base, ''{2}''. + derivation-ok-restriction.5.3.2 = derivation-ok-restriction.5.3.2: Error for type ''{0}''. The content type of this type is empty, but the content type of the base, ''{1}'', is not empty or emptiable. + derivation-ok-restriction.5.4.1.2 = derivation-ok-restriction.5.4.1.2: Error for type ''{0}''. The content type of this type is mixed, but the content type of the base, ''{1}'', is not. + derivation-ok-restriction.5.4.2 = derivation-ok-restriction.5.4.2: Error for type ''{0}''. The particle of the type is not a valid restriction of the particle of the base. + enumeration-required-notation = enumeration-required-notation: The NOTATION type, ''{0}'' used by {2} ''{1}'', must have an enumeration facet value which specifies the notation elements used by this type. + enumeration-valid-restriction = enumeration-valid-restriction: Enumeration value ''{0}'' is not in the value space of the base type, {1}. + e-props-correct.2 = e-props-correct.2: Invalid value constraint value ''{1}'' in element ''{0}''. + e-props-correct.4 = e-props-correct.4: The '{'type definition'}' of element ''{0}'' is not validly derived from the '{'type definition'}' of the substitutionHead ''{1}'', or the '{'substitution group exclusions'}' property of ''{1}'' does not allow this derivation. + e-props-correct.5 = e-props-correct.5: A '{'value constraint'}' must not be present on element ''{0}'', because the element''s '{'type definition'}' or '{'type definition'}'''s '{'content type'}' is ID, or is derived from ID. + e-props-correct.6 = e-props-correct.6: Circular substitution group detected for element ''{0}''. + fractionDigits-valid-restriction = fractionDigits-valid-restriction: In the definition of {2}, the value ''{0}'' for the facet ''fractionDigits'' is invalid, because it must be <= the value for ''fractionDigits'' which was set to ''{1}'' in one of the ancestor types. + fractionDigits-totalDigits = fractionDigits-totalDigits: In the definition of {2}, the value ''{0}'' for the facet ''fractionDigits'' is invalid, because the value must be <= the value for ''totalDigits'' which is ''{1}''. + length-minLength-maxLength.1.1 = length-minLength-maxLength.1.1: For type {0}, it is an error for the value of length ''{1}'' to be less than the value of minLength ''{2}''. + length-minLength-maxLength.1.2.a = length-minLength-maxLength.1.2.a: For type {0}, it is an error for the base to not have a minLength facet if the current restriction has the minLength facet and the current restriction or base has the length facet. + length-minLength-maxLength.1.2.b = length-minLength-maxLength.1.2.b: For type {0}, it is an error for the current minLength ''{1}'' to not equal the base minLength ''{2}''. + length-minLength-maxLength.2.1 = length-minLength-maxLength.2.1: For type {0}, it is an error for the value of length ''{1}'' to be greater than the value of maxLength ''{2}''. + length-minLength-maxLength.2.2.a = length-minLength-maxLength.2.2.a: For type {0}, it is an error for the base to not have a maxLength facet if the current restriction has the maxLength facet and the current restriction or base has the length facet. + length-minLength-maxLength.2.2.b = length-minLength-maxLength.2.2.b: For type {0}, it is an error for the current maxLength ''{1}'' to not equal the base maxLength ''{2}''. + length-valid-restriction = length-valid-restriction: Error for type ''{2}''. The value of length = ''{0}'' must be = the value of that of the base type ''{1}''. + maxExclusive-valid-restriction.1 = maxExclusive-valid-restriction.1: Error for type ''{2}''. The maxExclusive value =''{0}'' must be <= maxExclusive of the base type ''{1}''. + maxExclusive-valid-restriction.2 = maxExclusive-valid-restriction.2: Error for type ''{2}''. The maxExclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + maxExclusive-valid-restriction.3 = maxExclusive-valid-restriction.3: Error for type ''{2}''. The maxExclusive value =''{0}'' must be > minInclusive of the base type ''{1}''. + maxExclusive-valid-restriction.4 = maxExclusive-valid-restriction.4: Error for type ''{2}''. The maxExclusive value =''{0}'' must be > minExclusive of the base type ''{1}''. + maxInclusive-maxExclusive = maxInclusive-maxExclusive: It is an error for both maxInclusive and maxExclusive to be specified for the same datatype. In {2}, maxInclusive = ''{0}'' and maxExclusive = ''{1}''. + maxInclusive-valid-restriction.1 = maxInclusive-valid-restriction.1: Error for type ''{2}''. The maxInclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + maxInclusive-valid-restriction.2 = maxInclusive-valid-restriction.2: Error for type ''{2}''. The maxInclusive value =''{0}'' must be < maxExclusive of the base type ''{1}''. + maxInclusive-valid-restriction.3 = maxInclusive-valid-restriction.3: Error for type ''{2}''. The maxInclusive value =''{0}'' must be >= minInclusive of the base type ''{1}''. + maxInclusive-valid-restriction.4 = maxInclusive-valid-restriction.4: Error for type ''{2}''. The maxInclusive value =''{0}'' must be > minExclusive of the base type ''{1}''. + maxLength-valid-restriction = maxLength-valid-restriction: In the definition of {2}, maxLength value = ''{0}'' must be <= that of the base type ''{1}''. + mg-props-correct.2 = mg-props-correct.2: Circular definitions detected for group ''{0}''. Recursively following the '{'term'}' values of the particles leads to a particle whose '{'term'}' is the group itself. + minExclusive-less-than-equal-to-maxExclusive = minExclusive-less-than-equal-to-maxExclusive: In the definition of {2}, minExclusive value = ''{0}'' must be <= maxExclusive value = ''{1}''. + minExclusive-less-than-maxInclusive = minExclusive-less-than-maxInclusive: In the definition of {2}, minExclusive value = ''{0}'' must be < maxInclusive value = ''{1}''. + minExclusive-valid-restriction.1 = minExclusive-valid-restriction.1: Error for type ''{2}''. The minExclusive value =''{0}'' must be >= minExclusive of the base type ''{1}''. + minExclusive-valid-restriction.2 = minExclusive-valid-restriction.2: Error for type ''{2}''. The minExclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + minExclusive-valid-restriction.3 = minExclusive-valid-restriction.3: Error for type ''{2}''. The minExclusive value =''{0}'' must be >= minInclusive of the base type ''{1}''. + minExclusive-valid-restriction.4 = minExclusive-valid-restriction.4: Error for type ''{2}''. The minExclusive value =''{0}'' must be < maxExclusive of the base type ''{1}''. + minInclusive-less-than-equal-to-maxInclusive = minInclusive-less-than-equal-to-maxInclusive: In the definition of {2}, minInclusive value = ''{0}'' must be <= maxInclusive value = ''{1}''. + minInclusive-less-than-maxExclusive = minInclusive-less-than-maxExclusive: In the definition of {2}, minInclusive value = ''{0}'' must be < maxExclusive value = ''{1}''. + minInclusive-minExclusive = minInclusive-minExclusive: It is an error for both minInclusive and minExclusive to be specified for the same datatype. In {2}, minInclusive = ''{0}'' and minExclusive = ''{1}''. + minInclusive-valid-restriction.1 = minInclusive-valid-restriction.1: Error for type ''{2}''. The minInclusive value =''{0}'' must be >= minInclusive of the base type ''{1}''. + minInclusive-valid-restriction.2 = minInclusive-valid-restriction.2: Error for type ''{2}''. The minInclusive value =''{0}'' must be <= maxInclusive of the base type ''{1}''. + minInclusive-valid-restriction.3 = minInclusive-valid-restriction.3: Error for type ''{2}''. The minInclusive value =''{0}'' must be > minExclusive of the base type ''{1}''. + minInclusive-valid-restriction.4 = minInclusive-valid-restriction.4: Error for type ''{2}''. The minInclusive value =''{0}'' must be < maxExclusive of the base type ''{1}''. + minLength-less-than-equal-to-maxLength = minLength-less-than-equal-to-maxLength: In the definition of {2}, value of minLength = ''{0}'' must be < value of maxLength = ''{1}''. + minLength-valid-restriction = minLength-valid-restriction: In the definition of {2}, minLength = ''{0}'' must be >= than that of the base type, ''{1}''. + no-xmlns = no-xmlns: The {name} of an attribute declaration must not match 'xmlns'. + no-xsi = no-xsi: The '{'target namespace'}' of an attribute declaration must not match ''{0}''. + p-props-correct.2.1 = p-props-correct.2.1: In the declaration of ''{0}'', the value of ''minOccurs'' is ''{1}'', but it must not be greater than the value of ''maxOccurs'', which is ''{2}''. + rcase-MapAndSum.1 = rcase-MapAndSum.1: There is not a complete functional mapping between the particles. + rcase-MapAndSum.2 = rcase-MapAndSum.2: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-NameAndTypeOK.1 = rcase-NameAndTypeOK.1: Elements have names and target namespaces which are not the same: Element ''{0}'' in namespace ''{1}'' and element ''{2}'' in namespace ''{3}''. + rcase-NameAndTypeOK.2 = rcase-NameAndTypeOK.2: Error for the particle whose '{'term'}' is the element declaration ''{0}''. The element declaration''s '{'nillable'}' is true, but the corresponding particle in the base type has an element declaration whose '{'nillable'}' is false. + rcase-NameAndTypeOK.3 = rcase-NameAndTypeOK.3: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}), of the corresponding particle in the base type. + rcase-NameAndTypeOK.4.a = rcase-NameAndTypeOK.4.a: Element ''{0}'' is not fixed, but the corresponding element in the base type is fixed with value ''{1}''. + rcase-NameAndTypeOK.4.b = rcase-NameAndTypeOK.4.b: Element ''{0}'' is fixed with value ''{1}'', but the corresponding element in the base type is fixed with value ''{2}''. + rcase-NameAndTypeOK.5 = rcase-NameAndTypeOK.5: Identity constraints for element ''{0}'' are not a subset of those in base. + rcase-NameAndTypeOK.6 = rcase-NameAndTypeOK.6: The disallowed substitutions for element ''{0}'' are not a superset of those in the base. + rcase-NameAndTypeOK.7 = rcase-NameAndTypeOK.7: The type of element ''{0}'', ''{1}'', is not derived from the type of the base element, ''{2}''. + rcase-NSCompat.1 = rcase-NSCompat.1: Element ''{0}'' has a namespace ''{1}'' which is not allowed by the wildcard in the base. + rcase-NSCompat.2 = rcase-NSCompat.2: Error for the particle whose '{'term'}' is the element declaration ''{0}''. Its occurrence range, ({1},{2}), is not a valid restriction of the range, ({3},{4}), of the corresponding particle in the base type. + rcase-NSRecurseCheckCardinality.1 = rcase-NSRecurseCheckCardinality.1: There is not a complete functional mapping between the particles. + rcase-NSRecurseCheckCardinality.2 = rcase-NSRecurseCheckCardinality.2: Group''s occurrence range, ({0},{1}), is not a valid restriction of base wildcard''s range, ({2},{3}). + rcase-NSSubset.1 = rcase-NSSubset.1: Wildcard is not a subset of corresponding wildcard in base. + rcase-NSSubset.2 = rcase-NSSubset.2: Wildcard''s occurrence range, ({0},{1}), is not a valid restriction of that in the base, ({2},{3}),. + rcase-NSSubset.3 = rcase-NSSubset.3: Wildcard''s process contents, ''{0}'', is weaker than that in the base, ''{1}''. + rcase-Recurse.1 = rcase-Recurse.1: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-Recurse.2 = rcase-Recurse.2: There is not a complete functional mapping between the particles. + rcase-RecurseLax.1 = rcase-RecurseLax.1: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-RecurseLax.2 = rcase-RecurseLax.2: There is not a complete functional mapping between the particles. + rcase-RecurseUnordered.1 = rcase-RecurseUnordered.1: Group''s occurrence range, ({0},{1}), is not a valid restriction of base group''s occurrence range, ({2},{3}). + rcase-RecurseUnordered.2 = rcase-RecurseUnordered.2: There is not a complete functional mapping between the particles. +# We're using sch-props-correct.2 instead of the old src-redefine.1 +# src-redefine.1 = src-redefine.1: The component ''{0}'' is begin redefined, but its corresponding component isn't in the schema document being redefined (with namespace ''{2}''), but in a different document, with namespace ''{1}''. + sch-props-correct.2 = sch-props-correct.2: A schema cannot contain two global components with the same name; this schema contains two occurrences of ''{0}''. + st-props-correct.2 = st-props-correct.2: Circular definitions have been detected for simple type ''{0}''. This means that ''{0}'' is contained in its own type hierarchy, which is an error. + st-props-correct.3 = st-props-correct.3: Error for type ''{0}''. The value of '{'final'}' of the '{'base type definition'}', ''{1}'', forbids derivation by restriction. + totalDigits-valid-restriction = totalDigits-valid-restriction: In the definition of {2}, the value ''{0}'' for the facet ''totalDigits'' is invalid, because it must be <= the value for ''totalDigits'' which was set to ''{1}'' in one of the ancestor types. + whiteSpace-valid-restriction.1 = whiteSpace-valid-restriction.1: In the definition of {0}, the value ''{1}'' for the facet ''whitespace'' is invalid, because the value for ''whitespace'' has been set to ''collapse'' in one of the ancestor types. + whiteSpace-valid-restriction.2 = whiteSpace-valid-restriction.2: In the definition of {0}, the value ''preserve'' for the facet ''whitespace'' is invalid, because the value for ''whitespace'' has been set to ''replace'' in one of the ancestor types. + +#schema for Schemas + + s4s-att-invalid-value = s4s-att-invalid-value: Invalid attribute value for ''{1}'' in element ''{0}''. Recorded reason: {2} + s4s-att-must-appear = s4s-att-must-appear: Attribute ''{1}'' must appear in element ''{0}''. + s4s-att-not-allowed = s4s-att-not-allowed: Attribute ''{1}'' cannot appear in element ''{0}''. + s4s-elt-invalid = s4s-elt-invalid: Element ''{0}'' is not a valid element in a schema document. + s4s-elt-must-match.1 = s4s-elt-must-match.1: The content of ''{0}'' must match {1}. A problem was found starting at: {2}. + s4s-elt-must-match.2 = s4s-elt-must-match.2: The content of ''{0}'' must match {1}. Not enough elements were found. + # the "invalid-content" messages provide less information than the "must-match" counterparts above. They're used for complex types when providing a "match" would be an information dump + s4s-elt-invalid-content.1 = s4s-elt-invalid-content.1: The content of ''{0}'' is invalid. Element ''{1}'' is invalid, misplaced, or occurs too often. + s4s-elt-invalid-content.2 = s4s-elt-invalid-content.2: The content of ''{0}'' is invalid. Element ''{1}'' cannot be empty. + s4s-elt-invalid-content.3 = s4s-elt-invalid-content.3: Elements of type ''{0}'' cannot appear after declarations as children of a <schema> element. + s4s-elt-schema-ns = s4s-elt-schema-ns: The namespace of element ''{0}'' must be from the schema namespace, ''http://www.w3.org/2001/XMLSchema''. + s4s-elt-character = s4s-elt-character: Non-whitespace characters are not allowed in schema elements other than ''xs:appinfo'' and ''xs:documentation''. Saw ''{0}''. + +# codes not defined by the spec + + c-fields-xpaths = c-fields-xpaths: The field value = ''{0}'' is not valid. + c-general-xpath = c-general-xpath: The expression ''{0}'' is not valid with respect to the XPath subset supported by XML Schema. + c-general-xpath-ns = c-general-xpath-ns: A namespace prefix in XPath expression ''{0}'' was not bound to a namespace. + c-selector-xpath = c-selector-xpath: The selector value = ''{0}'' is not valid; selector xpaths cannot contain attributes. + EmptyTargetNamespace = EmptyTargetNamespace: In schema document ''{0}'', the value of the ''targetNamespace'' attribute cannot be an empty string. + FacetValueFromBase = FacetValueFromBase: In the declaration of type ''{0}'', value ''{1}'' of facet ''{2}'' must be from the value space of the base type, ''{3}''. + FixedFacetValue = FixedFacetValue: In the definition of {3}, the value ''{1}'' for the facet ''{0}'' is invalid, because the value for ''{0}'' has been set to ''{2}'' in one of the ancestor types, and '{'fixed'}' = true. + InvalidRegex = InvalidRegex: Pattern value ''{0}'' is not a valid regular expression. The reported error was: ''{1}''. + maxOccurLimit = Current configuration of the parser doesn''t allow the expansion of a content model for a complex type to contain more than {0} nodes. + PublicSystemOnNotation = PublicSystemOnNotation: At least one of 'public' and 'system' must appear in element 'notation'. + SchemaLocation = SchemaLocation: schemaLocation value = ''{0}'' must have even number of URI''s. + TargetNamespace.1 = TargetNamespace.1: Expecting namespace ''{0}'', but the target namespace of the schema document is ''{1}''. + TargetNamespace.2 = TargetNamespace.2: Expecting no namespace, but the schema document has a target namespace of ''{1}''. + UndeclaredEntity = UndeclaredEntity: Entity ''{0}'' is not declared. + UndeclaredPrefix = UndeclaredPrefix: Cannot resolve ''{0}'' as a QName: the prefix ''{1}'' is not declared. + +# JAXP 1.2 schema source property errors + + jaxp12-schema-source-type.1 = The ''http://java.sun.com/xml/jaxp/properties/schemaSource'' property cannot have a value of type ''{0}''. Possible types of the value supported are String, File, InputStream, InputSource or an array of these types. + jaxp12-schema-source-type.2 = The ''http://java.sun.com/xml/jaxp/properties/schemaSource'' property cannot have an array value of type ''{0}''. Possible types of the array supported are Object, String, File, InputStream and InputSource. + jaxp12-schema-source-ns = When using an array of Objects as the value of the 'http://java.sun.com/xml/jaxp/properties/schemaSource' property, it is illegal to have two schemas that share the same target namespace. + diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XMLSerializerMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSerializerMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..5a86e03b88815ada2343e864fe8079cf0ceb6e64 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSerializerMessages.properties @@ -0,0 +1,50 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores error messages for the Xerces XML +# serializer. Many DOM Load/Save error messages also +# live here, since the serializer largely implements that package. +# +# As usual with properties files, the messages are arranged in +# key/value tuples. +# +# @version $Id: XMLSerializerMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + + ArgumentIsNull = Argument ''{0}'' is null. + NoWriterSupplied = No writer supplied for serializer. + MethodNotSupported = The method ''{0}'' is not supported by this factory. + ResetInMiddle = The serializer may not be reset in the middle of serialization. + Internal = Internal error: element state is zero. + NoName = There is no rawName and localName is null. + ElementQName = The element name ''{0}'' is not a QName. + ElementPrefix = Element ''{0}'' does not belong to any namespace: prefix could be undeclared or bound to some namespace. + AttributeQName = The attribute name ''{0}'' is not a QName. + AttributePrefix = Attribute ''{0}'' does not belong to any namespace: prefix could be undeclared or bound to some namespace. + InvalidNSDecl = Namespace declaration syntax is incorrect: {0}. + EndingCDATA = The character sequence \"]]>\" must not appear in content unless used to mark the end of a CDATA section. + SplittingCDATA = Splitting a CDATA section containing the CDATA section termination marker \"]]>\". + ResourceNotFound = The resource ''{0}'' could not be found. + ResourceNotLoaded = The resource ''{0}'' could not be loaded. {1} + SerializationStopped = Serialization stopped at user request. + + # DOM Level 3 load and save messages + no-output-specified = no-output-specified: The output destination for data to be written to was null. + unsupported-encoding = unsupported-encoding: An unsupported encoding is encountered. + unable-to-serialize-node = unable-to-serialize-node: The node could not be serialized. diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XMLSerializerMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSerializerMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..5a86e03b88815ada2343e864fe8079cf0ceb6e64 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XMLSerializerMessages_en.properties @@ -0,0 +1,50 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores error messages for the Xerces XML +# serializer. Many DOM Load/Save error messages also +# live here, since the serializer largely implements that package. +# +# As usual with properties files, the messages are arranged in +# key/value tuples. +# +# @version $Id: XMLSerializerMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + + BadMessageKey = The error message corresponding to the message key can not be found. + FormatFailed = An internal error occurred while formatting the following message:\n + + ArgumentIsNull = Argument ''{0}'' is null. + NoWriterSupplied = No writer supplied for serializer. + MethodNotSupported = The method ''{0}'' is not supported by this factory. + ResetInMiddle = The serializer may not be reset in the middle of serialization. + Internal = Internal error: element state is zero. + NoName = There is no rawName and localName is null. + ElementQName = The element name ''{0}'' is not a QName. + ElementPrefix = Element ''{0}'' does not belong to any namespace: prefix could be undeclared or bound to some namespace. + AttributeQName = The attribute name ''{0}'' is not a QName. + AttributePrefix = Attribute ''{0}'' does not belong to any namespace: prefix could be undeclared or bound to some namespace. + InvalidNSDecl = Namespace declaration syntax is incorrect: {0}. + EndingCDATA = The character sequence \"]]>\" must not appear in content unless used to mark the end of a CDATA section. + SplittingCDATA = Splitting a CDATA section containing the CDATA section termination marker \"]]>\". + ResourceNotFound = The resource ''{0}'' could not be found. + ResourceNotLoaded = The resource ''{0}'' could not be loaded. {1} + SerializationStopped = Serialization stopped at user request. + + # DOM Level 3 load and save messages + no-output-specified = no-output-specified: The output destination for data to be written to was null. + unsupported-encoding = unsupported-encoding: An unsupported encoding is encountered. + unable-to-serialize-node = unable-to-serialize-node: The node could not be serialized. diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XPointerMessages.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XPointerMessages.properties new file mode 100644 index 0000000000000000000000000000000000000000..cdd4c6e38a345dd322e2b54f3fa3b7630785c0ab --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XPointerMessages.properties @@ -0,0 +1,44 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces XPointer implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XPointerMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +# Messages for message reporting +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# XPointer Framework Error Messages +XPointerProcessingError = XPointerProcessingError: An error occurred while processing the XPointer expression. +InvalidXPointerToken = InvalidXPointerToken: The XPointer expression contains the invalid token ''{0}'' +InvalidXPointerExpression = InvalidXPointerExpression: The XPointer expression ''{0}'' is invalid. +MultipleShortHandPointers = MultipleShortHandPointers: The XPointer expression ''{0}'' is invalid. It has more than one ShortHand Pointer. +SchemeDataNotFollowedByCloseParenthesis = SchemeDataNotFollowedByCloseParenthesis: The XPointer expression ''{0}'' is invalid. The SchemeData was not followed by a '')'' character. +SchemeUnsupported = SchemeUnsupported: The XPointer scheme ''{0}'' is not supported. +InvalidShortHandPointer = InvalidShortHandPointer: The NCName of the ShortHand Pointer ''{0}'' is invalid. +UnbalancedParenthesisInXPointerExpression = UnbalancedParenthesisInXPointerExpression: The XPointer expression ''{0}'' is invalid. The number of open parenthesis ''{1}'' is not equal to the number of close parenthesis ''{2}''. +InvalidSchemeDataInXPointer = InvalidSchemeDataInXPointer: The XPointer expression ''{0}'' contains invalid SchemeData. + +# XPointer Element Scheme Error Messages +InvalidElementSchemeToken = InvalidElementSchemeToken: The element() scheme XPointer expression contains the invalid token ''{0}'' +InvalidElementSchemeXPointer = InvalidElementSchemeXPointer: The Element Scheme XPointer expression ''{0}'' is invalid. +XPointerElementSchemeProcessingError = XPointerElementSchemeProcessingError: An error occurred while processing the XPointer element() Scheme expression. +InvalidNCNameInElementSchemeData = InvalidNCNameInElementSchemeData: The element() Scheme contains a ShortHand Pointer ''{0}'' with an invalid NCName. +InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''. \ No newline at end of file diff --git a/src/main/resources/org/python/apache/xerces/impl/msg/XPointerMessages_en.properties b/src/main/resources/org/python/apache/xerces/impl/msg/XPointerMessages_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..cdd4c6e38a345dd322e2b54f3fa3b7630785c0ab --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/msg/XPointerMessages_en.properties @@ -0,0 +1,44 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file stores localized messages for the Xerces XPointer implementation. +# +# The messages are arranged in key and value tuples in a ListResourceBundle. +# +# @version $Id: XPointerMessages.properties 595211 2007-11-15 05:28:12Z mrglavas $ + +# Messages for message reporting +BadMessageKey = The error message corresponding to the message key can not be found. +FormatFailed = An internal error occurred while formatting the following message:\n + +# XPointer Framework Error Messages +XPointerProcessingError = XPointerProcessingError: An error occurred while processing the XPointer expression. +InvalidXPointerToken = InvalidXPointerToken: The XPointer expression contains the invalid token ''{0}'' +InvalidXPointerExpression = InvalidXPointerExpression: The XPointer expression ''{0}'' is invalid. +MultipleShortHandPointers = MultipleShortHandPointers: The XPointer expression ''{0}'' is invalid. It has more than one ShortHand Pointer. +SchemeDataNotFollowedByCloseParenthesis = SchemeDataNotFollowedByCloseParenthesis: The XPointer expression ''{0}'' is invalid. The SchemeData was not followed by a '')'' character. +SchemeUnsupported = SchemeUnsupported: The XPointer scheme ''{0}'' is not supported. +InvalidShortHandPointer = InvalidShortHandPointer: The NCName of the ShortHand Pointer ''{0}'' is invalid. +UnbalancedParenthesisInXPointerExpression = UnbalancedParenthesisInXPointerExpression: The XPointer expression ''{0}'' is invalid. The number of open parenthesis ''{1}'' is not equal to the number of close parenthesis ''{2}''. +InvalidSchemeDataInXPointer = InvalidSchemeDataInXPointer: The XPointer expression ''{0}'' contains invalid SchemeData. + +# XPointer Element Scheme Error Messages +InvalidElementSchemeToken = InvalidElementSchemeToken: The element() scheme XPointer expression contains the invalid token ''{0}'' +InvalidElementSchemeXPointer = InvalidElementSchemeXPointer: The Element Scheme XPointer expression ''{0}'' is invalid. +XPointerElementSchemeProcessingError = XPointerElementSchemeProcessingError: An error occurred while processing the XPointer element() Scheme expression. +InvalidNCNameInElementSchemeData = InvalidNCNameInElementSchemeData: The element() Scheme contains a ShortHand Pointer ''{0}'' with an invalid NCName. +InvalidChildSequenceCharacter = InvalidChildSequenceCharacter: The element() Scheme contains an invalid child sequence character ''{0}''. \ No newline at end of file diff --git a/src/main/resources/org/python/apache/xerces/impl/validation/ConfigurableValidationState.class b/src/main/resources/org/python/apache/xerces/impl/validation/ConfigurableValidationState.class new file mode 100644 index 0000000000000000000000000000000000000000..2ebc7b039070e1a245ced2f86a25fa0467ab579b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/validation/ConfigurableValidationState.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/validation/EntityState.class b/src/main/resources/org/python/apache/xerces/impl/validation/EntityState.class new file mode 100644 index 0000000000000000000000000000000000000000..6d5df97a4563a127a0579d7efc9eca456d3af957 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/validation/EntityState.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/validation/ValidationManager.class b/src/main/resources/org/python/apache/xerces/impl/validation/ValidationManager.class new file mode 100644 index 0000000000000000000000000000000000000000..ad02f684c3f8853fac83a96582066bcd37dd01ed Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/validation/ValidationManager.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/validation/ValidationState.class b/src/main/resources/org/python/apache/xerces/impl/validation/ValidationState.class new file mode 100644 index 0000000000000000000000000000000000000000..b6d9d516891855153255e330be79a28d96726408 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/validation/ValidationState.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$1.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d5dfdca70abb4d759a3eab3730a9ea5949e6c0f4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Axis.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Axis.class new file mode 100644 index 0000000000000000000000000000000000000000..a352d036c1fb9026710a82cef2d876ff1cbf40e9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Axis.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$LocationPath.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$LocationPath.class new file mode 100644 index 0000000000000000000000000000000000000000..38bac66a5ec80953d86acfe37d5e9691ec6b9e4f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$LocationPath.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$NodeTest.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$NodeTest.class new file mode 100644 index 0000000000000000000000000000000000000000..a4508f993d605db6d4b24f6249a66a4726fef9cb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$NodeTest.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Scanner.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Scanner.class new file mode 100644 index 0000000000000000000000000000000000000000..e706aab76db2a9165ae1a8f73d8f0fc9373ba4a2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Scanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Step.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Step.class new file mode 100644 index 0000000000000000000000000000000000000000..b8865bc1b00da2550e522007a5c58422ba8a0df2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Step.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Tokens.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Tokens.class new file mode 100644 index 0000000000000000000000000000000000000000..a5df6154a2f4b1a7035ddae53044b4b7430c97fb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath$Tokens.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPath.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath.class new file mode 100644 index 0000000000000000000000000000000000000000..6db0abdccd6b3ce3afc4d01954c1df3ba81901e2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPath.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/XPathException.class b/src/main/resources/org/python/apache/xerces/impl/xpath/XPathException.class new file mode 100644 index 0000000000000000000000000000000000000000..5b76390b829f6ae3cb647b6878a7633d5122d983 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/XPathException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/BMPattern.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/BMPattern.class new file mode 100644 index 0000000000000000000000000000000000000000..13f46acd238ad238835de92a61a7386b4cb7486d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/BMPattern.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/CaseInsensitiveMap.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/CaseInsensitiveMap.class new file mode 100644 index 0000000000000000000000000000000000000000..a22f0d813a42f6c9103428760e121566d4a97570 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/CaseInsensitiveMap.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Match.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Match.class new file mode 100644 index 0000000000000000000000000000000000000000..aa48ba3af727f7a4a342bbfbf644f807d62c029c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Match.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$CharOp.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$CharOp.class new file mode 100644 index 0000000000000000000000000000000000000000..a7adbcdf8050e66e8ef93c898ae8173bd39dfbb7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$CharOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ChildOp.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ChildOp.class new file mode 100644 index 0000000000000000000000000000000000000000..d593f1adf2c7cce940b78b6774ae5a9f51a3df9f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ChildOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ConditionOp.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ConditionOp.class new file mode 100644 index 0000000000000000000000000000000000000000..f9f0ca92bef9fa8ae3092afe22f1105c4c79b87d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ConditionOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ModifierOp.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ModifierOp.class new file mode 100644 index 0000000000000000000000000000000000000000..2aab7acf4e8ef6c55807ecad5b9ab2ac48e4d657 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$ModifierOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$RangeOp.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$RangeOp.class new file mode 100644 index 0000000000000000000000000000000000000000..703b2415fdf2134181bb3940714c9be9526fcccf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$RangeOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$StringOp.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$StringOp.class new file mode 100644 index 0000000000000000000000000000000000000000..8ceb35431085b323e0847b50e0560d3c3a3a6c10 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$StringOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$UnionOp.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$UnionOp.class new file mode 100644 index 0000000000000000000000000000000000000000..b89e9e3df85e4ddc50fe86ce164c90079abc89d2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op$UnionOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op.class new file mode 100644 index 0000000000000000000000000000000000000000..c0b970429a6e9632529431d50ac428799c32988e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Op.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/ParseException.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/ParseException.class new file mode 100644 index 0000000000000000000000000000000000000000..3657228452dc9fca5a21007adca6a4bd154a7be5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/ParseException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/ParserForXMLSchema.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/ParserForXMLSchema.class new file mode 100644 index 0000000000000000000000000000000000000000..c7015543954cfe86dd47308cd0d3256784829f11 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/ParserForXMLSchema.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/REUtil.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/REUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..bcf74ed8b73f96b103c051d576ab735be5ad5cce Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/REUtil.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RangeToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RangeToken.class new file mode 100644 index 0000000000000000000000000000000000000000..397e6438cd43a5feef7f03f0ee97e2243a36366a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RangeToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegexParser$ReferencePosition.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegexParser$ReferencePosition.class new file mode 100644 index 0000000000000000000000000000000000000000..dbee5312d62d4a35e1b5e1ee2a4c89aa44fece5c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegexParser$ReferencePosition.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegexParser.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegexParser.class new file mode 100644 index 0000000000000000000000000000000000000000..bff5bf7bfca168b8ba9d8152d08e41ffa1857a90 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegexParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$CharArrayTarget.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$CharArrayTarget.class new file mode 100644 index 0000000000000000000000000000000000000000..a0549c1bbfb8d8bafe9ecec6b2380d7c46ccefb5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$CharArrayTarget.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$CharacterIteratorTarget.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$CharacterIteratorTarget.class new file mode 100644 index 0000000000000000000000000000000000000000..6e05f16f04f73db489b29f99cf6ac2eaeff66aa4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$CharacterIteratorTarget.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$ClosureContext.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$ClosureContext.class new file mode 100644 index 0000000000000000000000000000000000000000..74f8e07c094469e5bbc3f0e7624db4baee29f6c0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$ClosureContext.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$Context.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$Context.class new file mode 100644 index 0000000000000000000000000000000000000000..afb2eef4a9d9f81f753027e4c87103f20ae81384 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$Context.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$ExpressionTarget.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$ExpressionTarget.class new file mode 100644 index 0000000000000000000000000000000000000000..1b86dd2e63ebdbc89212bd839d153adb3819a739 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$ExpressionTarget.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$StringTarget.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$StringTarget.class new file mode 100644 index 0000000000000000000000000000000000000000..00bff61c519b28d745af6d8728d7aa4a2be1b627 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression$StringTarget.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression.class new file mode 100644 index 0000000000000000000000000000000000000000..cffc362d156f63c161c9137f4234835f356a9f44 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/RegularExpression.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$CharToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$CharToken.class new file mode 100644 index 0000000000000000000000000000000000000000..21e7d10dbccc56b467a700806fd62d93058a40f1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$CharToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ClosureToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ClosureToken.class new file mode 100644 index 0000000000000000000000000000000000000000..ce0aab5c01f9b12c82ea124cad1c058ebb3c9a40 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ClosureToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ConcatToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ConcatToken.class new file mode 100644 index 0000000000000000000000000000000000000000..6bd00b4e5a9fccd992b9e1c9bf58ff28d2675970 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ConcatToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ConditionToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ConditionToken.class new file mode 100644 index 0000000000000000000000000000000000000000..7cc449987f2fe6bc3b44f802f10d27ac99af3d8f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ConditionToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$FixedStringContainer.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$FixedStringContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..88d87ab0abf0a48befa98f3f736e02dfce076df8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$FixedStringContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ModifierToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ModifierToken.class new file mode 100644 index 0000000000000000000000000000000000000000..1fdb6e83e64067a93ce13b8817501d71183b58dc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ModifierToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ParenToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ParenToken.class new file mode 100644 index 0000000000000000000000000000000000000000..7284a06bdb72d46a6bc643063114964a749333e2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$ParenToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$StringToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$StringToken.class new file mode 100644 index 0000000000000000000000000000000000000000..368cdb14e27ed5a8936d3d28bb776c378cfeda6b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$StringToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$UnionToken.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$UnionToken.class new file mode 100644 index 0000000000000000000000000000000000000000..8002ad5d1da935e2206ca82b5c0a3cf507df9bb9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token$UnionToken.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token.class b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token.class new file mode 100644 index 0000000000000000000000000000000000000000..ac60c39ead176d83f299a4078e086013d027a211 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/Token.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message.properties b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message.properties new file mode 100644 index 0000000000000000000000000000000000000000..ee5d50d491b9ed1e5f4f36ec3e79dd9a1897c928 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message.properties @@ -0,0 +1,58 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# @version $Id: message.properties 595212 2007-11-15 05:28:57Z mrglavas $ + +parser.parse.1=Wrong character. +parser.parse.2=Invalid reference number. +parser.next.1=A character is required after \\. +parser.next.2='?' is not expected. '(?:' or '(?=' or '(?!' or '(?<' or '(?#' or '(?>'? +parser.next.3='(?<=' or '(?<!' is expected. +parser.next.4=A comment is not terminated. +parser.factor.1=')' is expected. +parser.factor.2=Unexpected end of the pattern in a modifier group. +parser.factor.3=':' is expected. +parser.factor.4=Unexpected end of the pattern in a conditional group. +parser.factor.5=A back reference or an anchor or a lookahead or a lookbehind is expected in a conditional pattern. +parser.factor.6=There are more than three choices in a conditional group. +parser.atom.1=A character in U+0040-U+005f must follow \\c. +parser.atom.2=A '{' is required before a character category. +parser.atom.3=A property name is not closed by '}'. +parser.atom.4=Unexpected meta character. +parser.atom.5=Unknown property. +parser.cc.1=A POSIX character class must be closed by ':]'. +parser.cc.2=Unexpected end of the pattern in a character class. +parser.cc.3=Unknown name for a POSIX character class. +parser.cc.4='-' is invalid here. +parser.cc.5=']' is expected. +parser.cc.6='[' is invalid in a character class. Write '\\['. +parser.cc.7=']' is invalid in a character class. Write '\\]'. +parser.cc.8='-' is an invalid character range. Write '\\-'. +parser.ope.1='[' is expected. +parser.ope.2=')' or '-[' or '+[' or '&[' is expected. +parser.ope.3=The range end code point is less than the start code point. +parser.descape.1=Invalid Unicode hex notation. +parser.descape.2=Overflow in a hex notation. +parser.descape.3='\\x{' must be closed by '}'. +parser.descape.4=Invalid Unicode code point. +parser.descape.5=An anchor must not be here. +parser.process.1=This expression is not supported in the current option setting. +parser.quantifier.1=Invalid quantifier. A digit is expected. +parser.quantifier.2=Invalid quantifier. Invalid quantity or a '}' is missing. +parser.quantifier.3=Invalid quantifier. A digit or '}' is expected. +parser.quantifier.4=Invalid quantifier. A min quantity must be <= a max quantity. +parser.quantifier.5=Invalid quantifier. A quantity value overflow. diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_en.properties b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..ee5d50d491b9ed1e5f4f36ec3e79dd9a1897c928 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_en.properties @@ -0,0 +1,58 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# @version $Id: message.properties 595212 2007-11-15 05:28:57Z mrglavas $ + +parser.parse.1=Wrong character. +parser.parse.2=Invalid reference number. +parser.next.1=A character is required after \\. +parser.next.2='?' is not expected. '(?:' or '(?=' or '(?!' or '(?<' or '(?#' or '(?>'? +parser.next.3='(?<=' or '(?<!' is expected. +parser.next.4=A comment is not terminated. +parser.factor.1=')' is expected. +parser.factor.2=Unexpected end of the pattern in a modifier group. +parser.factor.3=':' is expected. +parser.factor.4=Unexpected end of the pattern in a conditional group. +parser.factor.5=A back reference or an anchor or a lookahead or a lookbehind is expected in a conditional pattern. +parser.factor.6=There are more than three choices in a conditional group. +parser.atom.1=A character in U+0040-U+005f must follow \\c. +parser.atom.2=A '{' is required before a character category. +parser.atom.3=A property name is not closed by '}'. +parser.atom.4=Unexpected meta character. +parser.atom.5=Unknown property. +parser.cc.1=A POSIX character class must be closed by ':]'. +parser.cc.2=Unexpected end of the pattern in a character class. +parser.cc.3=Unknown name for a POSIX character class. +parser.cc.4='-' is invalid here. +parser.cc.5=']' is expected. +parser.cc.6='[' is invalid in a character class. Write '\\['. +parser.cc.7=']' is invalid in a character class. Write '\\]'. +parser.cc.8='-' is an invalid character range. Write '\\-'. +parser.ope.1='[' is expected. +parser.ope.2=')' or '-[' or '+[' or '&[' is expected. +parser.ope.3=The range end code point is less than the start code point. +parser.descape.1=Invalid Unicode hex notation. +parser.descape.2=Overflow in a hex notation. +parser.descape.3='\\x{' must be closed by '}'. +parser.descape.4=Invalid Unicode code point. +parser.descape.5=An anchor must not be here. +parser.process.1=This expression is not supported in the current option setting. +parser.quantifier.1=Invalid quantifier. A digit is expected. +parser.quantifier.2=Invalid quantifier. Invalid quantity or a '}' is missing. +parser.quantifier.3=Invalid quantifier. A digit or '}' is expected. +parser.quantifier.4=Invalid quantifier. A min quantity must be <= a max quantity. +parser.quantifier.5=Invalid quantifier. A quantity value overflow. diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_fr.properties b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6c1e84029e3b91d087a3030c55dd3db242c531f2 --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_fr.properties @@ -0,0 +1,58 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# @version $Id: message_fr.properties 595212 2007-11-15 05:28:57Z mrglavas $ + +parser.parse.1=Caract\u00e8re erron\u00e9. +parser.parse.2=Num\u00e9ro de r\u00e9f\u00e9rence non valide. +parser.next.1=Un caract\u00e8re est requis apr\u00e8s \\. +parser.next.2='?' n'est pas attendu. '(?:', '(?=', '(?!', '(?<', '(?#', '(?>'? +parser.next.3='(?<=' ou '(?<!' est attendu. +parser.next.4=Commentaire sans caract\u00e8re de terminaison. +parser.factor.1=')' attendu. +parser.factor.2=Fin du mod\u00e8le attendue dans un groupe de modificateurs. +parser.factor.3=':' attendu. +parser.factor.4=Fin du mod\u00e8le inattendue dans un groupe conditionnel. +parser.factor.5=Un mod\u00e8le conditionnel doit contenir un renvoi, une ancre, une lecture anticip\u00e9e ou une lecture diff\u00e9r\u00e9e. +parser.factor.6=Un groupe conditionnel comporte plus de trois choix. +parser.atom.1=Un caract\u00e8re de U+0040-U+005f doit suivre \\c. +parser.atom.2=Une accolade ('{') est obligatoire devant une cat\u00e9gorie de caract\u00e8res. +parser.atom.3=Un nom de propri\u00e9t\u00e9 n'est pas ferm\u00e9 par '}'. +parser.atom.4=M\u00e9ta-caract\u00e8re inattendu. +parser.atom.5=Propri\u00e9t\u00e9 inconnue. +parser.cc.1=Une classe de caract\u00e8res POSIX doit \u00eatre ferm\u00e9e par ':]'. +parser.cc.2=Fin du mod\u00e8le inattendue dans une classe de caract\u00e8res. +parser.cc.3=Nom inconnu pour une classe de caract\u00e8res POSIX. +parser.cc.4='-' n'est pas valide ici. +parser.cc.5=']' est attendu. +parser.cc.6='[' n'est pas valide dans une classe de caract\u00e8res. Ecrire '\\['. +parser.cc.7=']' n'est pas valide dans une classe de caract\u00e8res. Ecrire '\\['. +parser.cc.8='-' n'est pas valide dans un intervalle de caract\u00e8res. Ecrire '\\-'. +parser.ope.1='[' est attendu. +parser.ope.2=')', '-[', '+[' ou '&[' est attendu. +parser.ope.3=Le point de code final doit \u00eatre inf\u00e9rieur au point de code initial dans l'intervalle. +parser.descape.1=Notation hexad\u00e9cimale Unicode non valide. +parser.descape.2=D\u00e9passement d'une notation hexad\u00e9cimale. +parser.descape.3='\\x{' doit \u00eatre ferm\u00e9 par '}'. +parser.descape.4=Point de code Unicode non valide. +parser.descape.5=Une ancre ne doit pas figurer ici. +parser.process.1=Cette expression n'est pas prise en charge dans le param\u00e8tre d'option courant. +parser.quantifier.1=Quantifieur non valide. Valeur num\u00e9rique requise. +parser.quantifier.2=Quantifieur non valide. Quantit\u00e9 non valide ou '}' manquant. +parser.quantifier.3=Quantifieur non valide. Nombre ou '}' obligatoire. +parser.quantifier.4=Quantifieur non valide. Une quantit\u00e9 minimale doit \u00eatre <= \u00e0 une quantit\u00e9 maximale. +parser.quantifier.5=Quantifieur non valide. D\u00e9passement de quantit\u00e9. diff --git a/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_ja.properties b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_ja.properties new file mode 100644 index 0000000000000000000000000000000000000000..043e5fa66682b67d20a51f9a0508ae0adbdfa2ab --- /dev/null +++ b/src/main/resources/org/python/apache/xerces/impl/xpath/regex/message_ja.properties @@ -0,0 +1,58 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# @version $Id: message_ja.properties 595212 2007-11-15 05:28:57Z mrglavas $ + +parser.parse.1=\u4e0d\u5f53\u306a\u6587\u5b57\u3002 +parser.parse.2=\u7121\u52b9\u306a\u53c2\u7167\u756a\u53f7\u3002 +parser.next.1=\\ \u306e\u5f8c\u306b\u6587\u5b57\u304c\u5fc5\u8981\u3067\u3059\u3002 +parser.next.2='?' \u306f\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002'(?:' \u307e\u305f\u306f '(?=' \u307e\u305f\u306f '(?!' \u307e\u305f\u306f '(?<' \u307e\u305f\u306f '(?#' \u307e\u305f\u306f '(?>'? +parser.next.3='(?<=' \u307e\u305f\u306f '(?<!' \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.next.4=\u30b3\u30e1\u30f3\u30c8\u304c\u7d42\u7d50\u3057\u3066\u3044\u307e\u305b\u3093\u3002 +parser.factor.1=')' \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.factor.2=\u4fee\u98fe\u5b50\u30b0\u30eb\u30fc\u30d7\u5185\u3067\u30d1\u30bf\u30fc\u30f3\u306e\u4e88\u671f\u3057\u306a\u3044\u7d42\u4e86\u3002 +parser.factor.3=':' \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.factor.4=\u6761\u4ef6\u4ed8\u304d\u30b0\u30eb\u30fc\u30d7\u5185\u3067\u30d1\u30bf\u30fc\u30f3\u306e\u4e88\u671f\u3057\u306a\u3044\u7d42\u4e86\u3002 +parser.factor.5=\u6761\u4ef6\u4ed8\u304d\u30d1\u30bf\u30fc\u30f3\u3067\u306f\u9006\u53c2\u7167\u307e\u305f\u306f\u30a2\u30f3\u30ab\u30fc\u307e\u305f\u306f\u5148\u8aad\u307f\u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.factor.6=\u6761\u4ef6\u4ed8\u304d\u30b0\u30eb\u30fc\u30d7\u306b 3 \u3064\u3092\u8d85\u3048\u308b\u9078\u629e\u9805\u76ee\u304c\u3042\u308a\u307e\u3059\u3002 +parser.atom.1=\u5f8c\u306b \\c \u304c\u5fc5\u8981\u306a\u6587\u5b57\u304c U+0040-U+005f \u306b\u3042\u308a\u307e\u3059\u3002 +parser.atom.2=\u6587\u5b57\u30ab\u30c6\u30b4\u30ea\u30fc\u306e\u524d\u306b '{' \u304c\u5fc5\u8981\u3067\u3059\u3002 +parser.atom.3=\u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u540d\u304c '}' \u3067\u9589\u3058\u3089\u308c\u3066\u3044\u307e\u305b\u3093\u3002 +parser.atom.4=\u4e88\u671f\u3057\u306a\u3044\u30e1\u30bf\u6587\u5b57\u3002 +parser.atom.5=\u4e0d\u660e\u306a\u30d7\u30ed\u30d1\u30c6\u30a3\u30fc\u3002 +parser.cc.1=POSIX \u6587\u5b57\u30af\u30e9\u30b9\u306f ':]' \u3067\u9589\u3058\u3089\u308c\u3066\u3044\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002 +parser.cc.2=\u6587\u5b57\u30af\u30e9\u30b9\u5185\u3067\u30d1\u30bf\u30fc\u30f3\u306e\u4e88\u671f\u3057\u306a\u3044\u7d42\u4e86\u3002 +parser.cc.3=POSIX \u6587\u5b57\u30af\u30e9\u30b9\u306e\u540d\u524d\u304c\u4e0d\u660e\u3067\u3059\u3002 +parser.cc.4='-' \u306f\u3053\u3053\u3067\u306f\u7121\u52b9\u3067\u3059\u3002 +parser.cc.5=']' \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.cc.6='[' \u306f\u6587\u5b57\u30af\u30e9\u30b9\u5185\u3067\u306f\u7121\u52b9\u3067\u3059\u3002'\\[' \u3068\u66f8\u3044\u3066\u304f\u3060\u3055\u3044\u3002 +parser.cc.7=']' \u306f\u6587\u5b57\u30af\u30e9\u30b9\u5185\u3067\u306f\u7121\u52b9\u3067\u3059\u3002'\\]' \u3068\u66f8\u3044\u3066\u304f\u3060\u3055\u3044\u3002 +parser.cc.8='-' \u306f\u7121\u52b9\u306a\u6587\u5b57\u7bc4\u56f2\u3067\u3059\u3002'\\-' \u3068\u66f8\u3044\u3066\u304f\u3060\u3055\u3044\u3002 +parser.ope.1='[' \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.ope.2=')' \u307e\u305f\u306f '-[' \u307e\u305f\u306f '+[' \u307e\u305f\u306f '&[' \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.ope.3=\u7bc4\u56f2\u7d42\u4e86\u30b3\u30fc\u30c9\u30fb\u30dd\u30a4\u30f3\u30c8\u304c\u958b\u59cb\u30b3\u30fc\u30c9\u30fb\u30dd\u30a4\u30f3\u30c8\u3088\u308a\u5c0f\u3055\u3044\u5024\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002 +parser.descape.1=\u7121\u52b9\u306a Unicode 16 \u9032\u8868\u8a18\u3002 +parser.descape.2=16 \u9032\u8868\u8a18\u3067\u30aa\u30fc\u30d0\u30fc\u30d5\u30ed\u30fc\u3002 +parser.descape.3='\\x{' \u306f '}' \u3067\u9589\u3058\u3089\u308c\u3066\u3044\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002 +parser.descape.4=\u7121\u52b9\u306a Unicode \u30b3\u30fc\u30c9\u30fb\u30dd\u30a4\u30f3\u30c8\u3002 +parser.descape.5=\u3053\u3053\u306b\u30a2\u30f3\u30ab\u30fc\u304c\u3042\u3063\u3066\u306f\u306a\u308a\u307e\u305b\u3093\u3002 +parser.process.1=\u3053\u306e\u5f0f\u306f\u73fe\u5728\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u8a2d\u5b9a\u3067\u306f\u30b5\u30dd\u30fc\u30c8\u3055\u308c\u307e\u305b\u3093\u3002 +parser.quantifier.1=\u6570\u91cf\u8a5e\u304c\u7121\u52b9\u3067\u3059\u3002\u6570\u5b57\u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.quantifier.2=\u6570\u91cf\u8a5e\u304c\u7121\u52b9\u3067\u3059\u3002\u6570\u91cf\u304c\u7121\u52b9\u304b\u3001\u307e\u305f\u306f '}' \u304c\u3042\u308a\u307e\u305b\u3093\u3002 +parser.quantifier.3=\u6570\u91cf\u8a5e\u304c\u7121\u52b9\u3067\u3059\u3002\u6570\u5b57\u307e\u305f\u306f '}' \u304c\u671f\u5f85\u3055\u308c\u3066\u3044\u307e\u3059\u3002 +parser.quantifier.4=\u6570\u91cf\u8a5e\u304c\u7121\u52b9\u3067\u3059\u3002\u6700\u5c0f\u6570\u91cf\u306f\u6700\u5927\u6570\u91cf\u4ee5\u4e0b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002 +parser.quantifier.5=\u6570\u91cf\u8a5e\u304c\u7121\u52b9\u3067\u3059\u3002\u6570\u91cf\u5024\u304c\u30aa\u30fc\u30d0\u30fc\u30d5\u30ed\u30fc\u3057\u3066\u3044\u307e\u3059\u3002 diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/AttributePSVImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/AttributePSVImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..21e7816ba807102e42efceed1e3c5c53fb9deabc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/AttributePSVImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/ElementPSVImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/ElementPSVImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..355cd14ad172a0997491f8a49e37d6a6539f1c38 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/ElementPSVImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/FilePathToURI.class b/src/main/resources/org/python/apache/xerces/impl/xs/FilePathToURI.class new file mode 100644 index 0000000000000000000000000000000000000000..98e1f62f38a52ea4e78e00439f68a6974309eba4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/FilePathToURI.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/PSVIErrorList.class b/src/main/resources/org/python/apache/xerces/impl/xs/PSVIErrorList.class new file mode 100644 index 0000000000000000000000000000000000000000..951203d375d04dfd9b98323a5eb4241b13aff8e1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/PSVIErrorList.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$BuiltinAttrDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$BuiltinAttrDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..911b5a5dc700fa63bf25f9fd10b8b7b42272a9a8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$BuiltinAttrDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$BuiltinSchemaGrammar.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$BuiltinSchemaGrammar.class new file mode 100644 index 0000000000000000000000000000000000000000..0bacf0e703942a596fea7fc31e56cd4980e3d163 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$BuiltinSchemaGrammar.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$Schema4Annotations.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$Schema4Annotations.class new file mode 100644 index 0000000000000000000000000000000000000000..ee2861222ecfa3a0de9c251164e3d7888bb21007 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$Schema4Annotations.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$XSAnyType.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$XSAnyType.class new file mode 100644 index 0000000000000000000000000000000000000000..d6de9989e881644a9e4a5cf27127349f138fb02e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar$XSAnyType.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar.class new file mode 100644 index 0000000000000000000000000000000000000000..e636bf5c6ae83572cde2b363af315fd44642303b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaGrammar.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaNamespaceSupport$SchemaRootContext.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaNamespaceSupport$SchemaRootContext.class new file mode 100644 index 0000000000000000000000000000000000000000..4ae32d96c2b4935dee9ddd2ed538b1d66dc40b11 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaNamespaceSupport$SchemaRootContext.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaNamespaceSupport.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaNamespaceSupport.class new file mode 100644 index 0000000000000000000000000000000000000000..44b19584cc5021c16d5be89f27c6599d196008b0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaNamespaceSupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SchemaSymbols.class b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaSymbols.class new file mode 100644 index 0000000000000000000000000000000000000000..2899a31620fe89e443dbef5f2c93d1974e312239 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SchemaSymbols.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SubstitutionGroupHandler$OneSubGroup.class b/src/main/resources/org/python/apache/xerces/impl/xs/SubstitutionGroupHandler$OneSubGroup.class new file mode 100644 index 0000000000000000000000000000000000000000..d13b4e4d68d826dcd5b0e317b4519d962c4a4412 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SubstitutionGroupHandler$OneSubGroup.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/SubstitutionGroupHandler.class b/src/main/resources/org/python/apache/xerces/impl/xs/SubstitutionGroupHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..e787defd4ae52ddb6e4438b15b6679e820fd23ee Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/SubstitutionGroupHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaException.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaException.class new file mode 100644 index 0000000000000000000000000000000000000000..52bed19ce36b23f788b70a2dd0d8fbe2095f68d8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaException.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaLoader$LocationArray.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaLoader$LocationArray.class new file mode 100644 index 0000000000000000000000000000000000000000..5ba32356238c01ef4a0041e2e486e4028d935b56 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaLoader$LocationArray.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaLoader.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..5a9b39498aa8876c9bf581a7d9ff72a81b017ff1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaLoader.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$KeyRefValueStore.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$KeyRefValueStore.class new file mode 100644 index 0000000000000000000000000000000000000000..bee71650b32679d81f9e514fae020176cd30d25a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$KeyRefValueStore.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$KeyValueStore.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$KeyValueStore.class new file mode 100644 index 0000000000000000000000000000000000000000..4f42ba9dec1334ccc4c92d7b75270f451d384331 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$KeyValueStore.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$LocalIDKey.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$LocalIDKey.class new file mode 100644 index 0000000000000000000000000000000000000000..e50872b4a3118f9c7c0ad97c9d2bbcf5dc470aa7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$LocalIDKey.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ShortVector.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ShortVector.class new file mode 100644 index 0000000000000000000000000000000000000000..c96cc62c6cc0f5b26d6e704e62f47d573edacb70 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ShortVector.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$UniqueValueStore.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$UniqueValueStore.class new file mode 100644 index 0000000000000000000000000000000000000000..30f1113aa724a531f96b9eecdd1fc1fa8ed375cc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$UniqueValueStore.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ValueStoreBase.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ValueStoreBase.class new file mode 100644 index 0000000000000000000000000000000000000000..28874d71a06af5235e43451bc57fffa16942be2a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ValueStoreBase.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ValueStoreCache.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ValueStoreCache.class new file mode 100644 index 0000000000000000000000000000000000000000..797fbeb4a448890bee0128382fbeb72b9edde8c4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$ValueStoreCache.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$XPathMatcherStack.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$XPathMatcherStack.class new file mode 100644 index 0000000000000000000000000000000000000000..c02f55f38f24c33e29066d205a098de74e7fe488 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$XPathMatcherStack.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$XSIErrorReporter.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$XSIErrorReporter.class new file mode 100644 index 0000000000000000000000000000000000000000..44aecf686ea37f45c4ced79c7b00399f92372848 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator$XSIErrorReporter.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator.class b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..a8061a7a4e111ee4784e082e9af168ce02864831 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XMLSchemaValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSAnnotationImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSAnnotationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..4838439737ac305241bdc79b1931b3347468ec12 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSAnnotationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..609a8233a43cecf31ccad372271cedf967de73e9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeGroupDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeGroupDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..af19368c35f9357a723fc81a18c62f1df62efff9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeGroupDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeUseImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeUseImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8989d8deb69f5a9638620f5a5ddc07e7e57770ff Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSAttributeUseImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSComplexTypeDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSComplexTypeDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..a261a3d785a3c88618834eed2ab38addfc08d7d9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSComplexTypeDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSConstraints$1.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSConstraints$1.class new file mode 100644 index 0000000000000000000000000000000000000000..24118f55d7e786019cca3e6e7c5899814d785ef1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSConstraints$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSConstraints.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSConstraints.class new file mode 100644 index 0000000000000000000000000000000000000000..0486814ea9309980991fc3671ecf8cce399088ba Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSConstraints.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSDDescription.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSDDescription.class new file mode 100644 index 0000000000000000000000000000000000000000..31ba36faf6ef26bf0a5c935c73b2bcfca70fbc38 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSDDescription.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSDeclarationPool.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSDeclarationPool.class new file mode 100644 index 0000000000000000000000000000000000000000..8b41031fd9af803b3b5f08e7a24e5cfccf2a9996 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSDeclarationPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSElementDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSElementDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..6725583640aff37071edfe65ad656f4fba8e3678 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSElementDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSElementDeclHelper.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSElementDeclHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..dddc0fd5caa4e6cab5fdfd27b6a70a3ce9482b1f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSElementDeclHelper.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSGrammarBucket.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSGrammarBucket.class new file mode 100644 index 0000000000000000000000000000000000000000..710675ddc35aec1bc5820b224c25d9fe02dfd8ff Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSGrammarBucket.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSGroupDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSGroupDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..b93f1e4391803ff417cff6629ce84e3b122da9eb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSGroupDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSImplementationImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSImplementationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..f910c9ec09763ba0cd35f0f6118bcce2f5dc8abe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSImplementationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSLoaderImpl$XSGrammarMerger.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSLoaderImpl$XSGrammarMerger.class new file mode 100644 index 0000000000000000000000000000000000000000..0745d362a0b95a7fdbc9ba69a3da4a331d691e9c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSLoaderImpl$XSGrammarMerger.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSLoaderImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSLoaderImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..81556725e6711474e01245294cf3b780ab376c52 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSLoaderImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSMessageFormatter.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..b2c5a194494f79160bfd5ae8740c0d08893b8685 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSModelGroupImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSModelGroupImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..11c5e288ed6756ea029314ea26e099b46d86d139 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSModelGroupImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSModelImpl$XSNamespaceItemListIterator.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSModelImpl$XSNamespaceItemListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..2455b94ece9f5623a211860791eda8fc5992069b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSModelImpl$XSNamespaceItemListIterator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSModelImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSModelImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b5beeb7da4390df1ca2c8647cca88d5111609b08 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSModelImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSNotationDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSNotationDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..5b23b5206902f82b23efaf10a0c18954cb676b90 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSNotationDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSParticleDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSParticleDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..ee2c2d5f6cb959a63463648f5b6b5341984d3e87 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSParticleDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/XSWildcardDecl.class b/src/main/resources/org/python/apache/xerces/impl/xs/XSWildcardDecl.class new file mode 100644 index 0000000000000000000000000000000000000000..3533692ce88a087d9a44386c9de3d6389e31af13 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/XSWildcardDecl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field$Matcher.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field$Matcher.class new file mode 100644 index 0000000000000000000000000000000000000000..47b333798feaa3a818b5c06c658f8c50d0c2927c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field$Matcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field$XPath.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field$XPath.class new file mode 100644 index 0000000000000000000000000000000000000000..7301b16e49591a0eeadd0bcc88a037ce20c139e0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field$XPath.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field.class new file mode 100644 index 0000000000000000000000000000000000000000..5310f8f27cd64dedc8ca4e866a59ddc2b9410175 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Field.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/FieldActivator.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/FieldActivator.class new file mode 100644 index 0000000000000000000000000000000000000000..344b6fba8477d7f20ae0f40ec370c3ce75083208 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/FieldActivator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/IdentityConstraint.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/IdentityConstraint.class new file mode 100644 index 0000000000000000000000000000000000000000..4c48c9baffc002a0189ac60d2f5993b68bdfa3ac Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/IdentityConstraint.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/KeyRef.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/KeyRef.class new file mode 100644 index 0000000000000000000000000000000000000000..be20c4959bbbb9fa24d673bf87246f06073ea5eb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/KeyRef.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector$Matcher.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector$Matcher.class new file mode 100644 index 0000000000000000000000000000000000000000..10a652b0e63c55de7f8c5c8d4c6b48d0015f19e3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector$Matcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector$XPath.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector$XPath.class new file mode 100644 index 0000000000000000000000000000000000000000..21620dda894c04bc5ff787886b57e1569076b095 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector$XPath.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector.class new file mode 100644 index 0000000000000000000000000000000000000000..1cd5bbbcc4ea44dfcf970f29c33ba47d5e0d8a85 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/Selector.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/UniqueOrKey.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/UniqueOrKey.class new file mode 100644 index 0000000000000000000000000000000000000000..0c3c70209d0e0f7c4fdfe90dc3d836375e445239 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/UniqueOrKey.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/ValueStore.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/ValueStore.class new file mode 100644 index 0000000000000000000000000000000000000000..995f292c81c0fb3c562b5ecc18c4263257cf427b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/ValueStore.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/identity/XPathMatcher.class b/src/main/resources/org/python/apache/xerces/impl/xs/identity/XPathMatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..6329c5e9f5ddf0f96866cdfd4bd3106f3e0ed1eb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/identity/XPathMatcher.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/CMBuilder.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/CMBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..8804eca7b13b5425ae3455b9adf2533e9707b8e8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/CMBuilder.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/CMNodeFactory.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/CMNodeFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..43152f395de81bcfa28ef8d3cd539bb017d52ffa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/CMNodeFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSAllCM.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSAllCM.class new file mode 100644 index 0000000000000000000000000000000000000000..b7cbd230dbd167b3ece4f2b0d131f0dcd3e255d0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSAllCM.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMBinOp.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMBinOp.class new file mode 100644 index 0000000000000000000000000000000000000000..5534fde7fd5474049f6dd548a9fd2fcbdc54bc11 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMBinOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMLeaf.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMLeaf.class new file mode 100644 index 0000000000000000000000000000000000000000..4490b66295f7151ec1295cf530d712c021b84e3b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMLeaf.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMRepeatingLeaf.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMRepeatingLeaf.class new file mode 100644 index 0000000000000000000000000000000000000000..5a08d6ebb67110434b1751e805f0efb39549593f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMRepeatingLeaf.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMUniOp.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMUniOp.class new file mode 100644 index 0000000000000000000000000000000000000000..b35b296ff2c1af952aca228784319e8f2e37aa74 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMUniOp.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMValidator.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMValidator.class new file mode 100644 index 0000000000000000000000000000000000000000..7a6bb350f4e706e21beeddb10a58d0bbc7142ced Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSCMValidator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSDFACM$Occurence.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSDFACM$Occurence.class new file mode 100644 index 0000000000000000000000000000000000000000..d79190300e93ea114ef01e8bf2a39c9e5b4424d9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSDFACM$Occurence.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSDFACM.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSDFACM.class new file mode 100644 index 0000000000000000000000000000000000000000..cbd9c91f750e98c062b7a8f205647bb1697d0955 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSDFACM.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/models/XSEmptyCM.class b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSEmptyCM.class new file mode 100644 index 0000000000000000000000000000000000000000..286ce747cfa901d74bf6a73e5c94848688567db3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/models/XSEmptyCM.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/AttrImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/AttrImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7e4c747b67a7c51ddf6973a81cc4ca96b9e52937 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/AttrImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultDocument.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultDocument.class new file mode 100644 index 0000000000000000000000000000000000000000..fc6cd458b863d703098ec80916cfd7539c7f4231 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultDocument.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultElement.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultElement.class new file mode 100644 index 0000000000000000000000000000000000000000..e7baf6386a4ac1507eeac64abbcf9ab53a05cc75 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultElement.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultNode.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultNode.class new file mode 100644 index 0000000000000000000000000000000000000000..6b73e0169e5a4c1f753234f74d55044a12201b28 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultNode.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultText.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultText.class new file mode 100644 index 0000000000000000000000000000000000000000..7a618d1c7ab56dc178a853a69b0a6d99a0b33e19 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultText.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultXMLDocumentHandler.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultXMLDocumentHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..61262b42301299e1dd0040d8753cb0c44b5bb393 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/DefaultXMLDocumentHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/ElementImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/ElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..849388af2e7f8ee4eebe2dc338828e42ea80cb8c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/ElementImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/NamedNodeMapImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/NamedNodeMapImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a08382b3e799df9ed07f4c4e0352646fd0f718c9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/NamedNodeMapImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/NodeImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/NodeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b52f4c60d3dd037d260c65a698a8ac5f77db58bb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/NodeImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOM.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOM.class new file mode 100644 index 0000000000000000000000000000000000000000..bb1ed6ba6c529e1d0a429ba0206a3f542513a006 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOM.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMImplementation.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMImplementation.class new file mode 100644 index 0000000000000000000000000000000000000000..fd5fe10b590c9cf5c5461b7aedb2ab9035de0b9c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMImplementation.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMParser$BooleanStack.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMParser$BooleanStack.class new file mode 100644 index 0000000000000000000000000000000000000000..284f97a84036a5d2c4180e3e5a9d81043ae20504 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMParser$BooleanStack.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMParser.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMParser.class new file mode 100644 index 0000000000000000000000000000000000000000..cc41da398f2a9b2dab5f548377385653af184a5c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaDOMParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaParsingConfig.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaParsingConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..954ca8e54a873d2839c8a2bea1fe68fe5a38c9cd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/SchemaParsingConfig.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/opti/TextImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/opti/TextImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e00e0c6f7b2877de291f62b3bbebfaf26bc60593 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/opti/TextImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/Container.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/Container.class new file mode 100644 index 0000000000000000000000000000000000000000..58a50851addab6fcca7dddfe5adcbae980fd39ee Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/Container.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/LargeContainer.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/LargeContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..54d71ac1d3e311c5f1ad17e92ef8b58962628828 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/LargeContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/OneAttr.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/OneAttr.class new file mode 100644 index 0000000000000000000000000000000000000000..3129e7c064975921d7e3e5c433e5aebbc951c509 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/OneAttr.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/SchemaContentHandler.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/SchemaContentHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..f42ae444ed7e24b091af69ed96e58d26c44496d4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/SchemaContentHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/SmallContainer.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/SmallContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..c902cbe7555477cedfdb1e270bf8895404293d32 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/SmallContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/StAXSchemaParser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/StAXSchemaParser.class new file mode 100644 index 0000000000000000000000000000000000000000..bb552514f9e10fffa62e2155ca3b16cb2156726a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/StAXSchemaParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSAnnotationInfo.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSAnnotationInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..1ce511185ced007c5f2884e1b12b388731b3b7ca Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSAnnotationInfo.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSAttributeChecker.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSAttributeChecker.class new file mode 100644 index 0000000000000000000000000000000000000000..86e9418d1cb028ab348e55f68d2e65029e953139 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSAttributeChecker.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractIDConstraintTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractIDConstraintTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..99fddf1791ec4763d06898e9fa034dccd3be6fcf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractIDConstraintTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser$ParticleArray.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser$ParticleArray.class new file mode 100644 index 0000000000000000000000000000000000000000..44cbde3e2bb28a608b0573539bc1db2c2c3bdc33 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser$ParticleArray.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..e0aec9f6fe003ffaaea417ccce88dda2769165a9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractParticleTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractTraverser$FacetInfo.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractTraverser$FacetInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..5234e8f429932a926f223f3557433a9563b68faa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractTraverser$FacetInfo.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..4620c4d4883cbf54137362447686d4872cf09b21 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAbstractTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAttributeGroupTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAttributeGroupTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..085d1271d325d15599d9fe0eaae30298959b1b7d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAttributeGroupTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAttributeTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAttributeTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..2341fc48f0ce4c5d527c741c11df77f233d34e7d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDAttributeTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser$ComplexTypeRecoverableError.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser$ComplexTypeRecoverableError.class new file mode 100644 index 0000000000000000000000000000000000000000..6354eeac8b69677a96e8bc0cf99b1e4645ce8fe4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser$ComplexTypeRecoverableError.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..3da6cbca28f243f0996e50b3fe035de157964ce0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDComplexTypeTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDElementTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDElementTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..f143b12452a5209572145b2bac47a6118a96626b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDElementTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDGroupTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDGroupTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..bd5442d60f310b7a9cc8a526decd1a76878ccc9b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDGroupTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$1.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..262f2c6df6f81d717bf3da3ea1e538ba1ff32162 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$SAX2XNIUtil.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$SAX2XNIUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..cf7136f245e56a8ad769cb8b1b96d58d306b42a6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$SAX2XNIUtil.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$XSAnnotationGrammarPool.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$XSAnnotationGrammarPool.class new file mode 100644 index 0000000000000000000000000000000000000000..75a608fe98faae05ed8190dadea289ba6917fd1b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$XSAnnotationGrammarPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$XSDKey.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$XSDKey.class new file mode 100644 index 0000000000000000000000000000000000000000..4e61c6450d6150c4c2992d91300c2bb4fc9f93b1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler$XSDKey.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..e5e15797d7873e920664b66fe726cdefd59318fa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDKeyrefTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDKeyrefTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..1701aeebeca401f7e715a8fb437235143b8b9551 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDKeyrefTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDNotationTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDNotationTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..524bc799ccde72f7107b7a06fcc08c600579e3a8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDNotationTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDSimpleTypeTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDSimpleTypeTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..db8dd36771831be12106b5d08aefcd484816930d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDSimpleTypeTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDUniqueOrKeyTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDUniqueOrKeyTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..f37f3e99f7505db9697ddb2e32503f8f184fb350 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDUniqueOrKeyTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDWildcardTraverser.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDWildcardTraverser.class new file mode 100644 index 0000000000000000000000000000000000000000..5661ddc60f956f8fd259d3679c32fec7b026bb3f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDWildcardTraverser.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDocumentInfo.class b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDocumentInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..1b0b05fcc6a4371d52e61b081b896505a2759fad Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/traversers/XSDocumentInfo.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/LSInputListImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/LSInputListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5817fc00b9f59b0a8aeb6e1612cdf131d50ad349 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/LSInputListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/ObjectListImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/ObjectListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..53b10ddc4479e2d500c3d41a2aef0c563a55f44d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/ObjectListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/ShortListImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/ShortListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a95b62156aef1ed4abb7bbd30490b2d72907440e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/ShortListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/SimpleLocator.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/SimpleLocator.class new file mode 100644 index 0000000000000000000000000000000000000000..abd1b1fe8e50f4133f0e03b762b743414bb0abaf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/SimpleLocator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/StringListImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/StringListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..77b9a1c7fa03a0231b4d8ad378469f63f9722494 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/StringListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XInt.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XInt.class new file mode 100644 index 0000000000000000000000000000000000000000..0213b6c5f3f37157d36c8c408bd2863870366957 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XInt.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XIntPool.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XIntPool.class new file mode 100644 index 0000000000000000000000000000000000000000..52bedfa3804fa6c7236a16d2ca840864dfa75485 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XIntPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSGrammarPool.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSGrammarPool.class new file mode 100644 index 0000000000000000000000000000000000000000..feaa6c379a26efdd1557202bd1493d3f948622c2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSGrammarPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSInputSource.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSInputSource.class new file mode 100644 index 0000000000000000000000000000000000000000..74279c6a4b5d797d1b9b5c847a90d069921b2bf0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSInputSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMap4Types.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMap4Types.class new file mode 100644 index 0000000000000000000000000000000000000000..15299f52c7b1c750cbe12f1a8a2d8076b00c0dbc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMap4Types.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$1.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..135bf4706fad1e0bafdc96e3ec28b4ceec3cff6b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$2.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$2.class new file mode 100644 index 0000000000000000000000000000000000000000..3f027ea41d37492927df7675b6f867828be5784a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$XSNamedMapEntry.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$XSNamedMapEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..477876c1e7c1cf91d7e2443191f3c6c45def33df Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl$XSNamedMapEntry.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1667f7c06153f7b5ab75601f91848f6f57c1ed7b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSNamedMapImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl$1.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c13f80129ce62193d9bafee66096f2d7a3ea40d8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl$XSObjectListIterator.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl$XSObjectListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..54320eac8e581211d1e4dc9c080f6d66307ed3b1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl$XSObjectListIterator.class differ diff --git a/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl.class b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9d1cf3e08e1dbfc2d003c6099de2813ef8120158 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/impl/xs/util/XSObjectListImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/DefaultValidationErrorHandler.class b/src/main/resources/org/python/apache/xerces/jaxp/DefaultValidationErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..067a1eefd14c07f413b7038747f5d49c202b3a60 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/DefaultValidationErrorHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/DocumentBuilderFactoryImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/DocumentBuilderFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5ead69e65b3a441085a0a1bdacbd2d47bf1226cb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/DocumentBuilderFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/DocumentBuilderImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/DocumentBuilderImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..948c891313fcdcd5839c5e98909cafe1a56649f7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/DocumentBuilderImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPConstants.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..a223f412c11e3f6d9f3ae690bfd3f8f7e7bd679f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPConstants.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$1.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e18ef40ade41223b51ddd9969c949c0b81f75325 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$2.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$2.class new file mode 100644 index 0000000000000000000000000000000000000000..13e738fb021b9baef6128e16b058da54d49bfc00 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$3.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$3.class new file mode 100644 index 0000000000000000000000000000000000000000..5bd71f07feda13890f2e352aa046fb118fae4c3c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$3.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$DraconianErrorHandler.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$DraconianErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..cdbb159667501bb5c98573ba5d71fed1d4603bee Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$DraconianErrorHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$SAX2XNI.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$SAX2XNI.class new file mode 100644 index 0000000000000000000000000000000000000000..7ef406be4897bdd07ba0b532b948c95bb07e54dc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$SAX2XNI.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$XNI2SAX.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$XNI2SAX.class new file mode 100644 index 0000000000000000000000000000000000000000..7f93c5c2a08c3c54e386c4072759775837b88415 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent$XNI2SAX.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent.class b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent.class new file mode 100644 index 0000000000000000000000000000000000000000..0433e076d97eb6d55e5f6da95351166ec101919c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/JAXPValidatorComponent.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/SAXParserFactoryImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/SAXParserFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e95135f38c751c4309d7cb8987cb8ceb49617977 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/SAXParserFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/SAXParserImpl$JAXPSAXParser.class b/src/main/resources/org/python/apache/xerces/jaxp/SAXParserImpl$JAXPSAXParser.class new file mode 100644 index 0000000000000000000000000000000000000000..b38ce9750b00215799b2ca84ce126297a832e4ee Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/SAXParserImpl$JAXPSAXParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/SAXParserImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/SAXParserImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e37244b227efb9b76507b95c06e37d9aabff238c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/SAXParserImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/SchemaValidatorConfiguration.class b/src/main/resources/org/python/apache/xerces/jaxp/SchemaValidatorConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..4dbe7d3e27e53f40adaf297f21b51added62f920 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/SchemaValidatorConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/TeeXMLDocumentFilterImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/TeeXMLDocumentFilterImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d41185e4ecba3b0a0e9f476fbc970378a9bfcbc8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/TeeXMLDocumentFilterImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/UnparsedEntityHandler.class b/src/main/resources/org/python/apache/xerces/jaxp/UnparsedEntityHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..99ca659d726674690fbc702214868aebe1d98958 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/UnparsedEntityHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/DatatypeFactoryImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/DatatypeFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..e0addde8aa9064ba02d4ecc766d4489c15fcd360 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/DatatypeFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/DurationImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/DurationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..bf638b9a81c8da20a8d6a577b8069251201e9965 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/DurationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/SerializedDuration.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/SerializedDuration.class new file mode 100644 index 0000000000000000000000000000000000000000..217ba6f9108f887c04519f0d904ef0838a5cc8d6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/SerializedDuration.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/SerializedXMLGregorianCalendar.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/SerializedXMLGregorianCalendar.class new file mode 100644 index 0000000000000000000000000000000000000000..99dc6c7f408f25dac61e9895abf2bce0c5ae7083 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/SerializedXMLGregorianCalendar.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$1.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d62d8fda51e8d88dc437a866b38278d5c49a9b46 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$DaysInMonth.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$DaysInMonth.class new file mode 100644 index 0000000000000000000000000000000000000000..40d56e57c779a7a8424a11e7ddae2035acad08c6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$DaysInMonth.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$Parser.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$Parser.class new file mode 100644 index 0000000000000000000000000000000000000000..d0342b24a1c5486a83f8fdbe5c2e37223f575df7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl$Parser.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..0a907e3c942e92a2992508370818952ee0097425 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/datatype/XMLGregorianCalendarImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/AbstractXMLSchema.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/AbstractXMLSchema.class new file mode 100644 index 0000000000000000000000000000000000000000..47f5839dc772ea9c40a198a0c2f3c925139b70cd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/AbstractXMLSchema.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMDocumentHandler.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMDocumentHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..caef3d037c0909f0af98102169ff499c8aed1d70 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMDocumentHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMResultAugmentor.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMResultAugmentor.class new file mode 100644 index 0000000000000000000000000000000000000000..d9890e34c2667d38ef67eb687ad6b938619d4b2e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMResultAugmentor.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMResultBuilder.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMResultBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..1cbd494ec40d09a5055b58ce74431447348e7e75 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMResultBuilder.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMValidatorHelper$DOMNamespaceContext.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMValidatorHelper$DOMNamespaceContext.class new file mode 100644 index 0000000000000000000000000000000000000000..fe3fc6f8ebb0da0bd8dfc35075049314d8be5d76 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMValidatorHelper$DOMNamespaceContext.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMValidatorHelper.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMValidatorHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..dd9f5392d962701f30203c670ea588de4d19d946 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/DOMValidatorHelper.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/DraconianErrorHandler.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/DraconianErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..f5e64993e012ffbab0198199951532430feee068 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/DraconianErrorHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/EmptyXMLSchema.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/EmptyXMLSchema.class new file mode 100644 index 0000000000000000000000000000000000000000..5b25c2ac6ffcdea628c0beb17818ef08ebdeafca Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/EmptyXMLSchema.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/JAXPValidationMessageFormatter.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/JAXPValidationMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..e505f7fd9c693582c31cdfb4e08501496ec39725 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/JAXPValidationMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/ReadOnlyGrammarPool.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/ReadOnlyGrammarPool.class new file mode 100644 index 0000000000000000000000000000000000000000..4b720006c652c84e40fb6b7f371b1d6b8529aae4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/ReadOnlyGrammarPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/SimpleXMLSchema.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/SimpleXMLSchema.class new file mode 100644 index 0000000000000000000000000000000000000000..e9fbec04bbb9529ee8ff9b643c7f42697082929f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/SimpleXMLSchema.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool$Entry.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool$Entry.class new file mode 100644 index 0000000000000000000000000000000000000000..249aca91eac906031ae83c3e9e74b1691809ea35 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool$Entry.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool$SoftGrammarReference.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool$SoftGrammarReference.class new file mode 100644 index 0000000000000000000000000000000000000000..e9c046a9db7c329bfd4ead13d47f73a8d76af022 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool$SoftGrammarReference.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool.class new file mode 100644 index 0000000000000000000000000000000000000000..a0d07003ef3b525e8b9d5cdea5ebcb8fdf1502d3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/SoftReferenceGrammarPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXDocumentHandler.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXDocumentHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..bedb6f2e804d2374c6ed772d5342549dab984fcb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXDocumentHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$1.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4f30b062683e9bc196316b49f3ea0616812a9f60 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$AttributeIterator.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$AttributeIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..ae4816b07acc86eb5646c179ed1355ea2c0600a7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$AttributeIterator.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$NamespaceIterator.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$NamespaceIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..25023108ce621bddce843cd945f457516b43234d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder$NamespaceIterator.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..17c64c2445f407d6461c60b0983c1e4ce4ed85a9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXEventResultBuilder.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXStreamResultBuilder.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXStreamResultBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..e9ab776a845b80fc1cc31e339942a9fc70138f5a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXStreamResultBuilder.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$EventHelper.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$EventHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..391388bad2e376a06bc1878443e40a06fcd6573f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$EventHelper.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$StreamHelper.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$StreamHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..b8c3aab1cfc8f568a56a5a346cc5bc1e09386784 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$StreamHelper.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$XMLStreamReaderLocation.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$XMLStreamReaderLocation.class new file mode 100644 index 0000000000000000000000000000000000000000..9f83758536d3a412f1aa00bb1ab3bd99e0c7e824 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper$XMLStreamReaderLocation.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..1f85a9c03a10baac4cd09a01a5ded5832b54def3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StAXValidatorHelper.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/StreamValidatorHelper.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/StreamValidatorHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..a8e844a26cfef63f621e0518ccff4b50a7cfe357 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/StreamValidatorHelper.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/Util.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/Util.class new file mode 100644 index 0000000000000000000000000000000000000000..658482c13c176f829725e05a685cf974285f4484 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/Util.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$1.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..7c79431eea5e124ba8dc28a955cda244f1c059e2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$ResolutionForwarder.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$ResolutionForwarder.class new file mode 100644 index 0000000000000000000000000000000000000000..853b7d438c3ea63ad997b4a4980bcca2a05b93c7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$ResolutionForwarder.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$XMLSchemaTypeInfoProvider.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$XMLSchemaTypeInfoProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..84db4670cb9152a9b249f7009ad5e3002277f30b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl$XMLSchemaTypeInfoProvider.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..96e5701bb5c7b276c910e3df1533a5f7ccaac314 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHandlerImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHelper.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..0da208cb69af31f3b86522b22b7f8d1d053bcc77 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorHelper.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorImpl.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8127a23e56edac624f6631c4c8e39dd94ac3624a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/ValidatorImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/WeakReferenceXMLSchema.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/WeakReferenceXMLSchema.class new file mode 100644 index 0000000000000000000000000000000000000000..cf9f4dfd66e3970a9a32380cbcd1122833f23595 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/WeakReferenceXMLSchema.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchema.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchema.class new file mode 100644 index 0000000000000000000000000000000000000000..898a4333431b626147e91157b7055ce0697256fc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchema.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory$XMLGrammarPoolImplExtension.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory$XMLGrammarPoolImplExtension.class new file mode 100644 index 0000000000000000000000000000000000000000..c171d9a7d3866dde475755997ea66326d615f253 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory$XMLGrammarPoolImplExtension.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory$XMLGrammarPoolWrapper.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory$XMLGrammarPoolWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..f4654dcb328df229396e0e6626e0140c8b392c81 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory$XMLGrammarPoolWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..7cd148cac4229ed252ab60f3659019da853e956e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaValidatorComponentManager.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaValidatorComponentManager.class new file mode 100644 index 0000000000000000000000000000000000000000..cb9a009c5a47588a74b7d517403eb4d5b6a89396 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/XMLSchemaValidatorComponentManager.class differ diff --git a/src/main/resources/org/python/apache/xerces/jaxp/validation/XSGrammarPoolContainer.class b/src/main/resources/org/python/apache/xerces/jaxp/validation/XSGrammarPoolContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..8ebd503ebe2eb0df038fd18b62758c3670e58d6d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/jaxp/validation/XSGrammarPoolContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/AbstractDOMParser$Abort.class b/src/main/resources/org/python/apache/xerces/parsers/AbstractDOMParser$Abort.class new file mode 100644 index 0000000000000000000000000000000000000000..f232232503909f76ef63f6d5e466ebea8b5327c5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/AbstractDOMParser$Abort.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/AbstractDOMParser.class b/src/main/resources/org/python/apache/xerces/parsers/AbstractDOMParser.class new file mode 100644 index 0000000000000000000000000000000000000000..b4e4b9b0c21a5319995fa8bd6b81710bb2938674 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/AbstractDOMParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser$AttributesProxy.class b/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser$AttributesProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..e6c6e71914ca1870adb7f16d2aeb76dc1ed56c6f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser$AttributesProxy.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser$LocatorProxy.class b/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser$LocatorProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..cf9aa960aab2726b73947898d9b5e176e2a87a63 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser$LocatorProxy.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser.class b/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser.class new file mode 100644 index 0000000000000000000000000000000000000000..48c2ddd2414db7c8766c912bc3dfd340c772577d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/AbstractSAXParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/AbstractXMLDocumentParser.class b/src/main/resources/org/python/apache/xerces/parsers/AbstractXMLDocumentParser.class new file mode 100644 index 0000000000000000000000000000000000000000..84cb017281bb64643f0839bdbb88621c7e6ee58b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/AbstractXMLDocumentParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/BasicParserConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/BasicParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..af23064ba8ba12f9737bddd2deb4efd61d11f6b6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/BasicParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool$ShadowedGrammarPool.class b/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool$ShadowedGrammarPool.class new file mode 100644 index 0000000000000000000000000000000000000000..e7b13c4cb77d52fec3c4558efef8c19452394be6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool$ShadowedGrammarPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool$SynchronizedGrammarPool.class b/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool$SynchronizedGrammarPool.class new file mode 100644 index 0000000000000000000000000000000000000000..927dcb59b0564bbc2dc7834392c29efbd5b89f0f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool$SynchronizedGrammarPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool.class b/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool.class new file mode 100644 index 0000000000000000000000000000000000000000..8214ff51a27a47f6e7ada72b0920ee9e00d72bc6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/CachingParserPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DOMASBuilderImpl.class b/src/main/resources/org/python/apache/xerces/parsers/DOMASBuilderImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a244e301f470fc76a275045be3a8e7b6579ac217 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DOMASBuilderImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DOMParser.class b/src/main/resources/org/python/apache/xerces/parsers/DOMParser.class new file mode 100644 index 0000000000000000000000000000000000000000..71fd85616929119707dda65acac9b5f2e0bf7d37 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DOMParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$1.class b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0cd8619d4e41c697f5ec8ad5c982b5beb90d2c71 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$AbortHandler.class b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$AbortHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..b98b8d11eb6f4411ed34e0729e315ba827ca281a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$AbortHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$NullLSParserFilter.class b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$NullLSParserFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..60c69d283ea0a9c3da3c9d6237c79aefab7186db Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl$NullLSParserFilter.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl.class b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..da0cd4856c2e6c15bc608b9c355887195bad0565 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DOMParserImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DTDConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/DTDConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..372f5a2adff6d6f03cf5852c3c5fa3ef61617b47 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DTDConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/DTDParser.class b/src/main/resources/org/python/apache/xerces/parsers/DTDParser.class new file mode 100644 index 0000000000000000000000000000000000000000..2fda983fb583414d5b54e8d0691477a83a6f24b3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/DTDParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/IntegratedParserConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/IntegratedParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..c986c5190913bae833c87e7d595dbf46d641f183 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/IntegratedParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/NonValidatingConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/NonValidatingConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..3fe714be2e278e4c5fa0931a75efc95e99ef83ea Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/NonValidatingConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/ObjectFactory$ConfigurationError.class b/src/main/resources/org/python/apache/xerces/parsers/ObjectFactory$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..2ce81e7accb25546e22618d9566de05c13cf008e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/ObjectFactory$ConfigurationError.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/ObjectFactory.class b/src/main/resources/org/python/apache/xerces/parsers/ObjectFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..747012353823df6d388cc96794c9f9396cbcf4e1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/ObjectFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SAXParser.class b/src/main/resources/org/python/apache/xerces/parsers/SAXParser.class new file mode 100644 index 0000000000000000000000000000000000000000..8702e26293df80b3095b85385d17e93e3bed91f6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SAXParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecurityConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/SecurityConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..b79bfc7e030e713e21c2630baed95147fb55503d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecurityConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$1.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9ad1a554f11056c5bfa4ca79e719c7df1194e065 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$2.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..1ef3ee33aaf1f82fa18eeae3fa22e390d82e2857 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$3.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..8c531f004c72ac052cb7c6777051aabbbf8db9a1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$3.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$4.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..a66a42e6fbaebc299767fc5887c86b4c7586253e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$4.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$5.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..57f7ad7c0e9146f5ca794beb8d1a88b19e591174 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$5.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$6.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..6be68244e27ab9559b80d84ce3d7909e35a57d70 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$6.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$7.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..119403dfb3d388a3ce4b30c43756525b0e48b5ad Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$7.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$8.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..57ea4a9a48d9e95c4f0b66fd1dbbd6cbe586f3dc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport$8.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport.class b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..d67bfc1c955fd3edfb7fdf7443f8ffbe8ca5211d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SecuritySupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/SoftReferenceSymbolTableConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/SoftReferenceSymbolTableConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..2a42988060a1adb39e2b79f90c0bf27c531aeb75 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/SoftReferenceSymbolTableConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/StandardParserConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/StandardParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..c2a6cc81d41d1f60c1b7356b57559f3d7773f69b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/StandardParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XIncludeAwareParserConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/XIncludeAwareParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..4bd6982d625267a6ab23c23a909ea7bef3482808 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XIncludeAwareParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XIncludeParserConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/XIncludeParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..9996b7629058825926fcb6aae5801031713095a0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XIncludeParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XML11Configurable.class b/src/main/resources/org/python/apache/xerces/parsers/XML11Configurable.class new file mode 100644 index 0000000000000000000000000000000000000000..98310c3f31c5f6128e522f7fd904b21a2fda6dab Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XML11Configurable.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XML11Configuration.class b/src/main/resources/org/python/apache/xerces/parsers/XML11Configuration.class new file mode 100644 index 0000000000000000000000000000000000000000..07c10cfecb575c757dab3b91816ee662e2288b3c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XML11Configuration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XML11DTDConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/XML11DTDConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..8ee7c6aff119a306bc411e82d5bf665984aa41bf Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XML11DTDConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XML11NonValidatingConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/XML11NonValidatingConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..1a6c1fb702d87a682dc1d4cd752bb44476742307 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XML11NonValidatingConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XMLDocumentParser.class b/src/main/resources/org/python/apache/xerces/parsers/XMLDocumentParser.class new file mode 100644 index 0000000000000000000000000000000000000000..f167cb68256b01b78ab01de18077bf1e0e932437 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XMLDocumentParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarCachingConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarCachingConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..5a84a39f6de413e755404e7f362588b458e3f274 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarCachingConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarParser.class b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarParser.class new file mode 100644 index 0000000000000000000000000000000000000000..55e5767c7392ab16bb777426c183598de1530ad7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarPreparser$XMLGrammarLoaderContainer.class b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarPreparser$XMLGrammarLoaderContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..a4f1ce43dce9b932e7064e7c97b786c3ec691ec5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarPreparser$XMLGrammarLoaderContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarPreparser.class b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarPreparser.class new file mode 100644 index 0000000000000000000000000000000000000000..36ddd772e10736a286f5501448d86400122eeaef Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XMLGrammarPreparser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XMLParser.class b/src/main/resources/org/python/apache/xerces/parsers/XMLParser.class new file mode 100644 index 0000000000000000000000000000000000000000..756c4c57ad6d6f165ce88b59f441dffe4d138d5d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XMLParser.class differ diff --git a/src/main/resources/org/python/apache/xerces/parsers/XPointerParserConfiguration.class b/src/main/resources/org/python/apache/xerces/parsers/XPointerParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..8b8f4850e18286b76f14960ffbb7e4be8cea6f9e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/parsers/XPointerParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext$1.class b/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2d38214a497b12be8e2b56a523848692831e3baa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext$2.class b/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c85acae8d4f0e49a9cdeae31a96a2de3448efd2f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext.class b/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext.class new file mode 100644 index 0000000000000000000000000000000000000000..34dd42c85d3959af55fffb01d46c12e568bf96a9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/DefaultNamespaceContext.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/EmptyLocation.class b/src/main/resources/org/python/apache/xerces/stax/EmptyLocation.class new file mode 100644 index 0000000000000000000000000000000000000000..baa3f194bdb36789ea3e621ec9f0499b49dd1763 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/EmptyLocation.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/ImmutableLocation.class b/src/main/resources/org/python/apache/xerces/stax/ImmutableLocation.class new file mode 100644 index 0000000000000000000000000000000000000000..f707b8de3a23f26bb7f3b652f84042cbca4ea816 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/ImmutableLocation.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/XMLEventFactoryImpl.class b/src/main/resources/org/python/apache/xerces/stax/XMLEventFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d3203bdb717c7ee1585f8d7fa98fc14090aa61e2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/XMLEventFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/AttributeImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/AttributeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9d0f029248353e11cb09a3ef7e7847a505979c45 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/AttributeImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/CharactersImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/CharactersImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..39db7835fb7d399f4d3041a9c9fb759a04c76e26 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/CharactersImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/CommentImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/CommentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..9faee56f0affd29288d041407e18c5a9f12c1c9b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/CommentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/DTDImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/DTDImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..052ec8db75425b508c20f3a4b13131c8403ddee4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/DTDImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/ElementImpl$NoRemoveIterator.class b/src/main/resources/org/python/apache/xerces/stax/events/ElementImpl$NoRemoveIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..ff371e9cb4fea83bdf40140fa42aa27a1a69dd40 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/ElementImpl$NoRemoveIterator.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/ElementImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/ElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..6d73304d1ce38d463090758da2b8304a68ad713c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/ElementImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/EndDocumentImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/EndDocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8c8ac0ff34bd30ba68eeb533ff284d389dbf75a0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/EndDocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/EndElementImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/EndElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..96b3eec2b92383ac0683b8bad0eaf34391ac290f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/EndElementImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/EntityDeclarationImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/EntityDeclarationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..004cc82852a6e889cf9bbea180bf21acbbc239fd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/EntityDeclarationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/EntityReferenceImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/EntityReferenceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..6d8669a3574fd5e1ea91718edc510283ac7d21b3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/EntityReferenceImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/NamespaceImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/NamespaceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..ac1464009d8379d11258218141d6505794c3fbe4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/NamespaceImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/NotationDeclarationImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/NotationDeclarationImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8acb81081422739e3869581420bbf961a9862b05 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/NotationDeclarationImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/ProcessingInstructionImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/ProcessingInstructionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..6a92fa6c45ae20b41270d2665cfa9b87df074352 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/ProcessingInstructionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/StartDocumentImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/StartDocumentImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..5dd4b61fb158f0d2a7edf87c8a746d5d5d825537 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/StartDocumentImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/StartElementImpl$1.class b/src/main/resources/org/python/apache/xerces/stax/events/StartElementImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5f3e008b07d782de16d4fd7664fc4b556994d001 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/StartElementImpl$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/StartElementImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/StartElementImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..c745c9dee47e3dc4a9feb736324639353e10b75d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/StartElementImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/stax/events/XMLEventImpl.class b/src/main/resources/org/python/apache/xerces/stax/events/XMLEventImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..d917a84079dcf64011fc2eba8f21a030d48b824f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/stax/events/XMLEventImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/AttributesProxy.class b/src/main/resources/org/python/apache/xerces/util/AttributesProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..1623bb8768f92d309681d30633782c26c744193b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/AttributesProxy.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$AugmentationsItemsContainer.class b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$AugmentationsItemsContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..f9b652f4dd7cc0f872ed6d5514e2466edf6bdb8f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$AugmentationsItemsContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$LargeContainer.class b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$LargeContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..22ad06d67de9698a77353910fc26dbbbefc772ae Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$LargeContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$SmallContainer$SmallContainerKeyEnumeration.class b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$SmallContainer$SmallContainerKeyEnumeration.class new file mode 100644 index 0000000000000000000000000000000000000000..e535edfbd412cfce280a142970c1aab76871b964 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$SmallContainer$SmallContainerKeyEnumeration.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$SmallContainer.class b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$SmallContainer.class new file mode 100644 index 0000000000000000000000000000000000000000..7404e4700bc26fe3a02a2ea7c503d435413abfd2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl$SmallContainer.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl.class b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..3b4b819b0b6e4eb212cf81b2bf2c493f4844ff36 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/AugmentationsImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DOMEntityResolverWrapper.class b/src/main/resources/org/python/apache/xerces/util/DOMEntityResolverWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..30ed27bd6ea99bfdc6fb7c98971d8e41586e642e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DOMEntityResolverWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DOMErrorHandlerWrapper$DOMErrorTypeMap.class b/src/main/resources/org/python/apache/xerces/util/DOMErrorHandlerWrapper$DOMErrorTypeMap.class new file mode 100644 index 0000000000000000000000000000000000000000..2293e84b8cecfd31def29944e2136ae07f51b5df Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DOMErrorHandlerWrapper$DOMErrorTypeMap.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DOMErrorHandlerWrapper.class b/src/main/resources/org/python/apache/xerces/util/DOMErrorHandlerWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..f9f7b94d7be948028c753444c8dc9c1c7612b15d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DOMErrorHandlerWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DOMInputSource.class b/src/main/resources/org/python/apache/xerces/util/DOMInputSource.class new file mode 100644 index 0000000000000000000000000000000000000000..8c8490b4199d2988ba0e4ff2dfc9065ae136578b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DOMInputSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DOMUtil$ThrowableMethods.class b/src/main/resources/org/python/apache/xerces/util/DOMUtil$ThrowableMethods.class new file mode 100644 index 0000000000000000000000000000000000000000..f102213465afd31f640c91e90c2ad2aefd7109a7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DOMUtil$ThrowableMethods.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DOMUtil.class b/src/main/resources/org/python/apache/xerces/util/DOMUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..f2f340d5640916af2dffe686840fe63d5c842f4e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DOMUtil.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DatatypeMessageFormatter.class b/src/main/resources/org/python/apache/xerces/util/DatatypeMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..e4af604278a50cdb5eae7c8db1c3549dbe97296b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DatatypeMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/DefaultErrorHandler.class b/src/main/resources/org/python/apache/xerces/util/DefaultErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..c694d3e98db1defcc1cc948170804a3497587f02 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/DefaultErrorHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/EncodingMap.class b/src/main/resources/org/python/apache/xerces/util/EncodingMap.class new file mode 100644 index 0000000000000000000000000000000000000000..9ea53776caacf2c3701b4ac52e052de3991d7670 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/EncodingMap.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/EntityResolver2Wrapper.class b/src/main/resources/org/python/apache/xerces/util/EntityResolver2Wrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..91693b0b4efe08e9c075f24cfbc68fca6bd49539 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/EntityResolver2Wrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/EntityResolverWrapper.class b/src/main/resources/org/python/apache/xerces/util/EntityResolverWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..87b4e2ba13f93b6d2e3652f3738ae2d09c84ef04 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/EntityResolverWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/ErrorHandlerProxy.class b/src/main/resources/org/python/apache/xerces/util/ErrorHandlerProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..7821f89f543f711f899189038c0d17726ddb38f6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/ErrorHandlerProxy.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/ErrorHandlerWrapper$1.class b/src/main/resources/org/python/apache/xerces/util/ErrorHandlerWrapper$1.class new file mode 100644 index 0000000000000000000000000000000000000000..280a4edc31aba0b158e31340b046794e53c119b7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/ErrorHandlerWrapper$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/ErrorHandlerWrapper.class b/src/main/resources/org/python/apache/xerces/util/ErrorHandlerWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..d3b9ee8303efe204c27f33a4b2bf0be6b4112c56 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/ErrorHandlerWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/HTTPInputSource.class b/src/main/resources/org/python/apache/xerces/util/HTTPInputSource.class new file mode 100644 index 0000000000000000000000000000000000000000..254d9fcbd8abe6f62051e44f9e6e63aca19fa009 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/HTTPInputSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/IntStack.class b/src/main/resources/org/python/apache/xerces/util/IntStack.class new file mode 100644 index 0000000000000000000000000000000000000000..e3027b7e64aca7cf8aaec6b5cafce509cace5220 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/IntStack.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/JAXPNamespaceContextWrapper.class b/src/main/resources/org/python/apache/xerces/util/JAXPNamespaceContextWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..a7f61d88c539ae95b791f9fa06bcdb01135cd631 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/JAXPNamespaceContextWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/LocatorProxy.class b/src/main/resources/org/python/apache/xerces/util/LocatorProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..9d39323d14763aa54302abe98532f1085df69078 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/LocatorProxy.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/MessageFormatter.class b/src/main/resources/org/python/apache/xerces/util/MessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..2b831290756f2227a656e23e96a1558c0773abeb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/MessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/NamespaceSupport$Prefixes.class b/src/main/resources/org/python/apache/xerces/util/NamespaceSupport$Prefixes.class new file mode 100644 index 0000000000000000000000000000000000000000..05575018be3dea80c55b523f2fc881ae69400901 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/NamespaceSupport$Prefixes.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/NamespaceSupport.class b/src/main/resources/org/python/apache/xerces/util/NamespaceSupport.class new file mode 100644 index 0000000000000000000000000000000000000000..8cc2a25ebd7235492d50a07fe6921f3257607be8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/NamespaceSupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/ParserConfigurationSettings.class b/src/main/resources/org/python/apache/xerces/util/ParserConfigurationSettings.class new file mode 100644 index 0000000000000000000000000000000000000000..0377a8702a4e388e575d1f8b330d717991eb2e26 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/ParserConfigurationSettings.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SAXInputSource.class b/src/main/resources/org/python/apache/xerces/util/SAXInputSource.class new file mode 100644 index 0000000000000000000000000000000000000000..c5390cda6c466d87f8b66b6090905f011c8365bc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SAXInputSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SAXLocatorWrapper.class b/src/main/resources/org/python/apache/xerces/util/SAXLocatorWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..9d4f4cf009f4380b2e8e6e15523a4753ec08fe20 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SAXLocatorWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SAXMessageFormatter.class b/src/main/resources/org/python/apache/xerces/util/SAXMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..29bfd0936a4d15a4a50861b509efb8aec4b90d8a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SAXMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SecurityManager.class b/src/main/resources/org/python/apache/xerces/util/SecurityManager.class new file mode 100644 index 0000000000000000000000000000000000000000..94ec9272f936a98a091db3e4b7d143d928912967 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SecurityManager.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/ShadowedSymbolTable.class b/src/main/resources/org/python/apache/xerces/util/ShadowedSymbolTable.class new file mode 100644 index 0000000000000000000000000000000000000000..9db6c4754977d1290fe65bec324633a89b719cbc Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/ShadowedSymbolTable.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable$SREntry.class b/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable$SREntry.class new file mode 100644 index 0000000000000000000000000000000000000000..24a7fa1b1d70b4df7f5332c814ce80bd1bee6dde Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable$SREntry.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable$SREntryData.class b/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable$SREntryData.class new file mode 100644 index 0000000000000000000000000000000000000000..c98482b94e1ecba92d09453835eca57ae71b7e1f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable$SREntryData.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable.class b/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable.class new file mode 100644 index 0000000000000000000000000000000000000000..ab03ba3b9bf1fb99ffe5b4a44205db45540f689d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SoftReferenceSymbolTable.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/StAXInputSource.class b/src/main/resources/org/python/apache/xerces/util/StAXInputSource.class new file mode 100644 index 0000000000000000000000000000000000000000..89a6474d4eb0f2e5921b1704ad1755d023bb5398 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/StAXInputSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/StAXLocationWrapper.class b/src/main/resources/org/python/apache/xerces/util/StAXLocationWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..ed77c2ddfe6e5a3db004aed21510e4d97e76cccb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/StAXLocationWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SymbolHash$Entry.class b/src/main/resources/org/python/apache/xerces/util/SymbolHash$Entry.class new file mode 100644 index 0000000000000000000000000000000000000000..7fc51eeadf0948ebcc65488e02b34604992297d4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SymbolHash$Entry.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SymbolHash.class b/src/main/resources/org/python/apache/xerces/util/SymbolHash.class new file mode 100644 index 0000000000000000000000000000000000000000..6cfb27ad4094c5c4d19a3a2f927d32128597d855 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SymbolHash.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SymbolTable$Entry.class b/src/main/resources/org/python/apache/xerces/util/SymbolTable$Entry.class new file mode 100644 index 0000000000000000000000000000000000000000..c9d7de011400abd03b349db402cedf4fd82ab801 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SymbolTable$Entry.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SymbolTable.class b/src/main/resources/org/python/apache/xerces/util/SymbolTable.class new file mode 100644 index 0000000000000000000000000000000000000000..f9daa379c0b94a391e5cd34ea786b64907150d0a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SymbolTable.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/SynchronizedSymbolTable.class b/src/main/resources/org/python/apache/xerces/util/SynchronizedSymbolTable.class new file mode 100644 index 0000000000000000000000000000000000000000..df10aaf85adaa7526df229ac737d87c5e7dce5f6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/SynchronizedSymbolTable.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/URI$MalformedURIException.class b/src/main/resources/org/python/apache/xerces/util/URI$MalformedURIException.class new file mode 100644 index 0000000000000000000000000000000000000000..700914caecd80e33cc4b1911b02bffb81cba9378 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/URI$MalformedURIException.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/URI.class b/src/main/resources/org/python/apache/xerces/util/URI.class new file mode 100644 index 0000000000000000000000000000000000000000..0f61b91cbcd835deb823d45c264dd9dd08213774 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/URI.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XML11Char.class b/src/main/resources/org/python/apache/xerces/util/XML11Char.class new file mode 100644 index 0000000000000000000000000000000000000000..083dd4e46454c237d6ccef710602c9d43c280910 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XML11Char.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLAttributesImpl$Attribute.class b/src/main/resources/org/python/apache/xerces/util/XMLAttributesImpl$Attribute.class new file mode 100644 index 0000000000000000000000000000000000000000..c8e01de44a7177d2fad70b4d2847feeb813059c2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLAttributesImpl$Attribute.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLAttributesImpl.class b/src/main/resources/org/python/apache/xerces/util/XMLAttributesImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..2904106947e78217b8c94ed416db5cd379220aae Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLAttributesImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLCatalogResolver.class b/src/main/resources/org/python/apache/xerces/util/XMLCatalogResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..94c9ed3a338b92ad5a517da90bb777530a161c3f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLCatalogResolver.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLChar.class b/src/main/resources/org/python/apache/xerces/util/XMLChar.class new file mode 100644 index 0000000000000000000000000000000000000000..ff4f659f6e53fea33b234f5f30d4a9ed082141f9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLChar.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLEntityDescriptionImpl.class b/src/main/resources/org/python/apache/xerces/util/XMLEntityDescriptionImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..a48033fbf3f41e817a17939bbb4e46bbb1cf52d5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLEntityDescriptionImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLErrorCode.class b/src/main/resources/org/python/apache/xerces/util/XMLErrorCode.class new file mode 100644 index 0000000000000000000000000000000000000000..ab88b05fe20b557ad0acf731990569cfcc0ea155 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLErrorCode.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLGrammarPoolImpl$Entry.class b/src/main/resources/org/python/apache/xerces/util/XMLGrammarPoolImpl$Entry.class new file mode 100644 index 0000000000000000000000000000000000000000..2ed96742edc1cea5f995b5804066edaad6176183 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLGrammarPoolImpl$Entry.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLGrammarPoolImpl.class b/src/main/resources/org/python/apache/xerces/util/XMLGrammarPoolImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1f1bb5559100f925f6d4285699bd8b83e930edd5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLGrammarPoolImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLLocatorWrapper.class b/src/main/resources/org/python/apache/xerces/util/XMLLocatorWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..f933559571cc028f6443a3e80127fde6b7d7cde0 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLLocatorWrapper.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLResourceIdentifierImpl.class b/src/main/resources/org/python/apache/xerces/util/XMLResourceIdentifierImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1cd1402cb6811b526d512c5a70df6ef455c3a399 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLResourceIdentifierImpl.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLStringBuffer.class b/src/main/resources/org/python/apache/xerces/util/XMLStringBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..02cfd1d851f849bd8535c0e0695869b3e17f54f5 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLStringBuffer.class differ diff --git a/src/main/resources/org/python/apache/xerces/util/XMLSymbols.class b/src/main/resources/org/python/apache/xerces/util/XMLSymbols.class new file mode 100644 index 0000000000000000000000000000000000000000..8dbfda5f58377379cd7aeb3e7c13ac5d751feb82 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/util/XMLSymbols.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/MultipleScopeNamespaceSupport.class b/src/main/resources/org/python/apache/xerces/xinclude/MultipleScopeNamespaceSupport.class new file mode 100644 index 0000000000000000000000000000000000000000..51c2efee3c648086732af68565496a0d4810f5bb Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/MultipleScopeNamespaceSupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/ObjectFactory$ConfigurationError.class b/src/main/resources/org/python/apache/xerces/xinclude/ObjectFactory$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..be1a6fa15e0ff755f6823f6517440c3af871dcd9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/ObjectFactory$ConfigurationError.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/ObjectFactory.class b/src/main/resources/org/python/apache/xerces/xinclude/ObjectFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..e8fa799ee66944168d5902134cec65529a55f57b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/ObjectFactory.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$1.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..342cd3c27489c58cd6cdd6e3d53d6336914b3062 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$2.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c6714d6bd03c507a9a4fce40b6e15afa0683ce4c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$2.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$3.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..ba3f3fbccf3fabe747257a1987c34000ec921301 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$3.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$4.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..5633f341e2cd1184c7f760331da06e78a32fcc97 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$4.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$5.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..8c25f5029e0b07f9736bdfc9b8ce0ad98c455990 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$5.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$6.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..b589b207753ab3ce45e0122672da441ad5b77d47 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$6.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$7.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..803f735d321aac5f9457374e192fd8bdd2ec83c8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$7.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$8.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..e148c5c8e92a9242d0b735bdcec9f9abd2d8e96d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport$8.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport.class b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..9e66d47fdc8b7bc480424c46c317bc8133cd999f Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/SecuritySupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/XInclude11TextReader.class b/src/main/resources/org/python/apache/xerces/xinclude/XInclude11TextReader.class new file mode 100644 index 0000000000000000000000000000000000000000..89ab7f1f99791af2755ad1856d0b1658222cc573 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/XInclude11TextReader.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler$Notation.class b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler$Notation.class new file mode 100644 index 0000000000000000000000000000000000000000..631091c4b71d32dcb74c19f1e0444bcbb0bee292 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler$Notation.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler$UnparsedEntity.class b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler$UnparsedEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..ced9a861b70450cc1aa0e045d8d64599a0cf4661 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler$UnparsedEntity.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler.class b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..97c040f47afb0a4275bcafe487861c7b10a778aa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/XIncludeMessageFormatter.class b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..fd76fe7a0fd5d0680c3665368e5fcbafc22db13a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/XIncludeNamespaceSupport.class b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeNamespaceSupport.class new file mode 100644 index 0000000000000000000000000000000000000000..2325150627f338910702b69d64767275b1c4f9f6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeNamespaceSupport.class differ diff --git a/src/main/resources/org/python/apache/xerces/xinclude/XIncludeTextReader.class b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeTextReader.class new file mode 100644 index 0000000000000000000000000000000000000000..70ab7bbd8163c551c9c69d3bb04df05897ba2d8d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xinclude/XIncludeTextReader.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/Augmentations.class b/src/main/resources/org/python/apache/xerces/xni/Augmentations.class new file mode 100644 index 0000000000000000000000000000000000000000..f2d811061d4932b56ad6990220323f068e3460d3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/Augmentations.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/NamespaceContext.class b/src/main/resources/org/python/apache/xerces/xni/NamespaceContext.class new file mode 100644 index 0000000000000000000000000000000000000000..a27d86b305e15091611ba099f3df9d3580c76799 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/NamespaceContext.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/QName.class b/src/main/resources/org/python/apache/xerces/xni/QName.class new file mode 100644 index 0000000000000000000000000000000000000000..93d3bf30d262c6a01179201dd13437f640c256ba Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/QName.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLAttributes.class b/src/main/resources/org/python/apache/xerces/xni/XMLAttributes.class new file mode 100644 index 0000000000000000000000000000000000000000..36b3b4710c6a888bfcc29d67c1c9d259ab6d9251 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLAttributes.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLDTDContentModelHandler.class b/src/main/resources/org/python/apache/xerces/xni/XMLDTDContentModelHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..dd5dd822b07c9d1102a877540bd3723c93d36664 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLDTDContentModelHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLDTDHandler.class b/src/main/resources/org/python/apache/xerces/xni/XMLDTDHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..47be0ff7b5e73de1db5c8b85090f9ce1cc11cb59 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLDTDHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLDocumentFragmentHandler.class b/src/main/resources/org/python/apache/xerces/xni/XMLDocumentFragmentHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..7be47c9fa822c6270aded6a068b690ffcf5b18c2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLDocumentFragmentHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLDocumentHandler.class b/src/main/resources/org/python/apache/xerces/xni/XMLDocumentHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..37d7b95f2cc1191a10d6d548cf2331d6fef21ba3 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLDocumentHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLLocator.class b/src/main/resources/org/python/apache/xerces/xni/XMLLocator.class new file mode 100644 index 0000000000000000000000000000000000000000..6fa0bbcc8340ac081d0131cef460f0bde30d7a59 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLLocator.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLResourceIdentifier.class b/src/main/resources/org/python/apache/xerces/xni/XMLResourceIdentifier.class new file mode 100644 index 0000000000000000000000000000000000000000..9c978381c2c8f32f71357952d4aa3bc20b8f4084 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLResourceIdentifier.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XMLString.class b/src/main/resources/org/python/apache/xerces/xni/XMLString.class new file mode 100644 index 0000000000000000000000000000000000000000..c96bfd5722db1f2a2b8c4def382e857f373a2291 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XMLString.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/XNIException.class b/src/main/resources/org/python/apache/xerces/xni/XNIException.class new file mode 100644 index 0000000000000000000000000000000000000000..8f754f44e8e275d5583a0b1ecaf050dd2fdd29bd Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/XNIException.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/grammars/Grammar.class b/src/main/resources/org/python/apache/xerces/xni/grammars/Grammar.class new file mode 100644 index 0000000000000000000000000000000000000000..adc79596b3a75574eacb54e21a6b80cebaf88b11 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/grammars/Grammar.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/grammars/XMLDTDDescription.class b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLDTDDescription.class new file mode 100644 index 0000000000000000000000000000000000000000..4f67a5a5d7dbd96d511426013b0f0ce0bb5eb131 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLDTDDescription.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarDescription.class b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarDescription.class new file mode 100644 index 0000000000000000000000000000000000000000..551cbe1414bacc013b6357951b7047b3e4c1fca1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarDescription.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarLoader.class b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..f5de04c6ddd3496c6b67f8aaca77a82205be8fe6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarLoader.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarPool.class b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarPool.class new file mode 100644 index 0000000000000000000000000000000000000000..556e1c8996fcd535ed6268aeae05a6a4b10a7867 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLGrammarPool.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/grammars/XMLSchemaDescription.class b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLSchemaDescription.class new file mode 100644 index 0000000000000000000000000000000000000000..6c78e162e7e2ddfd964cd96f39eab07933de98f9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/grammars/XMLSchemaDescription.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/grammars/XSGrammar.class b/src/main/resources/org/python/apache/xerces/xni/grammars/XSGrammar.class new file mode 100644 index 0000000000000000000000000000000000000000..6837aedac54bcdfcb5840483286544dfe3a6c07e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/grammars/XSGrammar.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLComponent.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLComponent.class new file mode 100644 index 0000000000000000000000000000000000000000..b44a512401ef5af0a7ab16dcfc5b017608ddf6aa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLComponent.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLComponentManager.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLComponentManager.class new file mode 100644 index 0000000000000000000000000000000000000000..12cfae04480e35ad6ca09be21182a803c8d59859 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLComponentManager.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLConfigurationException.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLConfigurationException.class new file mode 100644 index 0000000000000000000000000000000000000000..f769549c85a6f8ab374d9851d1d33ed86f9001ca Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLConfigurationException.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDContentModelFilter.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDContentModelFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..29606e52e4b0c7f272e1ae7f066d642f8877ed19 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDContentModelFilter.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDContentModelSource.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDContentModelSource.class new file mode 100644 index 0000000000000000000000000000000000000000..0c80f96d65546a91d6ec90ed2d74ad4e9324c14b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDContentModelSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDFilter.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..743a704d52769508d7683dbba3637b71264bdbc4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDFilter.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDScanner.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDScanner.class new file mode 100644 index 0000000000000000000000000000000000000000..a38c71a6cdc836002e9aee439519fd143dd560a6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDScanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDSource.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDSource.class new file mode 100644 index 0000000000000000000000000000000000000000..2d313004a627ee99285adddba73e78f25deb6bc6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDTDSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentFilter.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..ea7fdd0d765b624daf984544492c001b610db6e6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentFilter.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentScanner.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentScanner.class new file mode 100644 index 0000000000000000000000000000000000000000..0ad7a273653f6b3d1814e046c6bc87a54cf351b6 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentScanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentSource.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentSource.class new file mode 100644 index 0000000000000000000000000000000000000000..32fc4e2482b970149df8c248ab128ec8fd1ee359 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLDocumentSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLEntityResolver.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLEntityResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..c4c0c4a4a3d9cdb38610418dd599750445f3fc01 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLEntityResolver.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLErrorHandler.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..b449aa65bee7a77f50075a7c229772d3086d80b4 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLErrorHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLInputSource.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLInputSource.class new file mode 100644 index 0000000000000000000000000000000000000000..43ba6adc1b58df345df5c4d5d3b5a1309709dd7b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLInputSource.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLParseException.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLParseException.class new file mode 100644 index 0000000000000000000000000000000000000000..a91084340b02e698e1524830e03e08ef5aa9751c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLParseException.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLParserConfiguration.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..76dd1293bf5182bb0506d682cfb3bd9152582bc2 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/xni/parser/XMLPullParserConfiguration.class b/src/main/resources/org/python/apache/xerces/xni/parser/XMLPullParserConfiguration.class new file mode 100644 index 0000000000000000000000000000000000000000..f3cc057064ea3e54306c1439a3c55d78b3a7b37e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xni/parser/XMLPullParserConfiguration.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$1.class b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9d67bc0ce0bb0a98b4f7149c62fcb2027d6abdc1 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$Scanner.class b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$Scanner.class new file mode 100644 index 0000000000000000000000000000000000000000..366163d92a7eeedc3105ef5bd0d82f4609bc11ab Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$Scanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$Tokens.class b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$Tokens.class new file mode 100644 index 0000000000000000000000000000000000000000..2c9d1634072f3f65e3461c1b7ad3b5d614789430 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer$Tokens.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer.class b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer.class new file mode 100644 index 0000000000000000000000000000000000000000..ad457fa3fd665a7ec3c1df32ea67eddb765857fa Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/ElementSchemePointer.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/ShortHandPointer.class b/src/main/resources/org/python/apache/xerces/xpointer/ShortHandPointer.class new file mode 100644 index 0000000000000000000000000000000000000000..5d5a92520482b4e9a2e68ab488c584cfc831c5c7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/ShortHandPointer.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerErrorHandler.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerErrorHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..bcae43b96cd4c1387163cf9c8d810242efdf1ffe Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerErrorHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$1.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..41ff9ac2332cada4eed66ae972467a63f3657a98 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$1.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$Scanner.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$Scanner.class new file mode 100644 index 0000000000000000000000000000000000000000..ae732c8c3b184af4c5a4dee1053f04e04281000d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$Scanner.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$Tokens.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$Tokens.class new file mode 100644 index 0000000000000000000000000000000000000000..0e5512f2d6eb48c9c454af25d2ea79a5691a4e13 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler$Tokens.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..a8274c892cc42c99631be4089bfe4a23a05d6603 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerHandler.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerMessageFormatter.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerMessageFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..0e2577d6ea088457b7f55b296ae05e3d04186c02 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerMessageFormatter.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerPart.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerPart.class new file mode 100644 index 0000000000000000000000000000000000000000..f9eb920bd9d8adabd582a572880a7922fff1da88 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerPart.class differ diff --git a/src/main/resources/org/python/apache/xerces/xpointer/XPointerProcessor.class b/src/main/resources/org/python/apache/xerces/xpointer/XPointerProcessor.class new file mode 100644 index 0000000000000000000000000000000000000000..e0d467870a83b629b73095520ca42ddef5fcc865 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xpointer/XPointerProcessor.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/AttributePSVI.class b/src/main/resources/org/python/apache/xerces/xs/AttributePSVI.class new file mode 100644 index 0000000000000000000000000000000000000000..f42c82ed81f6edae23c63795f62d932e0756e65b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/AttributePSVI.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/ElementPSVI.class b/src/main/resources/org/python/apache/xerces/xs/ElementPSVI.class new file mode 100644 index 0000000000000000000000000000000000000000..b6834261db636bb69720e99400d8771873166184 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/ElementPSVI.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/ItemPSVI.class b/src/main/resources/org/python/apache/xerces/xs/ItemPSVI.class new file mode 100644 index 0000000000000000000000000000000000000000..7314829d79b285a7d4a1799c3b266cb57aa877f7 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/ItemPSVI.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/LSInputList.class b/src/main/resources/org/python/apache/xerces/xs/LSInputList.class new file mode 100644 index 0000000000000000000000000000000000000000..bf980433e0bebbdee656f56a5455effa106c2d2e Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/LSInputList.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/PSVIProvider.class b/src/main/resources/org/python/apache/xerces/xs/PSVIProvider.class new file mode 100644 index 0000000000000000000000000000000000000000..7f5d491de94db7387a9b13bf7e0b30ef116d70d8 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/PSVIProvider.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/ShortList.class b/src/main/resources/org/python/apache/xerces/xs/ShortList.class new file mode 100644 index 0000000000000000000000000000000000000000..9dea5bf3aeda208368a7a93c9eda11bbf202160d Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/ShortList.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/StringList.class b/src/main/resources/org/python/apache/xerces/xs/StringList.class new file mode 100644 index 0000000000000000000000000000000000000000..102d39518a36e9a31e0c5f4a010a29af66026861 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/StringList.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSAnnotation.class b/src/main/resources/org/python/apache/xerces/xs/XSAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..ae77e07fad1de6a1b34b0c37400ab84dccaf7374 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSAnnotation.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSAttributeDeclaration.class b/src/main/resources/org/python/apache/xerces/xs/XSAttributeDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..36971423009bee46d5832fb9e566711c2658256c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSAttributeDeclaration.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSAttributeGroupDefinition.class b/src/main/resources/org/python/apache/xerces/xs/XSAttributeGroupDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..5ab5ab48566ea9cd55e4a4391683a03959c77770 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSAttributeGroupDefinition.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSAttributeUse.class b/src/main/resources/org/python/apache/xerces/xs/XSAttributeUse.class new file mode 100644 index 0000000000000000000000000000000000000000..fe1c5d704a4379955a962f1cc85d8bd2333f2899 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSAttributeUse.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSComplexTypeDefinition.class b/src/main/resources/org/python/apache/xerces/xs/XSComplexTypeDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..18a5c06a5cbacc385ed9ae5f9e63aff73f458c60 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSComplexTypeDefinition.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSConstants.class b/src/main/resources/org/python/apache/xerces/xs/XSConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..b1817c8554501b93dcc91440193722159ecd8f5a Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSConstants.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSElementDeclaration.class b/src/main/resources/org/python/apache/xerces/xs/XSElementDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..4266e37634f19bb95a48bbfb7f88098566bc8e58 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSElementDeclaration.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSException.class b/src/main/resources/org/python/apache/xerces/xs/XSException.class new file mode 100644 index 0000000000000000000000000000000000000000..08f828635773d795208650c98828aff6608638ba Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSException.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSFacet.class b/src/main/resources/org/python/apache/xerces/xs/XSFacet.class new file mode 100644 index 0000000000000000000000000000000000000000..4b9cc2692ad84403f2f3e74c71e5e773684ac9a9 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSFacet.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSIDCDefinition.class b/src/main/resources/org/python/apache/xerces/xs/XSIDCDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..e929aa643e986cdcb416059558c384c2a455e408 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSIDCDefinition.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSImplementation.class b/src/main/resources/org/python/apache/xerces/xs/XSImplementation.class new file mode 100644 index 0000000000000000000000000000000000000000..8c9c952c92ff302e5fb1517297c8e52a00cd27ae Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSImplementation.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSLoader.class b/src/main/resources/org/python/apache/xerces/xs/XSLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..b19885e76ea4a44d75f1d04fa7def69c2bc72408 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSLoader.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSModel.class b/src/main/resources/org/python/apache/xerces/xs/XSModel.class new file mode 100644 index 0000000000000000000000000000000000000000..0a30146cd1514e6f90998781d1eb07921bf44789 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSModel.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSModelGroup.class b/src/main/resources/org/python/apache/xerces/xs/XSModelGroup.class new file mode 100644 index 0000000000000000000000000000000000000000..9c885362a7fa4f06034c2f9fb871f6e6a0a86403 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSModelGroup.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSModelGroupDefinition.class b/src/main/resources/org/python/apache/xerces/xs/XSModelGroupDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..d89df94984ea807ec7a0f325f1b520635df7a259 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSModelGroupDefinition.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSMultiValueFacet.class b/src/main/resources/org/python/apache/xerces/xs/XSMultiValueFacet.class new file mode 100644 index 0000000000000000000000000000000000000000..d06e805ae5cafda5d6bb3bc12a5d7762935a3cee Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSMultiValueFacet.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSNamedMap.class b/src/main/resources/org/python/apache/xerces/xs/XSNamedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..58e78f24b44737bad459c9b9b382d9b1b9a51360 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSNamedMap.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSNamespaceItem.class b/src/main/resources/org/python/apache/xerces/xs/XSNamespaceItem.class new file mode 100644 index 0000000000000000000000000000000000000000..666bbfd76afdcde7ffb9e521599a167938692b12 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSNamespaceItem.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSNamespaceItemList.class b/src/main/resources/org/python/apache/xerces/xs/XSNamespaceItemList.class new file mode 100644 index 0000000000000000000000000000000000000000..0000d57400c153124edad4d35da13477fc229005 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSNamespaceItemList.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSNotationDeclaration.class b/src/main/resources/org/python/apache/xerces/xs/XSNotationDeclaration.class new file mode 100644 index 0000000000000000000000000000000000000000..9bab43589f90e66d7584188185140bd9e59a1e96 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSNotationDeclaration.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSObject.class b/src/main/resources/org/python/apache/xerces/xs/XSObject.class new file mode 100644 index 0000000000000000000000000000000000000000..24e654c0e685de82f316b335b179599f907e9b19 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSObject.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSObjectList.class b/src/main/resources/org/python/apache/xerces/xs/XSObjectList.class new file mode 100644 index 0000000000000000000000000000000000000000..128d86ba9589c6c0ae046aacba3fb64c9128751c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSObjectList.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSParticle.class b/src/main/resources/org/python/apache/xerces/xs/XSParticle.class new file mode 100644 index 0000000000000000000000000000000000000000..cd30b403d162fff66d50be93afba1540b54a78be Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSParticle.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSSimpleTypeDefinition.class b/src/main/resources/org/python/apache/xerces/xs/XSSimpleTypeDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..bd6781082924d30bd1c2124b928ce4590a049885 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSSimpleTypeDefinition.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSTerm.class b/src/main/resources/org/python/apache/xerces/xs/XSTerm.class new file mode 100644 index 0000000000000000000000000000000000000000..fcb3f91d15dc76aa79dc9d6e4f610f18c8d4ab34 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSTerm.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSTypeDefinition.class b/src/main/resources/org/python/apache/xerces/xs/XSTypeDefinition.class new file mode 100644 index 0000000000000000000000000000000000000000..3aa743ac8512e2a1f7b9f121ff00475783b4861b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSTypeDefinition.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSValue.class b/src/main/resources/org/python/apache/xerces/xs/XSValue.class new file mode 100644 index 0000000000000000000000000000000000000000..7faf08915cc72f93294c016ef1a07efc09b613ba Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSValue.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/XSWildcard.class b/src/main/resources/org/python/apache/xerces/xs/XSWildcard.class new file mode 100644 index 0000000000000000000000000000000000000000..4d5561648146957c72fe3174fc62ca654b49c635 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/XSWildcard.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/datatypes/ByteList.class b/src/main/resources/org/python/apache/xerces/xs/datatypes/ByteList.class new file mode 100644 index 0000000000000000000000000000000000000000..fd43d9f973af7b1b1a9fce7184c5b25dd5519408 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/datatypes/ByteList.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/datatypes/ObjectList.class b/src/main/resources/org/python/apache/xerces/xs/datatypes/ObjectList.class new file mode 100644 index 0000000000000000000000000000000000000000..ab05b93d0647be59aa33c56e14a796d41be2723c Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/datatypes/ObjectList.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDateTime.class b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDateTime.class new file mode 100644 index 0000000000000000000000000000000000000000..2fb6137457319d217f5d40f44fbf858b9e4212ad Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDateTime.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDecimal.class b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDecimal.class new file mode 100644 index 0000000000000000000000000000000000000000..5d6641fb88a0a78220523fb39dc690a21875b73b Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDecimal.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDouble.class b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDouble.class new file mode 100644 index 0000000000000000000000000000000000000000..754862bfc08f212f5792c23163d3e9d36718a152 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSDouble.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/datatypes/XSFloat.class b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSFloat.class new file mode 100644 index 0000000000000000000000000000000000000000..4ab9a1f3f1e094445c9639f48d7fdc2c30f14127 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSFloat.class differ diff --git a/src/main/resources/org/python/apache/xerces/xs/datatypes/XSQName.class b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSQName.class new file mode 100644 index 0000000000000000000000000000000000000000..357ea6e99dbdcf924d74b777d8fd48cb646a2846 Binary files /dev/null and b/src/main/resources/org/python/apache/xerces/xs/datatypes/XSQName.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/BaseMarkupSerializer.class b/src/main/resources/org/python/apache/xml/serialize/BaseMarkupSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..3fc5880455d06482b01a81429d6b641cf528e2a8 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/BaseMarkupSerializer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/DOMSerializer.class b/src/main/resources/org/python/apache/xml/serialize/DOMSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..c6c7a4e37c358873a855cc9a2d62a19a8457db57 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/DOMSerializer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/DOMSerializerImpl$DocumentMethods.class b/src/main/resources/org/python/apache/xml/serialize/DOMSerializerImpl$DocumentMethods.class new file mode 100644 index 0000000000000000000000000000000000000000..be86264e2803e964f8af43d3050685639cee1c8e Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/DOMSerializerImpl$DocumentMethods.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/DOMSerializerImpl.class b/src/main/resources/org/python/apache/xml/serialize/DOMSerializerImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..54728cabb2fa146fd86daa9c8601e0596d6d00e8 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/DOMSerializerImpl.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/ElementState.class b/src/main/resources/org/python/apache/xml/serialize/ElementState.class new file mode 100644 index 0000000000000000000000000000000000000000..a58cfd94aaf59d3b5696e205622aa6694e655be8 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/ElementState.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/EncodingInfo$CharToByteConverterMethods.class b/src/main/resources/org/python/apache/xml/serialize/EncodingInfo$CharToByteConverterMethods.class new file mode 100644 index 0000000000000000000000000000000000000000..74344298300be3ef3c30dc7630b65ee72a5f6c74 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/EncodingInfo$CharToByteConverterMethods.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/EncodingInfo$CharsetMethods.class b/src/main/resources/org/python/apache/xml/serialize/EncodingInfo$CharsetMethods.class new file mode 100644 index 0000000000000000000000000000000000000000..2a9aac060c9d6132f7ff82a7153f4eda02c21fe5 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/EncodingInfo$CharsetMethods.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/EncodingInfo.class b/src/main/resources/org/python/apache/xml/serialize/EncodingInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..6dfc78b1a4b15487f0d07518536403e6e1f18481 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/EncodingInfo.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/Encodings.class b/src/main/resources/org/python/apache/xml/serialize/Encodings.class new file mode 100644 index 0000000000000000000000000000000000000000..c36a20fc9d29c60f4eb626ad1843cb52124e0831 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/Encodings.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/HTMLEntities.res b/src/main/resources/org/python/apache/xml/serialize/HTMLEntities.res new file mode 100644 index 0000000000000000000000000000000000000000..fb70ec5cc3e6960d8013e61e7d6de19bf7236db8 --- /dev/null +++ b/src/main/resources/org/python/apache/xml/serialize/HTMLEntities.res @@ -0,0 +1,291 @@ +# $Id: HTMLEntities.res 316040 2000-08-30 18:59:22Z arkin $ +# +# @version $Revision: 316040 $ $Date: 2000-08-30 14:59:22 -0400 (Wed, 30 Aug 2000) $ +# @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a> +# +# Character entity references for markup-significant +# +quot 34 +amp 38 +lt 60 +gt 62 +nbsp 160 +# +# Character entity references for ISO 8859-1 characters +# +iexcl 161 +cent 162 +pound 163 +curren 164 +yen 165 +brvbar 166 +sect 167 +uml 168 +copy 169 +ordf 170 +laquo 171 +not 172 +shy 173 +reg 174 +macr 175 +deg 176 +plusmn 177 +sup2 178 +sup3 179 +acute 180 +micro 181 +para 182 +middot 183 +cedil 184 +sup1 185 +ordm 186 +raquo 187 +frac14 188 +frac12 189 +frac34 190 +iquest 191 +Agrave 192 +Aacute 193 +Acirc 194 +Atilde 195 +Auml 196 +Aring 197 +AElig 198 +Ccedil 199 +Egrave 200 +Eacute 201 +Ecirc 202 +Euml 203 +Igrave 204 +Iacute 205 +Icirc 206 +Iuml 207 +ETH 208 +Ntilde 209 +Ograve 210 +Oacute 211 +Ocirc 212 +Otilde 213 +Ouml 214 +times 215 +Oslash 216 +Ugrave 217 +Uacute 218 +Ucirc 219 +Uuml 220 +Yacute 221 +THORN 222 +szlig 223 +agrave 224 +aacute 225 +acirc 226 +atilde 227 +auml 228 +aring 229 +aelig 230 +ccedil 231 +egrave 232 +eacute 233 +ecirc 234 +euml 235 +igrave 236 +iacute 237 +icirc 238 +iuml 239 +eth 240 +ntilde 241 +ograve 242 +oacute 243 +ocirc 244 +otilde 245 +ouml 246 +divide 247 +oslash 248 +ugrave 249 +uacute 250 +ucirc 251 +uuml 252 +yacute 253 +thorn 254 +yuml 255 +# +# Character entity references for symbols, mathematical symbols, and Greek letters +# +# Latin Extended +fnof 402 +# +# Greek +Alpha 913 +Beta 914 +Gamma 915 +Delta 916 +Epsilon 917 +Zeta 918 +Eta 919 +Theta 920 +Iota 921 +Kappa 922 +Lambda 923 +Mu 924 +Nu 925 +Xi 926 +Omicron 927 +Pi 928 +Rho 929 +Sigma 931 +Tau 932 +Upsilon 933 +Phi 934 +Chi 935 +Psi 936 +Omega 937 +alpha 945 +beta 946 +gamma 947 +delta 948 +epsilon 949 +zeta 950 +eta 951 +theta 952 +iota 953 +kappa 954 +lambda 955 +mu 956 +nu 957 +xi 958 +omicron 959 +pi 960 +rho 961 +sigmaf 962 +sigma 963 +tau 964 +upsilon 965 +phi 966 +chi 967 +psi 968 +omega 969 +thetasym 977 +upsih 978 +piv 982 +# +# General Punctuation +bull 8226 +hellip 8230 +prime 8242 +Prime 8243 +oline 8254 +frasl 8260 +# +# Letterlike Symbols +weierp 8472 +image 8465 +real 8476 +trade 8482 +alefsym 8501 +# +# Arrows +larr 8592 +uarr 8593 +rarr 8594 +darr 8595 +harr 8596 +crarr 8629 +lArr 8656 +uArr 8657 +rArr 8658 +dArr 8659 +hArr 8660 +# +# Mathematical Operators +forall 8704 +part 8706 +exist 8707 +empty 8709 +nabla 8711 +isin 8712 +notin 8713 +ni 8715 +prod 8719 +sum 8721 +minus 8722 +lowast 8727 +radic 8730 +prop 8733 +infin 8734 +ang 8736 +and 8743 +or 8744 +cap 8745 +cup 8746 +int 8747 +there4 8756 +sim 8764 +cong 8773 +asymp 8776 +ne 8800 +equiv 8801 +le 8804 +ge 8805 +sub 8834 +sup 8835 +nsub 8836 +sube 8838 +supe 8839 +oplus 8853 +otimes 8855 +perp 8869 +sdot 8901 +# +# Miscellaneous Technical +lceil 8968 +rceil 8969 +lfloor 8970 +rfloor 8971 +lang 9001 +rang 9002 +# +# Geometric Shapes +loz 9674 +# +# Miscellaneous Symbols +spades 9824 +clubs 9827 +hearts 9829 +diams 9830 +# +# Character entity references for internationalization characters +# +# Latin Extended-A +OElig 338 +oelig 339 +#-- Commented out. NN 4.7 does not seem to support these -- +#Scaron 352 +#scaron 353 +Yuml 376 +# +# Spacing Modifier Letters +circ 710 +tilde 732 +# +# General Punctuation +ensp 8194 +emsp 8195 +thinsp 8201 +zwnj 8204 +zwj 8205 +lrm 8206 +rlm 8207 +ndash 8211 +mdash 8212 +lsquo 8216 +rsquo 8217 +sbquo 8218 +ldquo 8220 +rdquo 8221 +bdquo 8222 +dagger 8224 +Dagger 8225 +permil 8240 +lsaquo 8249 +rsaquo 8250 +euro 8364 diff --git a/src/main/resources/org/python/apache/xml/serialize/HTMLSerializer.class b/src/main/resources/org/python/apache/xml/serialize/HTMLSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..00e861320a10accc4d064cc4da3ec11ed3de2f3d Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/HTMLSerializer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/HTMLdtd.class b/src/main/resources/org/python/apache/xml/serialize/HTMLdtd.class new file mode 100644 index 0000000000000000000000000000000000000000..06d4347c004769dfbf8c38166cc53d1b9c531931 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/HTMLdtd.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/IndentPrinter.class b/src/main/resources/org/python/apache/xml/serialize/IndentPrinter.class new file mode 100644 index 0000000000000000000000000000000000000000..efdbdb5b9f8dd3eaf612ef5708d9b4343f7b55e9 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/IndentPrinter.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/LineSeparator.class b/src/main/resources/org/python/apache/xml/serialize/LineSeparator.class new file mode 100644 index 0000000000000000000000000000000000000000..d7b4dc8a70680a8940b39e29838b87430af571a0 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/LineSeparator.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/Method.class b/src/main/resources/org/python/apache/xml/serialize/Method.class new file mode 100644 index 0000000000000000000000000000000000000000..be7ea01e3e214da91de99fa856cbc4cbf0c82ace Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/Method.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/ObjectFactory$ConfigurationError.class b/src/main/resources/org/python/apache/xml/serialize/ObjectFactory$ConfigurationError.class new file mode 100644 index 0000000000000000000000000000000000000000..34d6f63e0822a34c3234b603b09be1ff92a65d20 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/ObjectFactory$ConfigurationError.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/ObjectFactory.class b/src/main/resources/org/python/apache/xml/serialize/ObjectFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..5f2de0ceecaa13a0639e40a9ad47d4adbc2063c2 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/ObjectFactory.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/OutputFormat$DTD.class b/src/main/resources/org/python/apache/xml/serialize/OutputFormat$DTD.class new file mode 100644 index 0000000000000000000000000000000000000000..ce09d75e4065bd4db4b7eae2679c711adbb4dd71 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/OutputFormat$DTD.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/OutputFormat$Defaults.class b/src/main/resources/org/python/apache/xml/serialize/OutputFormat$Defaults.class new file mode 100644 index 0000000000000000000000000000000000000000..14660afecde05bec9889e69b0980a121988b7a16 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/OutputFormat$Defaults.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/OutputFormat.class b/src/main/resources/org/python/apache/xml/serialize/OutputFormat.class new file mode 100644 index 0000000000000000000000000000000000000000..d2055faa7e2342a3366142d3b1f5aadbc7f2bf5d Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/OutputFormat.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/Printer.class b/src/main/resources/org/python/apache/xml/serialize/Printer.class new file mode 100644 index 0000000000000000000000000000000000000000..869dddd18f77fe0377e410ed75bfc83c1953de5e Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/Printer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$1.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8c6fe4ab7c9e76bf062ce9f4b2a8a127675142f2 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$1.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$2.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$2.class new file mode 100644 index 0000000000000000000000000000000000000000..7afe87a7ebfc42369b2492d8c2ab872798bda584 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$2.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$3.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$3.class new file mode 100644 index 0000000000000000000000000000000000000000..3983a37bea6bfaf6b5a7081fedba83c81804b3c4 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$3.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$4.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$4.class new file mode 100644 index 0000000000000000000000000000000000000000..ecffef100ff6a583866630761312c670a7aca710 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$4.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$5.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$5.class new file mode 100644 index 0000000000000000000000000000000000000000..ca95760d2417bfaf954491d74f1d84ebe7ba4a13 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$5.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$6.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$6.class new file mode 100644 index 0000000000000000000000000000000000000000..e3fdb419c5f455b16f315482d8966aecf8118363 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$6.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$7.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$7.class new file mode 100644 index 0000000000000000000000000000000000000000..fa64bf144921ed1b51b642b93a46f5ce25e4cbbf Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$7.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$8.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$8.class new file mode 100644 index 0000000000000000000000000000000000000000..1dd9ca7cb2d007f701a67690c88afbb9e95b8580 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport$8.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SecuritySupport.class b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport.class new file mode 100644 index 0000000000000000000000000000000000000000..1017cdd32e3e85fc52a4cdf56c9537b5d04bd2ab Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SecuritySupport.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/Serializer.class b/src/main/resources/org/python/apache/xml/serialize/Serializer.class new file mode 100644 index 0000000000000000000000000000000000000000..0165ce5d909a077bbe167c397699dc994e9117b7 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/Serializer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SerializerFactory.class b/src/main/resources/org/python/apache/xml/serialize/SerializerFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..dbc3c97e723a76c2eae97dbea31e2fb6064471e0 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SerializerFactory.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/SerializerFactoryImpl.class b/src/main/resources/org/python/apache/xml/serialize/SerializerFactoryImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..84243281675f1337c4560c19b928ec45265f7db1 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/SerializerFactoryImpl.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/TextSerializer.class b/src/main/resources/org/python/apache/xml/serialize/TextSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..eff98f1eaabc184493a4377508d187c6f1e5c95e Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/TextSerializer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/XHTMLSerializer.class b/src/main/resources/org/python/apache/xml/serialize/XHTMLSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..bf33197f9490a133a6160b8926b64f75ed279c05 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/XHTMLSerializer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/XML11Serializer.class b/src/main/resources/org/python/apache/xml/serialize/XML11Serializer.class new file mode 100644 index 0000000000000000000000000000000000000000..b61c5e68e82903a5e8d0d911d3226331317603cb Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/XML11Serializer.class differ diff --git a/src/main/resources/org/python/apache/xml/serialize/XMLSerializer.class b/src/main/resources/org/python/apache/xml/serialize/XMLSerializer.class new file mode 100644 index 0000000000000000000000000000000000000000..c436a80ed6d81cbd14a29b8a76f586dacaa75df6 Binary files /dev/null and b/src/main/resources/org/python/apache/xml/serialize/XMLSerializer.class differ diff --git a/src/main/resources/org/python/compiler/APIVersion.class b/src/main/resources/org/python/compiler/APIVersion.class new file mode 100644 index 0000000000000000000000000000000000000000..4546728bc0ef2f00de77c754a7da238f7aa30362 Binary files /dev/null and b/src/main/resources/org/python/compiler/APIVersion.class differ diff --git a/src/main/resources/org/python/compiler/AdapterMaker.class b/src/main/resources/org/python/compiler/AdapterMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..e1fd41a6010426f0c9b04e4f5a61f8f926df846e Binary files /dev/null and b/src/main/resources/org/python/compiler/AdapterMaker.class differ diff --git a/src/main/resources/org/python/compiler/ArgListCompiler.class b/src/main/resources/org/python/compiler/ArgListCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..deccdbba5b0883c929acf562ae880e369a48dce6 Binary files /dev/null and b/src/main/resources/org/python/compiler/ArgListCompiler.class differ diff --git a/src/main/resources/org/python/compiler/ClassConstants.class b/src/main/resources/org/python/compiler/ClassConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..f7d26a77757bdfa3c8b43b4f85cdd7334d2dd93b Binary files /dev/null and b/src/main/resources/org/python/compiler/ClassConstants.class differ diff --git a/src/main/resources/org/python/compiler/ClassFile.class b/src/main/resources/org/python/compiler/ClassFile.class new file mode 100644 index 0000000000000000000000000000000000000000..9185ee17dfcb4d9742ab022e6448d5c345aa938d Binary files /dev/null and b/src/main/resources/org/python/compiler/ClassFile.class differ diff --git a/src/main/resources/org/python/compiler/Code.class b/src/main/resources/org/python/compiler/Code.class new file mode 100644 index 0000000000000000000000000000000000000000..17e2d6077d6b9d11af9e9b6afee5ee8a45d01bde Binary files /dev/null and b/src/main/resources/org/python/compiler/Code.class differ diff --git a/src/main/resources/org/python/compiler/CodeCompiler$1.class b/src/main/resources/org/python/compiler/CodeCompiler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1a2c2d9f0ce3fbf926a370c110d380842a859fd6 Binary files /dev/null and b/src/main/resources/org/python/compiler/CodeCompiler$1.class differ diff --git a/src/main/resources/org/python/compiler/CodeCompiler$2.class b/src/main/resources/org/python/compiler/CodeCompiler$2.class new file mode 100644 index 0000000000000000000000000000000000000000..38f4ffc9d7f3f3ad25fd9eef34bc1a2c59a58bc3 Binary files /dev/null and b/src/main/resources/org/python/compiler/CodeCompiler$2.class differ diff --git a/src/main/resources/org/python/compiler/CodeCompiler$ExceptionHandler.class b/src/main/resources/org/python/compiler/CodeCompiler$ExceptionHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..68bac2c784ffd5b92252c28397189f4261fca861 Binary files /dev/null and b/src/main/resources/org/python/compiler/CodeCompiler$ExceptionHandler.class differ diff --git a/src/main/resources/org/python/compiler/CodeCompiler$LambdaSyntheticReturn.class b/src/main/resources/org/python/compiler/CodeCompiler$LambdaSyntheticReturn.class new file mode 100644 index 0000000000000000000000000000000000000000..5a9a4079b6344cd88dadd8f5c2f26464d9f4a97c Binary files /dev/null and b/src/main/resources/org/python/compiler/CodeCompiler$LambdaSyntheticReturn.class differ diff --git a/src/main/resources/org/python/compiler/CodeCompiler.class b/src/main/resources/org/python/compiler/CodeCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..d291d46c2f3fdfbe0d517ce7c0626291cddd7480 Binary files /dev/null and b/src/main/resources/org/python/compiler/CodeCompiler.class differ diff --git a/src/main/resources/org/python/compiler/CompilationContext.class b/src/main/resources/org/python/compiler/CompilationContext.class new file mode 100644 index 0000000000000000000000000000000000000000..8580d28152196c2f43fa3dc96dffe99130a0c4b9 Binary files /dev/null and b/src/main/resources/org/python/compiler/CompilationContext.class differ diff --git a/src/main/resources/org/python/compiler/Constant.class b/src/main/resources/org/python/compiler/Constant.class new file mode 100644 index 0000000000000000000000000000000000000000..ad7de99c42918f414c57427fce4e643450dc6d49 Binary files /dev/null and b/src/main/resources/org/python/compiler/Constant.class differ diff --git a/src/main/resources/org/python/compiler/CustomMaker.class b/src/main/resources/org/python/compiler/CustomMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..d12b811cf73d7b3aa2c7b9183eb9c641b703d3b3 Binary files /dev/null and b/src/main/resources/org/python/compiler/CustomMaker.class differ diff --git a/src/main/resources/org/python/compiler/Future$1.class b/src/main/resources/org/python/compiler/Future$1.class new file mode 100644 index 0000000000000000000000000000000000000000..973cea8a4b205894eda100e4365db2c9618d4677 Binary files /dev/null and b/src/main/resources/org/python/compiler/Future$1.class differ diff --git a/src/main/resources/org/python/compiler/Future.class b/src/main/resources/org/python/compiler/Future.class new file mode 100644 index 0000000000000000000000000000000000000000..e260f392ea9f2ddd3cabadce329e9c10c8acb632 Binary files /dev/null and b/src/main/resources/org/python/compiler/Future.class differ diff --git a/src/main/resources/org/python/compiler/JavaMaker.class b/src/main/resources/org/python/compiler/JavaMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..9bfb0235f7a28d86c9bf3aa6c04c6fb0e6e09700 Binary files /dev/null and b/src/main/resources/org/python/compiler/JavaMaker.class differ diff --git a/src/main/resources/org/python/compiler/JavaMakerSmokeTest.class b/src/main/resources/org/python/compiler/JavaMakerSmokeTest.class new file mode 100644 index 0000000000000000000000000000000000000000..f36e9201467e4de48a8f5c41106a2f38b9675840 Binary files /dev/null and b/src/main/resources/org/python/compiler/JavaMakerSmokeTest.class differ diff --git a/src/main/resources/org/python/compiler/LegacyCompiler$LazyLegacyBundle.class b/src/main/resources/org/python/compiler/LegacyCompiler$LazyLegacyBundle.class new file mode 100644 index 0000000000000000000000000000000000000000..d3544ef21408384b923afea7da541f85b7e501df Binary files /dev/null and b/src/main/resources/org/python/compiler/LegacyCompiler$LazyLegacyBundle.class differ diff --git a/src/main/resources/org/python/compiler/LegacyCompiler.class b/src/main/resources/org/python/compiler/LegacyCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..b85511c616de18b32beb8ed502f7ce7bc07e4a13 Binary files /dev/null and b/src/main/resources/org/python/compiler/LegacyCompiler.class differ diff --git a/src/main/resources/org/python/compiler/LineNumberTable.class b/src/main/resources/org/python/compiler/LineNumberTable.class new file mode 100644 index 0000000000000000000000000000000000000000..8174313153002dd939e942b31a25ec8623574695 Binary files /dev/null and b/src/main/resources/org/python/compiler/LineNumberTable.class differ diff --git a/src/main/resources/org/python/compiler/MTime.class b/src/main/resources/org/python/compiler/MTime.class new file mode 100644 index 0000000000000000000000000000000000000000..8061f23a63f82a1ffa35d14cbf022732d81c0034 Binary files /dev/null and b/src/main/resources/org/python/compiler/MTime.class differ diff --git a/src/main/resources/org/python/compiler/Module.class b/src/main/resources/org/python/compiler/Module.class new file mode 100644 index 0000000000000000000000000000000000000000..8fb2bb628723edd559c8265d7fce8f41e9a1ad7f Binary files /dev/null and b/src/main/resources/org/python/compiler/Module.class differ diff --git a/src/main/resources/org/python/compiler/ModuleTest.class b/src/main/resources/org/python/compiler/ModuleTest.class new file mode 100644 index 0000000000000000000000000000000000000000..16636da0b436b4a8a0fa339086a7c9005354019a Binary files /dev/null and b/src/main/resources/org/python/compiler/ModuleTest.class differ diff --git a/src/main/resources/org/python/compiler/ProxyCodeHelpers$AnnotationDescr.class b/src/main/resources/org/python/compiler/ProxyCodeHelpers$AnnotationDescr.class new file mode 100644 index 0000000000000000000000000000000000000000..6f0b7bc5b8c6845970bef7445a8a17ca31d0bfa5 Binary files /dev/null and b/src/main/resources/org/python/compiler/ProxyCodeHelpers$AnnotationDescr.class differ diff --git a/src/main/resources/org/python/compiler/ProxyCodeHelpers$ConstructorDescr.class b/src/main/resources/org/python/compiler/ProxyCodeHelpers$ConstructorDescr.class new file mode 100644 index 0000000000000000000000000000000000000000..acf765dcffd154a172369aa4592fa48f92145b98 Binary files /dev/null and b/src/main/resources/org/python/compiler/ProxyCodeHelpers$ConstructorDescr.class differ diff --git a/src/main/resources/org/python/compiler/ProxyCodeHelpers$MethodDescr.class b/src/main/resources/org/python/compiler/ProxyCodeHelpers$MethodDescr.class new file mode 100644 index 0000000000000000000000000000000000000000..e851ea30e2ae4139ecdf7998321375563be7b9e7 Binary files /dev/null and b/src/main/resources/org/python/compiler/ProxyCodeHelpers$MethodDescr.class differ diff --git a/src/main/resources/org/python/compiler/ProxyCodeHelpers.class b/src/main/resources/org/python/compiler/ProxyCodeHelpers.class new file mode 100644 index 0000000000000000000000000000000000000000..73b29c56379c563f990ecb2cc2e6af756cc99391 Binary files /dev/null and b/src/main/resources/org/python/compiler/ProxyCodeHelpers.class differ diff --git a/src/main/resources/org/python/compiler/ProxyMaker.class b/src/main/resources/org/python/compiler/ProxyMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..44384d346267900511a56fdcb15a240581267306 Binary files /dev/null and b/src/main/resources/org/python/compiler/ProxyMaker.class differ diff --git a/src/main/resources/org/python/compiler/PyCodeConstant.class b/src/main/resources/org/python/compiler/PyCodeConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..feda5a0412f8c9d202bd51af688c8ce0e2e62775 Binary files /dev/null and b/src/main/resources/org/python/compiler/PyCodeConstant.class differ diff --git a/src/main/resources/org/python/compiler/PyComplexConstant.class b/src/main/resources/org/python/compiler/PyComplexConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..747a55fb2c1bf606d5175dff874d4578e1c15b86 Binary files /dev/null and b/src/main/resources/org/python/compiler/PyComplexConstant.class differ diff --git a/src/main/resources/org/python/compiler/PyFloatConstant.class b/src/main/resources/org/python/compiler/PyFloatConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..55b78e8636dfaf6fe53440c6fbdb7a2329160ca6 Binary files /dev/null and b/src/main/resources/org/python/compiler/PyFloatConstant.class differ diff --git a/src/main/resources/org/python/compiler/PyIntegerConstant.class b/src/main/resources/org/python/compiler/PyIntegerConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..4e8377d588599b6f41d16cc63aea06e2f75d1029 Binary files /dev/null and b/src/main/resources/org/python/compiler/PyIntegerConstant.class differ diff --git a/src/main/resources/org/python/compiler/PyLongConstant.class b/src/main/resources/org/python/compiler/PyLongConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..c4284d377d5d7862e6730f338fc22237b51f87b6 Binary files /dev/null and b/src/main/resources/org/python/compiler/PyLongConstant.class differ diff --git a/src/main/resources/org/python/compiler/PyStringConstant.class b/src/main/resources/org/python/compiler/PyStringConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..16951bbc4d36b2fb32b2e5535b8071490fb55e9f Binary files /dev/null and b/src/main/resources/org/python/compiler/PyStringConstant.class differ diff --git a/src/main/resources/org/python/compiler/PyUnicodeConstant.class b/src/main/resources/org/python/compiler/PyUnicodeConstant.class new file mode 100644 index 0000000000000000000000000000000000000000..67eac6d28783bf8c3e8070d9f1d5bdb2172cbde3 Binary files /dev/null and b/src/main/resources/org/python/compiler/PyUnicodeConstant.class differ diff --git a/src/main/resources/org/python/compiler/ScopeConstants.class b/src/main/resources/org/python/compiler/ScopeConstants.class new file mode 100644 index 0000000000000000000000000000000000000000..1d7068680d74c7a2c6347aaeb52d17d98832125e Binary files /dev/null and b/src/main/resources/org/python/compiler/ScopeConstants.class differ diff --git a/src/main/resources/org/python/compiler/ScopeInfo.class b/src/main/resources/org/python/compiler/ScopeInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..826aa543af843c684a8ee69615df38ad465ccf75 Binary files /dev/null and b/src/main/resources/org/python/compiler/ScopeInfo.class differ diff --git a/src/main/resources/org/python/compiler/ScopesCompiler.class b/src/main/resources/org/python/compiler/ScopesCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..7d077d9fc2609c8d0ef0d3ab0b19e20141ad972a Binary files /dev/null and b/src/main/resources/org/python/compiler/ScopesCompiler.class differ diff --git a/src/main/resources/org/python/compiler/SymInfo.class b/src/main/resources/org/python/compiler/SymInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..cd374c35339aa2ab165f5c0abf0ea97153a3ec5b Binary files /dev/null and b/src/main/resources/org/python/compiler/SymInfo.class differ diff --git a/src/main/resources/org/python/compiler/custom_proxymaker/ClassAnnotationTest.class b/src/main/resources/org/python/compiler/custom_proxymaker/ClassAnnotationTest.class new file mode 100644 index 0000000000000000000000000000000000000000..328fe41666166289ca343d32827a23962587ab5d Binary files /dev/null and b/src/main/resources/org/python/compiler/custom_proxymaker/ClassAnnotationTest.class differ diff --git a/src/main/resources/org/python/compiler/custom_proxymaker/ConstructorSignatureTest.class b/src/main/resources/org/python/compiler/custom_proxymaker/ConstructorSignatureTest.class new file mode 100644 index 0000000000000000000000000000000000000000..e5f89e3950552626ab14d52883b067a20b263d5f Binary files /dev/null and b/src/main/resources/org/python/compiler/custom_proxymaker/ConstructorSignatureTest.class differ diff --git a/src/main/resources/org/python/compiler/custom_proxymaker/CustomAnnotation$Priority.class b/src/main/resources/org/python/compiler/custom_proxymaker/CustomAnnotation$Priority.class new file mode 100644 index 0000000000000000000000000000000000000000..ba11a0baf86e67672b119f8905b2cb48f5e78847 Binary files /dev/null and b/src/main/resources/org/python/compiler/custom_proxymaker/CustomAnnotation$Priority.class differ diff --git a/src/main/resources/org/python/compiler/custom_proxymaker/CustomAnnotation.class b/src/main/resources/org/python/compiler/custom_proxymaker/CustomAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..58c95001240a1b0f4824e63ea5bd20b85920e87a Binary files /dev/null and b/src/main/resources/org/python/compiler/custom_proxymaker/CustomAnnotation.class differ diff --git a/src/main/resources/org/python/compiler/custom_proxymaker/JUnitTest.class b/src/main/resources/org/python/compiler/custom_proxymaker/JUnitTest.class new file mode 100644 index 0000000000000000000000000000000000000000..188c75e9c99f89966162cf0a34e03518d499abc1 Binary files /dev/null and b/src/main/resources/org/python/compiler/custom_proxymaker/JUnitTest.class differ diff --git a/src/main/resources/org/python/compiler/custom_proxymaker/MethodSignatureTest.class b/src/main/resources/org/python/compiler/custom_proxymaker/MethodSignatureTest.class new file mode 100644 index 0000000000000000000000000000000000000000..cc7226f102d760b58a5eec6f044535e13d87ae12 Binary files /dev/null and b/src/main/resources/org/python/compiler/custom_proxymaker/MethodSignatureTest.class differ diff --git a/src/main/resources/org/python/compiler/custom_proxymaker/MiniClampMaker.class b/src/main/resources/org/python/compiler/custom_proxymaker/MiniClampMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..493e3a1ce22206006f89368464a23400058d3748 Binary files /dev/null and b/src/main/resources/org/python/compiler/custom_proxymaker/MiniClampMaker.class differ diff --git a/src/main/resources/org/python/core/AbstractArray.class b/src/main/resources/org/python/core/AbstractArray.class new file mode 100644 index 0000000000000000000000000000000000000000..9569da27ae3fde006b7445dae0d4460bb9196e43 Binary files /dev/null and b/src/main/resources/org/python/core/AbstractArray.class differ diff --git a/src/main/resources/org/python/core/AllFunction.class b/src/main/resources/org/python/core/AllFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..ff096520b21b50c48d0850c78c6813c53f984fe9 Binary files /dev/null and b/src/main/resources/org/python/core/AllFunction.class differ diff --git a/src/main/resources/org/python/core/AnnotationReader$1.class b/src/main/resources/org/python/core/AnnotationReader$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9eef45e5a4cff948693fd7469120bc0eff0e6ddd Binary files /dev/null and b/src/main/resources/org/python/core/AnnotationReader$1.class differ diff --git a/src/main/resources/org/python/core/AnnotationReader.class b/src/main/resources/org/python/core/AnnotationReader.class new file mode 100644 index 0000000000000000000000000000000000000000..f94ba8990d09f9f7ca3ebda430a623e105eb6482 Binary files /dev/null and b/src/main/resources/org/python/core/AnnotationReader.class differ diff --git a/src/main/resources/org/python/core/AnyFunction.class b/src/main/resources/org/python/core/AnyFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..bb882fc0e36a127c24e8a3aa2063b4255b216cb2 Binary files /dev/null and b/src/main/resources/org/python/core/AnyFunction.class differ diff --git a/src/main/resources/org/python/core/ArgParser.class b/src/main/resources/org/python/core/ArgParser.class new file mode 100644 index 0000000000000000000000000000000000000000..77fb24e6051c382dfa9beabca2296b11513d673d Binary files /dev/null and b/src/main/resources/org/python/core/ArgParser.class differ diff --git a/src/main/resources/org/python/core/AstList$PyExposer.class b/src/main/resources/org/python/core/AstList$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..01c250d6830582358dd971cbe84217d39d6d4881 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$PyExposer.class differ diff --git a/src/main/resources/org/python/core/AstList$_fields_descriptor.class b/src/main/resources/org/python/core/AstList$_fields_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..718ac14dfc67eb513632a20bd0f51ed91a5d3ad2 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$_fields_descriptor.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___add___exposer.class b/src/main/resources/org/python/core/AstList$astlist___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3550086119ea1efd1252deff4bc78aece193018d Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___add___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___contains___exposer.class b/src/main/resources/org/python/core/AstList$astlist___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0f19883845b1f04f2988e44309047a48fe82acec Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___delitem___exposer.class b/src/main/resources/org/python/core/AstList$astlist___delitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4b1cc82872f10bb49964b8980e5d4058b1c533b8 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___delitem___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___delslice___exposer.class b/src/main/resources/org/python/core/AstList$astlist___delslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..94b70633b3a84671e6aa53c1c128411821ce492d Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___delslice___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___eq___exposer.class b/src/main/resources/org/python/core/AstList$astlist___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a828f8264d26eb83475ea3d7306a9dedf3138555 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___ge___exposer.class b/src/main/resources/org/python/core/AstList$astlist___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..41a3cf0ed3dfe1d86316e9458b98b9cb5a855666 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___getitem___exposer.class b/src/main/resources/org/python/core/AstList$astlist___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..27f73d7aa7c405991039c1f0f4d02c8894b071d9 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___getslice___exposer.class b/src/main/resources/org/python/core/AstList$astlist___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..11d87c87faf15aa1441df6d01d13f913d25d1274 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___gt___exposer.class b/src/main/resources/org/python/core/AstList$astlist___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eaea90d364dc4b8991db7d9194e77024dc67d5aa Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___iadd___exposer.class b/src/main/resources/org/python/core/AstList$astlist___iadd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8d31df170378948054cc9bce074f747e01ee7013 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___iadd___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___imul___exposer.class b/src/main/resources/org/python/core/AstList$astlist___imul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7d695e4bf9416faa1d292be321313ffcb7d51906 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___imul___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___iter___exposer.class b/src/main/resources/org/python/core/AstList$astlist___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee46b4fe1a970bd6f5f48bdb0ab78ac28c026dd4 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___le___exposer.class b/src/main/resources/org/python/core/AstList$astlist___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f951de0bf80b6a319a212703646b07a342a2884c Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___le___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___lt___exposer.class b/src/main/resources/org/python/core/AstList$astlist___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9cc6b5b4125a32f27974e3f72fd2f4b6b5b23a18 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___mul___exposer.class b/src/main/resources/org/python/core/AstList$astlist___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b71e8659202a10ee8f529cd92cbb9f75592153a4 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___ne___exposer.class b/src/main/resources/org/python/core/AstList$astlist___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d7cf5e61cabad5b0e4aa99d3bdd0738e69ca0f74 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___nonzero___exposer.class b/src/main/resources/org/python/core/AstList$astlist___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fc9ff77e2868724585c9f4bbca33e7b2d4a7a06d Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___radd___exposer.class b/src/main/resources/org/python/core/AstList$astlist___radd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c04bc205b2c24c397027ef645c3f2bead588f7dd Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___radd___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___rmul___exposer.class b/src/main/resources/org/python/core/AstList$astlist___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee3753c365d7e6e9bb94c4f5e138856cb36037d3 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___setitem___exposer.class b/src/main/resources/org/python/core/AstList$astlist___setitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8ef067bb2cad8b92d3ce0f2e0a93df090994b4c3 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___setitem___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist___setslice___exposer.class b/src/main/resources/org/python/core/AstList$astlist___setslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bcabe8a2e9c4114b0115af3c4394e24cc2b2af37 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist___setslice___exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_append_exposer.class b/src/main/resources/org/python/core/AstList$astlist_append_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a2f7c2dbffaeeba5722329b964f439e3ef2a7a46 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_append_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_count_exposer.class b/src/main/resources/org/python/core/AstList$astlist_count_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9ce1b88bbb9cc046d57bba6a92478209b4ed8739 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_count_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_extend_exposer.class b/src/main/resources/org/python/core/AstList$astlist_extend_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..17db8716299115bad853b5171d39cda3e6d52430 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_extend_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_index_exposer.class b/src/main/resources/org/python/core/AstList$astlist_index_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a0fc98d382cb83baf4ec3efc04b8f1fa83ce6d84 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_index_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_insert_exposer.class b/src/main/resources/org/python/core/AstList$astlist_insert_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e03404cfd8dc4fb5d65cfb22d04cf1b1d933c757 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_insert_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_pop_exposer.class b/src/main/resources/org/python/core/AstList$astlist_pop_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f118632c7d6459fdacf15a0ad88ba4aa034a96b5 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_pop_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_remove_exposer.class b/src/main/resources/org/python/core/AstList$astlist_remove_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ad373755e1904215b899f98d4eec6d5daabf1f59 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_remove_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_reverse_exposer.class b/src/main/resources/org/python/core/AstList$astlist_reverse_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..75c735121a2e017f3577e95b401e4811f6472db3 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_reverse_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList$astlist_toString_exposer.class b/src/main/resources/org/python/core/AstList$astlist_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..841f1371a70848b050cc80b8b09d00b649a06f46 Binary files /dev/null and b/src/main/resources/org/python/core/AstList$astlist_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/AstList.class b/src/main/resources/org/python/core/AstList.class new file mode 100644 index 0000000000000000000000000000000000000000..2330f576148df131f3b61db1deb14c535bfca31c Binary files /dev/null and b/src/main/resources/org/python/core/AstList.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$1.class b/src/main/resources/org/python/core/BaseBytes$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1b657135837a213420de6595aa441b44838aa6f2 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$1.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$Builder.class b/src/main/resources/org/python/core/BaseBytes$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..7e2d6250ab44cea0dc58b405886d9429aa42000d Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$Builder.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$ByteSet.class b/src/main/resources/org/python/core/BaseBytes$ByteSet.class new file mode 100644 index 0000000000000000000000000000000000000000..377dd19b1233f9d9cfaac8efb5a40e41eaf58cf3 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$ByteSet.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$Finder.class b/src/main/resources/org/python/core/BaseBytes$Finder.class new file mode 100644 index 0000000000000000000000000000000000000000..016027f26446f05dfc2e5b97e241af3c91ad9fd3 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$Finder.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$Fragment.class b/src/main/resources/org/python/core/BaseBytes$Fragment.class new file mode 100644 index 0000000000000000000000000000000000000000..b2f7d576435e786c501cbedd9578204929a8fe2a Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$Fragment.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$FragmentList.class b/src/main/resources/org/python/core/BaseBytes$FragmentList.class new file mode 100644 index 0000000000000000000000000000000000000000..0ed09f82eb733729bc9683edaa48662197034b5a Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$FragmentList.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$IndexDelegate.class b/src/main/resources/org/python/core/BaseBytes$IndexDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..c2f86d287835bed50160c9309209dbecaa4971df Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$IndexDelegate.class differ diff --git a/src/main/resources/org/python/core/BaseBytes$ReverseFinder.class b/src/main/resources/org/python/core/BaseBytes$ReverseFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..468633b232c96dcdf1f09057861ca65b7617f9b3 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes$ReverseFinder.class differ diff --git a/src/main/resources/org/python/core/BaseBytes.class b/src/main/resources/org/python/core/BaseBytes.class new file mode 100644 index 0000000000000000000000000000000000000000..982be54ccb5e3afc978ad51a89501bc108b1ea2c Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytes.class differ diff --git a/src/main/resources/org/python/core/BaseBytesTest$BufferedObject.class b/src/main/resources/org/python/core/BaseBytesTest$BufferedObject.class new file mode 100644 index 0000000000000000000000000000000000000000..b78d13a8a4a7812cda241cebc126cb5d284191b2 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytesTest$BufferedObject.class differ diff --git a/src/main/resources/org/python/core/BaseBytesTest$Image.class b/src/main/resources/org/python/core/BaseBytesTest$Image.class new file mode 100644 index 0000000000000000000000000000000000000000..45e272943370997ade3d090c1731987a0a2d36e6 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytesTest$Image.class differ diff --git a/src/main/resources/org/python/core/BaseBytesTest$MyBytes$1.class b/src/main/resources/org/python/core/BaseBytesTest$MyBytes$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5649cf626f9b4f8ce1ad77f56f6fbd4fb97db7c9 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytesTest$MyBytes$1.class differ diff --git a/src/main/resources/org/python/core/BaseBytesTest$MyBytes.class b/src/main/resources/org/python/core/BaseBytesTest$MyBytes.class new file mode 100644 index 0000000000000000000000000000000000000000..68abda13f2cca0dd04f9c24c2d57d403e96fbf93 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytesTest$MyBytes.class differ diff --git a/src/main/resources/org/python/core/BaseBytesTest.class b/src/main/resources/org/python/core/BaseBytesTest.class new file mode 100644 index 0000000000000000000000000000000000000000..7f6d054e5afeea6b731ec74f335483c61b71f1c4 Binary files /dev/null and b/src/main/resources/org/python/core/BaseBytesTest.class differ diff --git a/src/main/resources/org/python/core/BaseDictionaryView.class b/src/main/resources/org/python/core/BaseDictionaryView.class new file mode 100644 index 0000000000000000000000000000000000000000..17656454d9f761823d5094b84d54453408923337 Binary files /dev/null and b/src/main/resources/org/python/core/BaseDictionaryView.class differ diff --git a/src/main/resources/org/python/core/BaseSet$1.class b/src/main/resources/org/python/core/BaseSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c4121bb4eea4b2a57add24f921381c781af70df3 Binary files /dev/null and b/src/main/resources/org/python/core/BaseSet$1.class differ diff --git a/src/main/resources/org/python/core/BaseSet$2.class b/src/main/resources/org/python/core/BaseSet$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5a7f50766c38c21a09d163febad14c3fc0b03fab Binary files /dev/null and b/src/main/resources/org/python/core/BaseSet$2.class differ diff --git a/src/main/resources/org/python/core/BaseSet.class b/src/main/resources/org/python/core/BaseSet.class new file mode 100644 index 0000000000000000000000000000000000000000..0659efbe52b9d841a14fa4e577f80c9d0bb99b73 Binary files /dev/null and b/src/main/resources/org/python/core/BaseSet.class differ diff --git a/src/main/resources/org/python/core/BinFunction.class b/src/main/resources/org/python/core/BinFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..0585b42f7f822873d0d91d4be1e8703e858af1e9 Binary files /dev/null and b/src/main/resources/org/python/core/BinFunction.class differ diff --git a/src/main/resources/org/python/core/BufferProtocol.class b/src/main/resources/org/python/core/BufferProtocol.class new file mode 100644 index 0000000000000000000000000000000000000000..a18c47f4fbb353e4fbbdcac68e5db888f3e1b04e Binary files /dev/null and b/src/main/resources/org/python/core/BufferProtocol.class differ diff --git a/src/main/resources/org/python/core/BuiltinDocs.class b/src/main/resources/org/python/core/BuiltinDocs.class new file mode 100644 index 0000000000000000000000000000000000000000..1347606c09e4c3e647d6f91fe6ebb4b0048c1aa3 Binary files /dev/null and b/src/main/resources/org/python/core/BuiltinDocs.class differ diff --git a/src/main/resources/org/python/core/BuiltinFunctions.class b/src/main/resources/org/python/core/BuiltinFunctions.class new file mode 100644 index 0000000000000000000000000000000000000000..f70d9c3c1808211ee0250759c9c808c6c27d0557 Binary files /dev/null and b/src/main/resources/org/python/core/BuiltinFunctions.class differ diff --git a/src/main/resources/org/python/core/BytecodeLoader$Loader.class b/src/main/resources/org/python/core/BytecodeLoader$Loader.class new file mode 100644 index 0000000000000000000000000000000000000000..be110d1f3c00b703edd64e40f6f1b1dd8afba831 Binary files /dev/null and b/src/main/resources/org/python/core/BytecodeLoader$Loader.class differ diff --git a/src/main/resources/org/python/core/BytecodeLoader.class b/src/main/resources/org/python/core/BytecodeLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..09bc81a0852e87972e69b8ac9695da07f5d3f38f Binary files /dev/null and b/src/main/resources/org/python/core/BytecodeLoader.class differ diff --git a/src/main/resources/org/python/core/ClassDictInit.class b/src/main/resources/org/python/core/ClassDictInit.class new file mode 100644 index 0000000000000000000000000000000000000000..6edfaec483fa0c4c7ea4038404d495406efe33ee Binary files /dev/null and b/src/main/resources/org/python/core/ClassDictInit.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporter$1.class b/src/main/resources/org/python/core/ClasspathPyImporter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..32c26cbe37042b938e606eee0d24f1a9f9b59c35 Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporter$1.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter___init___exposer.class b/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..da21e97f3351be59f5f7abe87d417c25676cb5b6 Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter___init___exposer.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter_find_module_exposer.class b/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter_find_module_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9f5b26046bf16a5ec8911427eb8d7f6a4c5968e5 Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter_find_module_exposer.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter_load_module_exposer.class b/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter_load_module_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee3f371c28c3cef0b05c54525b9f528baa22d6d2 Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporter$ClasspathPyImporter_load_module_exposer.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporter$PyExposer.class b/src/main/resources/org/python/core/ClasspathPyImporter$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..35d6a625758df6fcaaaf626c7d0ac85392379740 Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporter$PyExposer.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporter$exposed___new__.class b/src/main/resources/org/python/core/ClasspathPyImporter$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..32769756aa3180756b54e0ea6f2f66cb0c25f0ca Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporter$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporter.class b/src/main/resources/org/python/core/ClasspathPyImporter.class new file mode 100644 index 0000000000000000000000000000000000000000..38f18e784787c054762a52c2e0c443456ac9e494 Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporter.class differ diff --git a/src/main/resources/org/python/core/ClasspathPyImporterDerived.class b/src/main/resources/org/python/core/ClasspathPyImporterDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3bdf5fec9388bc3bb73b24d64c917261403e6605 Binary files /dev/null and b/src/main/resources/org/python/core/ClasspathPyImporterDerived.class differ diff --git a/src/main/resources/org/python/core/CodeBootstrap.class b/src/main/resources/org/python/core/CodeBootstrap.class new file mode 100644 index 0000000000000000000000000000000000000000..537a3e8f9bafef5c8543b91a562e00347548dd4b Binary files /dev/null and b/src/main/resources/org/python/core/CodeBootstrap.class differ diff --git a/src/main/resources/org/python/core/CodeFlag$1$1.class b/src/main/resources/org/python/core/CodeFlag$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b8d77ee5afc24442c0f8316b0f4bf0a1be115a4e Binary files /dev/null and b/src/main/resources/org/python/core/CodeFlag$1$1.class differ diff --git a/src/main/resources/org/python/core/CodeFlag$1.class b/src/main/resources/org/python/core/CodeFlag$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2ee0028473d99833873d486d4839ea2f2d6336df Binary files /dev/null and b/src/main/resources/org/python/core/CodeFlag$1.class differ diff --git a/src/main/resources/org/python/core/CodeFlag.class b/src/main/resources/org/python/core/CodeFlag.class new file mode 100644 index 0000000000000000000000000000000000000000..065b7742fe8497f922fad4264c6b43aeaf2327e3 Binary files /dev/null and b/src/main/resources/org/python/core/CodeFlag.class differ diff --git a/src/main/resources/org/python/core/CodeLoader$1.class b/src/main/resources/org/python/core/CodeLoader$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ab27b07c5b9a50b7e8a4c9606d7a0c9bd2be0ef2 Binary files /dev/null and b/src/main/resources/org/python/core/CodeLoader$1.class differ diff --git a/src/main/resources/org/python/core/CodeLoader.class b/src/main/resources/org/python/core/CodeLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..672a373e45e5ca9f64b407393c161bd38997f6e6 Binary files /dev/null and b/src/main/resources/org/python/core/CodeLoader.class differ diff --git a/src/main/resources/org/python/core/CompileFunction.class b/src/main/resources/org/python/core/CompileFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..911521cf462404428f3c0be0ebb0cc1d46219006 Binary files /dev/null and b/src/main/resources/org/python/core/CompileFunction.class differ diff --git a/src/main/resources/org/python/core/CompileMode$1.class b/src/main/resources/org/python/core/CompileMode$1.class new file mode 100644 index 0000000000000000000000000000000000000000..74d6d1b0d8721ab468d1a99e3b445ec91586185c Binary files /dev/null and b/src/main/resources/org/python/core/CompileMode$1.class differ diff --git a/src/main/resources/org/python/core/CompileMode$2.class b/src/main/resources/org/python/core/CompileMode$2.class new file mode 100644 index 0000000000000000000000000000000000000000..6de246700434d793f059f88d5a22c8faaa9aad73 Binary files /dev/null and b/src/main/resources/org/python/core/CompileMode$2.class differ diff --git a/src/main/resources/org/python/core/CompileMode$3.class b/src/main/resources/org/python/core/CompileMode$3.class new file mode 100644 index 0000000000000000000000000000000000000000..52e13e6ec1af4679e0dff57553e16321133cd1f4 Binary files /dev/null and b/src/main/resources/org/python/core/CompileMode$3.class differ diff --git a/src/main/resources/org/python/core/CompileMode.class b/src/main/resources/org/python/core/CompileMode.class new file mode 100644 index 0000000000000000000000000000000000000000..21f65eec5d5ab6ffb26caf7cd9044d56b6365d9d Binary files /dev/null and b/src/main/resources/org/python/core/CompileMode.class differ diff --git a/src/main/resources/org/python/core/CompilerFacade.class b/src/main/resources/org/python/core/CompilerFacade.class new file mode 100644 index 0000000000000000000000000000000000000000..32d86bc9561eadd65a52ed43239c2d16a12aaca3 Binary files /dev/null and b/src/main/resources/org/python/core/CompilerFacade.class differ diff --git a/src/main/resources/org/python/core/CompilerFlags.class b/src/main/resources/org/python/core/CompilerFlags.class new file mode 100644 index 0000000000000000000000000000000000000000..cfb8fa473e6ffdd282935ec5e6e38bf1758a1fb0 Binary files /dev/null and b/src/main/resources/org/python/core/CompilerFlags.class differ diff --git a/src/main/resources/org/python/core/Console.class b/src/main/resources/org/python/core/Console.class new file mode 100644 index 0000000000000000000000000000000000000000..0cce954feb316f0d59ce6aaba2224db88735ab9e Binary files /dev/null and b/src/main/resources/org/python/core/Console.class differ diff --git a/src/main/resources/org/python/core/ContextGuard$ContextCode$1.class b/src/main/resources/org/python/core/ContextGuard$ContextCode$1.class new file mode 100644 index 0000000000000000000000000000000000000000..65756f193348722028e08880651773390ef67734 Binary files /dev/null and b/src/main/resources/org/python/core/ContextGuard$ContextCode$1.class differ diff --git a/src/main/resources/org/python/core/ContextGuard$ContextCode$2.class b/src/main/resources/org/python/core/ContextGuard$ContextCode$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c7df47197145a765428a6c71417bb2308f02ae78 Binary files /dev/null and b/src/main/resources/org/python/core/ContextGuard$ContextCode$2.class differ diff --git a/src/main/resources/org/python/core/ContextGuard$ContextCode.class b/src/main/resources/org/python/core/ContextGuard$ContextCode.class new file mode 100644 index 0000000000000000000000000000000000000000..eda8d309c2691811dad9237e14747edede146276 Binary files /dev/null and b/src/main/resources/org/python/core/ContextGuard$ContextCode.class differ diff --git a/src/main/resources/org/python/core/ContextGuard$GeneratorContextManager.class b/src/main/resources/org/python/core/ContextGuard$GeneratorContextManager.class new file mode 100644 index 0000000000000000000000000000000000000000..9bd6e12077272ac8866676158d4f22ef8ab5db24 Binary files /dev/null and b/src/main/resources/org/python/core/ContextGuard$GeneratorContextManager.class differ diff --git a/src/main/resources/org/python/core/ContextGuard.class b/src/main/resources/org/python/core/ContextGuard.class new file mode 100644 index 0000000000000000000000000000000000000000..19f8467c4118401bfc287b9afed3ac76d348bbfd Binary files /dev/null and b/src/main/resources/org/python/core/ContextGuard.class differ diff --git a/src/main/resources/org/python/core/ContextManager.class b/src/main/resources/org/python/core/ContextManager.class new file mode 100644 index 0000000000000000000000000000000000000000..6c4a82d694f73b8b8ecd85d8419ae59aa9791b24 Binary files /dev/null and b/src/main/resources/org/python/core/ContextManager.class differ diff --git a/src/main/resources/org/python/core/Deriveds.class b/src/main/resources/org/python/core/Deriveds.class new file mode 100644 index 0000000000000000000000000000000000000000..79accf96b77fbb05211a8ab0d42fbe4959453d5e Binary files /dev/null and b/src/main/resources/org/python/core/Deriveds.class differ diff --git a/src/main/resources/org/python/core/FilelikeInputStream.class b/src/main/resources/org/python/core/FilelikeInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..b77db5133531c3acc95dc0809c1154fb2f86a08c Binary files /dev/null and b/src/main/resources/org/python/core/FilelikeInputStream.class differ diff --git a/src/main/resources/org/python/core/FixedFileWrapper.class b/src/main/resources/org/python/core/FixedFileWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..b7b99391a45add2b6658a89a80a672c02a887da8 Binary files /dev/null and b/src/main/resources/org/python/core/FixedFileWrapper.class differ diff --git a/src/main/resources/org/python/core/FloatInfo.class b/src/main/resources/org/python/core/FloatInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..e2379d007e5f41006196b1f48e80d1737b813704 Binary files /dev/null and b/src/main/resources/org/python/core/FloatInfo.class differ diff --git a/src/main/resources/org/python/core/FormatFunction.class b/src/main/resources/org/python/core/FormatFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..62fe0c649c6c258e2e14ba23e5fde14511e372b0 Binary files /dev/null and b/src/main/resources/org/python/core/FormatFunction.class differ diff --git a/src/main/resources/org/python/core/FunctionThread.class b/src/main/resources/org/python/core/FunctionThread.class new file mode 100644 index 0000000000000000000000000000000000000000..7bf5234565b4427914dadd94dae9b238304ad72d Binary files /dev/null and b/src/main/resources/org/python/core/FunctionThread.class differ diff --git a/src/main/resources/org/python/core/FutureFeature$1.class b/src/main/resources/org/python/core/FutureFeature$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ff663366ca5e32bd35e1f2a2ec441537f41088d4 Binary files /dev/null and b/src/main/resources/org/python/core/FutureFeature$1.class differ diff --git a/src/main/resources/org/python/core/FutureFeature$2.class b/src/main/resources/org/python/core/FutureFeature$2.class new file mode 100644 index 0000000000000000000000000000000000000000..590d167f5132e7928cca7eeff033e0879983a491 Binary files /dev/null and b/src/main/resources/org/python/core/FutureFeature$2.class differ diff --git a/src/main/resources/org/python/core/FutureFeature$3.class b/src/main/resources/org/python/core/FutureFeature$3.class new file mode 100644 index 0000000000000000000000000000000000000000..bf9badbc29105e8a62fe262771509016e9369acf Binary files /dev/null and b/src/main/resources/org/python/core/FutureFeature$3.class differ diff --git a/src/main/resources/org/python/core/FutureFeature$4.class b/src/main/resources/org/python/core/FutureFeature$4.class new file mode 100644 index 0000000000000000000000000000000000000000..bc99eb7c1031fb4dc0e2418bc61062a1be00c2fd Binary files /dev/null and b/src/main/resources/org/python/core/FutureFeature$4.class differ diff --git a/src/main/resources/org/python/core/FutureFeature.class b/src/main/resources/org/python/core/FutureFeature.class new file mode 100644 index 0000000000000000000000000000000000000000..517dcdc3b3e572ff7713d9b94d300f8018782575 Binary files /dev/null and b/src/main/resources/org/python/core/FutureFeature.class differ diff --git a/src/main/resources/org/python/core/IdImpl$WeakIdentityMap$WeakIdKey.class b/src/main/resources/org/python/core/IdImpl$WeakIdentityMap$WeakIdKey.class new file mode 100644 index 0000000000000000000000000000000000000000..6ec780b075bfdccb47d7bc3340da2d6edb0610d8 Binary files /dev/null and b/src/main/resources/org/python/core/IdImpl$WeakIdentityMap$WeakIdKey.class differ diff --git a/src/main/resources/org/python/core/IdImpl$WeakIdentityMap.class b/src/main/resources/org/python/core/IdImpl$WeakIdentityMap.class new file mode 100644 index 0000000000000000000000000000000000000000..857a09a952d33f5622363c08c9152409a433c74a Binary files /dev/null and b/src/main/resources/org/python/core/IdImpl$WeakIdentityMap.class differ diff --git a/src/main/resources/org/python/core/IdImpl.class b/src/main/resources/org/python/core/IdImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..8829b9ae4038270170141bb20c2e3be7df790b5c Binary files /dev/null and b/src/main/resources/org/python/core/IdImpl.class differ diff --git a/src/main/resources/org/python/core/ImportFunction.class b/src/main/resources/org/python/core/ImportFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..e5e22642b26b017c958aabc401b462549e4a46a3 Binary files /dev/null and b/src/main/resources/org/python/core/ImportFunction.class differ diff --git a/src/main/resources/org/python/core/InitModule.class b/src/main/resources/org/python/core/InitModule.class new file mode 100644 index 0000000000000000000000000000000000000000..e5bbb6582ea69585c17dbbc0e9ce26f000dae6e3 Binary files /dev/null and b/src/main/resources/org/python/core/InitModule.class differ diff --git a/src/main/resources/org/python/core/JavaCode.class b/src/main/resources/org/python/core/JavaCode.class new file mode 100644 index 0000000000000000000000000000000000000000..027e40509f66659c543cefaa7fbdc80fe3d8c7d6 Binary files /dev/null and b/src/main/resources/org/python/core/JavaCode.class differ diff --git a/src/main/resources/org/python/core/JavaFunc.class b/src/main/resources/org/python/core/JavaFunc.class new file mode 100644 index 0000000000000000000000000000000000000000..a2b434b21e369a9b42aa9ef3ec5cfa58b480470e Binary files /dev/null and b/src/main/resources/org/python/core/JavaFunc.class differ diff --git a/src/main/resources/org/python/core/JavaImportHelper.class b/src/main/resources/org/python/core/JavaImportHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..9bb6a5c1e8febe5b10d019c2780bc01daf2568e7 Binary files /dev/null and b/src/main/resources/org/python/core/JavaImportHelper.class differ diff --git a/src/main/resources/org/python/core/JavaImporter.class b/src/main/resources/org/python/core/JavaImporter.class new file mode 100644 index 0000000000000000000000000000000000000000..3a912420f10b67d7b14d34181cb9592a96f8775d Binary files /dev/null and b/src/main/resources/org/python/core/JavaImporter.class differ diff --git a/src/main/resources/org/python/core/JavaToPyMapEntry.class b/src/main/resources/org/python/core/JavaToPyMapEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..51322d3feb148e3480ed5638fe02234502a4b9b7 Binary files /dev/null and b/src/main/resources/org/python/core/JavaToPyMapEntry.class differ diff --git a/src/main/resources/org/python/core/JythonInitializer.class b/src/main/resources/org/python/core/JythonInitializer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee86789a6d05c4dbe2a21372116f4e20901dadb6 Binary files /dev/null and b/src/main/resources/org/python/core/JythonInitializer.class differ diff --git a/src/main/resources/org/python/core/LongInfo.class b/src/main/resources/org/python/core/LongInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..b37c7865f7797642f33032173e31470edbe3ef03 Binary files /dev/null and b/src/main/resources/org/python/core/LongInfo.class differ diff --git a/src/main/resources/org/python/core/MakeProxies.class b/src/main/resources/org/python/core/MakeProxies.class new file mode 100644 index 0000000000000000000000000000000000000000..3234d4564f54d4261f6732674a765d54a14a12d8 Binary files /dev/null and b/src/main/resources/org/python/core/MakeProxies.class differ diff --git a/src/main/resources/org/python/core/MaxFunction.class b/src/main/resources/org/python/core/MaxFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..cae6d6200f65663d2ba573fe6433f397325031f8 Binary files /dev/null and b/src/main/resources/org/python/core/MaxFunction.class differ diff --git a/src/main/resources/org/python/core/MinFunction.class b/src/main/resources/org/python/core/MinFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..30bcd0757c43e6455a427c0c0acfc3ee9c6f6b97 Binary files /dev/null and b/src/main/resources/org/python/core/MinFunction.class differ diff --git a/src/main/resources/org/python/core/NewCompilerResources.class b/src/main/resources/org/python/core/NewCompilerResources.class new file mode 100644 index 0000000000000000000000000000000000000000..c38788638645fc6b78f1be6bfb74e7b6e0b4f52e Binary files /dev/null and b/src/main/resources/org/python/core/NewCompilerResources.class differ diff --git a/src/main/resources/org/python/core/NextFunction.class b/src/main/resources/org/python/core/NextFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..156cbf8b9fc9e6cbd816c786ecaa1da7e3ca147e Binary files /dev/null and b/src/main/resources/org/python/core/NextFunction.class differ diff --git a/src/main/resources/org/python/core/Opcode.class b/src/main/resources/org/python/core/Opcode.class new file mode 100644 index 0000000000000000000000000000000000000000..f200b1809a3ab83cf64e4161d22a9f6ca88e7bac Binary files /dev/null and b/src/main/resources/org/python/core/Opcode.class differ diff --git a/src/main/resources/org/python/core/OpenFunction.class b/src/main/resources/org/python/core/OpenFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..c0e842c87247cd6dd3c01d08055c10ddaddf9692 Binary files /dev/null and b/src/main/resources/org/python/core/OpenFunction.class differ diff --git a/src/main/resources/org/python/core/Options.class b/src/main/resources/org/python/core/Options.class new file mode 100644 index 0000000000000000000000000000000000000000..b060501c51f810d5cb1b55e9d4922720e4815861 Binary files /dev/null and b/src/main/resources/org/python/core/Options.class differ diff --git a/src/main/resources/org/python/core/ParserFacade$1.class b/src/main/resources/org/python/core/ParserFacade$1.class new file mode 100644 index 0000000000000000000000000000000000000000..7576a75e53055d860b9a75b543b67d30e3f5493f Binary files /dev/null and b/src/main/resources/org/python/core/ParserFacade$1.class differ diff --git a/src/main/resources/org/python/core/ParserFacade$ExpectedEncodingBufferedReader.class b/src/main/resources/org/python/core/ParserFacade$ExpectedEncodingBufferedReader.class new file mode 100644 index 0000000000000000000000000000000000000000..2634aa9ae6d4353911163129ac4ecc5b932c75b4 Binary files /dev/null and b/src/main/resources/org/python/core/ParserFacade$ExpectedEncodingBufferedReader.class differ diff --git a/src/main/resources/org/python/core/ParserFacade.class b/src/main/resources/org/python/core/ParserFacade.class new file mode 100644 index 0000000000000000000000000000000000000000..41fc71b10b8a04ffa408c8a50eb9678900adb9de Binary files /dev/null and b/src/main/resources/org/python/core/ParserFacade.class differ diff --git a/src/main/resources/org/python/core/PlainConsole.class b/src/main/resources/org/python/core/PlainConsole.class new file mode 100644 index 0000000000000000000000000000000000000000..0b4714a56f1d8c47277b150c88c7c1a58e0ed4ab Binary files /dev/null and b/src/main/resources/org/python/core/PlainConsole.class differ diff --git a/src/main/resources/org/python/core/Pragma$ForbiddenPragmaModule.class b/src/main/resources/org/python/core/Pragma$ForbiddenPragmaModule.class new file mode 100644 index 0000000000000000000000000000000000000000..a4b557d3b1ea82e85e183cad7439ed5987b28128 Binary files /dev/null and b/src/main/resources/org/python/core/Pragma$ForbiddenPragmaModule.class differ diff --git a/src/main/resources/org/python/core/Pragma$PragmaModule.class b/src/main/resources/org/python/core/Pragma$PragmaModule.class new file mode 100644 index 0000000000000000000000000000000000000000..ef77586932a3eef66f549cb5f4950ec17c890304 Binary files /dev/null and b/src/main/resources/org/python/core/Pragma$PragmaModule.class differ diff --git a/src/main/resources/org/python/core/Pragma.class b/src/main/resources/org/python/core/Pragma.class new file mode 100644 index 0000000000000000000000000000000000000000..44e929fa260143a62f002cc6c1f3c33733e976ad Binary files /dev/null and b/src/main/resources/org/python/core/Pragma.class differ diff --git a/src/main/resources/org/python/core/PragmaReceiver.class b/src/main/resources/org/python/core/PragmaReceiver.class new file mode 100644 index 0000000000000000000000000000000000000000..a5a74da0d9c363e6ef9384e4dbeaca2251313945 Binary files /dev/null and b/src/main/resources/org/python/core/PragmaReceiver.class differ diff --git a/src/main/resources/org/python/core/PrintFunction.class b/src/main/resources/org/python/core/PrintFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..bdafe61f75ca3c9b52e52ca7d46e49cae18ce049 Binary files /dev/null and b/src/main/resources/org/python/core/PrintFunction.class differ diff --git a/src/main/resources/org/python/core/Py$SingletonResolver.class b/src/main/resources/org/python/core/Py$SingletonResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..fcad515a955a50a9ab1f77cf478000a492e695bf Binary files /dev/null and b/src/main/resources/org/python/core/Py$SingletonResolver.class differ diff --git a/src/main/resources/org/python/core/Py.class b/src/main/resources/org/python/core/Py.class new file mode 100644 index 0000000000000000000000000000000000000000..f2ca808776bc41d2dcb2c88374c76313c8b95a12 Binary files /dev/null and b/src/main/resources/org/python/core/Py.class differ diff --git a/src/main/resources/org/python/core/Py.class-bak.class b/src/main/resources/org/python/core/Py.class-bak.class new file mode 100644 index 0000000000000000000000000000000000000000..e95dd3e6091b796d841ea82df12903492174fca4 Binary files /dev/null and b/src/main/resources/org/python/core/Py.class-bak.class differ diff --git a/src/main/resources/org/python/core/Py2kBuffer$PyExposer.class b/src/main/resources/org/python/core/Py2kBuffer$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7a5d576946759a9dc4b1d7ce11e03b33fec17386 Binary files /dev/null and b/src/main/resources/org/python/core/Py2kBuffer$PyExposer.class differ diff --git a/src/main/resources/org/python/core/Py2kBuffer$buffer___add___exposer.class b/src/main/resources/org/python/core/Py2kBuffer$buffer___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ba1e91b174a59b7fbc1a0f918c441034137dda2e Binary files /dev/null and b/src/main/resources/org/python/core/Py2kBuffer$buffer___add___exposer.class differ diff --git a/src/main/resources/org/python/core/Py2kBuffer$buffer___mul___exposer.class b/src/main/resources/org/python/core/Py2kBuffer$buffer___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..14ea9f4c1c2074ff7054643d2e08ccb5e6f968e4 Binary files /dev/null and b/src/main/resources/org/python/core/Py2kBuffer$buffer___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/Py2kBuffer$buffer___rmul___exposer.class b/src/main/resources/org/python/core/Py2kBuffer$buffer___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a264c943ed6cc006fcadf89e74543ab0257686b5 Binary files /dev/null and b/src/main/resources/org/python/core/Py2kBuffer$buffer___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/Py2kBuffer$exposed___new__.class b/src/main/resources/org/python/core/Py2kBuffer$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..897552226f172eb75cd291cc2a2b527c9dc5419c Binary files /dev/null and b/src/main/resources/org/python/core/Py2kBuffer$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/Py2kBuffer.class b/src/main/resources/org/python/core/Py2kBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..482cb8a225b53f356f69e42353db9d9881708174 Binary files /dev/null and b/src/main/resources/org/python/core/Py2kBuffer.class differ diff --git a/src/main/resources/org/python/core/PyArray$1.class b/src/main/resources/org/python/core/PyArray$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d3f4cd4f5b70afcd9e70b00570f0f5f64cd5a39d Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$1.class differ diff --git a/src/main/resources/org/python/core/PyArray$ArrayDelegate.class b/src/main/resources/org/python/core/PyArray$ArrayDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..56cc33f2b67769d99555ca6fc1d4fcaa1d8316b6 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$ArrayDelegate.class differ diff --git a/src/main/resources/org/python/core/PyArray$PyExposer.class b/src/main/resources/org/python/core/PyArray$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..af33c2d46f516c0b08c03cab0ea837ff1854627f Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___add___exposer.class b/src/main/resources/org/python/core/PyArray$array___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5aca3bd0d767dda34a3dee220f17d752208d2b2e Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___contains___exposer.class b/src/main/resources/org/python/core/PyArray$array___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..19e68d60f664fa6737f1dd000611410bfbab2295 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___delitem___exposer.class b/src/main/resources/org/python/core/PyArray$array___delitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8daf065b148e0a15dbbfcef3dfa4beaad91c7994 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___delitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___delslice___exposer.class b/src/main/resources/org/python/core/PyArray$array___delslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f67305e56dfbfb3b3613a58162590f62aac58684 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___delslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___eq___exposer.class b/src/main/resources/org/python/core/PyArray$array___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..931bba6f22a4574cd89f4e7fc844f8d63615cabd Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___ge___exposer.class b/src/main/resources/org/python/core/PyArray$array___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..841b8c2d2b90396b5fba86f2454def8fe63450a2 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___getitem___exposer.class b/src/main/resources/org/python/core/PyArray$array___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bb56ece506d299ffa882b84be55486e2672772d5 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___getslice___exposer.class b/src/main/resources/org/python/core/PyArray$array___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8cf6660f93676dbf1a5ba8e08b5faa3d579bc5e3 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___gt___exposer.class b/src/main/resources/org/python/core/PyArray$array___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..81b8ee3c817b1ad9b62e175d1f6ddab475a6eed1 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___iadd___exposer.class b/src/main/resources/org/python/core/PyArray$array___iadd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7c13919fb819913c1683c0d5a40be81442286103 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___iadd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___imul___exposer.class b/src/main/resources/org/python/core/PyArray$array___imul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9a6eb31e43a937f23bf56a9596cccee311402fb8 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___imul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___iter___exposer.class b/src/main/resources/org/python/core/PyArray$array___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8348e78dc13bd3e9a5afcbeb1db3f5d88151f9a8 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___le___exposer.class b/src/main/resources/org/python/core/PyArray$array___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..efd36f2c88494486b56b37668c705d281010f099 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___len___exposer.class b/src/main/resources/org/python/core/PyArray$array___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3866d77b389353903be336efcc532b6214465530 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___lt___exposer.class b/src/main/resources/org/python/core/PyArray$array___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7a6613efc6db28d2df09e5a31b993998ded1ca8f Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___mul___exposer.class b/src/main/resources/org/python/core/PyArray$array___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d9fab98bef2e5368685f31b2f85431c5fbab0d1b Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___ne___exposer.class b/src/main/resources/org/python/core/PyArray$array___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2a34232a62a9f340bce329311bb1aa27ca2172f2 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___nonzero___exposer.class b/src/main/resources/org/python/core/PyArray$array___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..787e1f20cb2a6d92b5fb836a3bc93686551c4ee5 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___reduce___exposer.class b/src/main/resources/org/python/core/PyArray$array___reduce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1dd28050070be60ec11e1f385a2fd66f19e2890b Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___reduce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___rmul___exposer.class b/src/main/resources/org/python/core/PyArray$array___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..50dc271beaba5bd35935d2aa914f3e9b8d7a7102 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___setitem___exposer.class b/src/main/resources/org/python/core/PyArray$array___setitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..16a3b38e1e7d9a00d68bfa3b39a89464d4f9ae88 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___setitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array___setslice___exposer.class b/src/main/resources/org/python/core/PyArray$array___setslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e3abe590e8b1ca497c76357faff629de271c8033 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array___setslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_append_exposer.class b/src/main/resources/org/python/core/PyArray$array_append_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..370df6b1e49f61da80b2e62e10dc29011a4da57f Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_append_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_byteswap_exposer.class b/src/main/resources/org/python/core/PyArray$array_byteswap_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e939e12beafeeac8ef6e1dd2b7d2ccf60aa7094d Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_byteswap_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_count_exposer.class b/src/main/resources/org/python/core/PyArray$array_count_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9be2d5524506c20aa659f94d520cd9139730ddc4 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_count_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_extend_exposer.class b/src/main/resources/org/python/core/PyArray$array_extend_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7d535ec2aa5c848762686ec08627bfc3d3cf4832 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_extend_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_fromfile_exposer.class b/src/main/resources/org/python/core/PyArray$array_fromfile_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4db8eced48a328c3a871d2454933541f049d9344 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_fromfile_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_fromlist_exposer.class b/src/main/resources/org/python/core/PyArray$array_fromlist_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..82ba50cfee629d9b7453a7945fdd1824e2f5a779 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_fromlist_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_fromstring_exposer.class b/src/main/resources/org/python/core/PyArray$array_fromstring_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..96f0a460289781ad907ce1077b53d444d030252e Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_fromstring_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_fromunicode_exposer.class b/src/main/resources/org/python/core/PyArray$array_fromunicode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..65c78ec55dc75723db8f11ec0b8d79854dbce288 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_fromunicode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_index_exposer.class b/src/main/resources/org/python/core/PyArray$array_index_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..31c1844df243531d3e9860bddb0d462f171b1735 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_index_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_insert_exposer.class b/src/main/resources/org/python/core/PyArray$array_insert_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6e56070fae778cca1f0d66c78d60736e0d554634 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_insert_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_pop_exposer.class b/src/main/resources/org/python/core/PyArray$array_pop_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c95f0cafd290e2113eb97a05e3cb5424d0dfa75b Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_pop_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_remove_exposer.class b/src/main/resources/org/python/core/PyArray$array_remove_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6096bd87e9f4430070f48a3966e8c3afb6b1f4ab Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_remove_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_reverse_exposer.class b/src/main/resources/org/python/core/PyArray$array_reverse_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f3ea5fab13d8dc8ea5fd304f168dcd2571283143 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_reverse_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_tofile_exposer.class b/src/main/resources/org/python/core/PyArray$array_tofile_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..53386f15876130713e2e2335ff76eb936b276c8a Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_tofile_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_tolist_exposer.class b/src/main/resources/org/python/core/PyArray$array_tolist_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6b18d113f0f501405ba6b60ce1447e050fc12745 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_tolist_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_tostring_exposer.class b/src/main/resources/org/python/core/PyArray$array_tostring_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c591e827e00b1e32eee85e75b96e272a189966dd Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_tostring_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_tounicode_exposer.class b/src/main/resources/org/python/core/PyArray$array_tounicode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0c3824c479e954be39c6f37a1c3b7ac454a53153 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_tounicode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$array_write_exposer.class b/src/main/resources/org/python/core/PyArray$array_write_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..559e9e7fe1f59adecc3d2317801e199df75295ef Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$array_write_exposer.class differ diff --git a/src/main/resources/org/python/core/PyArray$exposed___new__.class b/src/main/resources/org/python/core/PyArray$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..0887d17af44ea8f851b0ac638a0d7c5b7c783108 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyArray$itemsize_descriptor.class b/src/main/resources/org/python/core/PyArray$itemsize_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..87ac23e91a600f212024486ab42288a97631f6c6 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$itemsize_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyArray$typecode_descriptor.class b/src/main/resources/org/python/core/PyArray$typecode_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d3c41857ed3575044019b1777888e482a8c3c2e7 Binary files /dev/null and b/src/main/resources/org/python/core/PyArray$typecode_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyArray.class b/src/main/resources/org/python/core/PyArray.class new file mode 100644 index 0000000000000000000000000000000000000000..6b46062b13abff20dc09b70570cbf2d4cdfbf3cf Binary files /dev/null and b/src/main/resources/org/python/core/PyArray.class differ diff --git a/src/main/resources/org/python/core/PyArrayDerived.class b/src/main/resources/org/python/core/PyArrayDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..9703c344b49f3971dc0a8109c7af0b54cdd31383 Binary files /dev/null and b/src/main/resources/org/python/core/PyArrayDerived.class differ diff --git a/src/main/resources/org/python/core/PyArrayTest.class b/src/main/resources/org/python/core/PyArrayTest.class new file mode 100644 index 0000000000000000000000000000000000000000..df930051c73e23200498ab319bbe0971825fa79d Binary files /dev/null and b/src/main/resources/org/python/core/PyArrayTest.class differ diff --git a/src/main/resources/org/python/core/PyAttributeDeleted.class b/src/main/resources/org/python/core/PyAttributeDeleted.class new file mode 100644 index 0000000000000000000000000000000000000000..bf25afab010eacdaf0c91f35c0b19539d705996a Binary files /dev/null and b/src/main/resources/org/python/core/PyAttributeDeleted.class differ diff --git a/src/main/resources/org/python/core/PyBUF.class b/src/main/resources/org/python/core/PyBUF.class new file mode 100644 index 0000000000000000000000000000000000000000..9b27cf33128a100624ec9f09f9f2adfa91b1f649 Binary files /dev/null and b/src/main/resources/org/python/core/PyBUF.class differ diff --git a/src/main/resources/org/python/core/PyBaseCode.class b/src/main/resources/org/python/core/PyBaseCode.class new file mode 100644 index 0000000000000000000000000000000000000000..47976162d8dd46bbb94ad96a4692ece5db8f1a04 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseCode.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___getitem___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bc6cb408515c98a68d75833f023870cb35476771 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___getslice___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cf58999a140fdc7da39b2783b4e9685c64fcd3ed Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___init___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d2e5a335124cebe9821e4f8cc72724b315ea813e Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___reduce___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___reduce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4fe223bca27c1b27002cf9deae8e9c11f7395a2e Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___reduce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___setattr___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___setattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ce34e5ab72bd7996b1b280b8242b4dbd8a96dfab Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___setattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___setstate___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___setstate___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a07ed2fc7900d78fd4afc8ca6392e79ba0ab98b5 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___setstate___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___str___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___str___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b69dd013222d0ca23e510593f8e5a008f0f0fdcc Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___str___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException___unicode___exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException___unicode___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2d399afc0f9943361dba0aee8af6436ac8e9f66a Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException___unicode___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$BaseException_toString_exposer.class b/src/main/resources/org/python/core/PyBaseException$BaseException_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ff65958458792831c10ed78c5bc9a6fe4e2814b5 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$BaseException_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$PyExposer.class b/src/main/resources/org/python/core/PyBaseException$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4fa909cd80d4d4a02e76330ff00bb80dce7d671f Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$__dict___descriptor.class b/src/main/resources/org/python/core/PyBaseException$__dict___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..570c6e02f83fe5f5690bace0ebdf23afbcdbb6b8 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$__dict___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$args_descriptor.class b/src/main/resources/org/python/core/PyBaseException$args_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..086f72e408e46b8d9dddeff6dec03db6220da5a2 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$args_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$exposed___new__.class b/src/main/resources/org/python/core/PyBaseException$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..9485edc518e2ed51b4345e1fc256b3d86b21eee3 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyBaseException$message_descriptor.class b/src/main/resources/org/python/core/PyBaseException$message_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fb18bafca5494db244b7abdef1774a7386554ac2 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException$message_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBaseException.class b/src/main/resources/org/python/core/PyBaseException.class new file mode 100644 index 0000000000000000000000000000000000000000..4ee762e7b5d93de1e4d7ddcc748ae946fe02888c Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseException.class differ diff --git a/src/main/resources/org/python/core/PyBaseExceptionDerived.class b/src/main/resources/org/python/core/PyBaseExceptionDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..2dea1c69fca3b7fdb698cdc9000701e52d750c7b Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseExceptionDerived.class differ diff --git a/src/main/resources/org/python/core/PyBaseString$PyExposer.class b/src/main/resources/org/python/core/PyBaseString$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6c980703a245bb7f62d695a304448bd59848177d Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseString$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyBaseString.class b/src/main/resources/org/python/core/PyBaseString.class new file mode 100644 index 0000000000000000000000000000000000000000..941cb1ee9feabe13369e5fd20a137fb0cb09e5f9 Binary files /dev/null and b/src/main/resources/org/python/core/PyBaseString.class differ diff --git a/src/main/resources/org/python/core/PyBeanEvent.class b/src/main/resources/org/python/core/PyBeanEvent.class new file mode 100644 index 0000000000000000000000000000000000000000..aef6e82b6948a38bcf6c8c81af64953f4141e5c1 Binary files /dev/null and b/src/main/resources/org/python/core/PyBeanEvent.class differ diff --git a/src/main/resources/org/python/core/PyBeanEventProperty.class b/src/main/resources/org/python/core/PyBeanEventProperty.class new file mode 100644 index 0000000000000000000000000000000000000000..f20874f9ab7e477ef81bea9cdd8a94281a36e4a9 Binary files /dev/null and b/src/main/resources/org/python/core/PyBeanEventProperty.class differ diff --git a/src/main/resources/org/python/core/PyBeanProperty.class b/src/main/resources/org/python/core/PyBeanProperty.class new file mode 100644 index 0000000000000000000000000000000000000000..831f6c33d29b07230d69f302fdd0871bb39e19ac Binary files /dev/null and b/src/main/resources/org/python/core/PyBeanProperty.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$PyExposer.class b/src/main/resources/org/python/core/PyBoolean$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2b89fda75250ec308fa176b9bb66be15821ea3f4 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___abs___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___abs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f5c7ef9f24e1c1e19649f27bca4f6e72a609f543 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___abs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___and___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..20c88a30dde5ee4f537fc229fcf4e30400ff59a1 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___hash___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..16e7074e6d30661cc370e5f8e13255b3380716e6 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___neg___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___neg___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bcd049b5b91eb236d0efdbc6ed5d3c2773b21761 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___neg___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___nonzero___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c4de1651c68e46a8f36cef6aa8d723d1477138f6 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___or___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..73b010ef478c8b7d8bd388cf4c3d4483d40b9d37 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___pos___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___pos___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9093e9c79c659275518af6567d2c7b46f2c223b2 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___pos___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool___xor___exposer.class b/src/main/resources/org/python/core/PyBoolean$bool___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ec2ee8372d118d23e79429166f98ecbdf301f22e Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$bool_toString_exposer.class b/src/main/resources/org/python/core/PyBoolean$bool_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..16e1c84196745249e3a32c4e27ecea5598dcffbd Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$bool_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyBoolean$exposed___new__.class b/src/main/resources/org/python/core/PyBoolean$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..bd25bd8eb5cbf8df6378ddcda837fb9cf3f9561f Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyBoolean.class b/src/main/resources/org/python/core/PyBoolean.class new file mode 100644 index 0000000000000000000000000000000000000000..56ff670e6e5b983c2c18f145105cc848f84372c9 Binary files /dev/null and b/src/main/resources/org/python/core/PyBoolean.class differ diff --git a/src/main/resources/org/python/core/PyBuffer$Pointer.class b/src/main/resources/org/python/core/PyBuffer$Pointer.class new file mode 100644 index 0000000000000000000000000000000000000000..06b815303b5bd3caf07bae30d7ba901ec4e75f9d Binary files /dev/null and b/src/main/resources/org/python/core/PyBuffer$Pointer.class differ diff --git a/src/main/resources/org/python/core/PyBuffer.class b/src/main/resources/org/python/core/PyBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..59abffed6bcfd21ca6c2fb70bcdbc06985a613bc Binary files /dev/null and b/src/main/resources/org/python/core/PyBuffer.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest$BufferTestPair.class b/src/main/resources/org/python/core/PyBufferTest$BufferTestPair.class new file mode 100644 index 0000000000000000000000000000000000000000..7a134a9b01ea086bcbaa7e99b0ac37719a58c866 Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest$BufferTestPair.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest$ByteMaterial.class b/src/main/resources/org/python/core/PyBufferTest$ByteMaterial.class new file mode 100644 index 0000000000000000000000000000000000000000..742d77e9f54e3c621e9d74a89cfe1f8cafb6f7f1 Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest$ByteMaterial.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest$SimpleExporter.class b/src/main/resources/org/python/core/PyBufferTest$SimpleExporter.class new file mode 100644 index 0000000000000000000000000000000000000000..c7875940f5c03d89cf46306809f59314b8b5b30c Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest$SimpleExporter.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest$SimpleWritableExporter$1.class b/src/main/resources/org/python/core/PyBufferTest$SimpleWritableExporter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2bcd2b7da2d98492c9c052924a5ebc305adc5a0b Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest$SimpleWritableExporter$1.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest$SimpleWritableExporter.class b/src/main/resources/org/python/core/PyBufferTest$SimpleWritableExporter.class new file mode 100644 index 0000000000000000000000000000000000000000..eb10d551b836ebb24530ccd814bce4731f2a1afa Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest$SimpleWritableExporter.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest$StringExporter.class b/src/main/resources/org/python/core/PyBufferTest$StringExporter.class new file mode 100644 index 0000000000000000000000000000000000000000..3d62f018b262c34e5394069828ccd80f7b411308 Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest$StringExporter.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest$TestableExporter.class b/src/main/resources/org/python/core/PyBufferTest$TestableExporter.class new file mode 100644 index 0000000000000000000000000000000000000000..8496915503cbb239b507a0248533bceabd90ba0c Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest$TestableExporter.class differ diff --git a/src/main/resources/org/python/core/PyBufferTest.class b/src/main/resources/org/python/core/PyBufferTest.class new file mode 100644 index 0000000000000000000000000000000000000000..cf6cd8e5f62516dbc097fc35acfb779f16751f78 Binary files /dev/null and b/src/main/resources/org/python/core/PyBufferTest.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$DefaultInfo.class b/src/main/resources/org/python/core/PyBuiltinCallable$DefaultInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..cd7ed3d3823f7da6425b2c16089c73c375e2d3b4 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$DefaultInfo.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$Info.class b/src/main/resources/org/python/core/PyBuiltinCallable$Info.class new file mode 100644 index 0000000000000000000000000000000000000000..481e269f3dc21060f5c2784067bf8f8ee7708d13 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$Info.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$PyExposer.class b/src/main/resources/org/python/core/PyBuiltinCallable$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..aa58337aad65c6eee218186c7ec68ba42c3630db Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$__call___descriptor.class b/src/main/resources/org/python/core/PyBuiltinCallable$__call___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..06e858c9ddba4839165360d35f99a3918eb97669 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$__call___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$__doc___descriptor.class b/src/main/resources/org/python/core/PyBuiltinCallable$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1906fb2d63373f6ae0be8aeffd160fa2cc51b636 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$__module___descriptor.class b/src/main/resources/org/python/core/PyBuiltinCallable$__module___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4e9a58777089e4c9e77c097f7112c5682dab2b4f Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$__module___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$__name___descriptor.class b/src/main/resources/org/python/core/PyBuiltinCallable$__name___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a31ac0a5211b3bc9ea5f015ae06feaa0cf3dadbe Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$__name___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable$__self___descriptor.class b/src/main/resources/org/python/core/PyBuiltinCallable$__self___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2a5a5b11c6ff7ee30b893a4db3364541caa94538 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable$__self___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinCallable.class b/src/main/resources/org/python/core/PyBuiltinCallable.class new file mode 100644 index 0000000000000000000000000000000000000000..c52d6931d169297c6272125e7f3d8e0f35e7f829 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinCallable.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinClassMethodNarrow.class b/src/main/resources/org/python/core/PyBuiltinClassMethodNarrow.class new file mode 100644 index 0000000000000000000000000000000000000000..ca73b364f8c289eea587d513d2b9641c1411c809 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinClassMethodNarrow.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinFunction.class b/src/main/resources/org/python/core/PyBuiltinFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..d5980e3aef5d8ccdd6c5195c3314ce8b96512a05 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinFunction.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinFunctionNarrow.class b/src/main/resources/org/python/core/PyBuiltinFunctionNarrow.class new file mode 100644 index 0000000000000000000000000000000000000000..91050419142ac4f8f6d76f399c00193ea909ab9e Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinFunctionNarrow.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinFunctionSet.class b/src/main/resources/org/python/core/PyBuiltinFunctionSet.class new file mode 100644 index 0000000000000000000000000000000000000000..c9721a7f09b90574df6c288ce1b85bb3f2029fd5 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinFunctionSet.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinMethod.class b/src/main/resources/org/python/core/PyBuiltinMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..bff7800f3115c01b8e227ae44361a42bd7339f81 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinMethod.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinMethodNarrow.class b/src/main/resources/org/python/core/PyBuiltinMethodNarrow.class new file mode 100644 index 0000000000000000000000000000000000000000..bbfb95b7150375fac63c23541fbee7fc1bc2df92 Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinMethodNarrow.class differ diff --git a/src/main/resources/org/python/core/PyBuiltinMethodSet.class b/src/main/resources/org/python/core/PyBuiltinMethodSet.class new file mode 100644 index 0000000000000000000000000000000000000000..3ad1def3fafb291eb7d8195cebc586d6f049bc2e Binary files /dev/null and b/src/main/resources/org/python/core/PyBuiltinMethodSet.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$1.class b/src/main/resources/org/python/core/PyByteArray$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9c947fb7a43adcc3f2a17a36fb8a05295b44a96a Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$1.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$PyExposer.class b/src/main/resources/org/python/core/PyByteArray$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..77f98d0496222a9d0d333e73c11868aeb6c73c15 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___add___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e468329a7dd219c6daa5e8d48e1d2e2f0354d566 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___alloc___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___alloc___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2cfb54a8cb4886ee7712b0860543cc1f678311b8 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___alloc___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___contains___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f415d0a8f3dc4d8a0e34739a8f0a8e386f3be76a Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___eq___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f09b7a0b9971abc10bd394d8793941739e02fde1 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___ge___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a065b1b050c4ee7473df7716714e7444757533f7 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___getitem___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5c6e140e2ce7f55b3801e5eb7ec267b28be461bf Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___gt___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e0d90d92b218e88e5f91bba65e7893612c4d4770 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___hash___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..134714d3d537f29f4ea904806bc4de1aa599e2ed Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___iadd___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___iadd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..32ed01914f3d042b8e8f0837f94e3f8acfab6eb3 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___iadd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___imul___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___imul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..23360104c564841bc70d6f05f12d90d09388e122 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___imul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___init___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cf81cc00da96298e3751c8954eb17ff8fd31163c Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___le___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3d4e5223dadca3e8faa5100c7984f7d87c5b5d95 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___len___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..62015fe2039b5c527bb27c7947dda620b55485b3 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___lt___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8521a3914e88235add8095fdc235ff205ee0635b Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___mul___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..45c014d7fb92e6bb8f4c61a7a17b05ce6ce9602a Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___ne___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a4fdbb176ea9c1aa4747437e6ec36d24701671c4 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___reduce___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___reduce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb3d087f34feb46bcf3705a755ce2351fe51355f Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___reduce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___rmul___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..392a993dd6e15d48f4b4e53666b7a33a2c5c246d Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray___setitem___exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray___setitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..48228c1577a7e6cf738e73fccd6f74731eb04168 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray___setitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_append_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_append_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f73657403ca13114c9e5f9afde61164554c1b4ae Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_append_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_capitalize_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_capitalize_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..70b7070d7677d302c54a8e39915ec4c0cd083814 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_capitalize_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_center_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_center_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d116fa6f21500f6a23cf1a6d17292405d65b6ba7 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_center_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_count_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_count_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b00d51157f6415d2ecafed27c938346c8c97548e Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_count_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_decode_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_decode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bac8fdde05a1957520151a7cc468c6668a44020a Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_decode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_endswith_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_endswith_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dc0ac1fe5c1c088f392458aa9c7504697dc1dbce Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_endswith_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_expandtabs_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_expandtabs_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..95928ef703a9d4855f579de2ce8c2bdb10340394 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_expandtabs_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_extend_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_extend_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f64728cd1c135c2586943b342f54bf627af61921 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_extend_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_find_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_find_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9bf265c47f965a004f619ad50c6c3bc6bfe4564d Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_find_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_fromhex_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_fromhex_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cfb88184747cd0ea1e5c1f62a6e0b8c09bd68ed0 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_fromhex_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_index_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_index_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c190d9e025dfa8a0b6acdfcc134d55fbae5c6044 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_index_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_insert_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_insert_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e2139ab356c774113a1d938e44de789f9892efaa Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_insert_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_isalnum_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_isalnum_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0f9433ae02ad2e0fb7e78a1c1f64c0f7255217ea Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_isalnum_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_isalpha_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_isalpha_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b293b016c67d222f1ebca8249c5114ba3cc6a601 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_isalpha_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_isdigit_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_isdigit_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cd80bfcfaf472ff97547aea985df6a55cedee588 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_isdigit_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_islower_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_islower_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0244a0cb99ef7e9201dce81dfed0609f87e160a1 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_islower_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_isspace_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_isspace_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0b0ffd9992da778a9a958f3dd89d702e464eaa64 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_isspace_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_istitle_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_istitle_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d9663c510a34807cb87e8b02e75de787f0ee79a0 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_istitle_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_isupper_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_isupper_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9c99f3c94cb48775a745567247d9cd4635dd7ab5 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_isupper_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_join_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_join_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8d58632a5a84cd4263e7adeead02fdb5544d6ea7 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_join_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_ljust_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_ljust_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9913b00522de7072864f593c836a966eaa0e2e77 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_ljust_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_lower_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_lower_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a4fcc8666aba044c106ae2a6649ca6f022e53b21 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_lower_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_lstrip_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_lstrip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f8f200b69f6aafc2a97357513b71bdc7c4c313c9 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_lstrip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_partition_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_partition_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..afee93600fa5f97b0a1e21697798bb990f3321ef Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_partition_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_pop_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_pop_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..493518b14a0e891c5136699f148bdb2a8d72ab44 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_pop_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_remove_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_remove_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..37e2b3d63fc15116244eda8e5c842e81adb02921 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_remove_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_replace_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_replace_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4ab308f6882af109608547d85a1a747a2675711a Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_replace_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_repr_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_repr_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0c641591645da498eafd6f307cf07c49705825e3 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_repr_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_reverse_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_reverse_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..de74b9292369bf25efc9a1810b07fb9b9571c84b Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_reverse_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_rfind_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_rfind_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b60e429fd87c3f842e725ed03f5a49a516d25023 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_rfind_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_rindex_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_rindex_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..168f86a1b6c642f192cb0bc19ba5eeb9ecf9c432 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_rindex_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_rjust_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_rjust_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b87701eae9f6e622b699b5fcd20cd8cfc9bd60d7 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_rjust_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_rpartition_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_rpartition_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3c4d68b9c5cee5bc014e2077ddff89596d04cba6 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_rpartition_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_rsplit_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_rsplit_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ea6ece94ae0e837ad627033690432f67ec24c8ab Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_rsplit_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_rstrip_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_rstrip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..36f5909ce80189461e000a0e93c4ad162cb9e5be Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_rstrip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_split_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_split_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..572a856c65a623c52dce01616f66f4b46f092039 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_split_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_splitlines_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_splitlines_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d4c7038d1832d02b5cd3e3b35b1f46806e3f279a Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_splitlines_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_startswith_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_startswith_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2edbf04177e22c441ded79a7e659c02b7b12c254 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_startswith_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_str_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_str_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1e7439784fa6482c4267f3aefbbac3fcf335ac0a Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_str_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_strip_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_strip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..478815bb8927890da74f272373d4779efe5d0e27 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_strip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_swapcase_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_swapcase_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..41058ff8898ddfd4bddd07c0f2b8cf3322358518 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_swapcase_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_title_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_title_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..25b88bb27ca54bf569d0ae31565fb38a72be3ed4 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_title_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_translate_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_translate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..605c26a47ef282cf8d41681aa2feb20ddfce4cda Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_translate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_upper_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_upper_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7868ac316448603f38629d8db7a7b9decbebc158 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_upper_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$bytearray_zfill_exposer.class b/src/main/resources/org/python/core/PyByteArray$bytearray_zfill_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0b6fc924595f9a390291142a95217c795a4de3e6 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$bytearray_zfill_exposer.class differ diff --git a/src/main/resources/org/python/core/PyByteArray$exposed___new__.class b/src/main/resources/org/python/core/PyByteArray$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..3b870e0af60ede21521fe7e67581e53004799d3f Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyByteArray.class b/src/main/resources/org/python/core/PyByteArray.class new file mode 100644 index 0000000000000000000000000000000000000000..4b70995f33adbb5502580820fbbd0211a3d05069 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArray.class differ diff --git a/src/main/resources/org/python/core/PyByteArrayDerived.class b/src/main/resources/org/python/core/PyByteArrayDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..5165f9bf1cc25994c6e18c86d6460820c132472d Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArrayDerived.class differ diff --git a/src/main/resources/org/python/core/PyByteArrayTest.class b/src/main/resources/org/python/core/PyByteArrayTest.class new file mode 100644 index 0000000000000000000000000000000000000000..20d02eadfe1d4f5222d2984c42250a5fc5dd0390 Binary files /dev/null and b/src/main/resources/org/python/core/PyByteArrayTest.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$1.class b/src/main/resources/org/python/core/PyBytecode$1.class new file mode 100644 index 0000000000000000000000000000000000000000..abf227c8ae4cbc6e2e5508d6dbb59132cd8fccac Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$1.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$LineCache$Pair.class b/src/main/resources/org/python/core/PyBytecode$LineCache$Pair.class new file mode 100644 index 0000000000000000000000000000000000000000..c0930810b9a19aaf0ba92cdf268fa985dfab391e Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$LineCache$Pair.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$LineCache.class b/src/main/resources/org/python/core/PyBytecode$LineCache.class new file mode 100644 index 0000000000000000000000000000000000000000..6a0c6dbae8d15b9c2ed77f3bcd02b0fcd00a49c9 Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$LineCache.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$PyStack.class b/src/main/resources/org/python/core/PyBytecode$PyStack.class new file mode 100644 index 0000000000000000000000000000000000000000..571b55fc2ddf3bc39d6bc20801b534bbcff9d56c Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$PyStack.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$PyStackException.class b/src/main/resources/org/python/core/PyBytecode$PyStackException.class new file mode 100644 index 0000000000000000000000000000000000000000..a12fa3e56d10caeb11edf81f6ee02bb3d8b55deb Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$PyStackException.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$PyStackWhy.class b/src/main/resources/org/python/core/PyBytecode$PyStackWhy.class new file mode 100644 index 0000000000000000000000000000000000000000..a3382436ddbea86c62fad8e9bca0a5bd90135585 Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$PyStackWhy.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$PyTryBlock.class b/src/main/resources/org/python/core/PyBytecode$PyTryBlock.class new file mode 100644 index 0000000000000000000000000000000000000000..149cfb5eac13d1e6b76be4ee3822ec6b1150b0c5 Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$PyTryBlock.class differ diff --git a/src/main/resources/org/python/core/PyBytecode$Why.class b/src/main/resources/org/python/core/PyBytecode$Why.class new file mode 100644 index 0000000000000000000000000000000000000000..2c04448244d20d5168262e9fda1c6f36cb0bf5ee Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode$Why.class differ diff --git a/src/main/resources/org/python/core/PyBytecode.class b/src/main/resources/org/python/core/PyBytecode.class new file mode 100644 index 0000000000000000000000000000000000000000..5f882eb201836aeaeefd8ff8c78e248ee2c7e342 Binary files /dev/null and b/src/main/resources/org/python/core/PyBytecode.class differ diff --git a/src/main/resources/org/python/core/PyCallIter.class b/src/main/resources/org/python/core/PyCallIter.class new file mode 100644 index 0000000000000000000000000000000000000000..3d8f8ed80100ced43a3b54fafdae90f346fde1ec Binary files /dev/null and b/src/main/resources/org/python/core/PyCallIter.class differ diff --git a/src/main/resources/org/python/core/PyCell$PyExposer.class b/src/main/resources/org/python/core/PyCell$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3b21f8910ec375f1aab37766ed712424960316ce Binary files /dev/null and b/src/main/resources/org/python/core/PyCell$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyCell$cell_contents_descriptor.class b/src/main/resources/org/python/core/PyCell$cell_contents_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a11b5c09cc95ec9b157a4803adf94afe7138398f Binary files /dev/null and b/src/main/resources/org/python/core/PyCell$cell_contents_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyCell.class b/src/main/resources/org/python/core/PyCell.class new file mode 100644 index 0000000000000000000000000000000000000000..ef2dc226523902fa44e3db72ba9bcb60b4e791ee Binary files /dev/null and b/src/main/resources/org/python/core/PyCell.class differ diff --git a/src/main/resources/org/python/core/PyClass$PyExposer.class b/src/main/resources/org/python/core/PyClass$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dcc0e2339c155e829221359404d9c68b15809b0c Binary files /dev/null and b/src/main/resources/org/python/core/PyClass$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyClass$exposed___new__.class b/src/main/resources/org/python/core/PyClass$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..010d5c68b3641125466cd0d53e8250e1a3211368 Binary files /dev/null and b/src/main/resources/org/python/core/PyClass$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyClass.class b/src/main/resources/org/python/core/PyClass.class new file mode 100644 index 0000000000000000000000000000000000000000..b327ed2e4214c4aead6495f3a4c00fa57e0fe45e Binary files /dev/null and b/src/main/resources/org/python/core/PyClass.class differ diff --git a/src/main/resources/org/python/core/PyClassMethod$PyExposer.class b/src/main/resources/org/python/core/PyClassMethod$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4f5ac0b7abd12614734b1729dbed5172d906ca45 Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethod$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyClassMethod$classmethod___get___exposer.class b/src/main/resources/org/python/core/PyClassMethod$classmethod___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b06850121addd4515cb7d4eb43c064de7dba7ccb Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethod$classmethod___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyClassMethod$exposed___new__.class b/src/main/resources/org/python/core/PyClassMethod$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..3732d5b2e1c7581854fd9cac2ddf9e90c10c4ffa Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethod$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyClassMethod.class b/src/main/resources/org/python/core/PyClassMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..5035dc69025c16b717d60d00b9911d1df13f70fb Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethod.class differ diff --git a/src/main/resources/org/python/core/PyClassMethodDerived.class b/src/main/resources/org/python/core/PyClassMethodDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..deabdabf021ad254580b82a107ee6d9ff2b0e4de Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethodDerived.class differ diff --git a/src/main/resources/org/python/core/PyClassMethodDescr$PyExposer.class b/src/main/resources/org/python/core/PyClassMethodDescr$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..04478bc4efdb46c961585bd3650dcc78e621f8e4 Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethodDescr$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyClassMethodDescr$__doc___descriptor.class b/src/main/resources/org/python/core/PyClassMethodDescr$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b6492e1d49af5a7ee5bb12430fceee85f802c667 Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethodDescr$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyClassMethodDescr$classmethod_descriptor___get___exposer.class b/src/main/resources/org/python/core/PyClassMethodDescr$classmethod_descriptor___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1f32d1daa4169ee6fb5df1814ec6ade99cb14ad9 Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethodDescr$classmethod_descriptor___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyClassMethodDescr.class b/src/main/resources/org/python/core/PyClassMethodDescr.class new file mode 100644 index 0000000000000000000000000000000000000000..65b8b776b696e840c2b3a9f4df878e14a64e811a Binary files /dev/null and b/src/main/resources/org/python/core/PyClassMethodDescr.class differ diff --git a/src/main/resources/org/python/core/PyCode.class b/src/main/resources/org/python/core/PyCode.class new file mode 100644 index 0000000000000000000000000000000000000000..ba5ed25f5be0c0ed2fef61d1925d7348f63a7fd7 Binary files /dev/null and b/src/main/resources/org/python/core/PyCode.class differ diff --git a/src/main/resources/org/python/core/PyComplex$PyExposer.class b/src/main/resources/org/python/core/PyComplex$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7339a3f76c1ab7cf4ffe7727e3d1922dc0cdfd5a Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___abs___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___abs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4af6cd2b9dd6cafb9006da3f9688eefb1718ff43 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___abs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___add___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1450a0486103ac827a6fc1df0c24f457edc82410 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___coerce___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___coerce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1a6b8dc2ff58572ac7145b5a2cb777303ea3994c Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___coerce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___div___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___div___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4593fc46e736e0d29e36d96231f8a094b8b67951 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___div___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___divmod___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___divmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..13def8bee246708b0ebb961beb3d94431a7e5aec Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___divmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___eq___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1a923c7d2122ba8f74b36e01682ac18a24321682 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___float___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___float___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..da69ad2b792ded25261905f67b8f957daf67171d Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___float___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___floordiv___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___floordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..298f34749c606add38cdc0d1cc89afa9c9fd3dec Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___floordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___format___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___format___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..92c6e3af65bd62db541cd9b1ecc75880c7c84cde Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___format___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___ge___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2648c3c3d75a7c51c5d494c6dcf4328448ac820c Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___getnewargs___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___getnewargs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0dcd6a71ab26d8030c2de2dd89265e66d7c860da Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___getnewargs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___gt___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..694357601755f171d30ca40b3454796b5d7c9dd6 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___hash___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8cc84c3465d7cc75881cddb7a102756f22827f8a Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___int___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee687f5fec779abf6fdf03e6d2745fab74a43827 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___int___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___le___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4c3500b82b9d66ec2c0151f0672b991ebc9f2d19 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___long___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___long___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1694471b3d2c1d8cc474a73934676db0e8281ffc Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___long___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___lt___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3a3c323a67465bc8fb65c4991533a09dd58f474c Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___mod___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___mod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..732ede01eac934ae33ab81f22bb5401d89d9a2ef Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___mod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___mul___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5e1015c713be2e3107369751ad427124515fb44f Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___ne___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6691910f21568f587782ec6ef2fe4c719fe17aab Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___neg___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___neg___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7a011185f24f6290571cd09bbec66d08c9c24511 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___neg___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___nonzero___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..62719de8474d40f7eca1483515fb33a5420eb1b4 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___pos___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___pos___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2891aae7c9a270df9334e4e93100f09a5ce139e5 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___pos___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___pow___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___pow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b329785c6e4e4a89a14ef9e14af8b5210aa4bab2 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___pow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___radd___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___radd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c2d182201abfec550475cb4d0f826024976c7796 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___radd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rdiv___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rdiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..36a189a64c3291d535e42b3cd4b33f1d6371d59f Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rdiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rdivmod___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rdivmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..26d6bdba52233164543f49a7193544d6a5466616 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rdivmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rfloordiv___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rfloordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2de4dd61b60f5c3516263062c707a56ad37b519d Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rfloordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rmod___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..353b6e393752edfd9b031649303d211bf631f5ab Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rmul___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..77ce1f6d7e04a1d4d5d731ac42faeb453f8c3703 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rpow___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rpow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4c4c47c66edb1367dc69d6d7d6298f51d14592be Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rpow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rsub___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rsub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4325261daa313c5835817e37b2c701a894e08eb7 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rsub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___rtruediv___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___rtruediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d1b1062148757fea3012ab35b1e23ad6c646d113 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___rtruediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___sub___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..31c071476fc470889ff9684d93f2a82c968a805d Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex___truediv___exposer.class b/src/main/resources/org/python/core/PyComplex$complex___truediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..262d1bb34c6f31cf8f9ebb5edeb99d4a37cc172a Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex___truediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex_conjugate_exposer.class b/src/main/resources/org/python/core/PyComplex$complex_conjugate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a9dcd52f1a093ffe202390cba2368bf1af197864 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex_conjugate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$complex_toString_exposer.class b/src/main/resources/org/python/core/PyComplex$complex_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..20c7f2af7350dfcd4fd0172a2584b9d47ddecbbb Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$complex_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyComplex$exposed___new__.class b/src/main/resources/org/python/core/PyComplex$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..901e98ee3d2c7f0bfb289e19a6b6a712a3127faa Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyComplex$imag_descriptor.class b/src/main/resources/org/python/core/PyComplex$imag_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cb00fa5e3effbf05a2a662a56126667d98c45bb9 Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$imag_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyComplex$real_descriptor.class b/src/main/resources/org/python/core/PyComplex$real_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8280f1ebc3cfa51661c14a202a6f0798381bb3eb Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex$real_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyComplex.class b/src/main/resources/org/python/core/PyComplex.class new file mode 100644 index 0000000000000000000000000000000000000000..a770bb8a3b7cf351ef1173ea901f9df67ef9d40b Binary files /dev/null and b/src/main/resources/org/python/core/PyComplex.class differ diff --git a/src/main/resources/org/python/core/PyComplexDerived.class b/src/main/resources/org/python/core/PyComplexDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..0d7a1eda8206454095849e9ba483a821d6cd9f4d Binary files /dev/null and b/src/main/resources/org/python/core/PyComplexDerived.class differ diff --git a/src/main/resources/org/python/core/PyCompoundCallable.class b/src/main/resources/org/python/core/PyCompoundCallable.class new file mode 100644 index 0000000000000000000000000000000000000000..f14fa99bb46d4e15821e2545f9de5c0d4ae11e24 Binary files /dev/null and b/src/main/resources/org/python/core/PyCompoundCallable.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr$PyExposer.class b/src/main/resources/org/python/core/PyDataDescr$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..001aba531f5dca31a7f482962de1478e80cdf1ba Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr$__doc___descriptor.class b/src/main/resources/org/python/core/PyDataDescr$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9722f34b8c59e34b5fe79752cb6399b6a126b8fc Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr$__name___descriptor.class b/src/main/resources/org/python/core/PyDataDescr$__name___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1605804bd682df1e16f73de2b34e839547448ec8 Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr$__name___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr$__objclass___descriptor.class b/src/main/resources/org/python/core/PyDataDescr$__objclass___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4ac56979a616a702463602a8e2e33feceec0c736 Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr$__objclass___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___delete___exposer.class b/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___delete___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0f0ca48076ca3025ac0671a4f0e4c9bd7ae3691a Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___delete___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___get___exposer.class b/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..069becc49055ca1d91775a028eb185d6ca8c6afc Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___set___exposer.class b/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___set___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fbf19b3a585105b9d77b1900162213017c8e6dfc Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr$getset_descriptor___set___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDataDescr.class b/src/main/resources/org/python/core/PyDataDescr.class new file mode 100644 index 0000000000000000000000000000000000000000..8cee3a865a146e8a7f0dc57c4369e377ce0090a7 Binary files /dev/null and b/src/main/resources/org/python/core/PyDataDescr.class differ diff --git a/src/main/resources/org/python/core/PyDescriptor.class b/src/main/resources/org/python/core/PyDescriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9559806655949df0c0ca1bdfc262df8bd515a95c Binary files /dev/null and b/src/main/resources/org/python/core/PyDescriptor.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$PyExposer.class b/src/main/resources/org/python/core/PyDictProxy$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d8e61a685d70900895d657574327f33627aba57e Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$__str___exposer.class b/src/main/resources/org/python/core/PyDictProxy$__str___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f9879fcc7bed21467d35aba231a51133d804d000 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$__str___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___cmp___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1f67c697a2d317635bb7a19945cb9c3deb5a45d Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___contains___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e1535aadac1257db1c1d2bdbc24fe90ec622a4e7 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___eq___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f4ef3f76aa32bb00df1c29fb758e2401d3698821 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___ge___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3a1ebcdc86b151a31e763ddcbd9e1eea5fb2ca72 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___getitem___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0ca877c760bc26a7a6a5cd1fd2c9d455acc1e5d0 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___gt___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9a639ddda8d61bab57941c5060037d3aae363d72 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___le___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2670a982f40039b8d9f25c79218352838a9456c7 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___lt___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..21a4957d6f51b51f34a2b70502ef288e6981e85f Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy___ne___exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f64e3364ac56d13cea357ba9c3397eb59e03ccd7 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_copy_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_copy_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ac598abb247a684336ac86512824c95b44291f0b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_copy_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_get_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_get_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3f21ce1f1d1238c37690cc77d7e8c40e5b2536ce Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_get_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_has_key_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_has_key_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e671def0a2bed3d896c1d3bdb6a32dddfe816df4 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_has_key_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_items_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_items_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..21358ba378d55435137685b4fe34198307c2235a Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_items_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_iteritems_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_iteritems_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a709becb9babd9100089e897e05fafb61501d630 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_iteritems_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_iterkeys_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_iterkeys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..72299499b5b238dc046c6d081380eeed9b21e6e4 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_iterkeys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_itervalues_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_itervalues_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..80106c62b9c071c67edc984875fc3071673cf137 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_itervalues_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_keys_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_keys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..aec7043fa858f5d5f7c4d225408501c6e2b5a6cc Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_keys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy$dictproxy_values_exposer.class b/src/main/resources/org/python/core/PyDictProxy$dictproxy_values_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1020022bdab889f49c33e467f0987f27bc5fb559 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy$dictproxy_values_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictProxy.class b/src/main/resources/org/python/core/PyDictProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..41c59b4ad52259fe12ba4be3d1eb9fe2f2be542a Binary files /dev/null and b/src/main/resources/org/python/core/PyDictProxy.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$ItemsIter.class b/src/main/resources/org/python/core/PyDictionary$ItemsIter.class new file mode 100644 index 0000000000000000000000000000000000000000..99b7f1765e0c4ba9df8167c9dd692fccaf9a4095 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$ItemsIter.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$PyExposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1ce7702e833c1a289cc45958864e237798ef026 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___and___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2ea1f66c7c1431b7a92a0208c5dd670d7da14c9c Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___contains___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2b85f2837dfec8547210cb0648739fb6a7d08421 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___eq___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a70773129d73a6bfad22f88157306664119bbc49 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___ge___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..846e5100c0545c49930ddae975dcfba856dae983 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___gt___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e1795839797385a89f8980dd9753f354832f21ab Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___iter___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..aae1d9a6deb5e8e19a3509a117f2c5f42fc2f53b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___le___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c4d4831e8d9ca94bef1d3b84a247452366cb92f9 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___lt___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3f34d16c71c31f5b5f9cf0d31a3c8882849aee73 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___ne___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..89884fbd2a510949d9f3ef21f2bf1a724ba1fbf7 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___or___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dbc9a4aed330598e543ff4cffc6d35930fa93a21 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___sub___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..241d1d9410fcf38d7d1ad275509d00992a5939c9 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___xor___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6a95c398a883a0c7447753123c09c4854a3514f8 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_items___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_keys_toString_exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_keys_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..790f47b8c425497c6ea5a6701ee73102f5ea37f5 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems$dict_keys_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems.class new file mode 100644 index 0000000000000000000000000000000000000000..bdca78438839ecd925b4bf8be43bf2ed36b76e42 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewItems.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$PyExposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..03f5f4d89b0ddc638a5b0c9eb5c4e3f2da02400a Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___and___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cf7e304c48fcf1c95ed396c8e17cb0d35386f4d6 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___contains___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4451bad6289c0b911c6dfd0bd0ec2d19325027ba Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___eq___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..48338aba646c68290d7185b83d213251c53c0093 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___ge___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..58dbe8d0ef9095ff0e0ea96ceb5bd043852b9ea8 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___gt___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4e5ae625162196c462103aaeb12e556a39feaaf4 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___iter___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..53a8a264fc3cb589eeb7c9a4eecf89440a8b55de Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___le___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d5ed53ffa3ee6abd5baeaeac657fd1443293ba9a Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___lt___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c2b4e17d3549115a7311cb6f1fe414b7ccc7b179 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___ne___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1772831602b1730be6df917cc908240c0d40927b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___or___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b821435e36ba2a75bcfd2bcc87a712eccae0cafb Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___sub___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..61b0e29f8090590eaec94722f4b688162f38723e Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___xor___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8c2a04ebc0ddf399c83105ebb56f9f0bc5850584 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys_toString_exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..be16e59e6e4166bcda3db03518b966092e124961 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys$dict_keys_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys.class new file mode 100644 index 0000000000000000000000000000000000000000..25f8e2faaf5e9e387cfe8b530a37b6cdf4ebec36 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewKeys.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$PyExposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fbf1cdb317a24a7241a2e0ef7a79f8897b514f7b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values___iter___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5c5c4b9db5ea06a06a66388391aa7d4fcd3e4dfa Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values___len___exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e9377b9af466bcfd33e619391dfb5e46070b9a4f Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values_toString_exposer.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f4e875c0352bd0d11a3bb5d629fa8634d75538b5 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues$dict_values_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues.class b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues.class new file mode 100644 index 0000000000000000000000000000000000000000..354612fcc62bd7bec3a9e20bfaae2daebc605c50 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyDictionaryViewValues.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$PyExposer.class b/src/main/resources/org/python/core/PyDictionary$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ea9e3ce16d03b56f284298a8b6bd17c010cc5578 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$ValuesIter.class b/src/main/resources/org/python/core/PyDictionary$ValuesIter.class new file mode 100644 index 0000000000000000000000000000000000000000..0cf0d88bd3248934c7c96497de81a298ccfe587b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$ValuesIter.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___cmp___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dacdbf547e07f724ec8602265a6bf2a20cbccbbc Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___contains___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb81e1465064ca6ac78bfe047cca58f89577a4ca Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___delitem___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___delitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e72931495921ee74fd5787c8779dfc386ce68d5d Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___delitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___eq___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e5703a42a299a619480a687f8c1a5dc067b33c1f Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___ge___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fcca7daafc302905842568a5d3fd060a44a31794 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___getitem___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..87f336faa4d8c6cd96c0d6ceb5a151e10ef1562b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___gt___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0fe293445cd36ff80a403f9b869e696209b74210 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___hash___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e2ef00ace13b25bad210275754b32c2db7c2a3bd Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___init___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..93c9869049671c02dba81100d2001212de4e8779 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___iter___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fb9a774646390d49dc322698169df599badc6319 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___le___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..86c6eed769d73d0ff58e3703beac532a774215f9 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___len___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1dfba574ee6deb9cf74d603876579238faaac7a3 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___lt___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..acef1abd279f80ff2553aeaf982eb50a920ae753 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___ne___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..504821d270075e33455ec0d1a600e3b6446a31a7 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict___setitem___exposer.class b/src/main/resources/org/python/core/PyDictionary$dict___setitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7984c889b32426f9a4ebe559afbbf18788f6ba08 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict___setitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_clear_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_clear_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..88d56dd4ec432a3e29d5a7a882a2b0e30e83b99b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_clear_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_copy_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_copy_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fa73719bc071e2f13929b1b40bff27921b46932e Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_copy_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_fromkeys_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_fromkeys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..14f946f88e7f4b5f3783b97326aff253d269d0b8 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_fromkeys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_get_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_get_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e07b281e84a0d9d2758aca273d1cd517c725c676 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_get_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_has_key_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_has_key_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..80d8f3c63cdfa096718b98635eb30b5fb6cd1c15 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_has_key_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_items_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_items_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..57ac2c0400268f1819af68e0ce09df4e3dc86d4d Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_items_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_iteritems_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_iteritems_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..84bd8ff8ff34b4ff2238d448cd42c79ed16eb309 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_iteritems_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_iterkeys_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_iterkeys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..83803a8c4a40b00a18502415cc8cac1ee7be7cd1 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_iterkeys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_itervalues_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_itervalues_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c7766f6990e98ed4f81eadac4ccce46e6390e5c1 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_itervalues_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_keys_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_keys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..910d07e98f5bdb5467c22cd733c760ec726de168 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_keys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_pop_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_pop_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a6d26edae7a958d133319bae404a4670fcf526f4 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_pop_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_popitem_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_popitem_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..500ea2a75fdd7d291fb285e58f947094c5c6b058 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_popitem_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_setdefault_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_setdefault_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1bf8100c8a82447e3b4603e3a02cff5a9cdd0b8c Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_setdefault_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_setifabsent_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_setifabsent_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..10b7cfec766190dccca4d3ddd90f0643259b2728 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_setifabsent_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_toString_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2a8da5ef4f453750b8410e7281c37d310978e14e Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_update_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_update_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ade78f0683471e20205766bc388c1fccad89b971 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_update_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$dict_values_exposer.class b/src/main/resources/org/python/core/PyDictionary$dict_values_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bcbcf55230200c690de326806c3629205dccd7cf Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$dict_values_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$exposed___new__.class b/src/main/resources/org/python/core/PyDictionary$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..05e1415ff9b396cee1e0b86670ad380cca10d624 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$viewitems_exposer.class b/src/main/resources/org/python/core/PyDictionary$viewitems_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cda528c54ecec43d046b5cdb1b4ca6f35e262212 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$viewitems_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$viewkeys_exposer.class b/src/main/resources/org/python/core/PyDictionary$viewkeys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6d40330cbd9a5d67f8a7c3ce20609056224af40b Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$viewkeys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary$viewvalues_exposer.class b/src/main/resources/org/python/core/PyDictionary$viewvalues_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..04186303b2e5c3c5b4849a21d879e321c6f210fc Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary$viewvalues_exposer.class differ diff --git a/src/main/resources/org/python/core/PyDictionary.class b/src/main/resources/org/python/core/PyDictionary.class new file mode 100644 index 0000000000000000000000000000000000000000..af0a179c9ed1a429c16160f3f53fd2e0f3d18b19 Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionary.class differ diff --git a/src/main/resources/org/python/core/PyDictionaryDerived.class b/src/main/resources/org/python/core/PyDictionaryDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..5a0eb76988a24b9e7b7338069fa538377553e85d Binary files /dev/null and b/src/main/resources/org/python/core/PyDictionaryDerived.class differ diff --git a/src/main/resources/org/python/core/PyEllipsis$PyExposer.class b/src/main/resources/org/python/core/PyEllipsis$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c072362fe0d99a80c4d5d20c4e359c02e090d318 Binary files /dev/null and b/src/main/resources/org/python/core/PyEllipsis$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyEllipsis.class b/src/main/resources/org/python/core/PyEllipsis.class new file mode 100644 index 0000000000000000000000000000000000000000..abd6cba4158d6ff08b9e9e58f42fe25fc5cdab38 Binary files /dev/null and b/src/main/resources/org/python/core/PyEllipsis.class differ diff --git a/src/main/resources/org/python/core/PyEnumerate$PyExposer.class b/src/main/resources/org/python/core/PyEnumerate$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..928ecda677b3f8db1c35225ffa6983263703761c Binary files /dev/null and b/src/main/resources/org/python/core/PyEnumerate$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyEnumerate$enumerate___iter___exposer.class b/src/main/resources/org/python/core/PyEnumerate$enumerate___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a1cc8f44114defaba1dcabf9321849a347e36b3e Binary files /dev/null and b/src/main/resources/org/python/core/PyEnumerate$enumerate___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyEnumerate$enumerate_next_exposer.class b/src/main/resources/org/python/core/PyEnumerate$enumerate_next_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a9da71ade89e59a18df8d92121e8d8675975cf77 Binary files /dev/null and b/src/main/resources/org/python/core/PyEnumerate$enumerate_next_exposer.class differ diff --git a/src/main/resources/org/python/core/PyEnumerate$exposed___new__.class b/src/main/resources/org/python/core/PyEnumerate$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b18d2d1519dcb2fff30320d0766d92cd77fd4b4a Binary files /dev/null and b/src/main/resources/org/python/core/PyEnumerate$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyEnumerate.class b/src/main/resources/org/python/core/PyEnumerate.class new file mode 100644 index 0000000000000000000000000000000000000000..11f02e82de53be65994c8b9f21d0b089ecd02971 Binary files /dev/null and b/src/main/resources/org/python/core/PyEnumerate.class differ diff --git a/src/main/resources/org/python/core/PyEnumerateDerived.class b/src/main/resources/org/python/core/PyEnumerateDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..4c3edf64ab8cd4c080fe0ea1fcebec121fb2c7e7 Binary files /dev/null and b/src/main/resources/org/python/core/PyEnumerateDerived.class differ diff --git a/src/main/resources/org/python/core/PyException.class b/src/main/resources/org/python/core/PyException.class new file mode 100644 index 0000000000000000000000000000000000000000..72a347288cc8beeeb05cf2bbefe07a24c29408ee Binary files /dev/null and b/src/main/resources/org/python/core/PyException.class differ diff --git a/src/main/resources/org/python/core/PyFastSequenceIter$PyExposer.class b/src/main/resources/org/python/core/PyFastSequenceIter$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e01c54bb729c54d85cd6efb5a4fc22f9dab4b1af Binary files /dev/null and b/src/main/resources/org/python/core/PyFastSequenceIter$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyFastSequenceIter$fastsequenceiterator_next_exposer.class b/src/main/resources/org/python/core/PyFastSequenceIter$fastsequenceiterator_next_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5efe65fb58f50c0a2573dd3fae5d8e93d320e817 Binary files /dev/null and b/src/main/resources/org/python/core/PyFastSequenceIter$fastsequenceiterator_next_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFastSequenceIter.class b/src/main/resources/org/python/core/PyFastSequenceIter.class new file mode 100644 index 0000000000000000000000000000000000000000..0b5e5336fd963c12520936f38dff8bad40f99775 Binary files /dev/null and b/src/main/resources/org/python/core/PyFastSequenceIter.class differ diff --git a/src/main/resources/org/python/core/PyFile$Closer.class b/src/main/resources/org/python/core/PyFile$Closer.class new file mode 100644 index 0000000000000000000000000000000000000000..650f95e3e5357a23e16438a505d15eed3b2d8bb6 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$Closer.class differ diff --git a/src/main/resources/org/python/core/PyFile$PyExposer.class b/src/main/resources/org/python/core/PyFile$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b0adb5e32df9a38f0f1b38cdd93a3686b9a8002a Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$closed_descriptor.class b/src/main/resources/org/python/core/PyFile$closed_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7d14a3176097039c473126ba4fc57873ef8ebc38 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$closed_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFile$encoding_descriptor.class b/src/main/resources/org/python/core/PyFile$encoding_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..267177c61615c66378dc6b1f06f515ddd5e97638 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$encoding_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFile$exposed___new__.class b/src/main/resources/org/python/core/PyFile$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..de34007772685dc8b46d36628bcee21eec528aa5 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyFile$file___exit___exposer.class b/src/main/resources/org/python/core/PyFile$file___exit___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a5b0b9ed7c57ca6e4fd7b5de4ca6aaca2ed6b345 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file___exit___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file___init___exposer.class b/src/main/resources/org/python/core/PyFile$file___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f461e3359da2ddef0cad57b3d82724b6746146a1 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_close_exposer.class b/src/main/resources/org/python/core/PyFile$file_close_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fa64bac62ebbbda7f872879a52d71f04270edb28 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_close_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_fileno_exposer.class b/src/main/resources/org/python/core/PyFile$file_fileno_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..02ce260e34424e33e436b6a9aa39c1675b899c61 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_fileno_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_flush_exposer.class b/src/main/resources/org/python/core/PyFile$file_flush_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3d7633ca4afef1bdf3001a4d8f5579647852127f Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_flush_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_isatty_exposer.class b/src/main/resources/org/python/core/PyFile$file_isatty_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0af14082d2b5a6a74d5d486b724358403e9dec07 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_isatty_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_next_exposer.class b/src/main/resources/org/python/core/PyFile$file_next_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..190127aa3299e405d71da2d6531abedd41f85aa3 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_next_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_read_exposer.class b/src/main/resources/org/python/core/PyFile$file_read_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2ac916e42132b3ab43e35b8cfdfd23cdb0f636fe Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_read_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_readinto_exposer.class b/src/main/resources/org/python/core/PyFile$file_readinto_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9c609460aafd8155a80cd2287dce10b0061ba146 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_readinto_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_readline_exposer.class b/src/main/resources/org/python/core/PyFile$file_readline_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7f95f4bcf294ebfdc9aebe1cdf13398090f862c9 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_readline_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_readlines_exposer.class b/src/main/resources/org/python/core/PyFile$file_readlines_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..87af895314f0015347b92aefb12d04e0e62fd603 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_readlines_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_seek_exposer.class b/src/main/resources/org/python/core/PyFile$file_seek_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8a404c34615540814130f27944bf3961c9710f6c Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_seek_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_self_exposer.class b/src/main/resources/org/python/core/PyFile$file_self_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7c612cea332c849c7d8a6d9f635c48e9aec1e440 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_self_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_tell_exposer.class b/src/main/resources/org/python/core/PyFile$file_tell_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e2c675ecd226a48f7bfd74b640f1ced9aa49ed67 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_tell_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_toString_exposer.class b/src/main/resources/org/python/core/PyFile$file_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fd5007cf012d96c6bb94713a5964e6b89faea7e9 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_truncate_exposer.class b/src/main/resources/org/python/core/PyFile$file_truncate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ac6388b6fbab5e47057394baab53f3726dc4d618 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_truncate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_write_exposer.class b/src/main/resources/org/python/core/PyFile$file_write_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..adc04fdd85fab4d6f6c87bb2d0de633e45445482 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_write_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$file_writelines_exposer.class b/src/main/resources/org/python/core/PyFile$file_writelines_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..efa681560b90f3927f7a422a8d1c36f172c5fdea Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$file_writelines_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFile$mode_descriptor.class b/src/main/resources/org/python/core/PyFile$mode_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d3e2b577d5ef65610d0aa1f1e7cccc80a4170754 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$mode_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFile$name_descriptor.class b/src/main/resources/org/python/core/PyFile$name_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a5f236f6c3df1f6770c399488b650e66ec45fde1 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$name_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFile$newlines_descriptor.class b/src/main/resources/org/python/core/PyFile$newlines_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b6a991cea5a73227588359edbf1d85e8616ec110 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$newlines_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFile$softspace_descriptor.class b/src/main/resources/org/python/core/PyFile$softspace_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..62ebd9565d49784330b89f8055156e09af0026c0 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile$softspace_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFile.class b/src/main/resources/org/python/core/PyFile.class new file mode 100644 index 0000000000000000000000000000000000000000..55f3ffc133c6aabc56eb1bc4e49326ba5707d515 Binary files /dev/null and b/src/main/resources/org/python/core/PyFile.class differ diff --git a/src/main/resources/org/python/core/PyFileDerived.class b/src/main/resources/org/python/core/PyFileDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..338eb6bda908589c60e2c3b021debcf60937b157 Binary files /dev/null and b/src/main/resources/org/python/core/PyFileDerived.class differ diff --git a/src/main/resources/org/python/core/PyFileReader.class b/src/main/resources/org/python/core/PyFileReader.class new file mode 100644 index 0000000000000000000000000000000000000000..7931cdbd80b085a67b514fa51b999c0743c2b3fa Binary files /dev/null and b/src/main/resources/org/python/core/PyFileReader.class differ diff --git a/src/main/resources/org/python/core/PyFileWriter.class b/src/main/resources/org/python/core/PyFileWriter.class new file mode 100644 index 0000000000000000000000000000000000000000..55ced7dad6b7df955983022678f9fc6fac3873d1 Binary files /dev/null and b/src/main/resources/org/python/core/PyFileWriter.class differ diff --git a/src/main/resources/org/python/core/PyFinalizableInstance.class b/src/main/resources/org/python/core/PyFinalizableInstance.class new file mode 100644 index 0000000000000000000000000000000000000000..8474d559b09c479a30069c4f8d625a12f3196295 Binary files /dev/null and b/src/main/resources/org/python/core/PyFinalizableInstance.class differ diff --git a/src/main/resources/org/python/core/PyFloat$Format.class b/src/main/resources/org/python/core/PyFloat$Format.class new file mode 100644 index 0000000000000000000000000000000000000000..be40a25c1b762c2a497d99b5586e863612297596 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$Format.class differ diff --git a/src/main/resources/org/python/core/PyFloat$PyExposer.class b/src/main/resources/org/python/core/PyFloat$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7023932ca8c34331b3ba9c96a106c2dcf47a76fb Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$as_integer_ratio_exposer.class b/src/main/resources/org/python/core/PyFloat$as_integer_ratio_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d8b98719f0d70b82ded42fb4766d4dcd8df5ea87 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$as_integer_ratio_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$exposed___new__.class b/src/main/resources/org/python/core/PyFloat$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..807a8de5fd085fcd11a2e4358ebbdc001a06396b Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___abs___exposer.class b/src/main/resources/org/python/core/PyFloat$float___abs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..824f0b11867d25c1bf39cf25a33011a279e4e75e Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___abs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___add___exposer.class b/src/main/resources/org/python/core/PyFloat$float___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2a46317d653b53eb9d765557ef923c3cfd34fc56 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___cmp___exposer.class b/src/main/resources/org/python/core/PyFloat$float___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7e7ad8013208be58fa9f99b64823a7236066da22 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___coerce___exposer.class b/src/main/resources/org/python/core/PyFloat$float___coerce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2f25c25eddfe032850f1df8b79cdf101b30fb60c Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___coerce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___div___exposer.class b/src/main/resources/org/python/core/PyFloat$float___div___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b2d5751728fc382efa6e50eb65f9fcc56a6fada4 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___div___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___divmod___exposer.class b/src/main/resources/org/python/core/PyFloat$float___divmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b77e80d666f30e2833bfb26dbbfe8c5d4fda40d3 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___divmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___float___exposer.class b/src/main/resources/org/python/core/PyFloat$float___float___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fca75cfe1af39a3eef231b6e1a7f56d06da97f4f Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___float___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___floordiv___exposer.class b/src/main/resources/org/python/core/PyFloat$float___floordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f5028e4b4f9daf89adebeca826dd6e3ef3b8b293 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___floordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___format___exposer.class b/src/main/resources/org/python/core/PyFloat$float___format___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ae7c68fd453e453128766f8f85cd9695823003b6 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___format___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___getformat___exposer.class b/src/main/resources/org/python/core/PyFloat$float___getformat___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c21561b103ed2871af1055dd57bc6e54718171cb Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___getformat___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___getnewargs___exposer.class b/src/main/resources/org/python/core/PyFloat$float___getnewargs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..add850424c30b9777e09e7dbdc61da74a14fdaed Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___getnewargs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___hash___exposer.class b/src/main/resources/org/python/core/PyFloat$float___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f894c86fdaaf013be144d7227ff2931bf284e750 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___int___exposer.class b/src/main/resources/org/python/core/PyFloat$float___int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..69b2f213faaef5f798dd600c3e8b4a669a7f972f Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___int___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___long___exposer.class b/src/main/resources/org/python/core/PyFloat$float___long___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..db6843de6bd5e5112598ba6d706a528b9e33467e Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___long___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___mod___exposer.class b/src/main/resources/org/python/core/PyFloat$float___mod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e861525c1f6d8ebf34dfd8f0f6f0994c5a137b3a Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___mod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___mul___exposer.class b/src/main/resources/org/python/core/PyFloat$float___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0e331ef3e422c08fc39f537bff646b0fc31cf3be Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___neg___exposer.class b/src/main/resources/org/python/core/PyFloat$float___neg___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..345d38b431ef007f48fa884226f7e85844e9ea9d Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___neg___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___nonzero___exposer.class b/src/main/resources/org/python/core/PyFloat$float___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dab1bc4d41329ecd8cfc56c6cad790163e9a3ab2 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___pos___exposer.class b/src/main/resources/org/python/core/PyFloat$float___pos___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9971eed502835253a4229a3ce951c77cc215d1c2 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___pos___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___pow___exposer.class b/src/main/resources/org/python/core/PyFloat$float___pow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..45252c48940e766a847205996f325b3884ea975b Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___pow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___radd___exposer.class b/src/main/resources/org/python/core/PyFloat$float___radd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..18df95a5f84a62e6d7d53a220b24718e0725a643 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___radd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rdiv___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rdiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..54c31cd83b28a41d4382e334a16bcc1eef8f22e7 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rdiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rdivmod___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rdivmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7864f1a11897bd01074acd5171cf761c09309837 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rdivmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___repr___exposer.class b/src/main/resources/org/python/core/PyFloat$float___repr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..61a3eb4977fb5db66ee9f3e2fdd98951d1f7922f Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___repr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rfloordiv___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rfloordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..43c667e80d28313b69c189527aa22b997caad0ee Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rfloordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rmod___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee175582fc105166ee82be224082ae6cf1b82200 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rmul___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b39ffdf228e4d427513cad4370672c003f3e5e69 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rpow___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rpow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0e7545398d88fae1b30b5e33e40c1a6757b6f821 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rpow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rsub___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rsub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..af8f879b47890dc2246f7cb9e430ccd2723d33be Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rsub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___rtruediv___exposer.class b/src/main/resources/org/python/core/PyFloat$float___rtruediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b0d4a599b489d37b86a18f78a8285e55ee1ab94d Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___rtruediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___setformat___exposer.class b/src/main/resources/org/python/core/PyFloat$float___setformat___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3c911de32a4806fad680360c3cbc386915ba8d62 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___setformat___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___str___exposer.class b/src/main/resources/org/python/core/PyFloat$float___str___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..448311690b6ab08f4330d8a160e9a2fc4dc13cdb Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___str___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___sub___exposer.class b/src/main/resources/org/python/core/PyFloat$float___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4fa1e44e1b88653ca1ff63910e91db524d8647b5 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___truediv___exposer.class b/src/main/resources/org/python/core/PyFloat$float___truediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..56ca12329a391276c8da9c02662690a642eac4b8 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___truediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float___trunc___exposer.class b/src/main/resources/org/python/core/PyFloat$float___trunc___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..74398eddcedd77d82e1262e2cd6f90d867165655 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float___trunc___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float_conjugate_exposer.class b/src/main/resources/org/python/core/PyFloat$float_conjugate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4406bb32c6fe4422de0a52349133848b45960fe4 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float_conjugate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float_fromhex_exposer.class b/src/main/resources/org/python/core/PyFloat$float_fromhex_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0b07a9adc8286569707ed6a18a54c0c0aab772f2 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float_fromhex_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float_hex_exposer.class b/src/main/resources/org/python/core/PyFloat$float_hex_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a9899edf9e412b417e998891af3fe02fa4ccf714 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float_hex_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$float_is_integer_exposer.class b/src/main/resources/org/python/core/PyFloat$float_is_integer_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..718eee459ba07003c4f57a8c2dd4119de40cafa7 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$float_is_integer_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFloat$imag_descriptor.class b/src/main/resources/org/python/core/PyFloat$imag_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d6feb1594539c03ecc52cf768cb83b0671457b34 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$imag_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFloat$real_descriptor.class b/src/main/resources/org/python/core/PyFloat$real_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e1f7c0a7f18091dd3ba00e7442b763407b30ece5 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat$real_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFloat.class b/src/main/resources/org/python/core/PyFloat.class new file mode 100644 index 0000000000000000000000000000000000000000..af5a7fcbcff45fe2fc582029257d34eb13dc6fb9 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloat.class differ diff --git a/src/main/resources/org/python/core/PyFloatDerived.class b/src/main/resources/org/python/core/PyFloatDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..0b623a7c4512c8b83f221516918879fe3f504105 Binary files /dev/null and b/src/main/resources/org/python/core/PyFloatDerived.class differ diff --git a/src/main/resources/org/python/core/PyFloatTest.class b/src/main/resources/org/python/core/PyFloatTest.class new file mode 100644 index 0000000000000000000000000000000000000000..b8a5562928bebb4e83a5668ea21e161a2a28df4f Binary files /dev/null and b/src/main/resources/org/python/core/PyFloatTest.class differ diff --git a/src/main/resources/org/python/core/PyFrame$PyExposer.class b/src/main/resources/org/python/core/PyFrame$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..025c6ba051a2c974d3692f24eac713124d39607b Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_back_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_back_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2c01ce5b5bde29443ea2b3b67573c59e49a162be Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_back_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_builtins_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_builtins_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..8de3e9f6b44fa8d067b90d42939663ac2abaf2f0 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_builtins_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_code_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_code_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fa31e044fb2b1db04695605f22482b6682cc27fe Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_code_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_globals_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_globals_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ff497cd15b2c72ac16c02a292640b0f516c2a5f9 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_globals_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_lasti_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_lasti_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7bc9cc4d288bcbd4fc93ae173fe1049239eebf07 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_lasti_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_lineno_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fda5a71fce6ed05214b51da22f462073446b363d Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_lineno_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_locals_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_locals_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cf4d8924bbd6e2553863fc42675720767eccb32e Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_locals_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame$f_trace_descriptor.class b/src/main/resources/org/python/core/PyFrame$f_trace_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a5ff53b00df609a86023e66621d8dc5ebdce86b4 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame$f_trace_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFrame.class b/src/main/resources/org/python/core/PyFrame.class new file mode 100644 index 0000000000000000000000000000000000000000..9dccc00aaa0ee9856da118e48e47d5a7b3ba4aa7 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrame.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$1.class b/src/main/resources/org/python/core/PyFrozenSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..32b29bdb4266f6ed841b9a66209f218ae53e5766 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$1.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$PyExposer.class b/src/main/resources/org/python/core/PyFrozenSet$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee7e4b9217339784201f306f59e4f3edc82d94fd Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$exposed___new__.class b/src/main/resources/org/python/core/PyFrozenSet$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..dbec4fa369759f67f0b6e30afa8fbd6f77b1a13a Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___and___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1c7ff7d1acf0834434939377d1024405b05f99ff Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___cmp___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2ac6f8d084324987d00eb6956149c27f929c03be Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___contains___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cf63bbcddd1d15cb434a27e9adfa8a8bada15973 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___eq___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1b9a23ed9d54dcad37e4a02c640d01b6fb4e4b9 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___ge___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3426db8376f75ab2a0a7653ec716a3bec4ee3d25 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___gt___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..90709a064a2a9610d110548ecb93d5745c3c97c9 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___hash___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e0b49c73f3d932a9a25b0ae04ad56b9b6ba687fe Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___iter___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d01939fc912099870327f0383cd67a4b82a610e3 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___le___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ea715c4de8c49530eea034ba5a20a4aabeede6fd Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___len___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f971c4d1586da905e49906c94c1bd0481fbff115 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___lt___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ed52300d7662df5d0bf31f328576120331dceb96 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___ne___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..46ce437d55063aff47af35b5df9c81270260a48f Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___or___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6cae6bbb15d90bbf55b10ee80f5956abeaab35f3 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___reduce___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___reduce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..27a5a4653c2aa68d4477d2fb51db9ea6bac2bd6c Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___reduce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___sub___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..db4fd5255a3c88199d46d337d76ed96b4f4ae309 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset___xor___exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..368102894fff65dd1b693b6b2486c519add9564d Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_copy_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_copy_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..359eb25ffc9ef7e6786fe856e754511dcf531da0 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_copy_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_difference_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_difference_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..71d4ea25e01681c5409b00177b35697812b36912 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_difference_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_intersection_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_intersection_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f785933bbccd1798e1c4a681723f7ea4f1256ec8 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_intersection_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_isdisjoint_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_isdisjoint_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d8bef5a4aec6fef4ea6aa284c24d9bc19c37018e Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_isdisjoint_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_issubset_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_issubset_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9890ec496185bb5fbdedf40146032b024d9b5f14 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_issubset_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_issuperset_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_issuperset_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c3fdd664c4aae68279f078d99fd859785e56ce77 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_issuperset_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_symmetric_difference_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_symmetric_difference_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d4e73aaf8c5c6e26ef92c0142b097ba544a572b4 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_symmetric_difference_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_toString_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f8de5d4568fec9601d88262e3a87b7776fcff0ea Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet$frozenset_union_exposer.class b/src/main/resources/org/python/core/PyFrozenSet$frozenset_union_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..49d3d7a62348ad76cf23803b9701b86b7ce07359 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet$frozenset_union_exposer.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSet.class b/src/main/resources/org/python/core/PyFrozenSet.class new file mode 100644 index 0000000000000000000000000000000000000000..b9020261fbbd0b54d9f87c6febcdcbaba2bca41b Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSet.class differ diff --git a/src/main/resources/org/python/core/PyFrozenSetDerived.class b/src/main/resources/org/python/core/PyFrozenSetDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..09528e13dfabb4a9ea6c51d0bbb2f731c4796cf6 Binary files /dev/null and b/src/main/resources/org/python/core/PyFrozenSetDerived.class differ diff --git a/src/main/resources/org/python/core/PyFunction$PyExposer.class b/src/main/resources/org/python/core/PyFunction$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a6bd341d0df62ca5b346275136714444f43bac30 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyFunction$__code___descriptor.class b/src/main/resources/org/python/core/PyFunction$__code___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9ccec5604daf5e4999749a725d69a1dd5dad506b Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$__code___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$__dict___descriptor.class b/src/main/resources/org/python/core/PyFunction$__dict___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bb33231f533aadc37be25f2f11d19f537001901b Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$__dict___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$__doc___descriptor.class b/src/main/resources/org/python/core/PyFunction$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c580908b9cd21b40aaf185f9b7a6b85114ba576f Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$__globals___descriptor.class b/src/main/resources/org/python/core/PyFunction$__globals___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..a9430946a65e15ac3ef380d709309cdf6f9c171e Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$__globals___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$__module___descriptor.class b/src/main/resources/org/python/core/PyFunction$__module___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..748d389d96eb825128bdccb0d8178eb77820d76b Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$__module___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$__name___descriptor.class b/src/main/resources/org/python/core/PyFunction$__name___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2d88f849e4a10c729d6fba669d6a99d30ada40f8 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$__name___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$exposed___new__.class b/src/main/resources/org/python/core/PyFunction$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..828ae56fdc376b2bc94574a5f40edfb8c0910134 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyFunction$func_closure_descriptor.class b/src/main/resources/org/python/core/PyFunction$func_closure_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..5934b0f831df3e077fa4243b93ad4e8b795d13e5 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$func_closure_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$func_code_descriptor.class b/src/main/resources/org/python/core/PyFunction$func_code_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..77405ee0f7bdd455853395b542f41f418cf717a4 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$func_code_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$func_defaults_descriptor.class b/src/main/resources/org/python/core/PyFunction$func_defaults_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3994c2a334149dcc80e8f66f14172b41b4f59855 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$func_defaults_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$func_dict_descriptor.class b/src/main/resources/org/python/core/PyFunction$func_dict_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9c162d7aa0860c4963a1d1919001bde088f64af3 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$func_dict_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$func_doc_descriptor.class b/src/main/resources/org/python/core/PyFunction$func_doc_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f5dd766006b31daf9ae97a4b0c733a264ca9d2b3 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$func_doc_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$func_globals_descriptor.class b/src/main/resources/org/python/core/PyFunction$func_globals_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e176a22e447616693aec053886034fdff2563756 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$func_globals_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$func_name_descriptor.class b/src/main/resources/org/python/core/PyFunction$func_name_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..e7684762b37bdd1b8ff65abe3a93ce3fb294c7d9 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$func_name_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyFunction$function___call___exposer.class b/src/main/resources/org/python/core/PyFunction$function___call___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4581a86c8bc7bb8c9f1106eb6d21710b1a941d58 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$function___call___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFunction$function___get___exposer.class b/src/main/resources/org/python/core/PyFunction$function___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..69e77316ab0d2b960f45cf3f5d8125251c0bf305 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$function___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFunction$function___setattr___exposer.class b/src/main/resources/org/python/core/PyFunction$function___setattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ac4e57459d2b11864d937b506933a847bae12dee Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction$function___setattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyFunction.class b/src/main/resources/org/python/core/PyFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..708b8422657ae5b03928dbbd42944b1ab9dd4cc7 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunction.class differ diff --git a/src/main/resources/org/python/core/PyFunctionTable.class b/src/main/resources/org/python/core/PyFunctionTable.class new file mode 100644 index 0000000000000000000000000000000000000000..dff537cb8940a7a15a38b7888c387d56f3e12777 Binary files /dev/null and b/src/main/resources/org/python/core/PyFunctionTable.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$PyExposer.class b/src/main/resources/org/python/core/PyGenerator$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4fdfcc311fd9ad190f1ed1c42c337e26007c112a Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$generator___iter___exposer.class b/src/main/resources/org/python/core/PyGenerator$generator___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ba291a6d3a5a7a7a3ed197cd5f8c1980a4c22fab Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$generator___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$generator_close_exposer.class b/src/main/resources/org/python/core/PyGenerator$generator_close_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2567de3f7f14c1d88ae15216471f55083022d4d3 Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$generator_close_exposer.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$generator_next_exposer.class b/src/main/resources/org/python/core/PyGenerator$generator_next_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2b79073e577d304d4ee8d773c469423faec769a9 Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$generator_next_exposer.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$generator_send_exposer.class b/src/main/resources/org/python/core/PyGenerator$generator_send_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..17e966c9cdfecd62af20ff8bc780e3559258e74d Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$generator_send_exposer.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$generator_throw$_exposer.class b/src/main/resources/org/python/core/PyGenerator$generator_throw$_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a1703aa55606b63b872aa908387aa6fb29db6d4f Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$generator_throw$_exposer.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$gi_code_descriptor.class b/src/main/resources/org/python/core/PyGenerator$gi_code_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..2e6e716938c0a1a00c8fb1e4b81dedb296b7d8e0 Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$gi_code_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$gi_frame_descriptor.class b/src/main/resources/org/python/core/PyGenerator$gi_frame_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..63de8034b55dc66d65011aa7dbfce9b940b7d893 Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$gi_frame_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyGenerator$gi_running_descriptor.class b/src/main/resources/org/python/core/PyGenerator$gi_running_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b066b651f342fab98fd6ba0cc2fd3bf9e2df312f Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator$gi_running_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyGenerator.class b/src/main/resources/org/python/core/PyGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..a34022f9b23dacadebd384f22812db0aeb9b0012 Binary files /dev/null and b/src/main/resources/org/python/core/PyGenerator.class differ diff --git a/src/main/resources/org/python/core/PyIdentityTuple.class b/src/main/resources/org/python/core/PyIdentityTuple.class new file mode 100644 index 0000000000000000000000000000000000000000..e6bb747e94fbf447e77b3793764a6b4181c0e5de Binary files /dev/null and b/src/main/resources/org/python/core/PyIdentityTuple.class differ diff --git a/src/main/resources/org/python/core/PyIgnoreMethodTag.class b/src/main/resources/org/python/core/PyIgnoreMethodTag.class new file mode 100644 index 0000000000000000000000000000000000000000..efe0c132faba96a469f8bb70bd528e659e8b5a60 Binary files /dev/null and b/src/main/resources/org/python/core/PyIgnoreMethodTag.class differ diff --git a/src/main/resources/org/python/core/PyIndentationError.class b/src/main/resources/org/python/core/PyIndentationError.class new file mode 100644 index 0000000000000000000000000000000000000000..3f5940e22c0edee326eddfaf3c898bad6128083f Binary files /dev/null and b/src/main/resources/org/python/core/PyIndentationError.class differ diff --git a/src/main/resources/org/python/core/PyInstance$PyExposer.class b/src/main/resources/org/python/core/PyInstance$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8833958251194ae505caed542a365ccb50a4d788 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$exposed___new__.class b/src/main/resources/org/python/core/PyInstance$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..ab531e45148b51b499acf3a28ff2c6ed118deb7c Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___abs___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___abs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ae2fd050a56346fbe169884878ebbf5971c79aff Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___abs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___add___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1498a55dd2235b59d9fa9624bf097193eaf91f36 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___and___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..184902a985953573e3608a3488feebb22dd26124 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___call___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___call___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3c78073f39d118a53bbe4ddf9d9174b4a0201a30 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___call___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___cmp___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bc071154c05ae259b486e9f16aceb0ce983ffdc5 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___complex___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___complex___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5afe090b505bf1c9135aa15b3e6ba9a04a591aea Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___complex___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___contains___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..63a6d7e6447e669a2474e0006f26747e2538dea6 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___delattr___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___delattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1b1584a085713c0fe25fb9daf101fc5b81b031a Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___delattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___delitem___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___delitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a675b113e1502b37d41bfdb81674e49248c79f9d Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___delitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___delslice___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___delslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7e742ba0efc05b82233edee09639cf342e53f5c3 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___delslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___div___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___div___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0d834bb7898ceb20fc1338bb4271112b8e1c559a Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___div___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___divmod___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___divmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1a5ba9d4cbca92c2da1d6668a8234e349653dac2 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___divmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___eq___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ae3ab20d1a6989cfd5edebac97e20db35c4781d0 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___float___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___float___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..18aebf3d57af06f722fd2e0429677d94eb16538b Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___float___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___floordiv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___floordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7d18ac5d3e08dd6e80076eac58415ad4e6b5f52b Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___floordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___format___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___format___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4eb0d4932bdee27927669a95a199a7665536cfea Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___format___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ge___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dbc44927ca475f00d9c09f4907e92bd8ee6debaf Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___getitem___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f3a822c06050d73b0ad9d286e5d25c58c3b6b0dd Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___getslice___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..536a108f3a78562be58848d50162ad545d50277e Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___gt___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..28fb97ce3c39afe1f0b0d7d7396744f086f32d9d Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___hex___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___hex___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d0d48e7bdae4edfb4f230cbf60434752b1c33756 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___hex___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___iadd___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___iadd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..517d1d186410f94027c81342cfdf4c8c37a40a15 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___iadd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___iand___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___iand___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2117529d081c674aaf5f8ff315a2200dc42d31f4 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___iand___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___idiv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___idiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1d38bcb1ade7031bc86d6dcace7e4327f030a2d Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___idiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ifloordiv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ifloordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fa46d98e517160b0615387fcc3884fa0eed79769 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ifloordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ilshift___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ilshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4dd213ffed8de7ec527e8b5e6d46a605afa59504 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ilshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___imod___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___imod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d4b16b20842b59bae5c8f9f7ece69a483c0c738b Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___imod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___imul___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___imul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d79597b679fca52a8aee1bef3d44b1c846d477bc Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___imul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___index___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___index___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4a5a57b367170f958fd83cc94e83014ca76e5cf5 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___index___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___int___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e8dcecd1a25a7f35c8ace7d229508f7fbf8fe6db Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___int___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___invert___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___invert___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3bbee45f370c40ef78d8a7d277211fd5791bd30a Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___invert___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ior___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ior___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..225894e54658d80f1f73f52409cc7efa89a5b2f5 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ior___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ipow___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ipow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ef6ca99bb6bf49f3fe7efc058bc0141e26fd8c60 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ipow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___irshift___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___irshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5215bfd39daea7a7efc7e518815feaecf60a9a21 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___irshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___isub___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___isub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0b7854471a5cfccb8780302b707018685222f8b7 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___isub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___iter___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b151aae6369ed5b8e470ebc570574955b1aecd66 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___itruediv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___itruediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f61f901d2c10cd1ae14ea879b082842c879862cc Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___itruediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ixor___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ixor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e01a7792d9290fecfe9c47c0755135d446bd2547 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ixor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___le___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ff73b6ebf5b2fc8a6b3b5ae50e3404ff145464ab Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___len___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..38c794cff8829270efc80ea875b37852abb16ca9 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___long___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___long___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ab58ead1109000664c82fc764eaf15be437b4961 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___long___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___lshift___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___lshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..69fd425b1eebd209a70fc812b83d0201da1251a8 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___lshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___lt___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d5a2ec5f68a95285af6ddf32d8edb48ea3208b6d Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___mod___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___mod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..95e2e9721c7027aa12f58c9d81faa96bd9582da8 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___mod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___mul___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..915c92e0402548453b7e998a31d667754521b781 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ne___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5f25f4dbc9938d47ee3f3b4b51ba068b1876779a Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___neg___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___neg___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..52077ef8d3250fe63a92531f9f0ccfa6fb7204b5 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___neg___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___nonzero___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8462c800887ff8f8d08f8ddb893aac50de60b9d0 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___oct___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___oct___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..24942becfd594ad5caad98becd33c68ee91ab7a9 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___oct___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___or___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..500d827e0d41ebb3803e3c33a2cdd0241b815189 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___pos___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___pos___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f6188f18af635e16f599fbe7afc4ac3c7946757f Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___pos___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___pow___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___pow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..787f8737e928440d88110ea9396aa587252a4761 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___pow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___radd___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___radd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1435be87d9f0f6536c150ba63a24c9827328983c Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___radd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rand___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rand___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..57406b5129cb7b2c284c1929863f96540061ba30 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rand___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rdiv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rdiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ac02770a67df3cc5f4d7ec974102298dd5e7a059 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rdiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rdivmod___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rdivmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bbb11b0094d9a66e6fed9f704e475c8a7e31249b Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rdivmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___repr___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___repr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb173f1d933aa6dfdfd73b41c122b3472f204db2 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___repr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rfloordiv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rfloordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6768345fd48d37e2b6e8d5e1397942e7a468422f Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rfloordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rlshift___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rlshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0c6a8dad4734453070956b17e9306afd399f4a4c Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rlshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rmod___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bc1e0d3301e93f8d275c349e222df69b964a31c8 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rmul___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dc378f95eb7336aa3c68959bba8caffff46f85fb Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___ror___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___ror___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1bba19b53ad853ff8d5ee6f548f020f0fcb9fa57 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___ror___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rpow___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rpow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bb9634fcbaba149abc4f8220af90750c0f69887e Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rpow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rrshift___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rrshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2e4cf7ff4ba3dbc3497e96d1b96043b614d80439 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rrshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rshift___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5aac9ea39bf15717f3fb9cc9dc999cbca3834123 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rsub___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rsub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..00308cead3de2541cfe71aa8b9f45abc53280626 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rsub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rtruediv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rtruediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c78d14d3bf001e1151ed27f040c42b5ad7284878 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rtruediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___rxor___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___rxor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f4d7cb68165b7c17345c2efe51e92ebc3dd3b02d Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___rxor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___setattr___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___setattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1dc9cdea5859887742b0f997b8f6086235870281 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___setattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___setitem___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___setitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3b4a601dcdbac720f2b19dd263bcec0aa23051ea Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___setitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___setslice___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___setslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..996b65e81ebb261795456662b3a71aae7b95cbdc Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___setslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___str___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___str___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2b6fe811f090fffaa3127e3d5491ee8b6d81861b Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___str___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___sub___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e1f403618b2fc78e4412fabbace7cd386a68cb0b Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___truediv___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___truediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..106e13c45c827d3be8b28b8d7512477961c40b51 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___truediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___unicode___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___unicode___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2dc2dad7a5ee31b0ff17fe1f5a91a7b089dbd4e2 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___unicode___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance$instance___xor___exposer.class b/src/main/resources/org/python/core/PyInstance$instance___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c64b59480e64e10c945ee2e5f504823df13736b2 Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance$instance___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInstance.class b/src/main/resources/org/python/core/PyInstance.class new file mode 100644 index 0000000000000000000000000000000000000000..b4492e23fb9ffa9361cb9832e8e0c89ec708c3ac Binary files /dev/null and b/src/main/resources/org/python/core/PyInstance.class differ diff --git a/src/main/resources/org/python/core/PyInteger$PyExposer.class b/src/main/resources/org/python/core/PyInteger$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..56b4cb555338865051764cd7e1c4c3401aaeb0eb Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$denominator_descriptor.class b/src/main/resources/org/python/core/PyInteger$denominator_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..30435dccd0540510fa2e293da22d849ed3690238 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$denominator_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyInteger$exposed___new__.class b/src/main/resources/org/python/core/PyInteger$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..b65326ebfb4486e7c268c281b2d9e28128973e11 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyInteger$imag_descriptor.class b/src/main/resources/org/python/core/PyInteger$imag_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d4ccab4e48352066843f330dfed6d11b095b0599 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$imag_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___abs___exposer.class b/src/main/resources/org/python/core/PyInteger$int___abs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cf01af2756aeef7f31695933c910e6732b5f4b30 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___abs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___add___exposer.class b/src/main/resources/org/python/core/PyInteger$int___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d406db3d14dfc74a43fb6459b94e974668036b2b Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___and___exposer.class b/src/main/resources/org/python/core/PyInteger$int___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..001ce8dfb3a9187d7b4c0fa723231b636767c67d Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___cmp___exposer.class b/src/main/resources/org/python/core/PyInteger$int___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7193a1dbc330f46544b62de116b5101d3489e3a1 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___coerce___exposer.class b/src/main/resources/org/python/core/PyInteger$int___coerce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..882ff70d4ecaab0f1266c1c685482c4385c92a12 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___coerce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___div___exposer.class b/src/main/resources/org/python/core/PyInteger$int___div___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..38bcbb5511272cf7a66a13efba07ae821c8b792b Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___div___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___divmod___exposer.class b/src/main/resources/org/python/core/PyInteger$int___divmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f0957c36c45e6ad966cb6ccbcc70a4d3bb6b9c29 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___divmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___float___exposer.class b/src/main/resources/org/python/core/PyInteger$int___float___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..64983e77fdf96ecd653a1ee371f16c1adbaa707d Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___float___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___floordiv___exposer.class b/src/main/resources/org/python/core/PyInteger$int___floordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..55540ea0f6ccc7408c2ecb587a5888ef46b9139e Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___floordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___format___exposer.class b/src/main/resources/org/python/core/PyInteger$int___format___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..252680172184f3b8a2bac6a87cad5eba37d7698e Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___format___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___getnewargs___exposer.class b/src/main/resources/org/python/core/PyInteger$int___getnewargs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a307f5039f350194a4b42533e1daa84f2102c133 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___getnewargs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___hex___exposer.class b/src/main/resources/org/python/core/PyInteger$int___hex___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1590e2d3bc8ffdfacb887ef717a9ad4208a03e04 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___hex___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___index___exposer.class b/src/main/resources/org/python/core/PyInteger$int___index___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..681d41d04ca8c0c3d533241fc2640d786f02bd1e Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___index___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___int___exposer.class b/src/main/resources/org/python/core/PyInteger$int___int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5da10ffdafe7bd2608324f604f1893efb271eaa9 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___int___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___invert___exposer.class b/src/main/resources/org/python/core/PyInteger$int___invert___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..acee7bb4a46b5aae517b2fba4f8c3dff66ac1adc Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___invert___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___long___exposer.class b/src/main/resources/org/python/core/PyInteger$int___long___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..da2a15d86a893a0d5fd58b3c1745c184f1858952 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___long___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___lshift___exposer.class b/src/main/resources/org/python/core/PyInteger$int___lshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..795671eb7d2dfbf2a1564029ddea1b109e14c350 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___lshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___mod___exposer.class b/src/main/resources/org/python/core/PyInteger$int___mod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5500131b4ad2a0187aa9c12081e41ae5f5d943a4 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___mod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___mul___exposer.class b/src/main/resources/org/python/core/PyInteger$int___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bdb60c7814cc3abc86cb7fc3b80f795b3dbcdcae Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___neg___exposer.class b/src/main/resources/org/python/core/PyInteger$int___neg___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b3ec02048827059881c231421134473bde142293 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___neg___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___nonzero___exposer.class b/src/main/resources/org/python/core/PyInteger$int___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fb3fdc792c9184a35920e0ead8e834ab3af3cb42 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___oct___exposer.class b/src/main/resources/org/python/core/PyInteger$int___oct___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..164854180b2fd5eb5e2fcd88c71f6ea8a4b9edbf Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___oct___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___or___exposer.class b/src/main/resources/org/python/core/PyInteger$int___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ad56ede803fc51a3dd60be0eac58413abce213e6 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___pos___exposer.class b/src/main/resources/org/python/core/PyInteger$int___pos___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f8607b76a9b3f74e5fd35b6706846d172c7ad590 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___pos___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___pow___exposer.class b/src/main/resources/org/python/core/PyInteger$int___pow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d17191d583ec7b85eadb6649bbd9da5291fd2dfc Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___pow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___radd___exposer.class b/src/main/resources/org/python/core/PyInteger$int___radd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b0c8469d12d3324024704979d46522d763bbf678 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___radd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rand___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rand___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3ce680a300c0c8c1440a60165a3ebdd099a3c65b Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rand___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rdiv___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rdiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..918c2e5b19ed3c403102fa8e501d3a114f6c71b3 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rdiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rdivmod___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rdivmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e180307ca7c892973ef4de2e40d38447fc24316b Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rdivmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rfloordiv___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rfloordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a67e19d7e470807117e3f078b339f40fe2363f1c Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rfloordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rlshift___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rlshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8fb931fb2bd11b6d141b004052f4f03e42532e47 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rlshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rmod___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8cb73e087c7d9d1dbfee1d3d89ec4656a3d5a1ad Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rmul___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..425abd192fb187e576b334992594f01d313a8fb2 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___ror___exposer.class b/src/main/resources/org/python/core/PyInteger$int___ror___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3aa5adee1d98e2462f07e7a1b89fe285946c30c3 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___ror___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rpow___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rpow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f5a7bdc7bc68e4cd915acf860508a70726ddfb7d Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rpow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rrshift___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rrshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0ac8eb9c1838b5a00393a9b4b743902c767659e1 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rrshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rshift___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ea5a6a18e4ae3246454f12b5d7e109903144bec9 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rsub___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rsub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7266cce3f36fe5e4d5926c5719dae11f0ee689d8 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rsub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rtruediv___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rtruediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d2cdd39c82c1b73957bc0956d2e0eea3635489ef Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rtruediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___rxor___exposer.class b/src/main/resources/org/python/core/PyInteger$int___rxor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..af786e4d988aaf8fd7d37417b5ce989a6b9a9b55 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___rxor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___sub___exposer.class b/src/main/resources/org/python/core/PyInteger$int___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d3a5e0b34c0692a61010f624e34bcac56669b99f Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___truediv___exposer.class b/src/main/resources/org/python/core/PyInteger$int___truediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a4b5e837a6cc2a2d0231259ac5994f3068248ecd Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___truediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___trunc___exposer.class b/src/main/resources/org/python/core/PyInteger$int___trunc___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..63b5024cfcf4291f8a9a71270297ef012ffaa0bd Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___trunc___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int___xor___exposer.class b/src/main/resources/org/python/core/PyInteger$int___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fc6716eeb523b0e2a2a6411150a3d97e0974c1db Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int_bit_length_exposer.class b/src/main/resources/org/python/core/PyInteger$int_bit_length_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..39d3cd1d4519ebcb2676d659b3d9fe4bd603df9c Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int_bit_length_exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int_conjugate_exposer.class b/src/main/resources/org/python/core/PyInteger$int_conjugate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..392bfac10cae31e022229b71875de69f7849e638 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int_conjugate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int_hashCode_exposer.class b/src/main/resources/org/python/core/PyInteger$int_hashCode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8aa1cafb5868c65d0983da0361b1b8faa8cbb1c9 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int_hashCode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$int_toString_exposer.class b/src/main/resources/org/python/core/PyInteger$int_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..468ca79306ee4eb142054d70e56e0d29f9d1b6de Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$int_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyInteger$numerator_descriptor.class b/src/main/resources/org/python/core/PyInteger$numerator_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..27fbdb06dc562c3cf1a1087cdaafdcaf870765ae Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$numerator_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyInteger$real_descriptor.class b/src/main/resources/org/python/core/PyInteger$real_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ece38734e2d22b2dd71eee19da71f58a995bd013 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger$real_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyInteger.class b/src/main/resources/org/python/core/PyInteger.class new file mode 100644 index 0000000000000000000000000000000000000000..fa1777589b7a180e2fdd65050a5e6daecbfa61e7 Binary files /dev/null and b/src/main/resources/org/python/core/PyInteger.class differ diff --git a/src/main/resources/org/python/core/PyIntegerDerived.class b/src/main/resources/org/python/core/PyIntegerDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..b2e1d7ddbc51801326238bae0f4a7fa6d59d3082 Binary files /dev/null and b/src/main/resources/org/python/core/PyIntegerDerived.class differ diff --git a/src/main/resources/org/python/core/PyIterator$1.class b/src/main/resources/org/python/core/PyIterator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..60766b3954e676a47f03a8f41227835a9d0e61ca Binary files /dev/null and b/src/main/resources/org/python/core/PyIterator$1.class differ diff --git a/src/main/resources/org/python/core/PyIterator.class b/src/main/resources/org/python/core/PyIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..5ff77f67b000baa2e8812b76be546a2676f2de1b Binary files /dev/null and b/src/main/resources/org/python/core/PyIterator.class differ diff --git a/src/main/resources/org/python/core/PyJavaPackage.class b/src/main/resources/org/python/core/PyJavaPackage.class new file mode 100644 index 0000000000000000000000000000000000000000..8e4847626f9612103821d23d398ea864fd11e295 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaPackage.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$1.class b/src/main/resources/org/python/core/PyJavaType$1.class new file mode 100644 index 0000000000000000000000000000000000000000..92b2d0aa883d4eb5a9a839c9b8bab89030427d03 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$1.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$10.class b/src/main/resources/org/python/core/PyJavaType$10.class new file mode 100644 index 0000000000000000000000000000000000000000..1c9ffe20033543b36fb9f8eb3f17031c2102e1dd Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$10.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$11.class b/src/main/resources/org/python/core/PyJavaType$11.class new file mode 100644 index 0000000000000000000000000000000000000000..d756ccbd19893bee9892b6b927909f200382e85c Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$11.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$12.class b/src/main/resources/org/python/core/PyJavaType$12.class new file mode 100644 index 0000000000000000000000000000000000000000..dc74f877d43f2db947d550bc8a7fd9701f391c6f Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$12.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$13.class b/src/main/resources/org/python/core/PyJavaType$13.class new file mode 100644 index 0000000000000000000000000000000000000000..b5b3993e0a9c5c2346077b759eccc9755aadd447 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$13.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$14.class b/src/main/resources/org/python/core/PyJavaType$14.class new file mode 100644 index 0000000000000000000000000000000000000000..84ee3fde21a02a2625ffe7425c0bde6d7eceac4c Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$14.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$15.class b/src/main/resources/org/python/core/PyJavaType$15.class new file mode 100644 index 0000000000000000000000000000000000000000..3a7b3349fbeb98c79865700930c5b35c284ff964 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$15.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$16.class b/src/main/resources/org/python/core/PyJavaType$16.class new file mode 100644 index 0000000000000000000000000000000000000000..3f57922775984e4206aaaa285a8ae51b904284e3 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$16.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$17.class b/src/main/resources/org/python/core/PyJavaType$17.class new file mode 100644 index 0000000000000000000000000000000000000000..37b5e3c8c8b811024469aff3f6a5d33897fefa77 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$17.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$18.class b/src/main/resources/org/python/core/PyJavaType$18.class new file mode 100644 index 0000000000000000000000000000000000000000..58527690efff6494cf45c7751420581cbe484472 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$18.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$19.class b/src/main/resources/org/python/core/PyJavaType$19.class new file mode 100644 index 0000000000000000000000000000000000000000..983ba07c46df7878513755a15c55f3533c42b785 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$19.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$2.class b/src/main/resources/org/python/core/PyJavaType$2.class new file mode 100644 index 0000000000000000000000000000000000000000..129e377a6b8f32234a99a25e568c10d4c4a7a0fa Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$2.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$20.class b/src/main/resources/org/python/core/PyJavaType$20.class new file mode 100644 index 0000000000000000000000000000000000000000..f858260965513a26cb479414a11decd6287445db Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$20.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$21.class b/src/main/resources/org/python/core/PyJavaType$21.class new file mode 100644 index 0000000000000000000000000000000000000000..ed88f45af1d9412c06aceb89d8f30ba6a1df1dcc Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$21.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$22.class b/src/main/resources/org/python/core/PyJavaType$22.class new file mode 100644 index 0000000000000000000000000000000000000000..22eeae87647bdb429f3cc6791c45685be49ab7e1 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$22.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$23.class b/src/main/resources/org/python/core/PyJavaType$23.class new file mode 100644 index 0000000000000000000000000000000000000000..911a4cbdfe4bccf6149b7c744c52261a2c1184f7 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$23.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$24.class b/src/main/resources/org/python/core/PyJavaType$24.class new file mode 100644 index 0000000000000000000000000000000000000000..ecb841d8c1792fac064abb24c653645ba40bb45c Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$24.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$25.class b/src/main/resources/org/python/core/PyJavaType$25.class new file mode 100644 index 0000000000000000000000000000000000000000..77c1261170585c4aa31c0031adbbb9bea41484fb Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$25.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$26.class b/src/main/resources/org/python/core/PyJavaType$26.class new file mode 100644 index 0000000000000000000000000000000000000000..a480f7f0d6466092df32b4c2702807fda6a742af Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$26.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$27.class b/src/main/resources/org/python/core/PyJavaType$27.class new file mode 100644 index 0000000000000000000000000000000000000000..a0f3fc784ccec1919ae004715b5371c70aebc607 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$27.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$28.class b/src/main/resources/org/python/core/PyJavaType$28.class new file mode 100644 index 0000000000000000000000000000000000000000..432fb1e2d255307213498939f175c23ad816e170 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$28.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$29.class b/src/main/resources/org/python/core/PyJavaType$29.class new file mode 100644 index 0000000000000000000000000000000000000000..504781cfafa43591087f79d6734ae5d9d35b8901 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$29.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$3.class b/src/main/resources/org/python/core/PyJavaType$3.class new file mode 100644 index 0000000000000000000000000000000000000000..14facf81038bd69d311f3e9eb3e31edb0a09e5a3 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$3.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$4.class b/src/main/resources/org/python/core/PyJavaType$4.class new file mode 100644 index 0000000000000000000000000000000000000000..6ffa8ecd9d0025073c8cfdde05a4c9f1d8fdcaba Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$4.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$5.class b/src/main/resources/org/python/core/PyJavaType$5.class new file mode 100644 index 0000000000000000000000000000000000000000..e2c0ac2a8116b8cada9ba68ede446dacf0c751ec Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$5.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$6.class b/src/main/resources/org/python/core/PyJavaType$6.class new file mode 100644 index 0000000000000000000000000000000000000000..e908eb3e009287c9ecf6ee2104b8c5def74b82ef Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$6.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$7.class b/src/main/resources/org/python/core/PyJavaType$7.class new file mode 100644 index 0000000000000000000000000000000000000000..943c72f7b4111808ca2f719ef7ce7f25093eb740 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$7.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$8.class b/src/main/resources/org/python/core/PyJavaType$8.class new file mode 100644 index 0000000000000000000000000000000000000000..404251bf2f38d50bccf108d1bcb9edafc70576de Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$8.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$9.class b/src/main/resources/org/python/core/PyJavaType$9.class new file mode 100644 index 0000000000000000000000000000000000000000..6ee29e799999310c54a64b5fb0cb8f2e873840be Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$9.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$CloneInput.class b/src/main/resources/org/python/core/PyJavaType$CloneInput.class new file mode 100644 index 0000000000000000000000000000000000000000..54e48fd7237613e288833b3dc4d832b43308b9da Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$CloneInput.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$CloneOutput.class b/src/main/resources/org/python/core/PyJavaType$CloneOutput.class new file mode 100644 index 0000000000000000000000000000000000000000..9e01dbcedcd208ccd2581afd2fb75255005e73f4 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$CloneOutput.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$ComparableMethod.class b/src/main/resources/org/python/core/PyJavaType$ComparableMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..415b1c6b5ed37f9ba547200df54cf23eb9839f6f Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$ComparableMethod.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$EnumerationIter.class b/src/main/resources/org/python/core/PyJavaType$EnumerationIter.class new file mode 100644 index 0000000000000000000000000000000000000000..7581e9ecb995efa8db03dd9635cb6e496d2c5ae1 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$EnumerationIter.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$IteratorIter.class b/src/main/resources/org/python/core/PyJavaType$IteratorIter.class new file mode 100644 index 0000000000000000000000000000000000000000..35c18abf4f6dc9eccb2fe886fe727f2af349f1ec Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$IteratorIter.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$ListIndexDelegate.class b/src/main/resources/org/python/core/PyJavaType$ListIndexDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..a4c4406905c147110e0b4bba27f433bb682ee0c6 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$ListIndexDelegate.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$ListMethod.class b/src/main/resources/org/python/core/PyJavaType$ListMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..c1f1d2262af8e683f0603c1aa6247b15ebe77e08 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$ListMethod.class differ diff --git a/src/main/resources/org/python/core/PyJavaType$MapMethod.class b/src/main/resources/org/python/core/PyJavaType$MapMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..2d972a5f89155b9216a8568c94a43ccc066b7a05 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType$MapMethod.class differ diff --git a/src/main/resources/org/python/core/PyJavaType.class b/src/main/resources/org/python/core/PyJavaType.class new file mode 100644 index 0000000000000000000000000000000000000000..a9b4bf9f92d79458f80f2df16f7ec2efcd0bb2b3 Binary files /dev/null and b/src/main/resources/org/python/core/PyJavaType.class differ diff --git a/src/main/resources/org/python/core/PyList$1.class b/src/main/resources/org/python/core/PyList$1.class new file mode 100644 index 0000000000000000000000000000000000000000..14d1e0c748ed420d17c61136ac9d80fd84bce603 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$1.class differ diff --git a/src/main/resources/org/python/core/PyList$2.class b/src/main/resources/org/python/core/PyList$2.class new file mode 100644 index 0000000000000000000000000000000000000000..127e2ba67282bf2542f2f6ea8d17b9ae4382d29e Binary files /dev/null and b/src/main/resources/org/python/core/PyList$2.class differ diff --git a/src/main/resources/org/python/core/PyList$KV.class b/src/main/resources/org/python/core/PyList$KV.class new file mode 100644 index 0000000000000000000000000000000000000000..8495f5a4bf65fa45958f32e05dcac6bc2dad7c68 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$KV.class differ diff --git a/src/main/resources/org/python/core/PyList$KVComparator.class b/src/main/resources/org/python/core/PyList$KVComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..81646a07988292b27bdc6f8ba95b71d6546da926 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$KVComparator.class differ diff --git a/src/main/resources/org/python/core/PyList$PyExposer.class b/src/main/resources/org/python/core/PyList$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6f0c7b1573afc5c46e73c4ad5fa688fcb243be0d Binary files /dev/null and b/src/main/resources/org/python/core/PyList$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyList$PyObjectComparator.class b/src/main/resources/org/python/core/PyList$PyObjectComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..39663f2748d4682fc801ad947ceda8f28c49524f Binary files /dev/null and b/src/main/resources/org/python/core/PyList$PyObjectComparator.class differ diff --git a/src/main/resources/org/python/core/PyList$PyObjectDefaultComparator.class b/src/main/resources/org/python/core/PyList$PyObjectDefaultComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..765907d5cd659a6e50c6f95f690993d3910c6cbc Binary files /dev/null and b/src/main/resources/org/python/core/PyList$PyObjectDefaultComparator.class differ diff --git a/src/main/resources/org/python/core/PyList$exposed___new__.class b/src/main/resources/org/python/core/PyList$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..cc17321d5f4fb85eae799095ad221fc06ffd1a61 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyList$list___add___exposer.class b/src/main/resources/org/python/core/PyList$list___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d6fc54765b10eb2d654e13cffa54fdac6bc1d775 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___contains___exposer.class b/src/main/resources/org/python/core/PyList$list___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9e7869f03f9aca8cd4df02c3412284a82a1ccd91 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___delitem___exposer.class b/src/main/resources/org/python/core/PyList$list___delitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..622e31b90eb64a47b5fc056e098fa5953704623e Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___delitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___delslice___exposer.class b/src/main/resources/org/python/core/PyList$list___delslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1efd042ff65b143e2441d4e674817f2b85cb22e6 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___delslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___eq___exposer.class b/src/main/resources/org/python/core/PyList$list___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ab14c8b7145d2f146fc3c9b4fbe7d1460f7f11e8 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___ge___exposer.class b/src/main/resources/org/python/core/PyList$list___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b2a5dc1a2f59972218aa9e9586c2d769d0198279 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___getitem___exposer.class b/src/main/resources/org/python/core/PyList$list___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a1a4d25f97a574aaa95eceb7e08461eb8dbabc3e Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___getslice___exposer.class b/src/main/resources/org/python/core/PyList$list___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bc2115c17584e8e29fbc94fa9340f4e72ca013fc Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___gt___exposer.class b/src/main/resources/org/python/core/PyList$list___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e9014100fa4cbae978f48a26a25f300cf8eca71d Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___hash___exposer.class b/src/main/resources/org/python/core/PyList$list___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0e28329498cabc7ca7ffd2084d9f17cf0cb1e8e5 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___iadd___exposer.class b/src/main/resources/org/python/core/PyList$list___iadd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5206ac505096e332a220d4d21fd55025af14fee8 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___iadd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___imul___exposer.class b/src/main/resources/org/python/core/PyList$list___imul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..588166429696d3cacde48ac19d79502f29aa0602 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___imul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___init___exposer.class b/src/main/resources/org/python/core/PyList$list___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c932c096dd62512e141b8924556fbfc1ac29ad63 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___iter___exposer.class b/src/main/resources/org/python/core/PyList$list___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9608c5c6dcee88a6bf5bc055a237702892afadc3 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___le___exposer.class b/src/main/resources/org/python/core/PyList$list___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b087db8d6e83813e98c80583a66713535a7f1398 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___len___exposer.class b/src/main/resources/org/python/core/PyList$list___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..77251cef636b5dd2e23c55397f29b4986f0b12f7 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___lt___exposer.class b/src/main/resources/org/python/core/PyList$list___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..38738d74352004ee8f8a7ebcd251e3a445f3139f Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___mul___exposer.class b/src/main/resources/org/python/core/PyList$list___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5dd7f2bf693f76cb875d5a451b2ffb4032439ff5 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___ne___exposer.class b/src/main/resources/org/python/core/PyList$list___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7c6f9432ee4a5ba39d9163778f5dbc27318c4189 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___radd___exposer.class b/src/main/resources/org/python/core/PyList$list___radd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..dbe187e5cd353aa43d82e2a588c0dbfcff4543f0 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___radd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___reversed___exposer.class b/src/main/resources/org/python/core/PyList$list___reversed___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cc67480e32be8563c51063ebb5ba6459a440d31a Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___reversed___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___rmul___exposer.class b/src/main/resources/org/python/core/PyList$list___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1e31653b69c6398b217bbf637da467b4d0906f6a Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___setitem___exposer.class b/src/main/resources/org/python/core/PyList$list___setitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..26a8891053ac5fed03711af85e691efd6db44e2e Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___setitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list___setslice___exposer.class b/src/main/resources/org/python/core/PyList$list___setslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f93fdaa76751e948764cfb5b6b6cdb684d5ea76a Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list___setslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_append_exposer.class b/src/main/resources/org/python/core/PyList$list_append_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..07b1ca5e1b76f2082d4b7db65a8ac610fd03ac77 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_append_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_count_exposer.class b/src/main/resources/org/python/core/PyList$list_count_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e044260dbdad27e11febe4601823e648243fa34f Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_count_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_extend_exposer.class b/src/main/resources/org/python/core/PyList$list_extend_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3fb8e469c674a6c528c45355cd00c09a716dceff Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_extend_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_index_exposer.class b/src/main/resources/org/python/core/PyList$list_index_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ce64c1cef8e80bdbb46ff1258bf21504f40f69a4 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_index_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_insert_exposer.class b/src/main/resources/org/python/core/PyList$list_insert_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8ca6e70f66f0fea1fa2b47651aebac1ef844d845 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_insert_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_pop_exposer.class b/src/main/resources/org/python/core/PyList$list_pop_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9fc65277898a7098326d86cf0ccef5e600405cea Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_pop_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_remove_exposer.class b/src/main/resources/org/python/core/PyList$list_remove_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..784117b690080a76ab5a362e82f859826e158928 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_remove_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_reverse_exposer.class b/src/main/resources/org/python/core/PyList$list_reverse_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..76e6346166de5dba06bf7847dafcc33886a6a13b Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_reverse_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_sort_exposer.class b/src/main/resources/org/python/core/PyList$list_sort_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4f0e2afdd68ee366cf3ec2947326e05283ecbff3 Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_sort_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList$list_toString_exposer.class b/src/main/resources/org/python/core/PyList$list_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cad7e0049087237be8bc02b629535aafb22a51ac Binary files /dev/null and b/src/main/resources/org/python/core/PyList$list_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyList.class b/src/main/resources/org/python/core/PyList.class new file mode 100644 index 0000000000000000000000000000000000000000..d6a3f8fbe3c2003cc9d8146c9f821525d3613022 Binary files /dev/null and b/src/main/resources/org/python/core/PyList.class differ diff --git a/src/main/resources/org/python/core/PyListDerived.class b/src/main/resources/org/python/core/PyListDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..fe684023554e30a97a25afd59b2f62dc4eccfd36 Binary files /dev/null and b/src/main/resources/org/python/core/PyListDerived.class differ diff --git a/src/main/resources/org/python/core/PyListTest.class b/src/main/resources/org/python/core/PyListTest.class new file mode 100644 index 0000000000000000000000000000000000000000..ab9d6c7b7c51e01ed79d64d26c03aa923a5f60ab Binary files /dev/null and b/src/main/resources/org/python/core/PyListTest.class differ diff --git a/src/main/resources/org/python/core/PyLong$PyExposer.class b/src/main/resources/org/python/core/PyLong$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5c13785573cc4a5c44fc0f62ae3f2b413c377985 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$denominator_descriptor.class b/src/main/resources/org/python/core/PyLong$denominator_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..cda4491606707de0ed46db2ef316e4d1ac73d26c Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$denominator_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyLong$exposed___new__.class b/src/main/resources/org/python/core/PyLong$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..77d942d8e6910c829a1d74d840f72edb0dd5a45f Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyLong$imag_descriptor.class b/src/main/resources/org/python/core/PyLong$imag_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aae1d1b0fdbc29ec08d54d47435cac3d03b1279d Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$imag_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___abs___exposer.class b/src/main/resources/org/python/core/PyLong$long___abs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b7cb8aeaa8a762fd02de79e4c8b8036f9e220eab Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___abs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___add___exposer.class b/src/main/resources/org/python/core/PyLong$long___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1665e79e86eda01e31057d44dcb9ec9e6b3100a1 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___and___exposer.class b/src/main/resources/org/python/core/PyLong$long___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..416f8ca8260f1dd610c321c13c4dad634cacc8b7 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___cmp___exposer.class b/src/main/resources/org/python/core/PyLong$long___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..26e0351e0088c172efa0e7a56b4c9e375041d221 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___coerce___exposer.class b/src/main/resources/org/python/core/PyLong$long___coerce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5b3fe7cbd6b21695f6c2130ddadf83883f2b2d1b Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___coerce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___div___exposer.class b/src/main/resources/org/python/core/PyLong$long___div___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..80b2bc4989b66daa0032a6d87f6134c7f23ca04e Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___div___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___divmod___exposer.class b/src/main/resources/org/python/core/PyLong$long___divmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d56ea81b9f5bd6d94fdf6341006f90f445303af2 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___divmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___float___exposer.class b/src/main/resources/org/python/core/PyLong$long___float___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee561b70e040abbd54e8191bec002b61d397e2eb Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___float___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___floordiv___exposer.class b/src/main/resources/org/python/core/PyLong$long___floordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..89bb80f57c1013daab44d891395418303dcf361c Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___floordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___format___exposer.class b/src/main/resources/org/python/core/PyLong$long___format___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..05b0772d37ac67ebb73d8b32a2ee1085e3b49370 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___format___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___getnewargs___exposer.class b/src/main/resources/org/python/core/PyLong$long___getnewargs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..02410269722778ef76e6029ea91bdede95659825 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___getnewargs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___hash___exposer.class b/src/main/resources/org/python/core/PyLong$long___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1eece6707b475271d046aa13fde32eb16dfac75e Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___hex___exposer.class b/src/main/resources/org/python/core/PyLong$long___hex___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..942402d8b404839f8e1d1bbcdcf73d6dfb6a0a81 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___hex___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___index___exposer.class b/src/main/resources/org/python/core/PyLong$long___index___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..08b2954d273271080ba3a055ca658855e90a6a7c Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___index___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___int___exposer.class b/src/main/resources/org/python/core/PyLong$long___int___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8d62087ce870a6c527a619aecd0d95df7819a256 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___int___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___invert___exposer.class b/src/main/resources/org/python/core/PyLong$long___invert___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fa29c7729bb214740358fb30371853bbc5f47692 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___invert___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___long___exposer.class b/src/main/resources/org/python/core/PyLong$long___long___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8331fa0f1f956c7cabec54c7736ae7c4cd89e827 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___long___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___lshift___exposer.class b/src/main/resources/org/python/core/PyLong$long___lshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..47f3ca423218c70240537656efadcbfbe28df88e Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___lshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___mod___exposer.class b/src/main/resources/org/python/core/PyLong$long___mod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..48e245c33db8bbb82d6f67c91e1690c61513f97c Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___mod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___mul___exposer.class b/src/main/resources/org/python/core/PyLong$long___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4cde8bc3dc8f3b02934919e3f44f6072c2254551 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___neg___exposer.class b/src/main/resources/org/python/core/PyLong$long___neg___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cd9e4ca8f8ff047612b7c9d07727c762de3ce742 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___neg___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___nonzero___exposer.class b/src/main/resources/org/python/core/PyLong$long___nonzero___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c6043119e43b0ac7161c9c895f55bc640e99c475 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___nonzero___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___oct___exposer.class b/src/main/resources/org/python/core/PyLong$long___oct___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f4d4fb42a027b6565bc36b7a04e04587d35469a3 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___oct___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___or___exposer.class b/src/main/resources/org/python/core/PyLong$long___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e448b00cd63a3db0bb74477adcb5d34e44e35a04 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___pos___exposer.class b/src/main/resources/org/python/core/PyLong$long___pos___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..042a1da0cba5c240db9653bad84889099c787ed6 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___pos___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___pow___exposer.class b/src/main/resources/org/python/core/PyLong$long___pow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cb0f6ed089e402a48b6d95089dfaf466f8190004 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___pow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___radd___exposer.class b/src/main/resources/org/python/core/PyLong$long___radd___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..acf366f7339c7f10a7775e40ec03d1684c39fcdd Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___radd___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rand___exposer.class b/src/main/resources/org/python/core/PyLong$long___rand___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5115f1cb7fd209200b722f045628374f123a95ef Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rand___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rdiv___exposer.class b/src/main/resources/org/python/core/PyLong$long___rdiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e1e9a65c949e2e96436417aacb7f1709268e4a48 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rdiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rdivmod___exposer.class b/src/main/resources/org/python/core/PyLong$long___rdivmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..37de59e7b8c007a1752f030bb8e7be1c1689e01f Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rdivmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rfloordiv___exposer.class b/src/main/resources/org/python/core/PyLong$long___rfloordiv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c43af9ae95d5620593d209ca1b62534235420bca Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rfloordiv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rlshift___exposer.class b/src/main/resources/org/python/core/PyLong$long___rlshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8308b2d8184729106b07482e397a8b33abaf66d8 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rlshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rmod___exposer.class b/src/main/resources/org/python/core/PyLong$long___rmod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6bf97482402539f5f3cb29d8f05556919763ec53 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rmod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rmul___exposer.class b/src/main/resources/org/python/core/PyLong$long___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cb0de8372c71fa4e8a0493d536bf73ecc3d752af Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___ror___exposer.class b/src/main/resources/org/python/core/PyLong$long___ror___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..55ba88e22c7a3dab598df2bae1666008205904ba Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___ror___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rpow___exposer.class b/src/main/resources/org/python/core/PyLong$long___rpow___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..423a7576d31a7f6b89a43d5d5746739467df361e Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rpow___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rrshift___exposer.class b/src/main/resources/org/python/core/PyLong$long___rrshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..08fdfb12a02e096df45a6e93cee7cebc4f8f4516 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rrshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rshift___exposer.class b/src/main/resources/org/python/core/PyLong$long___rshift___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d407218b56531f256c0043ce5b94cc86a6fd645e Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rshift___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rsub___exposer.class b/src/main/resources/org/python/core/PyLong$long___rsub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c5569853827b03eb42ba772abdfec2e2569e4724 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rsub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rtruediv___exposer.class b/src/main/resources/org/python/core/PyLong$long___rtruediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..64accbad4ea219458eeb4e6be0a073fa64c4c6c0 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rtruediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___rxor___exposer.class b/src/main/resources/org/python/core/PyLong$long___rxor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8b75bf7138f4bd112dcb1027e42ec9336699b9a7 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___rxor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___str___exposer.class b/src/main/resources/org/python/core/PyLong$long___str___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cf3b50b2ae2e5db4ca0a4a7446c2275255ca0446 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___str___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___sub___exposer.class b/src/main/resources/org/python/core/PyLong$long___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8e6127b615e13a5a89fef74f652c9a583a6d0ceb Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___truediv___exposer.class b/src/main/resources/org/python/core/PyLong$long___truediv___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..538f6d53c447cc2eaaab3862cf68ca425dcfceb1 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___truediv___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___trunc___exposer.class b/src/main/resources/org/python/core/PyLong$long___trunc___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d345f0aee99eca09f6daf79ecb22f98d783f94a8 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___trunc___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long___xor___exposer.class b/src/main/resources/org/python/core/PyLong$long___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..58e91b04dee11df235a8e27b154b920945ecbf1f Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long_bit_length_exposer.class b/src/main/resources/org/python/core/PyLong$long_bit_length_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..23d5482f64a1ec72e5a9cb697053804f3ea47d62 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long_bit_length_exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long_conjugate_exposer.class b/src/main/resources/org/python/core/PyLong$long_conjugate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..773783706675d0bec98d954f938989157fd1574f Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long_conjugate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$long_toString_exposer.class b/src/main/resources/org/python/core/PyLong$long_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b0720a6c16492c920acad62add15fb7f33bcd9d6 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$long_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyLong$numerator_descriptor.class b/src/main/resources/org/python/core/PyLong$numerator_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..439eec9f746a644e590db64ec0451476edaeeb03 Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$numerator_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyLong$real_descriptor.class b/src/main/resources/org/python/core/PyLong$real_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9ea9051e2948669b18c6197be61cf5770106c84b Binary files /dev/null and b/src/main/resources/org/python/core/PyLong$real_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyLong.class b/src/main/resources/org/python/core/PyLong.class new file mode 100644 index 0000000000000000000000000000000000000000..af0895c083fc399bebfc0174d2a13549d1d613ff Binary files /dev/null and b/src/main/resources/org/python/core/PyLong.class differ diff --git a/src/main/resources/org/python/core/PyLongDerived.class b/src/main/resources/org/python/core/PyLongDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..8d4e775e2cbfb56223977f8d36b45cd7e3050ecb Binary files /dev/null and b/src/main/resources/org/python/core/PyLongDerived.class differ diff --git a/src/main/resources/org/python/core/PyMapEntrySet.class b/src/main/resources/org/python/core/PyMapEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..e2d86a02435ba2221d11b80446143873611ab126 Binary files /dev/null and b/src/main/resources/org/python/core/PyMapEntrySet.class differ diff --git a/src/main/resources/org/python/core/PyMapKeyValSet.class b/src/main/resources/org/python/core/PyMapKeyValSet.class new file mode 100644 index 0000000000000000000000000000000000000000..7fb46f5340584217e8c03944019f7830f8dacdee Binary files /dev/null and b/src/main/resources/org/python/core/PyMapKeyValSet.class differ diff --git a/src/main/resources/org/python/core/PyMapSet$PySetIter.class b/src/main/resources/org/python/core/PyMapSet$PySetIter.class new file mode 100644 index 0000000000000000000000000000000000000000..4a4f3ea1cb34bed3924edb8e3fa76141326f7cc3 Binary files /dev/null and b/src/main/resources/org/python/core/PyMapSet$PySetIter.class differ diff --git a/src/main/resources/org/python/core/PyMapSet.class b/src/main/resources/org/python/core/PyMapSet.class new file mode 100644 index 0000000000000000000000000000000000000000..477a519859e98edc3feaa72d699cece4f46a1881 Binary files /dev/null and b/src/main/resources/org/python/core/PyMapSet.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$PyExposer.class b/src/main/resources/org/python/core/PyMemoryView$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..355b955a306fb37eae15427335a3b7f6e3afa19d Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$exposed___new__.class b/src/main/resources/org/python/core/PyMemoryView$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..8457ccfdaf8e7021515cd9360c50e5117e3de344 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$format_descriptor.class b/src/main/resources/org/python/core/PyMemoryView$format_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f077391048ae3eeb5b8eda6bfc4444dbe422689f Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$format_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$itemsize_descriptor.class b/src/main/resources/org/python/core/PyMemoryView$itemsize_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b313a1c41995d240eb86e8c818e59e6a161e6956 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$itemsize_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___enter___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___enter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..778bcc51f7d566ce862d0166d7adc3e666c5ba26 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___enter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___eq___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb287ba78e2c228bd98c6eae2cad079753c2599e Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___exit___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___exit___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a5ff61badbc67f419fa238ba4d68860b984a98fe Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___exit___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___ge___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7e8ad19f93e2de77a0cf722e1695ab3c3d208fb1 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___gt___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..17f23e45d72f62db5fa3306ff71f02a690c20096 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___hash___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..19933f5f9674b305305476a6ca395b7da0bc9001 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___le___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1e058a3c9e009398a1472a0bee30080d8a4f237b Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___lt___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9eea31bcebccb0a91bb406d93d1fce53a2d93a5d Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview___ne___exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b546c8c3e523ee4e7bb0e5db1e88ebf0bdc4bb6c Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview_release_exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview_release_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1be1c1ed072ea12dfaf1f4be212d2520f8f82532 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview_release_exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview_tobytes_exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview_tobytes_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8a16de7045dc97e17fa6ef36e51cd10ebb43867f Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview_tobytes_exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$memoryview_tolist_exposer.class b/src/main/resources/org/python/core/PyMemoryView$memoryview_tolist_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a167ca1078221ec4798efcb4aa0abd4817b52272 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$memoryview_tolist_exposer.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$ndim_descriptor.class b/src/main/resources/org/python/core/PyMemoryView$ndim_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..21d2de2c6b37c9b1ea08ab0ceb0e463a4862814f Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$ndim_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$readonly_descriptor.class b/src/main/resources/org/python/core/PyMemoryView$readonly_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b7ee1e0b17918024187a2a85d49b3b2c2503b87b Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$readonly_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$shape_descriptor.class b/src/main/resources/org/python/core/PyMemoryView$shape_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..6b7d2b36a55d2033dfd0bbb2529808bf637f6aff Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$shape_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$strides_descriptor.class b/src/main/resources/org/python/core/PyMemoryView$strides_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0b9ac23d37928bcbd619cc19675c82ad6012984c Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$strides_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView$suboffsets_descriptor.class b/src/main/resources/org/python/core/PyMemoryView$suboffsets_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d76cd73cd81dc592e2bb445653ad9a6116f4c3bc Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView$suboffsets_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMemoryView.class b/src/main/resources/org/python/core/PyMemoryView.class new file mode 100644 index 0000000000000000000000000000000000000000..e4b4814a4bb0950aecf1b1e07cd7ad8333457659 Binary files /dev/null and b/src/main/resources/org/python/core/PyMemoryView.class differ diff --git a/src/main/resources/org/python/core/PyMethod$PyExposer.class b/src/main/resources/org/python/core/PyMethod$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0a797367f348c5b5e1e4b0e91afbab09c84fb391 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyMethod$__doc___descriptor.class b/src/main/resources/org/python/core/PyMethod$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..0e080d10dc29fcedb3725705cb399f72c4942d93 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethod$__func___descriptor.class b/src/main/resources/org/python/core/PyMethod$__func___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..42756f8b3d2506513027d67a8f86b8daf2072483 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$__func___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethod$__self___descriptor.class b/src/main/resources/org/python/core/PyMethod$__self___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bbd8f834ebc5a287de7dabed0719304b2c99e77a Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$__self___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethod$exposed___new__.class b/src/main/resources/org/python/core/PyMethod$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..4ef8795dd3345fbe9d232c9342ecf390d6804de9 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyMethod$im_class_descriptor.class b/src/main/resources/org/python/core/PyMethod$im_class_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..4a95540747ca0e8d4d0166746faa3c67a3c06b1d Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$im_class_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethod$im_func_descriptor.class b/src/main/resources/org/python/core/PyMethod$im_func_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b049b53fe317db6086110a7b15c2ae74b08cf2c5 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$im_func_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethod$im_self_descriptor.class b/src/main/resources/org/python/core/PyMethod$im_self_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..20e5b82ed4932448dd68b6cf6e81d36bcb42e2de Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$im_self_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethod$instancemethod___call___exposer.class b/src/main/resources/org/python/core/PyMethod$instancemethod___call___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6c70c4c9436caba842c9a47cb34590323f9b1670 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$instancemethod___call___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMethod$instancemethod___cmp___exposer.class b/src/main/resources/org/python/core/PyMethod$instancemethod___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..747ee6ef88d0e5f496d41465918e26d843d80aa3 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$instancemethod___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMethod$instancemethod___get___exposer.class b/src/main/resources/org/python/core/PyMethod$instancemethod___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8207c7662aa71cb959e79e93d34d65ee0c73e3c8 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$instancemethod___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMethod$instancemethod___getattribute___exposer.class b/src/main/resources/org/python/core/PyMethod$instancemethod___getattribute___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c772ee5ee266137639a1853182b174390180441c Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod$instancemethod___getattribute___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMethod.class b/src/main/resources/org/python/core/PyMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..2cf5e531cba3730433e0d778b503cf479490c421 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethod.class differ diff --git a/src/main/resources/org/python/core/PyMethodDescr$PyExposer.class b/src/main/resources/org/python/core/PyMethodDescr$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9faec2ba19ac83374328d0e3b780c0fee3c2975c Binary files /dev/null and b/src/main/resources/org/python/core/PyMethodDescr$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyMethodDescr$__doc___descriptor.class b/src/main/resources/org/python/core/PyMethodDescr$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3a4b7dc5bd59797f16540b80ed90ce30e696e839 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethodDescr$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethodDescr$__name___descriptor.class b/src/main/resources/org/python/core/PyMethodDescr$__name___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3c66dd7c74697861b80c6eab04435acded03852c Binary files /dev/null and b/src/main/resources/org/python/core/PyMethodDescr$__name___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethodDescr$__objclass___descriptor.class b/src/main/resources/org/python/core/PyMethodDescr$__objclass___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3a0b8cbb48bd58abf909651b57dc53a7cb67b7ce Binary files /dev/null and b/src/main/resources/org/python/core/PyMethodDescr$__objclass___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyMethodDescr$method_descriptor___call___exposer.class b/src/main/resources/org/python/core/PyMethodDescr$method_descriptor___call___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f225a61a0322876ce122bc6f8afbc76631144706 Binary files /dev/null and b/src/main/resources/org/python/core/PyMethodDescr$method_descriptor___call___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMethodDescr$method_descriptor___get___exposer.class b/src/main/resources/org/python/core/PyMethodDescr$method_descriptor___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4d7a730ac1d5c6d353f3b5493e8b3993bbbd5f3c Binary files /dev/null and b/src/main/resources/org/python/core/PyMethodDescr$method_descriptor___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyMethodDescr.class b/src/main/resources/org/python/core/PyMethodDescr.class new file mode 100644 index 0000000000000000000000000000000000000000..e85984178cc8c325230df81494d70337085458ec Binary files /dev/null and b/src/main/resources/org/python/core/PyMethodDescr.class differ diff --git a/src/main/resources/org/python/core/PyModule$PyExposer.class b/src/main/resources/org/python/core/PyModule$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..714ac0d07419e9f94a528082d68766e47fcb5afc Binary files /dev/null and b/src/main/resources/org/python/core/PyModule$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyModule$__dict___descriptor.class b/src/main/resources/org/python/core/PyModule$__dict___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..d625f1efc2a8118d6d93bb3af42127c0582ab921 Binary files /dev/null and b/src/main/resources/org/python/core/PyModule$__dict___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyModule$exposed___new__.class b/src/main/resources/org/python/core/PyModule$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..18d9a77128ebf2cf482d4d57546e6cfd1c77d177 Binary files /dev/null and b/src/main/resources/org/python/core/PyModule$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyModule$module___delattr___exposer.class b/src/main/resources/org/python/core/PyModule$module___delattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..aaaa402a80abe3c6de16948b98f2c264b0a5dcbe Binary files /dev/null and b/src/main/resources/org/python/core/PyModule$module___delattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyModule$module___init___exposer.class b/src/main/resources/org/python/core/PyModule$module___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4dd4efe55f09bdebeb7e8a5595c3206cfa995757 Binary files /dev/null and b/src/main/resources/org/python/core/PyModule$module___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyModule$module___setattr___exposer.class b/src/main/resources/org/python/core/PyModule$module___setattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..048f0650ea0fbb722aa5c9242206a8c41528e19a Binary files /dev/null and b/src/main/resources/org/python/core/PyModule$module___setattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyModule$module_toString_exposer.class b/src/main/resources/org/python/core/PyModule$module_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..216ed3eb2cee4c73a898cd4ecf66762932e1c9f0 Binary files /dev/null and b/src/main/resources/org/python/core/PyModule$module_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyModule.class b/src/main/resources/org/python/core/PyModule.class new file mode 100644 index 0000000000000000000000000000000000000000..7c8fcbaaf8377090b7085bcc904f5704f9fee20c Binary files /dev/null and b/src/main/resources/org/python/core/PyModule.class differ diff --git a/src/main/resources/org/python/core/PyModuleDerived.class b/src/main/resources/org/python/core/PyModuleDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..90c1e3fe3b455a3b9e9845512eb1357e77d5b096 Binary files /dev/null and b/src/main/resources/org/python/core/PyModuleDerived.class differ diff --git a/src/main/resources/org/python/core/PyNewWrapper.class b/src/main/resources/org/python/core/PyNewWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..9cdc7775e2d0d50a48933a5e633619be129b4122 Binary files /dev/null and b/src/main/resources/org/python/core/PyNewWrapper.class differ diff --git a/src/main/resources/org/python/core/PyNone$NoneType_toString_exposer.class b/src/main/resources/org/python/core/PyNone$NoneType_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cbf5faa22b039b47feaec497b140423590ea72ff Binary files /dev/null and b/src/main/resources/org/python/core/PyNone$NoneType_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyNone$PyExposer.class b/src/main/resources/org/python/core/PyNone$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2db05f0ae5c53450a418892e107ed2781ff10e96 Binary files /dev/null and b/src/main/resources/org/python/core/PyNone$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyNone.class b/src/main/resources/org/python/core/PyNone.class new file mode 100644 index 0000000000000000000000000000000000000000..65f1f6cb7a992ec0f813484a8433d02cf29d0a0f Binary files /dev/null and b/src/main/resources/org/python/core/PyNone.class differ diff --git a/src/main/resources/org/python/core/PyNotImplemented.class b/src/main/resources/org/python/core/PyNotImplemented.class new file mode 100644 index 0000000000000000000000000000000000000000..17985ee5d451790aa940c09817d1103995b163c8 Binary files /dev/null and b/src/main/resources/org/python/core/PyNotImplemented.class differ diff --git a/src/main/resources/org/python/core/PyObject$1$1.class b/src/main/resources/org/python/core/PyObject$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..412a88242da7bb12899a2adebc7c3da228880ae1 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$1$1.class differ diff --git a/src/main/resources/org/python/core/PyObject$1.class b/src/main/resources/org/python/core/PyObject$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fac0a6c6846dfdca28e0e4ae8030e7ff034d7eea Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$1.class differ diff --git a/src/main/resources/org/python/core/PyObject$ConversionException.class b/src/main/resources/org/python/core/PyObject$ConversionException.class new file mode 100644 index 0000000000000000000000000000000000000000..fe901d56ecaf68e037b5d5f1bb4583d2e118c0cc Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$ConversionException.class differ diff --git a/src/main/resources/org/python/core/PyObject$PyExposer.class b/src/main/resources/org/python/core/PyObject$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0fed6f19f2d82cd01d1cc1d4673d50abcf80f7ee Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$__class___descriptor.class b/src/main/resources/org/python/core/PyObject$__class___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f46cb3544c1be30f4ab08fee204554609ac1c621 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$__class___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyObject$__repr___exposer.class b/src/main/resources/org/python/core/PyObject$__repr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..19dbf0f2257a627785dc30e395312a10424358a9 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$__repr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$exposed___new__.class b/src/main/resources/org/python/core/PyObject$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..127437246b2693c1ccea5a2e9508ced39199ae8c Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___delattr___exposer.class b/src/main/resources/org/python/core/PyObject$object___delattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9b25f904650b9472f8308271a24244ce11c996cc Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___delattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___format___exposer.class b/src/main/resources/org/python/core/PyObject$object___format___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3b994a2871493f03a1732b353519861a3987b580 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___format___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___getattribute___exposer.class b/src/main/resources/org/python/core/PyObject$object___getattribute___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..adb554b22a8b555c89680cdfd53a443d61596679 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___getattribute___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___hash___exposer.class b/src/main/resources/org/python/core/PyObject$object___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9c306cbfa18a3ea7cf4c9d662ee8f38dda77fd6b Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___init___exposer.class b/src/main/resources/org/python/core/PyObject$object___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..43de1d4c0e2022c3711d80a8e72769c1ddab0f98 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___reduce___exposer.class b/src/main/resources/org/python/core/PyObject$object___reduce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1bd799b3062e29eb46bf33b47fafb094f2de9668 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___reduce___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___reduce_ex___exposer.class b/src/main/resources/org/python/core/PyObject$object___reduce_ex___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a7e154179230bc37a46ecc4167b03811d48b42c6 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___reduce_ex___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___setattr___exposer.class b/src/main/resources/org/python/core/PyObject$object___setattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..78874edcd1f729aa2753d0256d8ae36ce998f750 Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___setattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object___subclasshook___exposer.class b/src/main/resources/org/python/core/PyObject$object___subclasshook___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bb6f4e22d4a799385df326a7bcf3023e5a6ef2ff Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object___subclasshook___exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject$object_toString_exposer.class b/src/main/resources/org/python/core/PyObject$object_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..01e0e67bc7f52b8374d412930c627aac30c4e70b Binary files /dev/null and b/src/main/resources/org/python/core/PyObject$object_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyObject.class b/src/main/resources/org/python/core/PyObject.class new file mode 100644 index 0000000000000000000000000000000000000000..59443df1990f61aa2c788c899b05f56b4a44be8a Binary files /dev/null and b/src/main/resources/org/python/core/PyObject.class differ diff --git a/src/main/resources/org/python/core/PyObjectDerived.class b/src/main/resources/org/python/core/PyObjectDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..ccce8ed794461c8c07e8140bd6af22532091a5dd Binary files /dev/null and b/src/main/resources/org/python/core/PyObjectDerived.class differ diff --git a/src/main/resources/org/python/core/PyOverridableNew.class b/src/main/resources/org/python/core/PyOverridableNew.class new file mode 100644 index 0000000000000000000000000000000000000000..a7d9a873566c979c21ea7b1914da5d4c673e08ca Binary files /dev/null and b/src/main/resources/org/python/core/PyOverridableNew.class differ diff --git a/src/main/resources/org/python/core/PyProperty$PyExposer.class b/src/main/resources/org/python/core/PyProperty$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..487384e51a8917bac42c1fcf124432942247e197 Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty$__doc___descriptor.class b/src/main/resources/org/python/core/PyProperty$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..eea3c0420daffb44132bf6d16a602286ea26f71c Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyProperty$exposed___new__.class b/src/main/resources/org/python/core/PyProperty$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..810979e9906104f70e36dd1347950edfe640656a Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyProperty$fdel_descriptor.class b/src/main/resources/org/python/core/PyProperty$fdel_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..146c434021d09aba42aec4f3c88c796c2959a60f Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$fdel_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyProperty$fget_descriptor.class b/src/main/resources/org/python/core/PyProperty$fget_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..408e0642c0b837f75b0b26eab9e0e72b8a92619f Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$fget_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyProperty$fset_descriptor.class b/src/main/resources/org/python/core/PyProperty$fset_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..44ee1d320a45c66ffc25ca9dfd815fd1c6bc7a20 Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$fset_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyProperty$property___delete___exposer.class b/src/main/resources/org/python/core/PyProperty$property___delete___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e8c527f6a5f626ed1c009788718914aedcdfc536 Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$property___delete___exposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty$property___get___exposer.class b/src/main/resources/org/python/core/PyProperty$property___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ac9aa38494074b76e8f04f6e3676c665f0b1fb7a Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$property___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty$property___init___exposer.class b/src/main/resources/org/python/core/PyProperty$property___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a429aa16b715597d586153f57807c4de28b6ae8e Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$property___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty$property___set___exposer.class b/src/main/resources/org/python/core/PyProperty$property___set___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..03ef6ccd00c0669fd2814e4701d1e5d9040f5004 Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$property___set___exposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty$property_deleter_exposer.class b/src/main/resources/org/python/core/PyProperty$property_deleter_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c04da5ac35bf3b8eedab1652befbe6f28d684016 Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$property_deleter_exposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty$property_getter_exposer.class b/src/main/resources/org/python/core/PyProperty$property_getter_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5b1a31bea33752557578448595748615fedf6f88 Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$property_getter_exposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty$property_setter_exposer.class b/src/main/resources/org/python/core/PyProperty$property_setter_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..74f40823a4a922f12bebb6e7a61e93ee5077137a Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty$property_setter_exposer.class differ diff --git a/src/main/resources/org/python/core/PyProperty.class b/src/main/resources/org/python/core/PyProperty.class new file mode 100644 index 0000000000000000000000000000000000000000..e47ff456aaf83c52344fa14458b0933cf264f8d2 Binary files /dev/null and b/src/main/resources/org/python/core/PyProperty.class differ diff --git a/src/main/resources/org/python/core/PyPropertyDerived.class b/src/main/resources/org/python/core/PyPropertyDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..a4377d3a4774a5fbf9b37ffd27f421e4e322ff5b Binary files /dev/null and b/src/main/resources/org/python/core/PyPropertyDerived.class differ diff --git a/src/main/resources/org/python/core/PyProxy.class b/src/main/resources/org/python/core/PyProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..ca78a6bd446bf124cfab87f88c7e340afa8cf472 Binary files /dev/null and b/src/main/resources/org/python/core/PyProxy.class differ diff --git a/src/main/resources/org/python/core/PyReflectedConstructor.class b/src/main/resources/org/python/core/PyReflectedConstructor.class new file mode 100644 index 0000000000000000000000000000000000000000..68e946040fd9e1dc80521661e23ea782d4f565a0 Binary files /dev/null and b/src/main/resources/org/python/core/PyReflectedConstructor.class differ diff --git a/src/main/resources/org/python/core/PyReflectedField.class b/src/main/resources/org/python/core/PyReflectedField.class new file mode 100644 index 0000000000000000000000000000000000000000..10c678df570d74b7ff63254e1b362b82a4d4fb62 Binary files /dev/null and b/src/main/resources/org/python/core/PyReflectedField.class differ diff --git a/src/main/resources/org/python/core/PyReflectedFunction.class b/src/main/resources/org/python/core/PyReflectedFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..1fe572d282517ec10bfdf1b6643e2f42d6f66173 Binary files /dev/null and b/src/main/resources/org/python/core/PyReflectedFunction.class differ diff --git a/src/main/resources/org/python/core/PyReversedIterator.class b/src/main/resources/org/python/core/PyReversedIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..a739017c33096f142beccea2cf696de432e425a3 Binary files /dev/null and b/src/main/resources/org/python/core/PyReversedIterator.class differ diff --git a/src/main/resources/org/python/core/PyRunnable.class b/src/main/resources/org/python/core/PyRunnable.class new file mode 100644 index 0000000000000000000000000000000000000000..108f0fc8e02191ee42dca083b79e82ed81dd8566 Binary files /dev/null and b/src/main/resources/org/python/core/PyRunnable.class differ diff --git a/src/main/resources/org/python/core/PyRunnableBootstrap$1.class b/src/main/resources/org/python/core/PyRunnableBootstrap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0a45180c8738f1053875a90741b604349dcf09d2 Binary files /dev/null and b/src/main/resources/org/python/core/PyRunnableBootstrap$1.class differ diff --git a/src/main/resources/org/python/core/PyRunnableBootstrap.class b/src/main/resources/org/python/core/PyRunnableBootstrap.class new file mode 100644 index 0000000000000000000000000000000000000000..521f8bb2f1b1b5a4833941513e947e71f2c662f2 Binary files /dev/null and b/src/main/resources/org/python/core/PyRunnableBootstrap.class differ diff --git a/src/main/resources/org/python/core/PySequence$DefaultIndexDelegate.class b/src/main/resources/org/python/core/PySequence$DefaultIndexDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..5ba20866bd2f9ba81a9b65e4fd434e01111defe6 Binary files /dev/null and b/src/main/resources/org/python/core/PySequence$DefaultIndexDelegate.class differ diff --git a/src/main/resources/org/python/core/PySequence.class b/src/main/resources/org/python/core/PySequence.class new file mode 100644 index 0000000000000000000000000000000000000000..44ac96bca75c97d43fc4f60e36f6924d70b6a686 Binary files /dev/null and b/src/main/resources/org/python/core/PySequence.class differ diff --git a/src/main/resources/org/python/core/PySequenceIter.class b/src/main/resources/org/python/core/PySequenceIter.class new file mode 100644 index 0000000000000000000000000000000000000000..5dd4a5a5ad20d9ac0bc4a1ed5ed0de53e1de621b Binary files /dev/null and b/src/main/resources/org/python/core/PySequenceIter.class differ diff --git a/src/main/resources/org/python/core/PySequenceList.class b/src/main/resources/org/python/core/PySequenceList.class new file mode 100644 index 0000000000000000000000000000000000000000..7cd293a22497f19974efbce88e87c588cb5905df Binary files /dev/null and b/src/main/resources/org/python/core/PySequenceList.class differ diff --git a/src/main/resources/org/python/core/PySet$PyExposer.class b/src/main/resources/org/python/core/PySet$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a237bb2c76ea51cc98e08b4786d4fe5264114e1f Binary files /dev/null and b/src/main/resources/org/python/core/PySet$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PySet$exposed___new__.class b/src/main/resources/org/python/core/PySet$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..e1e1f508b2837e831333e44dd5a12f4242a84915 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PySet$set___and___exposer.class b/src/main/resources/org/python/core/PySet$set___and___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c790c41cb534500c8f9dcf5c8c251156ee2bc4c3 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___and___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___cmp___exposer.class b/src/main/resources/org/python/core/PySet$set___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5f7a511f312bf1675a98f114bdf3c0cdfb1c9b87 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___contains___exposer.class b/src/main/resources/org/python/core/PySet$set___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..790ca9fb3623537de559c74f0152094f6141542b Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___eq___exposer.class b/src/main/resources/org/python/core/PySet$set___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..be612ea0a1310105ee07517e47bd6eb69c10ceb5 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___ge___exposer.class b/src/main/resources/org/python/core/PySet$set___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b2caf164e752c7e435044d6fe6c2f7d24a0134c4 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___gt___exposer.class b/src/main/resources/org/python/core/PySet$set___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8f43cf1a3a9680a885a909521f301877f5758d0e Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___hash___exposer.class b/src/main/resources/org/python/core/PySet$set___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f5c10fd7d757db48991d9332ebe6a38229e585c0 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___iand___exposer.class b/src/main/resources/org/python/core/PySet$set___iand___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..55af91da9ab4840206a0e65c105267231f5cc489 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___iand___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___init___exposer.class b/src/main/resources/org/python/core/PySet$set___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1f9a5280f2012dab31e5cef224df8a3fb16f5475 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___ior___exposer.class b/src/main/resources/org/python/core/PySet$set___ior___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb20139817c3d8b17a81344655f95ccfe000d3aa Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___ior___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___isub___exposer.class b/src/main/resources/org/python/core/PySet$set___isub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..331b5efed8843552e92b5795cd92adc65629e9f5 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___isub___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___iter___exposer.class b/src/main/resources/org/python/core/PySet$set___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8fe1f443202beeae40b461f946e43aeecf73df4f Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___ixor___exposer.class b/src/main/resources/org/python/core/PySet$set___ixor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2c8ac3fc5ffac711e4727a1feb01f3da8cf75c5b Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___ixor___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___le___exposer.class b/src/main/resources/org/python/core/PySet$set___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cb9ce63e9f67347460673d0bfefe09551e3daeba Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___len___exposer.class b/src/main/resources/org/python/core/PySet$set___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d14c1285538e1615e55e5aed0e00aef6dc7eb7a5 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___lt___exposer.class b/src/main/resources/org/python/core/PySet$set___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..495f1ede44a704bff62b6a645bb47c3397257203 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___ne___exposer.class b/src/main/resources/org/python/core/PySet$set___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..61ff286e7a575554ecc1e4cb6a3bf5af32f0a43c Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___or___exposer.class b/src/main/resources/org/python/core/PySet$set___or___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..77e7f638e794ef5980d1ce028ae714b0882c51e2 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___or___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___reduce___exposer.class b/src/main/resources/org/python/core/PySet$set___reduce___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d4ed95e766a852d2a500f7db4590cdb0c6e94296 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___reduce___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___sub___exposer.class b/src/main/resources/org/python/core/PySet$set___sub___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cf7dae5d5036378764e24c8a9663e4e7eb7d37dc Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___sub___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set___xor___exposer.class b/src/main/resources/org/python/core/PySet$set___xor___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3cb20c9cc25e6f63bbf895a0cd2d962528fd6964 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set___xor___exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_add_exposer.class b/src/main/resources/org/python/core/PySet$set_add_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..12df5faa16a2d9f6da17d045e6baab4725bdc7ce Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_add_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_clear_exposer.class b/src/main/resources/org/python/core/PySet$set_clear_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7b8ef33e131846b5ba5973f75d09ac92cdcd3e4a Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_clear_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_copy_exposer.class b/src/main/resources/org/python/core/PySet$set_copy_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..949d202d350047b61db66adab8d043fdb64773d0 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_copy_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_difference_exposer.class b/src/main/resources/org/python/core/PySet$set_difference_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e9290bd7e4102e0f01327bd5ec43f0a988fcc7b4 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_difference_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_difference_update_exposer.class b/src/main/resources/org/python/core/PySet$set_difference_update_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bc6afb9027f0455b50824df204880e4e973fc3cd Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_difference_update_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_discard_exposer.class b/src/main/resources/org/python/core/PySet$set_discard_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f26d664b755bd9e49428ebedd959372f6cdd9b8b Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_discard_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_intersection_exposer.class b/src/main/resources/org/python/core/PySet$set_intersection_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f951d414fdc536b161367d5cdcbc86795a67b699 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_intersection_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_intersection_update_exposer.class b/src/main/resources/org/python/core/PySet$set_intersection_update_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ae7e43424f79488abd11e832b1bf03e3b83ca90f Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_intersection_update_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_isdisjoint_exposer.class b/src/main/resources/org/python/core/PySet$set_isdisjoint_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..605b2e9b4684248a011d335b17c5ff151acefde8 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_isdisjoint_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_issubset_exposer.class b/src/main/resources/org/python/core/PySet$set_issubset_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8f564ff2c31161c41407f6eb30d1766bff114ca5 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_issubset_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_issuperset_exposer.class b/src/main/resources/org/python/core/PySet$set_issuperset_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0115cfe14cc3900c8ea31ac0214d318962f8cfe3 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_issuperset_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_pop_exposer.class b/src/main/resources/org/python/core/PySet$set_pop_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4d664fb26459c33256b4cf0a3c6da16ec5d16939 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_pop_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_remove_exposer.class b/src/main/resources/org/python/core/PySet$set_remove_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fe71d6ee3742d294ac5e2d50e5ed880ca4427e0b Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_remove_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_symmetric_difference_exposer.class b/src/main/resources/org/python/core/PySet$set_symmetric_difference_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..61f91d17ee88c88d6ea80da15e022cbf349c33ef Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_symmetric_difference_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_symmetric_difference_update_exposer.class b/src/main/resources/org/python/core/PySet$set_symmetric_difference_update_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4c902b9bf7c3eb4ed3c9ad48eafac1a7c266014b Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_symmetric_difference_update_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_toString_exposer.class b/src/main/resources/org/python/core/PySet$set_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a3d1b745d9359b7fd11ccce2642270ab4a425493 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_union_exposer.class b/src/main/resources/org/python/core/PySet$set_union_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..19ad82a571063bb5531c92c72f21958d147718fd Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_union_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet$set_update_exposer.class b/src/main/resources/org/python/core/PySet$set_update_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a26cce57f361edc5c9561e4ef96ba62df5e68527 Binary files /dev/null and b/src/main/resources/org/python/core/PySet$set_update_exposer.class differ diff --git a/src/main/resources/org/python/core/PySet.class b/src/main/resources/org/python/core/PySet.class new file mode 100644 index 0000000000000000000000000000000000000000..525501f743f085ffa396e5696901b51991b61038 Binary files /dev/null and b/src/main/resources/org/python/core/PySet.class differ diff --git a/src/main/resources/org/python/core/PySetDerived.class b/src/main/resources/org/python/core/PySetDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..27fd4ceb893a2d1312813608b6c620bf970a3995 Binary files /dev/null and b/src/main/resources/org/python/core/PySetDerived.class differ diff --git a/src/main/resources/org/python/core/PySingleton.class b/src/main/resources/org/python/core/PySingleton.class new file mode 100644 index 0000000000000000000000000000000000000000..f0307d10a9afb1c30bc271b75e68bc746493c316 Binary files /dev/null and b/src/main/resources/org/python/core/PySingleton.class differ diff --git a/src/main/resources/org/python/core/PySlice$PyExposer.class b/src/main/resources/org/python/core/PySlice$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cfd94b20388e9220ffd7b75ab33124e36964dfb8 Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PySlice$exposed___new__.class b/src/main/resources/org/python/core/PySlice$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..4fc2090ec217031b7a628513d120ab300c1f3eef Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PySlice$slice___hash___exposer.class b/src/main/resources/org/python/core/PySlice$slice___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cff59ff6775b2034980613f42f64fb1f37c46f00 Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$slice___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PySlice$slice_indices_exposer.class b/src/main/resources/org/python/core/PySlice$slice_indices_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5fb3e440c5503b6329e8b35fe31e5f29cdcbbe48 Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$slice_indices_exposer.class differ diff --git a/src/main/resources/org/python/core/PySlice$slice_toString_exposer.class b/src/main/resources/org/python/core/PySlice$slice_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ab8e5948d06c1eeb7f0c97003cbcd1356bceebdd Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$slice_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PySlice$start_descriptor.class b/src/main/resources/org/python/core/PySlice$start_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..74a29d75f027ad15efda1910960e12a75b1e2183 Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$start_descriptor.class differ diff --git a/src/main/resources/org/python/core/PySlice$step_descriptor.class b/src/main/resources/org/python/core/PySlice$step_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3ba8430d17ca993d733d5e8306329924548e8f26 Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$step_descriptor.class differ diff --git a/src/main/resources/org/python/core/PySlice$stop_descriptor.class b/src/main/resources/org/python/core/PySlice$stop_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c429deffe519c33e5f229b01045d1740e3e17917 Binary files /dev/null and b/src/main/resources/org/python/core/PySlice$stop_descriptor.class differ diff --git a/src/main/resources/org/python/core/PySlice.class b/src/main/resources/org/python/core/PySlice.class new file mode 100644 index 0000000000000000000000000000000000000000..542d06bf1802a7f8c059e4e8d4f091d74c51b942 Binary files /dev/null and b/src/main/resources/org/python/core/PySlice.class differ diff --git a/src/main/resources/org/python/core/PySlot$PyExposer.class b/src/main/resources/org/python/core/PySlot$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..aa6f6ae406fa29f3dec5e5b4f9b05058220f71c5 Binary files /dev/null and b/src/main/resources/org/python/core/PySlot$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PySlot$__name___descriptor.class b/src/main/resources/org/python/core/PySlot$__name___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..761b0394ac8f37c98abbdf93235857820de5ce39 Binary files /dev/null and b/src/main/resources/org/python/core/PySlot$__name___descriptor.class differ diff --git a/src/main/resources/org/python/core/PySlot$__objclass___descriptor.class b/src/main/resources/org/python/core/PySlot$__objclass___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..fb1a93fa2ccf57e1bf74b4514b841fb4613e7db1 Binary files /dev/null and b/src/main/resources/org/python/core/PySlot$__objclass___descriptor.class differ diff --git a/src/main/resources/org/python/core/PySlot$member_descriptor___delete___exposer.class b/src/main/resources/org/python/core/PySlot$member_descriptor___delete___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b309778bab1e5609beedc44b038cccc0cb1c259d Binary files /dev/null and b/src/main/resources/org/python/core/PySlot$member_descriptor___delete___exposer.class differ diff --git a/src/main/resources/org/python/core/PySlot$member_descriptor___get___exposer.class b/src/main/resources/org/python/core/PySlot$member_descriptor___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5c586a635f70a9b82ba84d34f39cefe1d569e8d0 Binary files /dev/null and b/src/main/resources/org/python/core/PySlot$member_descriptor___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PySlot$member_descriptor___set___exposer.class b/src/main/resources/org/python/core/PySlot$member_descriptor___set___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..99fbad30fb87ed4034dc9359a38e6dc433f99fea Binary files /dev/null and b/src/main/resources/org/python/core/PySlot$member_descriptor___set___exposer.class differ diff --git a/src/main/resources/org/python/core/PySlot.class b/src/main/resources/org/python/core/PySlot.class new file mode 100644 index 0000000000000000000000000000000000000000..272db9135116458075f2c81bd5ad3b52e5a38cbf Binary files /dev/null and b/src/main/resources/org/python/core/PySlot.class differ diff --git a/src/main/resources/org/python/core/PyStaticMethod$PyExposer.class b/src/main/resources/org/python/core/PyStaticMethod$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2bfb9e3091d0aed419c3c4a03c71bdafa603d3d5 Binary files /dev/null and b/src/main/resources/org/python/core/PyStaticMethod$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyStaticMethod$exposed___new__.class b/src/main/resources/org/python/core/PyStaticMethod$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..2226db93b611a67a18150c7e2efa765d00790681 Binary files /dev/null and b/src/main/resources/org/python/core/PyStaticMethod$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyStaticMethod$staticmethod___get___exposer.class b/src/main/resources/org/python/core/PyStaticMethod$staticmethod___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..042c5c6248a965ec52c21c1394dbd5cb01d27485 Binary files /dev/null and b/src/main/resources/org/python/core/PyStaticMethod$staticmethod___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStaticMethod.class b/src/main/resources/org/python/core/PyStaticMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..97a91a615e5ec960a258e227a3414d6a2d39cd1f Binary files /dev/null and b/src/main/resources/org/python/core/PyStaticMethod.class differ diff --git a/src/main/resources/org/python/core/PyString$PyExposer.class b/src/main/resources/org/python/core/PyString$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..47101bec74d5faae341dfc9602e5ce3e31e9708e Binary files /dev/null and b/src/main/resources/org/python/core/PyString$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyString$exposed___new__.class b/src/main/resources/org/python/core/PyString$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..6df69fdcbd92f16f2a45b55f7017879f3d97bb13 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyString$str___add___exposer.class b/src/main/resources/org/python/core/PyString$str___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..762ba3bd53e52b6e62fb6368ca7a93539a9131b7 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___cmp___exposer.class b/src/main/resources/org/python/core/PyString$str___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8771638fa7f24dab70c5f780db436f1789dfa857 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___contains___exposer.class b/src/main/resources/org/python/core/PyString$str___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..63edb8b3be542b9098f3afa9c74679b62b4edfc2 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___eq___exposer.class b/src/main/resources/org/python/core/PyString$str___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d46680ae8953110943f33143527d93d4aac17efe Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___format___exposer.class b/src/main/resources/org/python/core/PyString$str___format___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a901988f1a39f1c055f438f5fb68b1ebffa0f355 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___format___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___ge___exposer.class b/src/main/resources/org/python/core/PyString$str___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c1c74701b41b0e6913f3b385816f75849867879e Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___getitem___exposer.class b/src/main/resources/org/python/core/PyString$str___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..47aafbbe49bb961333364e98c4b02cb77a1373e6 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___getnewargs___exposer.class b/src/main/resources/org/python/core/PyString$str___getnewargs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7d541b09c1368a159c9a3e2f1a02094ab80c7146 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___getnewargs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___getslice___exposer.class b/src/main/resources/org/python/core/PyString$str___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..149677cdb79df80ffe6f96fbe7c7aa09e8c407a6 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___gt___exposer.class b/src/main/resources/org/python/core/PyString$str___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d935cd93d3198eae5fb5cdf1809388d3852c5773 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___hash___exposer.class b/src/main/resources/org/python/core/PyString$str___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..247bcb2c8c9b89741f85f5450732f75bd4b607bd Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___le___exposer.class b/src/main/resources/org/python/core/PyString$str___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2867e7ebda3fed4e474bfb7a4b0da8cfcc9a82be Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___len___exposer.class b/src/main/resources/org/python/core/PyString$str___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6ad5a2ecbd36236068d0ffd3646bf52c5120e037 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___lt___exposer.class b/src/main/resources/org/python/core/PyString$str___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..457ad35c1c68b9988e1ec45e9f270e06d822d887 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___mod___exposer.class b/src/main/resources/org/python/core/PyString$str___mod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e466261199944038a2479eb421855782629fdb5f Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___mod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___mul___exposer.class b/src/main/resources/org/python/core/PyString$str___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..db0e1bf4b40e77055d50c57bd079dba835755370 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___ne___exposer.class b/src/main/resources/org/python/core/PyString$str___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c633eb586cbeb29c175aa15a1111f3cc999f40c5 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___repr___exposer.class b/src/main/resources/org/python/core/PyString$str___repr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ff63d24f99f1ba14d49c103203b581605e6fdd24 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___repr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___rmul___exposer.class b/src/main/resources/org/python/core/PyString$str___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0098326026748a091ed6f68a52799eedaf1fc921 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str___str___exposer.class b/src/main/resources/org/python/core/PyString$str___str___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0d2d0e3a4db5ef60d111952fbf1715c93dc6ced6 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str___str___exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str__formatter_field_name_split_exposer.class b/src/main/resources/org/python/core/PyString$str__formatter_field_name_split_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7251e325636febcccc4aed75f7369bbda8777a45 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str__formatter_field_name_split_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str__formatter_parser_exposer.class b/src/main/resources/org/python/core/PyString$str__formatter_parser_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c4b2aea10b3ba98e0a42d4d9152302f50ca3e965 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str__formatter_parser_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_capitalize_exposer.class b/src/main/resources/org/python/core/PyString$str_capitalize_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9da2a8a4c600e0b1bd36b113a1ae0bed22f3847d Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_capitalize_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_center_exposer.class b/src/main/resources/org/python/core/PyString$str_center_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d0de97d3c9a5b77549bb2b9a9eba8759e8a34892 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_center_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_count_exposer.class b/src/main/resources/org/python/core/PyString$str_count_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5ffa5baf10f123e357af9452eb98f9817b53c896 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_count_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_decode_exposer.class b/src/main/resources/org/python/core/PyString$str_decode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..92a40e1a918377771b0f227f0f9e36e0b8742015 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_decode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_encode_exposer.class b/src/main/resources/org/python/core/PyString$str_encode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..082bdabb9bf2cc076992fdb3ae18600effa3a17f Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_encode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_endswith_exposer.class b/src/main/resources/org/python/core/PyString$str_endswith_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ee007f234cd476591a92a06b50fd3d54ca85058e Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_endswith_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_expandtabs_exposer.class b/src/main/resources/org/python/core/PyString$str_expandtabs_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..23547d22ff6e79e311f5e7797d65c009b651625b Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_expandtabs_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_find_exposer.class b/src/main/resources/org/python/core/PyString$str_find_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5abc61bfd26cee01d4dca3c74db5cab030c43ea8 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_find_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_format_exposer.class b/src/main/resources/org/python/core/PyString$str_format_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..133364534f7cef7192457f546b400f6a1ef98cdc Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_format_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_index_exposer.class b/src/main/resources/org/python/core/PyString$str_index_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..20d42548ff443796d1338501bd9a54c9ca03d613 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_index_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isalnum_exposer.class b/src/main/resources/org/python/core/PyString$str_isalnum_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3441f4df99bcece0b479ba3df5911e906f443851 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isalnum_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isalpha_exposer.class b/src/main/resources/org/python/core/PyString$str_isalpha_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..be7983ad443e26e139b8f6863095c98fb982fd30 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isalpha_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isdecimal_exposer.class b/src/main/resources/org/python/core/PyString$str_isdecimal_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..20123f79e0f57c6aeb1ea7959686e0fba5b64a42 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isdecimal_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isdigit_exposer.class b/src/main/resources/org/python/core/PyString$str_isdigit_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..0a2fc8918297def137bc2be11f3da271b44a7a59 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isdigit_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_islower_exposer.class b/src/main/resources/org/python/core/PyString$str_islower_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d58af08e35ad2226a0b636622a24fbaf7fc6cd26 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_islower_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isnumeric_exposer.class b/src/main/resources/org/python/core/PyString$str_isnumeric_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..12bc2b071b916df07a67c7ee2185b3bf74ba551d Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isnumeric_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isspace_exposer.class b/src/main/resources/org/python/core/PyString$str_isspace_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f9fd6d58833bd3511cee7eafac256ae96e8cc119 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isspace_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_istitle_exposer.class b/src/main/resources/org/python/core/PyString$str_istitle_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3d13a027b1a980c5c1a552873a51cb4cc55ac047 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_istitle_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isunicode_exposer.class b/src/main/resources/org/python/core/PyString$str_isunicode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fd8c62fa77e188f4745de853d5d014a081305353 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isunicode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_isupper_exposer.class b/src/main/resources/org/python/core/PyString$str_isupper_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..538b9dce5f5797290d395ced0aaaf4fda70f59f7 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_isupper_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_join_exposer.class b/src/main/resources/org/python/core/PyString$str_join_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3a5d6e252340972352813337d191bcc2f98ea463 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_join_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_ljust_exposer.class b/src/main/resources/org/python/core/PyString$str_ljust_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cd536fbd8b4ead2f58ea1251843b02ec4e248739 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_ljust_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_lower_exposer.class b/src/main/resources/org/python/core/PyString$str_lower_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4b7c03a3e681ac6f68fbe53e0a418993ed6f83f1 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_lower_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_lstrip_exposer.class b/src/main/resources/org/python/core/PyString$str_lstrip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d0f4e43196d4072313ebea39a0a8fc1757e762d1 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_lstrip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_partition_exposer.class b/src/main/resources/org/python/core/PyString$str_partition_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..74ffc80ad02324de50ef64b2cf74c69b67964f36 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_partition_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_replace_exposer.class b/src/main/resources/org/python/core/PyString$str_replace_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3844522d81f9fbfafe312385a207abc40cd07482 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_replace_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_rfind_exposer.class b/src/main/resources/org/python/core/PyString$str_rfind_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5453742ed3a79ccaf282dfb28f3df94e34242e1f Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_rfind_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_rindex_exposer.class b/src/main/resources/org/python/core/PyString$str_rindex_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ff6375d79809b60671d5a826da8d3af96c942ba6 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_rindex_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_rjust_exposer.class b/src/main/resources/org/python/core/PyString$str_rjust_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4c516aa5d0f110ccab40c47713432e1ba1f2a235 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_rjust_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_rpartition_exposer.class b/src/main/resources/org/python/core/PyString$str_rpartition_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9ed3c52effed3d925f671cce4e0905eb342f6e51 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_rpartition_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_rsplit_exposer.class b/src/main/resources/org/python/core/PyString$str_rsplit_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9710bd4291bc4a25e711bb0c4e05f1183ebeda32 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_rsplit_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_rstrip_exposer.class b/src/main/resources/org/python/core/PyString$str_rstrip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..25de465b31126f7de1a585de854a7a96471b91a5 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_rstrip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_split_exposer.class b/src/main/resources/org/python/core/PyString$str_split_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..35c7fe618bd3473d8526c1867b4e990295d5aae3 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_split_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_splitlines_exposer.class b/src/main/resources/org/python/core/PyString$str_splitlines_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6294218e486f3378fff3051b5467c4311ad3029f Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_splitlines_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_startswith_exposer.class b/src/main/resources/org/python/core/PyString$str_startswith_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..73e44790083caea2c16f62df705f59c8893edb52 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_startswith_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_strip_exposer.class b/src/main/resources/org/python/core/PyString$str_strip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e9b11f3087634f5f2119a99006e38c2a1a2940bf Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_strip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_swapcase_exposer.class b/src/main/resources/org/python/core/PyString$str_swapcase_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d3449cf027dc0724ec613ff33facdf0fd26bc456 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_swapcase_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_title_exposer.class b/src/main/resources/org/python/core/PyString$str_title_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..807be4291893fae5d67efaf2a9fc92b936a081d0 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_title_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_translate_exposer.class b/src/main/resources/org/python/core/PyString$str_translate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c722dbcbc3c97e94eab36c75d9b53bdd22ff05df Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_translate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_upper_exposer.class b/src/main/resources/org/python/core/PyString$str_upper_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7231d444cdb36eb63f28d81d4ee13a0bfa66b86a Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_upper_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString$str_zfill_exposer.class b/src/main/resources/org/python/core/PyString$str_zfill_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5038b04e759c8ee48c016573ba5e7ac9e4fa1ce5 Binary files /dev/null and b/src/main/resources/org/python/core/PyString$str_zfill_exposer.class differ diff --git a/src/main/resources/org/python/core/PyString.class b/src/main/resources/org/python/core/PyString.class new file mode 100644 index 0000000000000000000000000000000000000000..f7a4e7371c193102b22548541414ee05853c4a58 Binary files /dev/null and b/src/main/resources/org/python/core/PyString.class differ diff --git a/src/main/resources/org/python/core/PyStringDerived.class b/src/main/resources/org/python/core/PyStringDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..3c10ad563d3afe574830050042505cf7c63f95ea Binary files /dev/null and b/src/main/resources/org/python/core/PyStringDerived.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$ItemsIter.class b/src/main/resources/org/python/core/PyStringMap$ItemsIter.class new file mode 100644 index 0000000000000000000000000000000000000000..e4249e4257b01067458e48d414cd7edb2ceeb2f7 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$ItemsIter.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$KeysIter.class b/src/main/resources/org/python/core/PyStringMap$KeysIter.class new file mode 100644 index 0000000000000000000000000000000000000000..4162d7b29b9f2e0e9896a2306333df797cc2443e Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$KeysIter.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$PyExposer.class b/src/main/resources/org/python/core/PyStringMap$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f676842c709ebcd6edec6fb84102260a28b2bb74 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$StringMapIter.class b/src/main/resources/org/python/core/PyStringMap$StringMapIter.class new file mode 100644 index 0000000000000000000000000000000000000000..02be6d003cf20bc2f0367cd10a4ed530296ed24e Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$StringMapIter.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$ValuesIter.class b/src/main/resources/org/python/core/PyStringMap$ValuesIter.class new file mode 100644 index 0000000000000000000000000000000000000000..c8f45704a6721b1303b138815579b9254c49d597 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$ValuesIter.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$exposed___new__.class b/src/main/resources/org/python/core/PyStringMap$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..725e1b7e99431b5aac5bbbcb123d4e37f4e6d337 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___cmp___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..27685abbb03c01a5c4c3115239dfeb7d3904065a Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___contains___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b21ededd11953c94b4cbad541049a0d0554bcd28 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___delitem___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___delitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..948639a96bde8c9b8ec9327f94e73a127bf7bb61 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___delitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___getitem___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ff577f2b50da6e51d45a3ada5581c8182a541618 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___hash___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6fd0f41b9cb4b26386765f35e54fb5f445171605 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___iter___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..239a64c97a55558132b68f6bb730010a6ae9b500 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___len___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f58a9a975d566756a838563e237ef20e5bb2fa88 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap___setitem___exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap___setitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..45231e681d51e6510e0a9c54f2dc5e3a88a88a93 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap___setitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_clear_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_clear_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ea04cf4c91644478ba5c342194562c869c5f0ee1 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_clear_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_copy_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_copy_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..15ba761d8fc45e120222097de7d71bf8dc6ba3b4 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_copy_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_get_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_get_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..be02ea3473d52e928c3241ed69732c7e935b76ce Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_get_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_has_key_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_has_key_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9ee81802fe5214baf871d8e03da7ecc22ccc1c7a Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_has_key_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_items_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_items_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e88b794d324645545f3b49f3707ab595ae9d668a Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_items_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_iteritems_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_iteritems_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..987904f4a2003e1560154a8fc025c676e941f455 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_iteritems_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_iterkeys_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_iterkeys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..98ab7265352093240787318f2ba23f8530861bad Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_iterkeys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_itervalues_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_itervalues_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..97715b8ba8c66c2a0929e8cbe7dcb48b507041e3 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_itervalues_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_keys_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_keys_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..25b4801b40655d038e2c12d79301ffdea9f28915 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_keys_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_pop_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_pop_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a559066d0608eb26f856081a973cca12971b9d3f Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_pop_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_popitem_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_popitem_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..48df05e5a7f6e928536104484385e93d5e953de2 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_popitem_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_setdefault_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_setdefault_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5db15700e26e7462bcea68d6e39887c921d88c58 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_setdefault_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_toString_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2955b23c49128f6e68b9cdf2f865225fd7b9c11a Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_update_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_update_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e967ffc35bef6d6fb9e3506720482004e10d8790 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_update_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap$stringmap_values_exposer.class b/src/main/resources/org/python/core/PyStringMap$stringmap_values_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c9f3eeb0c187bb8682b5965df93a9836e5dfcaf5 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap$stringmap_values_exposer.class differ diff --git a/src/main/resources/org/python/core/PyStringMap.class b/src/main/resources/org/python/core/PyStringMap.class new file mode 100644 index 0000000000000000000000000000000000000000..a9557908a733f3f35d2f6f13a8526c17c9119d31 Binary files /dev/null and b/src/main/resources/org/python/core/PyStringMap.class differ diff --git a/src/main/resources/org/python/core/PySuper$PyExposer.class b/src/main/resources/org/python/core/PySuper$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4addf72f10bd03bc9d43851d6ca36c989085a003 Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PySuper$__self___descriptor.class b/src/main/resources/org/python/core/PySuper$__self___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1afa149bce119d26390b776d592fc23452dd1742 Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$__self___descriptor.class differ diff --git a/src/main/resources/org/python/core/PySuper$__self_class___descriptor.class b/src/main/resources/org/python/core/PySuper$__self_class___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..f0cdac85b1cd2db5a2e85d9b24c383f05ca5e13f Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$__self_class___descriptor.class differ diff --git a/src/main/resources/org/python/core/PySuper$__thisclass___descriptor.class b/src/main/resources/org/python/core/PySuper$__thisclass___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..1dca562271ba84a7fe68bb8d146debf93d946f29 Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$__thisclass___descriptor.class differ diff --git a/src/main/resources/org/python/core/PySuper$exposed___new__.class b/src/main/resources/org/python/core/PySuper$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..4eaaf5d95baff33c416648c9fcf66927e9e94d02 Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PySuper$super___get___exposer.class b/src/main/resources/org/python/core/PySuper$super___get___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..35c8361071a616d2b7f60026a87463393eb55491 Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$super___get___exposer.class differ diff --git a/src/main/resources/org/python/core/PySuper$super___getattribute___exposer.class b/src/main/resources/org/python/core/PySuper$super___getattribute___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..78b187369d84b91069ca2709865502f7aa42eb45 Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$super___getattribute___exposer.class differ diff --git a/src/main/resources/org/python/core/PySuper$super___init___exposer.class b/src/main/resources/org/python/core/PySuper$super___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8fdfd2ea90bbd23c392faaa60453096079e5ad2a Binary files /dev/null and b/src/main/resources/org/python/core/PySuper$super___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PySuper.class b/src/main/resources/org/python/core/PySuper.class new file mode 100644 index 0000000000000000000000000000000000000000..72802f0d9fcdbc535e2c27dbdbbe519aa7e53ca8 Binary files /dev/null and b/src/main/resources/org/python/core/PySuper.class differ diff --git a/src/main/resources/org/python/core/PySuperDerived.class b/src/main/resources/org/python/core/PySuperDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..eeda402c9034c41214fed35f4284b337a7553b82 Binary files /dev/null and b/src/main/resources/org/python/core/PySuperDerived.class differ diff --git a/src/main/resources/org/python/core/PySyntaxError.class b/src/main/resources/org/python/core/PySyntaxError.class new file mode 100644 index 0000000000000000000000000000000000000000..5b653e039669d52ed233cb50dbf2807c18a30de5 Binary files /dev/null and b/src/main/resources/org/python/core/PySyntaxError.class differ diff --git a/src/main/resources/org/python/core/PySystemState$1.class b/src/main/resources/org/python/core/PySystemState$1.class new file mode 100644 index 0000000000000000000000000000000000000000..75cbfcfc69265b3e014401cd98e6163100ec28d9 Binary files /dev/null and b/src/main/resources/org/python/core/PySystemState$1.class differ diff --git a/src/main/resources/org/python/core/PySystemState$DefaultBuiltinsHolder.class b/src/main/resources/org/python/core/PySystemState$DefaultBuiltinsHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..ff84bc9ace42fa4c76affbb2b6f24b7bf532dcfc Binary files /dev/null and b/src/main/resources/org/python/core/PySystemState$DefaultBuiltinsHolder.class differ diff --git a/src/main/resources/org/python/core/PySystemState$PySystemStateCloser$ShutdownCloser.class b/src/main/resources/org/python/core/PySystemState$PySystemStateCloser$ShutdownCloser.class new file mode 100644 index 0000000000000000000000000000000000000000..eadebf46fea43486b9cfa87141f0baac3641aac7 Binary files /dev/null and b/src/main/resources/org/python/core/PySystemState$PySystemStateCloser$ShutdownCloser.class differ diff --git a/src/main/resources/org/python/core/PySystemState$PySystemStateCloser.class b/src/main/resources/org/python/core/PySystemState$PySystemStateCloser.class new file mode 100644 index 0000000000000000000000000000000000000000..ffba5fba18245574c1141128fd1a2158548d5d80 Binary files /dev/null and b/src/main/resources/org/python/core/PySystemState$PySystemStateCloser.class differ diff --git a/src/main/resources/org/python/core/PySystemState.class b/src/main/resources/org/python/core/PySystemState.class new file mode 100644 index 0000000000000000000000000000000000000000..9a03bd46942da805ca65b7b3d1ee41fbf0d80977 Binary files /dev/null and b/src/main/resources/org/python/core/PySystemState.class differ diff --git a/src/main/resources/org/python/core/PySystemStateFunctions.class b/src/main/resources/org/python/core/PySystemStateFunctions.class new file mode 100644 index 0000000000000000000000000000000000000000..0f8816b9261e2fc7841831b7e0789de6fb2d4a89 Binary files /dev/null and b/src/main/resources/org/python/core/PySystemStateFunctions.class differ diff --git a/src/main/resources/org/python/core/PySystemStateTest$TestJBossURLStreamHandler.class b/src/main/resources/org/python/core/PySystemStateTest$TestJBossURLStreamHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..7a8a50858ee2af3c5f9ab78475a35140f190a3ee Binary files /dev/null and b/src/main/resources/org/python/core/PySystemStateTest$TestJBossURLStreamHandler.class differ diff --git a/src/main/resources/org/python/core/PySystemStateTest.class b/src/main/resources/org/python/core/PySystemStateTest.class new file mode 100644 index 0000000000000000000000000000000000000000..a9279382ed803c409945da3989b28c77126d2989 Binary files /dev/null and b/src/main/resources/org/python/core/PySystemStateTest.class differ diff --git a/src/main/resources/org/python/core/PySystemState_registry_Test.class b/src/main/resources/org/python/core/PySystemState_registry_Test.class new file mode 100644 index 0000000000000000000000000000000000000000..ea5b27b7062d1167e43b0d57c44c3698645da082 Binary files /dev/null and b/src/main/resources/org/python/core/PySystemState_registry_Test.class differ diff --git a/src/main/resources/org/python/core/PyTableCode.class b/src/main/resources/org/python/core/PyTableCode.class new file mode 100644 index 0000000000000000000000000000000000000000..1c8872751976e37da124efffc149d3a948f57cba Binary files /dev/null and b/src/main/resources/org/python/core/PyTableCode.class differ diff --git a/src/main/resources/org/python/core/PyToJavaMapEntry.class b/src/main/resources/org/python/core/PyToJavaMapEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..b846ea06586eff76b181fb34114ba20e880bad44 Binary files /dev/null and b/src/main/resources/org/python/core/PyToJavaMapEntry.class differ diff --git a/src/main/resources/org/python/core/PyTraceback$PyExposer.class b/src/main/resources/org/python/core/PyTraceback$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a6ceae02903c5add3c11605619a926bdbd70a220 Binary files /dev/null and b/src/main/resources/org/python/core/PyTraceback$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyTraceback$tb_frame_descriptor.class b/src/main/resources/org/python/core/PyTraceback$tb_frame_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..11c3a02b2f19791bb0af00af834f9a04a39ce59e Binary files /dev/null and b/src/main/resources/org/python/core/PyTraceback$tb_frame_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyTraceback$tb_lineno_descriptor.class b/src/main/resources/org/python/core/PyTraceback$tb_lineno_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..7c738a0716883c226d930583eb3653e2c85ae839 Binary files /dev/null and b/src/main/resources/org/python/core/PyTraceback$tb_lineno_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyTraceback$tb_next_descriptor.class b/src/main/resources/org/python/core/PyTraceback$tb_next_descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..51d7b8e91b479ae75e5b9b846e2d9735f8309a42 Binary files /dev/null and b/src/main/resources/org/python/core/PyTraceback$tb_next_descriptor.class differ diff --git a/src/main/resources/org/python/core/PyTraceback.class b/src/main/resources/org/python/core/PyTraceback.class new file mode 100644 index 0000000000000000000000000000000000000000..90c9972129e3e0f8994759baaedc99c7d59c8ae8 Binary files /dev/null and b/src/main/resources/org/python/core/PyTraceback.class differ diff --git a/src/main/resources/org/python/core/PyTuple$1.class b/src/main/resources/org/python/core/PyTuple$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2dec959e2542752bcea5879ff249947086e1458f Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$1.class differ diff --git a/src/main/resources/org/python/core/PyTuple$2.class b/src/main/resources/org/python/core/PyTuple$2.class new file mode 100644 index 0000000000000000000000000000000000000000..f431586a2751c83386cdd8ce9ef56947cba0ee88 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$2.class differ diff --git a/src/main/resources/org/python/core/PyTuple$PyExposer.class b/src/main/resources/org/python/core/PyTuple$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..778f8ccf8d2068639496422b3c8934278bede4e2 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$exposed___new__.class b/src/main/resources/org/python/core/PyTuple$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..4e6af6e57e4aa67b1813768c6903e554c6228b11 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___add___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..88d8a0e6d74fe280c866f9f66396f62b9e976860 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___contains___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f4f757efe0cbc58d5ab42a5cd1d4689cc8a14b2f Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___eq___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b835493e80d6141c042a53f7e20d6e58e248b47c Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___ge___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..696b3c6d26524799baa52403c7d8827640a02711 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___getitem___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2d9e45c629d21eafa90eb93f0b2a4a72763fde56 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___getnewargs___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___getnewargs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6498dfeeda31073a10826f623658c66c9c99b0f2 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___getnewargs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___getslice___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..86ec78b530b2af9117733b63c6b6f4c9a4b7192f Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___gt___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7e94009161fc02e8224a763411fe234330d06a7c Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___hash___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..495c64068918aa72b47e4fddc5813926c4ce3a2c Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___iter___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..07b5ac6dc71603d21c63ff76420066efa53d70a9 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___le___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a39bc958b8314b2da26b6e62a11c4327b949d966 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___len___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c503c594350f4f93c2d78ec00e4eff47b4cb8301 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___lt___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d05363623dafd003191a1face98c02034d903474 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___mul___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..395293667e81b0937656eec22bf9cd5dcf25883e Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___ne___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..cb5b75312ad804935b18630be689f6981e125320 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___repr___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___repr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b3862da868e523da5fdb97ca4de920cc6e2bcc3e Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___repr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple___rmul___exposer.class b/src/main/resources/org/python/core/PyTuple$tuple___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b8398c3003bdc7c9a24f123391e4387717f2dc17 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple_count_exposer.class b/src/main/resources/org/python/core/PyTuple$tuple_count_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d23dc0cdc133c8c7d27e6724a347a5324a8f3bc4 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple_count_exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple$tuple_index_exposer.class b/src/main/resources/org/python/core/PyTuple$tuple_index_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..938a093755bf79c7b920a9589b83951fa2eef2a8 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple$tuple_index_exposer.class differ diff --git a/src/main/resources/org/python/core/PyTuple.class b/src/main/resources/org/python/core/PyTuple.class new file mode 100644 index 0000000000000000000000000000000000000000..05b6d320884c282709e60fd76ccd8af60acd2ef7 Binary files /dev/null and b/src/main/resources/org/python/core/PyTuple.class differ diff --git a/src/main/resources/org/python/core/PyTupleDerived.class b/src/main/resources/org/python/core/PyTupleDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..8d1d3599e06efbff78672d861d84def0db8b547a Binary files /dev/null and b/src/main/resources/org/python/core/PyTupleDerived.class differ diff --git a/src/main/resources/org/python/core/PyTupleTest.class b/src/main/resources/org/python/core/PyTupleTest.class new file mode 100644 index 0000000000000000000000000000000000000000..1100316fde5aeee1cc549b70951b14f77da22395 Binary files /dev/null and b/src/main/resources/org/python/core/PyTupleTest.class differ diff --git a/src/main/resources/org/python/core/PyType$1.class b/src/main/resources/org/python/core/PyType$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d05fe1810a84a0b3abe95a8b57227cf3d6a9e5d6 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$1.class differ diff --git a/src/main/resources/org/python/core/PyType$10.class b/src/main/resources/org/python/core/PyType$10.class new file mode 100644 index 0000000000000000000000000000000000000000..641f1d2aa553e500980fbecec9ee0512ea7e0b47 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$10.class differ diff --git a/src/main/resources/org/python/core/PyType$11.class b/src/main/resources/org/python/core/PyType$11.class new file mode 100644 index 0000000000000000000000000000000000000000..31bf07f41d9a5a13935c8b2c458c1d912073414b Binary files /dev/null and b/src/main/resources/org/python/core/PyType$11.class differ diff --git a/src/main/resources/org/python/core/PyType$12.class b/src/main/resources/org/python/core/PyType$12.class new file mode 100644 index 0000000000000000000000000000000000000000..de70ec6984ece388291cbbb165cb4873d8b07c01 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$12.class differ diff --git a/src/main/resources/org/python/core/PyType$2.class b/src/main/resources/org/python/core/PyType$2.class new file mode 100644 index 0000000000000000000000000000000000000000..f9be2453aee2f3e04a159afe6d3cd2dc2eb4eb22 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$2.class differ diff --git a/src/main/resources/org/python/core/PyType$3.class b/src/main/resources/org/python/core/PyType$3.class new file mode 100644 index 0000000000000000000000000000000000000000..8d72c0b321a0bdb93eeb35ff9a301dbf3571b447 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$3.class differ diff --git a/src/main/resources/org/python/core/PyType$4.class b/src/main/resources/org/python/core/PyType$4.class new file mode 100644 index 0000000000000000000000000000000000000000..b4300aaa68cc2e6dca0296f9b66e049c9fbe4604 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$4.class differ diff --git a/src/main/resources/org/python/core/PyType$5.class b/src/main/resources/org/python/core/PyType$5.class new file mode 100644 index 0000000000000000000000000000000000000000..a4001fd587e7e521895e1ced3d3156c1a56d5de7 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$5.class differ diff --git a/src/main/resources/org/python/core/PyType$6.class b/src/main/resources/org/python/core/PyType$6.class new file mode 100644 index 0000000000000000000000000000000000000000..e6c81b8f7ed75afc1b45b51cbdb4694ed7a9f5e8 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$6.class differ diff --git a/src/main/resources/org/python/core/PyType$7.class b/src/main/resources/org/python/core/PyType$7.class new file mode 100644 index 0000000000000000000000000000000000000000..d3217361f7d4cb259274d8941481c4d6d7e3a1f0 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$7.class differ diff --git a/src/main/resources/org/python/core/PyType$8.class b/src/main/resources/org/python/core/PyType$8.class new file mode 100644 index 0000000000000000000000000000000000000000..ee94b8febbc5f341512338376af36a9c457763b6 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$8.class differ diff --git a/src/main/resources/org/python/core/PyType$9.class b/src/main/resources/org/python/core/PyType$9.class new file mode 100644 index 0000000000000000000000000000000000000000..6b0882bb60cfe0cf73e48f7fa39fc5bdebfc9662 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$9.class differ diff --git a/src/main/resources/org/python/core/PyType$MROMergeState.class b/src/main/resources/org/python/core/PyType$MROMergeState.class new file mode 100644 index 0000000000000000000000000000000000000000..a5e7ca605670832f10dea1b64af78312b7e1d05c Binary files /dev/null and b/src/main/resources/org/python/core/PyType$MROMergeState.class differ diff --git a/src/main/resources/org/python/core/PyType$MethodCache$MethodCacheEntry.class b/src/main/resources/org/python/core/PyType$MethodCache$MethodCacheEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..e55af0817386fc767658c5546cf6d8f9cf7b8c1c Binary files /dev/null and b/src/main/resources/org/python/core/PyType$MethodCache$MethodCacheEntry.class differ diff --git a/src/main/resources/org/python/core/PyType$MethodCache.class b/src/main/resources/org/python/core/PyType$MethodCache.class new file mode 100644 index 0000000000000000000000000000000000000000..13c39a720ed40e280e7bb57a9a8deef6a7fa7eaa Binary files /dev/null and b/src/main/resources/org/python/core/PyType$MethodCache.class differ diff --git a/src/main/resources/org/python/core/PyType$OnType.class b/src/main/resources/org/python/core/PyType$OnType.class new file mode 100644 index 0000000000000000000000000000000000000000..486dc89036d55a2cd4e43cf73a7cd6640e3588d3 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$OnType.class differ diff --git a/src/main/resources/org/python/core/PyType$PyExposer.class b/src/main/resources/org/python/core/PyType$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..612f635daf6fc33ae637ecdd719610fdda2a0b97 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyType$TypeResolver.class b/src/main/resources/org/python/core/PyType$TypeResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..a081fdd5d2187da4652598401c131b80164dfa07 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$TypeResolver.class differ diff --git a/src/main/resources/org/python/core/PyType$__abstractmethods___descriptor.class b/src/main/resources/org/python/core/PyType$__abstractmethods___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..3f7640e39e8aa2fd55e0f9e4724361b3623c55af Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__abstractmethods___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__base___descriptor.class b/src/main/resources/org/python/core/PyType$__base___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..bd1b1d383b57455a64033ed207afec79eb04718a Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__base___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__bases___descriptor.class b/src/main/resources/org/python/core/PyType$__bases___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..c05477fc5efb2f8a8f2cc3c43684aeab6c4f3323 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__bases___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__dict___descriptor.class b/src/main/resources/org/python/core/PyType$__dict___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..debcd25ddab6e4696f8738b12e8cd751f3ac46d7 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__dict___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__doc___descriptor.class b/src/main/resources/org/python/core/PyType$__doc___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b6ea8c443d99e2c696f24e96b13a441fb27c1ab9 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__doc___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__flags___descriptor.class b/src/main/resources/org/python/core/PyType$__flags___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..aa53ec20c305104c6be94578062991c57bb529db Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__flags___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__module___descriptor.class b/src/main/resources/org/python/core/PyType$__module___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..ebfbddfd1e5ea7145a15f36bf7874a824ad4326d Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__module___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__mro___descriptor.class b/src/main/resources/org/python/core/PyType$__mro___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..9c378ecc6eb6be76882a2bc48199092908886c07 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__mro___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$__name___descriptor.class b/src/main/resources/org/python/core/PyType$__name___descriptor.class new file mode 100644 index 0000000000000000000000000000000000000000..b61b6242d231d874cadf803544786030cd32e514 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$__name___descriptor.class differ diff --git a/src/main/resources/org/python/core/PyType$exposed___new__.class b/src/main/resources/org/python/core/PyType$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..d9532f9282c0196eef8b83b9238c3e6ff33f5b27 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyType$type___call___exposer.class b/src/main/resources/org/python/core/PyType$type___call___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9f15ce40fe5a68dae0f686916b0e4e56dbf6217d Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___call___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___delattr___exposer.class b/src/main/resources/org/python/core/PyType$type___delattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..60433596faaeff543e85b8d6dc4311e52521af6a Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___delattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___eq___exposer.class b/src/main/resources/org/python/core/PyType$type___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5ba18b27f412f8afaaf4c0a1588820a5a57d5042 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___ge___exposer.class b/src/main/resources/org/python/core/PyType$type___ge___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2ee1081ce1da4ab60a11da8b893872191759d7ff Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___ge___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___getattribute___exposer.class b/src/main/resources/org/python/core/PyType$type___getattribute___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..ecf2797cbfc93dd1fc38d7425b758df5e83c17a3 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___getattribute___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___gt___exposer.class b/src/main/resources/org/python/core/PyType$type___gt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e13ea4ea4e5029051d0dd9674f87a444a15ef2b8 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___gt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___init___exposer.class b/src/main/resources/org/python/core/PyType$type___init___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2e53ccba3a79716d8a5f17523952920df734d02d Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___init___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___le___exposer.class b/src/main/resources/org/python/core/PyType$type___le___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..720134e71b9314e9e6ca8f0a9f74fff48d3dc7f8 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___le___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___lt___exposer.class b/src/main/resources/org/python/core/PyType$type___lt___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..367135ea947fca5982efc80fb8854032c8b73994 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___lt___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___ne___exposer.class b/src/main/resources/org/python/core/PyType$type___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..35452a31e248680c139c444117fc9117b03e7ecc Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___setattr___exposer.class b/src/main/resources/org/python/core/PyType$type___setattr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b9a97c1f8da383fbc2f7cea23e09833cfbfe3237 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___setattr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type___subclasses___exposer.class b/src/main/resources/org/python/core/PyType$type___subclasses___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..95888650f685068b9825e7ee949155d230621815 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type___subclasses___exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type_mro_exposer.class b/src/main/resources/org/python/core/PyType$type_mro_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..553c693ffaa234f733cc6df721e4e7e086ef1d22 Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type_mro_exposer.class differ diff --git a/src/main/resources/org/python/core/PyType$type_toString_exposer.class b/src/main/resources/org/python/core/PyType$type_toString_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..02b72c90cfd11984bc2130d8258ac120cdf743fe Binary files /dev/null and b/src/main/resources/org/python/core/PyType$type_toString_exposer.class differ diff --git a/src/main/resources/org/python/core/PyType.class b/src/main/resources/org/python/core/PyType.class new file mode 100644 index 0000000000000000000000000000000000000000..5010ce7d1959b9958da8d38440935706c02dc5e0 Binary files /dev/null and b/src/main/resources/org/python/core/PyType.class differ diff --git a/src/main/resources/org/python/core/PyTypeDerived.class b/src/main/resources/org/python/core/PyTypeDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..4c2379756f29c6870296b7b89c47b9702a19026c Binary files /dev/null and b/src/main/resources/org/python/core/PyTypeDerived.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$LineSplitIterator.class b/src/main/resources/org/python/core/PyUnicode$LineSplitIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..92830f77cd15c4ffae700abc68c5983e43ffc474 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$LineSplitIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$PeekIterator.class b/src/main/resources/org/python/core/PyUnicode$PeekIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..02be21c7191401e1855f1ab8797eb749c1b4f712 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$PeekIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$Plane.class b/src/main/resources/org/python/core/PyUnicode$Plane.class new file mode 100644 index 0000000000000000000000000000000000000000..2232d5871736c8da16b541fb8ac244471ead2d55 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$Plane.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$PyExposer.class b/src/main/resources/org/python/core/PyUnicode$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7d702f22d7c2a56afd5e585a231f373be02f9721 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$ReversedIterator.class b/src/main/resources/org/python/core/PyUnicode$ReversedIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..ea92249a60cb2e6e858381c05dce0886bbcdb9ef Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$ReversedIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$SepSplitIterator.class b/src/main/resources/org/python/core/PyUnicode$SepSplitIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..05b14bed680827a237016404a6beb3ed88af0ff4 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$SepSplitIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$SplitIterator.class b/src/main/resources/org/python/core/PyUnicode$SplitIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..ec5c04a46405463cb8687b9a14da59ab05c2d121 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$SplitIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$SteppedIterator.class b/src/main/resources/org/python/core/PyUnicode$SteppedIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..500ede0f6684a16e6e0725bf0ce4a729ccace457 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$SteppedIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$StripIterator.class b/src/main/resources/org/python/core/PyUnicode$StripIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..e04f282445856edf503ab6fbc95defd42e3fa817 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$StripIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$SubsequenceIteratorImpl.class b/src/main/resources/org/python/core/PyUnicode$SubsequenceIteratorImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..c96ce99adf05a350e71295590b01c44abaf35ad0 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$SubsequenceIteratorImpl.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$WhitespaceSplitIterator.class b/src/main/resources/org/python/core/PyUnicode$WhitespaceSplitIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..3248483f89fde58aea7b70dd017df5a843551ae9 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$WhitespaceSplitIterator.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$exposed___new__.class b/src/main/resources/org/python/core/PyUnicode$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..f3e978b639f88e59ab4508ce3b528d4a1d5e3975 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___add___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___add___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..f92e86fac3bcb9e6d390e84c874e163153e91cd7 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___add___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___cmp___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___cmp___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e96475dbdedaa19e71d40f06b9c2b981b74721e4 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___cmp___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___contains___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___contains___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4b8a252609a81b16715dfe339c8ba19dece39cf0 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___contains___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___eq___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___eq___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6a7b6bb7ddd20ef0c1863e6e6571df00edb4a779 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___eq___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___getitem___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..99c15084b98dc370582f6b0de5ddcdbb6a82e3b4 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___getnewargs___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___getnewargs___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a70b7b47457496f720955bf0758716bb5fafd180 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___getnewargs___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___getslice___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___getslice___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fc0fcdba6a3092329a5687f1d2ffcf12c542aa3e Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___getslice___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___hash___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___hash___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..fef6b3efb4bfb1555a41f9d42c9d21b3ffa21cc8 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___hash___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___len___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5dc3bd5465751447c9be170d156be49fd428e706 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___mod___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___mod___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b04bc455ebd49f7194df2263b7f82d831818b0b9 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___mod___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___mul___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___mul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4bd5aed156179b9eaed45996e945400e91039eeb Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___mul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___ne___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___ne___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..049e3875e5b9d7f61dcddacc28881ffaac10b569 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___ne___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___repr___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___repr___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb4753797bb5382d8ca6acf4720de808d3538cf5 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___repr___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___rmul___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___rmul___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8846702ebf51c7c5bc66cc9c134c57aa06b6c0f3 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___rmul___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode___str___exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode___str___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..14d29b38bf4587e32be634540212520c74704776 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode___str___exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_capitalize_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_capitalize_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..78e34be0b940571f23a349977eb0554482bc66d1 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_capitalize_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_center_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_center_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..384b64388a879af59e02edfe24a73b487cdedffc Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_center_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_count_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_count_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..4164165ea0a9dee54f03a74c23a80c5cbc09feed Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_count_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_decode_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_decode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b92c8748f4ad5f38f82bbafe3ccb6dc24d6b17b0 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_decode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_encode_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_encode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..23bccb563df0fd258c7b69c1db110f8780b3613b Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_encode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_endswith_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_endswith_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7fcf0c04e68f3c8c8ef130a43e03ca815b79c625 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_endswith_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_expandtabs_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_expandtabs_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1933792af1fc43948b2011fc4149ed98767af368 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_expandtabs_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_find_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_find_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8ad55b89edbccdb2f5c6975ff95ebb7c7241244d Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_find_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_format_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_format_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..839abe41328cb07bcefe834f2748837239069574 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_format_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_index_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_index_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..bf2727cea5fd32f4d8c28dd026ba43719a54447e Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_index_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isalnum_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isalnum_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..97e4343ea92ac7ba24d85950a86ae043706f9a05 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isalnum_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isalpha_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isalpha_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6994fda705f1de101dc82d51372d83fbcec44067 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isalpha_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isdecimal_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isdecimal_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..5fa5309ce36afbbc10307f2196cdd484774d86f4 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isdecimal_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isdigit_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isdigit_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e90399d21b7bc33a3ed2680ecd494ff757e626aa Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isdigit_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_islower_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_islower_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..071ed9aa31bdb5f53fd45ca323f13ec90423597c Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_islower_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isnumeric_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isnumeric_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..6a9e7d777eb26e40888e90beb8dd506678cb5d7c Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isnumeric_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isspace_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isspace_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..40a279570567d8d57968638890a80bd3657d4787 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isspace_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_istitle_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_istitle_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..657f2e47fcfb5540f291eb26567732bb166aa964 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_istitle_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isunicode_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isunicode_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..51f7eb5e22c1572495e6d4893d30e9bda59ee98a Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isunicode_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_isupper_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_isupper_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e0436993fa98382cd3a9a832d4927a9c9da73ee7 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_isupper_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_join_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_join_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1e89abe6896278fd8114d6d4e400d19c49d9ce62 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_join_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_ljust_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_ljust_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..43bc095c1b22139cb612caf954011607da719e18 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_ljust_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_lower_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_lower_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8cd8fa5caac4a5d21847a72784098253841a4439 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_lower_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_lstrip_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_lstrip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..41a3a24b430162b91dc27159ce034c141a8d8abd Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_lstrip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_partition_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_partition_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..faa918be7e3214be94b0933373b9341a9de61403 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_partition_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_replace_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_replace_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..b06d980fc322995788b8c20c03b04c887b7647ac Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_replace_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_rfind_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_rfind_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..d44705b5b57fb345c068424d20520a8b742c669f Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_rfind_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_rindex_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_rindex_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e1afb0a073f8ff89186cff92656d2a9bda39c01a Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_rindex_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_rjust_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_rjust_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..46b51cf2fe97f5713ed3b27f107ca22a9f1aad45 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_rjust_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_rpartition_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_rpartition_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3e16573818867b7c9c661ebee57565aa6d4abb87 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_rpartition_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_rsplit_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_rsplit_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..2831284ec13f98e25d4308e10290c896744cfe2f Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_rsplit_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_rstrip_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_rstrip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..7d595e15dce3d3862160da5cf6c50ba2e206492a Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_rstrip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_split_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_split_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..8da26b3d5a783bae86580e190e85c51877e87b6c Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_split_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_splitlines_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_splitlines_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1160a32787e6da79ddae1631dc6cc474e49db7ff Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_splitlines_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_startswith_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_startswith_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3713e42a91502a33f863549f8827d78d15887cda Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_startswith_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_strip_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_strip_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e143eac1a6af54f788783e5202507a4eb537f926 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_strip_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_swapcase_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_swapcase_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..3baea95eeb6172c076133620a5b0158c2a2b581b Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_swapcase_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_title_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_title_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e8c581e4d32ec1e89b1df5280ae2813b576ca970 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_title_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_translate_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_translate_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..64c975645735f953de213ed6757d97a093c404b2 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_translate_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_upper_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_upper_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..210956d78c4ad6152ee1b9e7141a83bff5aa42fc Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_upper_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode$unicode_zfill_exposer.class b/src/main/resources/org/python/core/PyUnicode$unicode_zfill_exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..e1c6a504647eb7f56d1e226f8b6031c1cfac7765 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode$unicode_zfill_exposer.class differ diff --git a/src/main/resources/org/python/core/PyUnicode.class b/src/main/resources/org/python/core/PyUnicode.class new file mode 100644 index 0000000000000000000000000000000000000000..6999c7a954abf3ac01bf06197356f9121ddb46ea Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicode.class differ diff --git a/src/main/resources/org/python/core/PyUnicodeDerived.class b/src/main/resources/org/python/core/PyUnicodeDerived.class new file mode 100644 index 0000000000000000000000000000000000000000..459b2a15194a4682c1e5dae403d26135b5246c56 Binary files /dev/null and b/src/main/resources/org/python/core/PyUnicodeDerived.class differ diff --git a/src/main/resources/org/python/core/PyXRange$PyExposer.class b/src/main/resources/org/python/core/PyXRange$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..1220b819c9d2f2b456c577685292e56907c804de Binary files /dev/null and b/src/main/resources/org/python/core/PyXRange$PyExposer.class differ diff --git a/src/main/resources/org/python/core/PyXRange$exposed___new__.class b/src/main/resources/org/python/core/PyXRange$exposed___new__.class new file mode 100644 index 0000000000000000000000000000000000000000..40e6428c3cd04912404d8c8afb1b2d251d43f57f Binary files /dev/null and b/src/main/resources/org/python/core/PyXRange$exposed___new__.class differ diff --git a/src/main/resources/org/python/core/PyXRange$xrange___getitem___exposer.class b/src/main/resources/org/python/core/PyXRange$xrange___getitem___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..c90768769b5fe1f36527df9f097035d077d953bf Binary files /dev/null and b/src/main/resources/org/python/core/PyXRange$xrange___getitem___exposer.class differ diff --git a/src/main/resources/org/python/core/PyXRange$xrange___iter___exposer.class b/src/main/resources/org/python/core/PyXRange$xrange___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..12fdd43fe1e50696087973200cffd8478d9d4424 Binary files /dev/null and b/src/main/resources/org/python/core/PyXRange$xrange___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/PyXRange$xrange___len___exposer.class b/src/main/resources/org/python/core/PyXRange$xrange___len___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..532842f78a1bdb489e85610aeee03cfa31eaed95 Binary files /dev/null and b/src/main/resources/org/python/core/PyXRange$xrange___len___exposer.class differ diff --git a/src/main/resources/org/python/core/PyXRange.class b/src/main/resources/org/python/core/PyXRange.class new file mode 100644 index 0000000000000000000000000000000000000000..c33b245865411f6f074644584a10d23f2666090f Binary files /dev/null and b/src/main/resources/org/python/core/PyXRange.class differ diff --git a/src/main/resources/org/python/core/PythonCodeBundle.class b/src/main/resources/org/python/core/PythonCodeBundle.class new file mode 100644 index 0000000000000000000000000000000000000000..c165a3841a5c17a6f33ce3a05f438ed35371124c Binary files /dev/null and b/src/main/resources/org/python/core/PythonCodeBundle.class differ diff --git a/src/main/resources/org/python/core/PythonCompiler.class b/src/main/resources/org/python/core/PythonCompiler.class new file mode 100644 index 0000000000000000000000000000000000000000..3e8df3863fed262b608cf3fab17ef6d92260952d Binary files /dev/null and b/src/main/resources/org/python/core/PythonCompiler.class differ diff --git a/src/main/resources/org/python/core/PythonTraceFunction.class b/src/main/resources/org/python/core/PythonTraceFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..a78b2e88e6ccff7289ec64c1cfe6bd9e5cf13edc Binary files /dev/null and b/src/main/resources/org/python/core/PythonTraceFunction.class differ diff --git a/src/main/resources/org/python/core/ReflectedArgs.class b/src/main/resources/org/python/core/ReflectedArgs.class new file mode 100644 index 0000000000000000000000000000000000000000..66402aaad3f41070309ecfde43e558a926af5872 Binary files /dev/null and b/src/main/resources/org/python/core/ReflectedArgs.class differ diff --git a/src/main/resources/org/python/core/ReflectedCallData.class b/src/main/resources/org/python/core/ReflectedCallData.class new file mode 100644 index 0000000000000000000000000000000000000000..ba7846f20bd7eb13781698689f75ab140a55e8f1 Binary files /dev/null and b/src/main/resources/org/python/core/ReflectedCallData.class differ diff --git a/src/main/resources/org/python/core/RoundFunction.class b/src/main/resources/org/python/core/RoundFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..7a0887f70e1fc33acc57b08b482af119584d8241 Binary files /dev/null and b/src/main/resources/org/python/core/RoundFunction.class differ diff --git a/src/main/resources/org/python/core/SequenceIndexDelegate.class b/src/main/resources/org/python/core/SequenceIndexDelegate.class new file mode 100644 index 0000000000000000000000000000000000000000..3998d6f34fd17308e1a43b06a31d9773dd86b062 Binary files /dev/null and b/src/main/resources/org/python/core/SequenceIndexDelegate.class differ diff --git a/src/main/resources/org/python/core/Shadow.class b/src/main/resources/org/python/core/Shadow.class new file mode 100644 index 0000000000000000000000000000000000000000..6e72258986cdad3d55ef7005e97b67098e10d9d3 Binary files /dev/null and b/src/main/resources/org/python/core/Shadow.class differ diff --git a/src/main/resources/org/python/core/SimpleEntry.class b/src/main/resources/org/python/core/SimpleEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..fa9b73102f1f8a10c179f5f7c0af96b6137caa6c Binary files /dev/null and b/src/main/resources/org/python/core/SimpleEntry.class differ diff --git a/src/main/resources/org/python/core/Slotted.class b/src/main/resources/org/python/core/Slotted.class new file mode 100644 index 0000000000000000000000000000000000000000..8970659e279c3963fd806fa745096511401e90df Binary files /dev/null and b/src/main/resources/org/python/core/Slotted.class differ diff --git a/src/main/resources/org/python/core/SortedFunction.class b/src/main/resources/org/python/core/SortedFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..33b82f994f0a9fd0ca19ae200f8ea163433d005b Binary files /dev/null and b/src/main/resources/org/python/core/SortedFunction.class differ diff --git a/src/main/resources/org/python/core/StderrWrapper.class b/src/main/resources/org/python/core/StderrWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..5a5dcfc9354e533691c83388ee3d784c152399b1 Binary files /dev/null and b/src/main/resources/org/python/core/StderrWrapper.class differ diff --git a/src/main/resources/org/python/core/StdoutWrapper.class b/src/main/resources/org/python/core/StdoutWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..59a238c09a0807e481a45086e816bbae82362da2 Binary files /dev/null and b/src/main/resources/org/python/core/StdoutWrapper.class differ diff --git a/src/main/resources/org/python/core/StringFormatTest.class b/src/main/resources/org/python/core/StringFormatTest.class new file mode 100644 index 0000000000000000000000000000000000000000..182d75466b99686678e30e3ae6542693fd5be6a4 Binary files /dev/null and b/src/main/resources/org/python/core/StringFormatTest.class differ diff --git a/src/main/resources/org/python/core/StringFormatter$DecimalFormatTemplate.class b/src/main/resources/org/python/core/StringFormatter$DecimalFormatTemplate.class new file mode 100644 index 0000000000000000000000000000000000000000..7b0a698ac569a58708c4a8984bbd959c484f460e Binary files /dev/null and b/src/main/resources/org/python/core/StringFormatter$DecimalFormatTemplate.class differ diff --git a/src/main/resources/org/python/core/StringFormatter.class b/src/main/resources/org/python/core/StringFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..24554ce4a08a6fe2c4272f3700ddcdd655fb1f73 Binary files /dev/null and b/src/main/resources/org/python/core/StringFormatter.class differ diff --git a/src/main/resources/org/python/core/StringSubsequenceIterator.class b/src/main/resources/org/python/core/StringSubsequenceIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..20fc1b4b713b87fb4ea8d4539e25c79d37f98082 Binary files /dev/null and b/src/main/resources/org/python/core/StringSubsequenceIterator.class differ diff --git a/src/main/resources/org/python/core/SyspathArchive.class b/src/main/resources/org/python/core/SyspathArchive.class new file mode 100644 index 0000000000000000000000000000000000000000..c6d72fdaac82bccb6ba3a8f9aa12436d51c3885b Binary files /dev/null and b/src/main/resources/org/python/core/SyspathArchive.class differ diff --git a/src/main/resources/org/python/core/SyspathJavaLoader.class b/src/main/resources/org/python/core/SyspathJavaLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..dd8fd5c7eae2059da26ece6832f80a60ff4606a8 Binary files /dev/null and b/src/main/resources/org/python/core/SyspathJavaLoader.class differ diff --git a/src/main/resources/org/python/core/ThreadContext.class b/src/main/resources/org/python/core/ThreadContext.class new file mode 100644 index 0000000000000000000000000000000000000000..0163212198bd39d9f7bd8cc8f6c9c9fdbe907c05 Binary files /dev/null and b/src/main/resources/org/python/core/ThreadContext.class differ diff --git a/src/main/resources/org/python/core/ThreadState.class b/src/main/resources/org/python/core/ThreadState.class new file mode 100644 index 0000000000000000000000000000000000000000..4d78aee59b4d87e40148c59916a442da0402de08 Binary files /dev/null and b/src/main/resources/org/python/core/ThreadState.class differ diff --git a/src/main/resources/org/python/core/ThreadStateMapping.class b/src/main/resources/org/python/core/ThreadStateMapping.class new file mode 100644 index 0000000000000000000000000000000000000000..a4656fc69b5ab151a1b0b78968ca47147de3c73d Binary files /dev/null and b/src/main/resources/org/python/core/ThreadStateMapping.class differ diff --git a/src/main/resources/org/python/core/ThreadStateMapping.class-bak.class b/src/main/resources/org/python/core/ThreadStateMapping.class-bak.class new file mode 100644 index 0000000000000000000000000000000000000000..b2f9fbddd2f51e393dd3ba32d8144ed50271be76 Binary files /dev/null and b/src/main/resources/org/python/core/ThreadStateMapping.class-bak.class differ diff --git a/src/main/resources/org/python/core/TraceFunction.class b/src/main/resources/org/python/core/TraceFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..6851a9b38dd7fe119d9851943efe596363531912 Binary files /dev/null and b/src/main/resources/org/python/core/TraceFunction.class differ diff --git a/src/main/resources/org/python/core/WrappedBooleanTest$WrappedBoolean.class b/src/main/resources/org/python/core/WrappedBooleanTest$WrappedBoolean.class new file mode 100644 index 0000000000000000000000000000000000000000..cb430a44589eaa2e3613717edbb56a41c42cf9fa Binary files /dev/null and b/src/main/resources/org/python/core/WrappedBooleanTest$WrappedBoolean.class differ diff --git a/src/main/resources/org/python/core/WrappedBooleanTest.class b/src/main/resources/org/python/core/WrappedBooleanTest.class new file mode 100644 index 0000000000000000000000000000000000000000..dd6cfc9b0727cdde6949318634c5dbca1fc3f792 Binary files /dev/null and b/src/main/resources/org/python/core/WrappedBooleanTest.class differ diff --git a/src/main/resources/org/python/core/WrappedFloatTest$WrappedFloat.class b/src/main/resources/org/python/core/WrappedFloatTest$WrappedFloat.class new file mode 100644 index 0000000000000000000000000000000000000000..caa7d43597427d0b89caf4be325a180620086ac2 Binary files /dev/null and b/src/main/resources/org/python/core/WrappedFloatTest$WrappedFloat.class differ diff --git a/src/main/resources/org/python/core/WrappedFloatTest.class b/src/main/resources/org/python/core/WrappedFloatTest.class new file mode 100644 index 0000000000000000000000000000000000000000..487290a3f0cb02ed487b6d386a920fd496bd6f59 Binary files /dev/null and b/src/main/resources/org/python/core/WrappedFloatTest.class differ diff --git a/src/main/resources/org/python/core/WrappedIntegerTest$WrappedInteger.class b/src/main/resources/org/python/core/WrappedIntegerTest$WrappedInteger.class new file mode 100644 index 0000000000000000000000000000000000000000..d493bb04f2f0947fb6422d310a2e4d9cb1c04db3 Binary files /dev/null and b/src/main/resources/org/python/core/WrappedIntegerTest$WrappedInteger.class differ diff --git a/src/main/resources/org/python/core/WrappedIntegerTest.class b/src/main/resources/org/python/core/WrappedIntegerTest.class new file mode 100644 index 0000000000000000000000000000000000000000..49a25e9fe13791313b79bdbd12b11fddad8043af Binary files /dev/null and b/src/main/resources/org/python/core/WrappedIntegerTest.class differ diff --git a/src/main/resources/org/python/core/WrappedIterIterator.class b/src/main/resources/org/python/core/WrappedIterIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..f39ec224d05fb57bcf581217127fd00bc48b7e43 Binary files /dev/null and b/src/main/resources/org/python/core/WrappedIterIterator.class differ diff --git a/src/main/resources/org/python/core/WrappedLongTest$WrappedLong.class b/src/main/resources/org/python/core/WrappedLongTest$WrappedLong.class new file mode 100644 index 0000000000000000000000000000000000000000..5d01696a99c2c1310f5ceb9fc0b434c9b0d9a9df Binary files /dev/null and b/src/main/resources/org/python/core/WrappedLongTest$WrappedLong.class differ diff --git a/src/main/resources/org/python/core/WrappedLongTest.class b/src/main/resources/org/python/core/WrappedLongTest.class new file mode 100644 index 0000000000000000000000000000000000000000..ef6aa0bfb75f0911e98d2e9f782d8c1dba7fcc6d Binary files /dev/null and b/src/main/resources/org/python/core/WrappedLongTest.class differ diff --git a/src/main/resources/org/python/core/__builtin__.class b/src/main/resources/org/python/core/__builtin__.class new file mode 100644 index 0000000000000000000000000000000000000000..fce130c685edbf9d87c1dba739654d126886d26b Binary files /dev/null and b/src/main/resources/org/python/core/__builtin__.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassAdapter.class b/src/main/resources/org/python/core/adapter/ClassAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..449b1e9544d03df7ab56a47fcdb2598722328895 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassAdapter.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$1.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..464e802a7fde3879b79e87ff00085bf608361a8f Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$1.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$2.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$2.class new file mode 100644 index 0000000000000000000000000000000000000000..cc1e53376aa96629cebfed1398427d34bfc48678 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$2.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$3.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$3.class new file mode 100644 index 0000000000000000000000000000000000000000..def05e6987fc0ddc35f6a74c249a73a9d4e82fd2 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$3.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$4.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$4.class new file mode 100644 index 0000000000000000000000000000000000000000..3ca84a8d0ccd52c10f902fb739c1f558da0bbc5b Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$4.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$5.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$5.class new file mode 100644 index 0000000000000000000000000000000000000000..ce99ad1a8acd957c6237227d0dc5913a9ed6c3d0 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$5.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$6.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$6.class new file mode 100644 index 0000000000000000000000000000000000000000..948a7669240f4d5467a9449980e3109edf5561a8 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$6.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$7.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$7.class new file mode 100644 index 0000000000000000000000000000000000000000..5a2b019b28481e34234638960efde021eb7c9a87 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$7.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$8.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$8.class new file mode 100644 index 0000000000000000000000000000000000000000..0cca7d97703d4de4b0b6395196921b0e7dd9fdbb Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$8.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$9.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$9.class new file mode 100644 index 0000000000000000000000000000000000000000..ad2eaed4efe7d23ad96fe388f6fb0adbbc9c41f8 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$9.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$NumberToPyFloat.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$NumberToPyFloat.class new file mode 100644 index 0000000000000000000000000000000000000000..6215ea02d882563b43c58cfef9066d9dcf2379c1 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$NumberToPyFloat.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$NumberToPyInteger.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$NumberToPyInteger.class new file mode 100644 index 0000000000000000000000000000000000000000..fc71a99b2cc89a2e67f8d17440a513d515625966 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter$NumberToPyInteger.class differ diff --git a/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter.class b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..c561e4051c9c783c27be34a0d0bdd79b8971d945 Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ClassicPyObjectAdapter.class differ diff --git a/src/main/resources/org/python/core/adapter/ExtensiblePyObjectAdapter.class b/src/main/resources/org/python/core/adapter/ExtensiblePyObjectAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..cf83707578f276143810c24083145ebc8f82f5eb Binary files /dev/null and b/src/main/resources/org/python/core/adapter/ExtensiblePyObjectAdapter.class differ diff --git a/src/main/resources/org/python/core/adapter/PyObjectAdapter.class b/src/main/resources/org/python/core/adapter/PyObjectAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..f9796cd70e51988152d63f44988f2b78a354b0bd Binary files /dev/null and b/src/main/resources/org/python/core/adapter/PyObjectAdapter.class differ diff --git a/src/main/resources/org/python/core/buffer/BaseBuffer.class b/src/main/resources/org/python/core/buffer/BaseBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..ac1130ee4e63709da32430c0961582ca276f028b Binary files /dev/null and b/src/main/resources/org/python/core/buffer/BaseBuffer.class differ diff --git a/src/main/resources/org/python/core/buffer/SimpleBuffer$SimpleView.class b/src/main/resources/org/python/core/buffer/SimpleBuffer$SimpleView.class new file mode 100644 index 0000000000000000000000000000000000000000..8ca53788d1ed4e988aedf6044a726e08e182043b Binary files /dev/null and b/src/main/resources/org/python/core/buffer/SimpleBuffer$SimpleView.class differ diff --git a/src/main/resources/org/python/core/buffer/SimpleBuffer.class b/src/main/resources/org/python/core/buffer/SimpleBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..4df6d993531faa7511af2a39ff72f0b3986c8ce9 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/SimpleBuffer.class differ diff --git a/src/main/resources/org/python/core/buffer/SimpleStringBuffer$SimpleStringView.class b/src/main/resources/org/python/core/buffer/SimpleStringBuffer$SimpleStringView.class new file mode 100644 index 0000000000000000000000000000000000000000..3eb04a8edc28ce7ffc99513a9eab0fa977016974 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/SimpleStringBuffer$SimpleStringView.class differ diff --git a/src/main/resources/org/python/core/buffer/SimpleStringBuffer.class b/src/main/resources/org/python/core/buffer/SimpleStringBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..fdc3cb157a8f492be6756a097e07c338b3bf46b7 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/SimpleStringBuffer.class differ diff --git a/src/main/resources/org/python/core/buffer/SimpleWritableBuffer$SimpleView.class b/src/main/resources/org/python/core/buffer/SimpleWritableBuffer$SimpleView.class new file mode 100644 index 0000000000000000000000000000000000000000..4e865e37b0baf44ed4b1a6577aa832d4f496ca85 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/SimpleWritableBuffer$SimpleView.class differ diff --git a/src/main/resources/org/python/core/buffer/SimpleWritableBuffer.class b/src/main/resources/org/python/core/buffer/SimpleWritableBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..f6afad8056725a1f2dc2cb92a9038194ea3b9dcd Binary files /dev/null and b/src/main/resources/org/python/core/buffer/SimpleWritableBuffer.class differ diff --git a/src/main/resources/org/python/core/buffer/Strided1DBuffer$SlicedView.class b/src/main/resources/org/python/core/buffer/Strided1DBuffer$SlicedView.class new file mode 100644 index 0000000000000000000000000000000000000000..df1cc9dc767e9d2c7bf1aaa684ca78d7090dd7b1 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/Strided1DBuffer$SlicedView.class differ diff --git a/src/main/resources/org/python/core/buffer/Strided1DBuffer.class b/src/main/resources/org/python/core/buffer/Strided1DBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..5867e8c0fb605675ec8b9d35647ff64bad5972f5 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/Strided1DBuffer.class differ diff --git a/src/main/resources/org/python/core/buffer/Strided1DWritableBuffer$SlicedView.class b/src/main/resources/org/python/core/buffer/Strided1DWritableBuffer$SlicedView.class new file mode 100644 index 0000000000000000000000000000000000000000..498d9405f3cb8a52a974b6e494d063e772cf53b8 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/Strided1DWritableBuffer$SlicedView.class differ diff --git a/src/main/resources/org/python/core/buffer/Strided1DWritableBuffer.class b/src/main/resources/org/python/core/buffer/Strided1DWritableBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..c9813dbcb7b3fea3caffb69e0bf36cc501cfcc63 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/Strided1DWritableBuffer.class differ diff --git a/src/main/resources/org/python/core/buffer/ZeroByteBuffer$View.class b/src/main/resources/org/python/core/buffer/ZeroByteBuffer$View.class new file mode 100644 index 0000000000000000000000000000000000000000..b4f9829fb28c02790839d6198a3a6589c87bfb86 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/ZeroByteBuffer$View.class differ diff --git a/src/main/resources/org/python/core/buffer/ZeroByteBuffer.class b/src/main/resources/org/python/core/buffer/ZeroByteBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..c343139389c737bfae602734b8793ad98382eee1 Binary files /dev/null and b/src/main/resources/org/python/core/buffer/ZeroByteBuffer.class differ diff --git a/src/main/resources/org/python/core/codecs$CodecState.class b/src/main/resources/org/python/core/codecs$CodecState.class new file mode 100644 index 0000000000000000000000000000000000000000..f887603a84f08262be13680f267d362f8949c21b Binary files /dev/null and b/src/main/resources/org/python/core/codecs$CodecState.class differ diff --git a/src/main/resources/org/python/core/codecs$Punycode.class b/src/main/resources/org/python/core/codecs$Punycode.class new file mode 100644 index 0000000000000000000000000000000000000000..13a595f0e0f46b38d01a06f6989c301b2370eade Binary files /dev/null and b/src/main/resources/org/python/core/codecs$Punycode.class differ diff --git a/src/main/resources/org/python/core/codecs$UTF7Error.class b/src/main/resources/org/python/core/codecs$UTF7Error.class new file mode 100644 index 0000000000000000000000000000000000000000..5bce4b14bdf22ea8a87e8d04d9738cbdb2a97403 Binary files /dev/null and b/src/main/resources/org/python/core/codecs$UTF7Error.class differ diff --git a/src/main/resources/org/python/core/codecs.class b/src/main/resources/org/python/core/codecs.class new file mode 100644 index 0000000000000000000000000000000000000000..dc3f39d47fae3738f94142d2a062088d89ae9987 Binary files /dev/null and b/src/main/resources/org/python/core/codecs.class differ diff --git a/src/main/resources/org/python/core/exceptions$BoundStaticJavaMethod.class b/src/main/resources/org/python/core/exceptions$BoundStaticJavaMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..0b6d937bb7cb09546f4b5f4f26e52417c1d31fd2 Binary files /dev/null and b/src/main/resources/org/python/core/exceptions$BoundStaticJavaMethod.class differ diff --git a/src/main/resources/org/python/core/exceptions.class b/src/main/resources/org/python/core/exceptions.class new file mode 100644 index 0000000000000000000000000000000000000000..4c7f56e206d13783e6d381df0bfc666a7c920a8f Binary files /dev/null and b/src/main/resources/org/python/core/exceptions.class differ diff --git a/src/main/resources/org/python/core/imp.class b/src/main/resources/org/python/core/imp.class new file mode 100644 index 0000000000000000000000000000000000000000..b52bc1459842378e6a868429cb56066f4e52cb63 Binary files /dev/null and b/src/main/resources/org/python/core/imp.class differ diff --git a/src/main/resources/org/python/core/io/BinaryIOWrapper.class b/src/main/resources/org/python/core/io/BinaryIOWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..4f3696835392c9bc049c4fc075b7dd1d500d993e Binary files /dev/null and b/src/main/resources/org/python/core/io/BinaryIOWrapper.class differ diff --git a/src/main/resources/org/python/core/io/BufferedIOBase.class b/src/main/resources/org/python/core/io/BufferedIOBase.class new file mode 100644 index 0000000000000000000000000000000000000000..5aeff03bd3b863fcd7883c553d4bb0484f78762f Binary files /dev/null and b/src/main/resources/org/python/core/io/BufferedIOBase.class differ diff --git a/src/main/resources/org/python/core/io/BufferedIOMixin.class b/src/main/resources/org/python/core/io/BufferedIOMixin.class new file mode 100644 index 0000000000000000000000000000000000000000..7ca65b6b9d0581b76e97921eeb71a59560266d4c Binary files /dev/null and b/src/main/resources/org/python/core/io/BufferedIOMixin.class differ diff --git a/src/main/resources/org/python/core/io/BufferedRandom.class b/src/main/resources/org/python/core/io/BufferedRandom.class new file mode 100644 index 0000000000000000000000000000000000000000..def0d6eb8e189bb5ed2d70dc62a0617b02530132 Binary files /dev/null and b/src/main/resources/org/python/core/io/BufferedRandom.class differ diff --git a/src/main/resources/org/python/core/io/BufferedReader.class b/src/main/resources/org/python/core/io/BufferedReader.class new file mode 100644 index 0000000000000000000000000000000000000000..7fb8a37dba18cbe5d6457b2f57058549d8710529 Binary files /dev/null and b/src/main/resources/org/python/core/io/BufferedReader.class differ diff --git a/src/main/resources/org/python/core/io/BufferedWriter.class b/src/main/resources/org/python/core/io/BufferedWriter.class new file mode 100644 index 0000000000000000000000000000000000000000..111a7f527946ac91ef1cdb84b3fb9b51bcb9df36 Binary files /dev/null and b/src/main/resources/org/python/core/io/BufferedWriter.class differ diff --git a/src/main/resources/org/python/core/io/DatagramSocketIO.class b/src/main/resources/org/python/core/io/DatagramSocketIO.class new file mode 100644 index 0000000000000000000000000000000000000000..51fbb5fb8454dddf08d82a9171794075a8f30d0f Binary files /dev/null and b/src/main/resources/org/python/core/io/DatagramSocketIO.class differ diff --git a/src/main/resources/org/python/core/io/FileDescriptors.class b/src/main/resources/org/python/core/io/FileDescriptors.class new file mode 100644 index 0000000000000000000000000000000000000000..636108b4650db095d80d982b2a00a77aff073a02 Binary files /dev/null and b/src/main/resources/org/python/core/io/FileDescriptors.class differ diff --git a/src/main/resources/org/python/core/io/FileIO.class b/src/main/resources/org/python/core/io/FileIO.class new file mode 100644 index 0000000000000000000000000000000000000000..d40597f6c3f0e22a69717571833e470a98270389 Binary files /dev/null and b/src/main/resources/org/python/core/io/FileIO.class differ diff --git a/src/main/resources/org/python/core/io/IOBase.class b/src/main/resources/org/python/core/io/IOBase.class new file mode 100644 index 0000000000000000000000000000000000000000..a1860bd30f649ff794c8b180cc417881aa15e4c9 Binary files /dev/null and b/src/main/resources/org/python/core/io/IOBase.class differ diff --git a/src/main/resources/org/python/core/io/LineBufferedRandom.class b/src/main/resources/org/python/core/io/LineBufferedRandom.class new file mode 100644 index 0000000000000000000000000000000000000000..4e2b5d36c38e240b19f53ba73e3c15fe1704dc76 Binary files /dev/null and b/src/main/resources/org/python/core/io/LineBufferedRandom.class differ diff --git a/src/main/resources/org/python/core/io/LineBufferedWriter.class b/src/main/resources/org/python/core/io/LineBufferedWriter.class new file mode 100644 index 0000000000000000000000000000000000000000..fa72c9583e9dcee6768f6f941ddee842c4b27ac4 Binary files /dev/null and b/src/main/resources/org/python/core/io/LineBufferedWriter.class differ diff --git a/src/main/resources/org/python/core/io/RawIOBase.class b/src/main/resources/org/python/core/io/RawIOBase.class new file mode 100644 index 0000000000000000000000000000000000000000..dac845d27a58af0d90b3031292609492b43e14fd Binary files /dev/null and b/src/main/resources/org/python/core/io/RawIOBase.class differ diff --git a/src/main/resources/org/python/core/io/ServerSocketIO.class b/src/main/resources/org/python/core/io/ServerSocketIO.class new file mode 100644 index 0000000000000000000000000000000000000000..3a029cfed4d1b7a8c8b6c088fa30f7b28ba144c3 Binary files /dev/null and b/src/main/resources/org/python/core/io/ServerSocketIO.class differ diff --git a/src/main/resources/org/python/core/io/SocketIO.class b/src/main/resources/org/python/core/io/SocketIO.class new file mode 100644 index 0000000000000000000000000000000000000000..8f46ccd3eee8addf2dd45c3885993ddffea33cb0 Binary files /dev/null and b/src/main/resources/org/python/core/io/SocketIO.class differ diff --git a/src/main/resources/org/python/core/io/SocketIOBase.class b/src/main/resources/org/python/core/io/SocketIOBase.class new file mode 100644 index 0000000000000000000000000000000000000000..400feec83dfebe208e3bc720d6dfc5f2a317010c Binary files /dev/null and b/src/main/resources/org/python/core/io/SocketIOBase.class differ diff --git a/src/main/resources/org/python/core/io/StreamIO.class b/src/main/resources/org/python/core/io/StreamIO.class new file mode 100644 index 0000000000000000000000000000000000000000..567712a1b88c27f47cfe2674ba2b0e86d6236e82 Binary files /dev/null and b/src/main/resources/org/python/core/io/StreamIO.class differ diff --git a/src/main/resources/org/python/core/io/TextIOBase.class b/src/main/resources/org/python/core/io/TextIOBase.class new file mode 100644 index 0000000000000000000000000000000000000000..3c0ae5d040845ea82ad1e3960f1f034eca968fb9 Binary files /dev/null and b/src/main/resources/org/python/core/io/TextIOBase.class differ diff --git a/src/main/resources/org/python/core/io/TextIOInputStream.class b/src/main/resources/org/python/core/io/TextIOInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..da8348dfb75eb1af7f9456b4458f49862f6d8aa0 Binary files /dev/null and b/src/main/resources/org/python/core/io/TextIOInputStream.class differ diff --git a/src/main/resources/org/python/core/io/TextIOWrapper.class b/src/main/resources/org/python/core/io/TextIOWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..152c30fec022e0d50b21a81b691343ee097af2b0 Binary files /dev/null and b/src/main/resources/org/python/core/io/TextIOWrapper.class differ diff --git a/src/main/resources/org/python/core/io/UniversalIOWrapper$Newline.class b/src/main/resources/org/python/core/io/UniversalIOWrapper$Newline.class new file mode 100644 index 0000000000000000000000000000000000000000..b3ef529c678b0823f68000ccc7428dc733e84e15 Binary files /dev/null and b/src/main/resources/org/python/core/io/UniversalIOWrapper$Newline.class differ diff --git a/src/main/resources/org/python/core/io/UniversalIOWrapper.class b/src/main/resources/org/python/core/io/UniversalIOWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..257650b62821f904a42b86cd7884d5edb32fee14 Binary files /dev/null and b/src/main/resources/org/python/core/io/UniversalIOWrapper.class differ diff --git a/src/main/resources/org/python/core/packagecache/CachedJarsOver64kTest$TestCachePackageManager.class b/src/main/resources/org/python/core/packagecache/CachedJarsOver64kTest$TestCachePackageManager.class new file mode 100644 index 0000000000000000000000000000000000000000..0115b2cc65ab65db57400c70df939be4ecc1ad8b Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/CachedJarsOver64kTest$TestCachePackageManager.class differ diff --git a/src/main/resources/org/python/core/packagecache/CachedJarsOver64kTest.class b/src/main/resources/org/python/core/packagecache/CachedJarsOver64kTest.class new file mode 100644 index 0000000000000000000000000000000000000000..7004d10144885ac20568f5612cdc9eb13ffc50f0 Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/CachedJarsOver64kTest.class differ diff --git a/src/main/resources/org/python/core/packagecache/CachedJarsPackageManager$JarXEntry.class b/src/main/resources/org/python/core/packagecache/CachedJarsPackageManager$JarXEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..416a36389e405f7d8cacffedec9b6154c2658b69 Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/CachedJarsPackageManager$JarXEntry.class differ diff --git a/src/main/resources/org/python/core/packagecache/CachedJarsPackageManager.class b/src/main/resources/org/python/core/packagecache/CachedJarsPackageManager.class new file mode 100644 index 0000000000000000000000000000000000000000..987abe2d3bf9422016fbea624467666b304ebaff Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/CachedJarsPackageManager.class differ diff --git a/src/main/resources/org/python/core/packagecache/PackageManager.class b/src/main/resources/org/python/core/packagecache/PackageManager.class new file mode 100644 index 0000000000000000000000000000000000000000..4c7bfea2f86e32fc69a8c4acc14668e0d465dc52 Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/PackageManager.class differ diff --git a/src/main/resources/org/python/core/packagecache/PathPackageManager$1.class b/src/main/resources/org/python/core/packagecache/PathPackageManager$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c99bb2da19bb2af6efd8ba9805cf50c83737f219 Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/PathPackageManager$1.class differ diff --git a/src/main/resources/org/python/core/packagecache/PathPackageManager$PackageExistsFileFilter.class b/src/main/resources/org/python/core/packagecache/PathPackageManager$PackageExistsFileFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..ccc4c9b5a3c26103eb23f582253e880f732f7073 Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/PathPackageManager$PackageExistsFileFilter.class differ diff --git a/src/main/resources/org/python/core/packagecache/PathPackageManager.class b/src/main/resources/org/python/core/packagecache/PathPackageManager.class new file mode 100644 index 0000000000000000000000000000000000000000..66f55db350f929b11fb53808c9e0b4a49574e79d Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/PathPackageManager.class differ diff --git a/src/main/resources/org/python/core/packagecache/SysPackageManager.class b/src/main/resources/org/python/core/packagecache/SysPackageManager.class new file mode 100644 index 0000000000000000000000000000000000000000..bdf9505b2e6e563358a09dd01f62b8cb6fa91f8f Binary files /dev/null and b/src/main/resources/org/python/core/packagecache/SysPackageManager.class differ diff --git a/src/main/resources/org/python/core/stringlib/FieldNameIterator$Chunk.class b/src/main/resources/org/python/core/stringlib/FieldNameIterator$Chunk.class new file mode 100644 index 0000000000000000000000000000000000000000..3049b04bd2c66407208fc4155cd266bef9e6c861 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/FieldNameIterator$Chunk.class differ diff --git a/src/main/resources/org/python/core/stringlib/FieldNameIterator$PyExposer.class b/src/main/resources/org/python/core/stringlib/FieldNameIterator$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..00b3bbe654e995afa0a65db50be64f75034f1f2d Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/FieldNameIterator$PyExposer.class differ diff --git a/src/main/resources/org/python/core/stringlib/FieldNameIterator$fieldnameiterator___iter___exposer.class b/src/main/resources/org/python/core/stringlib/FieldNameIterator$fieldnameiterator___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..a093534478f86e552a05e076dfaa4f1afd2e6643 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/FieldNameIterator$fieldnameiterator___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/stringlib/FieldNameIterator$fieldnameiterator___iternext___exposer.class b/src/main/resources/org/python/core/stringlib/FieldNameIterator$fieldnameiterator___iternext___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..113e707eaf3d93767179d250e36a8d90d5ebd769 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/FieldNameIterator$fieldnameiterator___iternext___exposer.class differ diff --git a/src/main/resources/org/python/core/stringlib/FieldNameIterator.class b/src/main/resources/org/python/core/stringlib/FieldNameIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..9d055a0cc98811bd199189cfa685d9ca5d95fd8a Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/FieldNameIterator.class differ diff --git a/src/main/resources/org/python/core/stringlib/Formatter.class b/src/main/resources/org/python/core/stringlib/Formatter.class new file mode 100644 index 0000000000000000000000000000000000000000..fe871a23234fd4066a4079421610d7c86e2cac51 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/Formatter.class differ diff --git a/src/main/resources/org/python/core/stringlib/InternalFormatSpec.class b/src/main/resources/org/python/core/stringlib/InternalFormatSpec.class new file mode 100644 index 0000000000000000000000000000000000000000..22dbec834a17b006d1523c5743001077c9aa9dc4 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/InternalFormatSpec.class differ diff --git a/src/main/resources/org/python/core/stringlib/InternalFormatSpecParser.class b/src/main/resources/org/python/core/stringlib/InternalFormatSpecParser.class new file mode 100644 index 0000000000000000000000000000000000000000..36d19bb45fe650da785a8c8c19a4f0c1c07f74c9 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/InternalFormatSpecParser.class differ diff --git a/src/main/resources/org/python/core/stringlib/InternalFormatter$DecimalFormatTemplate.class b/src/main/resources/org/python/core/stringlib/InternalFormatter$DecimalFormatTemplate.class new file mode 100644 index 0000000000000000000000000000000000000000..86961cdc44e327c52aa15b5d6e4f9c5255001b07 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/InternalFormatter$DecimalFormatTemplate.class differ diff --git a/src/main/resources/org/python/core/stringlib/InternalFormatter$PercentageFormatTemplate.class b/src/main/resources/org/python/core/stringlib/InternalFormatter$PercentageFormatTemplate.class new file mode 100644 index 0000000000000000000000000000000000000000..35197edaccfe7881eaa97f6643bb35763a8314d3 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/InternalFormatter$PercentageFormatTemplate.class differ diff --git a/src/main/resources/org/python/core/stringlib/InternalFormatter.class b/src/main/resources/org/python/core/stringlib/InternalFormatter.class new file mode 100644 index 0000000000000000000000000000000000000000..fa81f04ce62d477134ad27dbaa13ef46c20f9c73 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/InternalFormatter.class differ diff --git a/src/main/resources/org/python/core/stringlib/MarkupIterator$Chunk.class b/src/main/resources/org/python/core/stringlib/MarkupIterator$Chunk.class new file mode 100644 index 0000000000000000000000000000000000000000..db244075f2c5b78ece5496be9708ce3de15ee1be Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/MarkupIterator$Chunk.class differ diff --git a/src/main/resources/org/python/core/stringlib/MarkupIterator$FieldNumbering.class b/src/main/resources/org/python/core/stringlib/MarkupIterator$FieldNumbering.class new file mode 100644 index 0000000000000000000000000000000000000000..0374ef22fe47bd020b850e1e094ed4ad2af0b8c5 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/MarkupIterator$FieldNumbering.class differ diff --git a/src/main/resources/org/python/core/stringlib/MarkupIterator$PyExposer.class b/src/main/resources/org/python/core/stringlib/MarkupIterator$PyExposer.class new file mode 100644 index 0000000000000000000000000000000000000000..eb4908059555a748e31c4f4b163272145cbce8bc Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/MarkupIterator$PyExposer.class differ diff --git a/src/main/resources/org/python/core/stringlib/MarkupIterator$formatteriterator___iter___exposer.class b/src/main/resources/org/python/core/stringlib/MarkupIterator$formatteriterator___iter___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..12f17b254c421d2c27c6719ef659bc24384c1820 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/MarkupIterator$formatteriterator___iter___exposer.class differ diff --git a/src/main/resources/org/python/core/stringlib/MarkupIterator$formatteriterator___iternext___exposer.class b/src/main/resources/org/python/core/stringlib/MarkupIterator$formatteriterator___iternext___exposer.class new file mode 100644 index 0000000000000000000000000000000000000000..9731518bdabe888aaef57ef1fd0703318f55404a Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/MarkupIterator$formatteriterator___iternext___exposer.class differ diff --git a/src/main/resources/org/python/core/stringlib/MarkupIterator.class b/src/main/resources/org/python/core/stringlib/MarkupIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..c6afed91fa342baf58197d7295b351207fbcfbb5 Binary files /dev/null and b/src/main/resources/org/python/core/stringlib/MarkupIterator.class differ diff --git a/src/main/resources/org/python/core/ucnhashAPI.class b/src/main/resources/org/python/core/ucnhashAPI.class new file mode 100644 index 0000000000000000000000000000000000000000..e5d516abe24f058f5f4a3634abdaf165809ffe72 Binary files /dev/null and b/src/main/resources/org/python/core/ucnhashAPI.class differ diff --git a/src/main/resources/org/python/core/util/ByteSwapper.class b/src/main/resources/org/python/core/util/ByteSwapper.class new file mode 100644 index 0000000000000000000000000000000000000000..5375e9581e1d4ac4ce161326db02fb3f8f56c713 Binary files /dev/null and b/src/main/resources/org/python/core/util/ByteSwapper.class differ diff --git a/src/main/resources/org/python/core/util/ExtraMath.class b/src/main/resources/org/python/core/util/ExtraMath.class new file mode 100644 index 0000000000000000000000000000000000000000..634481b7f3e4fdb9c6816b31d86ac98089450687 Binary files /dev/null and b/src/main/resources/org/python/core/util/ExtraMath.class differ diff --git a/src/main/resources/org/python/core/util/FileUtil.class b/src/main/resources/org/python/core/util/FileUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..846eb48fd5074051505798b92ea143826d0a1db3 Binary files /dev/null and b/src/main/resources/org/python/core/util/FileUtil.class differ diff --git a/src/main/resources/org/python/core/util/PlatformUtil.class b/src/main/resources/org/python/core/util/PlatformUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..0ee141e7e8c30e6c846f0bd47671b2f8770ba2fb Binary files /dev/null and b/src/main/resources/org/python/core/util/PlatformUtil.class differ diff --git a/src/main/resources/org/python/core/util/RelativeFile.class b/src/main/resources/org/python/core/util/RelativeFile.class new file mode 100644 index 0000000000000000000000000000000000000000..33ca17a15f7d4b1c4271ad234ed7340210c7eb48 Binary files /dev/null and b/src/main/resources/org/python/core/util/RelativeFile.class differ diff --git a/src/main/resources/org/python/core/util/StringUtil.class b/src/main/resources/org/python/core/util/StringUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..064fc5264d28858821ed1456d532aa4136a87ecb Binary files /dev/null and b/src/main/resources/org/python/core/util/StringUtil.class differ diff --git a/src/main/resources/org/python/core/util/importer$Bundle.class b/src/main/resources/org/python/core/util/importer$Bundle.class new file mode 100644 index 0000000000000000000000000000000000000000..e8acae9ae080ea6dd9ff4336a251da98bc691d1a Binary files /dev/null and b/src/main/resources/org/python/core/util/importer$Bundle.class differ diff --git a/src/main/resources/org/python/core/util/importer$EntryType.class b/src/main/resources/org/python/core/util/importer$EntryType.class new file mode 100644 index 0000000000000000000000000000000000000000..11fcd829669d6902449d320b1e85c5b3880be679 Binary files /dev/null and b/src/main/resources/org/python/core/util/importer$EntryType.class differ diff --git a/src/main/resources/org/python/core/util/importer$ModuleCodeData.class b/src/main/resources/org/python/core/util/importer$ModuleCodeData.class new file mode 100644 index 0000000000000000000000000000000000000000..f3335f93107c558281be86ba26679cbc7d13c3d5 Binary files /dev/null and b/src/main/resources/org/python/core/util/importer$ModuleCodeData.class differ diff --git a/src/main/resources/org/python/core/util/importer$ModuleInfo.class b/src/main/resources/org/python/core/util/importer$ModuleInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..0ad1e36dddc4ad23e0d93a759e10e0ee7e494b64 Binary files /dev/null and b/src/main/resources/org/python/core/util/importer$ModuleInfo.class differ diff --git a/src/main/resources/org/python/core/util/importer$SearchOrderEntry.class b/src/main/resources/org/python/core/util/importer$SearchOrderEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..78c8c0a6f5614bb7323fc469b0d579622b531884 Binary files /dev/null and b/src/main/resources/org/python/core/util/importer$SearchOrderEntry.class differ diff --git a/src/main/resources/org/python/core/util/importer.class b/src/main/resources/org/python/core/util/importer.class new file mode 100644 index 0000000000000000000000000000000000000000..482875bf031b901c74ba1826e084e569126e2439 Binary files /dev/null and b/src/main/resources/org/python/core/util/importer.class differ diff --git a/src/main/resources/org/python/expose/BaseTypeBuilder.class b/src/main/resources/org/python/expose/BaseTypeBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..9f1df4f7c705d31cc1ff059308a84f1cc484ad6c Binary files /dev/null and b/src/main/resources/org/python/expose/BaseTypeBuilder.class differ diff --git a/src/main/resources/org/python/expose/ExposeAsSuperclass.class b/src/main/resources/org/python/expose/ExposeAsSuperclass.class new file mode 100644 index 0000000000000000000000000000000000000000..27ec6058abeaca8c0e1923dc5f4360ac06fd1206 Binary files /dev/null and b/src/main/resources/org/python/expose/ExposeAsSuperclass.class differ diff --git a/src/main/resources/org/python/expose/ExposedClassMethod.class b/src/main/resources/org/python/expose/ExposedClassMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..1ef1aba298a7184d91bfe4de445ff06e53d72d46 Binary files /dev/null and b/src/main/resources/org/python/expose/ExposedClassMethod.class differ diff --git a/src/main/resources/org/python/expose/ExposedDelete.class b/src/main/resources/org/python/expose/ExposedDelete.class new file mode 100644 index 0000000000000000000000000000000000000000..b304910664db0aa7d6bca317a684d5b4763c8be5 Binary files /dev/null and b/src/main/resources/org/python/expose/ExposedDelete.class differ diff --git a/src/main/resources/org/python/expose/ExposedGet.class b/src/main/resources/org/python/expose/ExposedGet.class new file mode 100644 index 0000000000000000000000000000000000000000..2ebac9e828e0599042a73fdb3d8416d01651fe1a Binary files /dev/null and b/src/main/resources/org/python/expose/ExposedGet.class differ diff --git a/src/main/resources/org/python/expose/ExposedMethod.class b/src/main/resources/org/python/expose/ExposedMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..19eb885868c34e2a6af0deac9d0cf787830cd875 Binary files /dev/null and b/src/main/resources/org/python/expose/ExposedMethod.class differ diff --git a/src/main/resources/org/python/expose/ExposedNew.class b/src/main/resources/org/python/expose/ExposedNew.class new file mode 100644 index 0000000000000000000000000000000000000000..eb51499ef58d6f7bb47480a737ba30c19a12cc64 Binary files /dev/null and b/src/main/resources/org/python/expose/ExposedNew.class differ diff --git a/src/main/resources/org/python/expose/ExposedSet.class b/src/main/resources/org/python/expose/ExposedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..00355f20f68d331b2977a612fb672925fbd428dd Binary files /dev/null and b/src/main/resources/org/python/expose/ExposedSet.class differ diff --git a/src/main/resources/org/python/expose/ExposedType.class b/src/main/resources/org/python/expose/ExposedType.class new file mode 100644 index 0000000000000000000000000000000000000000..6b64e71ea550d25acbf30f1d2cc5503735849a4a Binary files /dev/null and b/src/main/resources/org/python/expose/ExposedType.class differ diff --git a/src/main/resources/org/python/expose/MethodType.class b/src/main/resources/org/python/expose/MethodType.class new file mode 100644 index 0000000000000000000000000000000000000000..8a7b068f17ccf5e466ac41fa2126254ce8eca8ce Binary files /dev/null and b/src/main/resources/org/python/expose/MethodType.class differ diff --git a/src/main/resources/org/python/expose/TypeBuilder.class b/src/main/resources/org/python/expose/TypeBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..c85376144aa09d60e381bb55f0003c62e03a44eb Binary files /dev/null and b/src/main/resources/org/python/expose/TypeBuilder.class differ diff --git a/src/main/resources/org/python/google/common/annotations/Beta.class b/src/main/resources/org/python/google/common/annotations/Beta.class new file mode 100644 index 0000000000000000000000000000000000000000..72047a72c02ea99b086880f43e2d7160413e615d Binary files /dev/null and b/src/main/resources/org/python/google/common/annotations/Beta.class differ diff --git a/src/main/resources/org/python/google/common/annotations/GwtCompatible.class b/src/main/resources/org/python/google/common/annotations/GwtCompatible.class new file mode 100644 index 0000000000000000000000000000000000000000..a02089e539ea01ffc01dd11d2b19755882068869 Binary files /dev/null and b/src/main/resources/org/python/google/common/annotations/GwtCompatible.class differ diff --git a/src/main/resources/org/python/google/common/annotations/GwtIncompatible.class b/src/main/resources/org/python/google/common/annotations/GwtIncompatible.class new file mode 100644 index 0000000000000000000000000000000000000000..22307227a90d508e8c114f8595d9ccca12aabdf9 Binary files /dev/null and b/src/main/resources/org/python/google/common/annotations/GwtIncompatible.class differ diff --git a/src/main/resources/org/python/google/common/annotations/VisibleForTesting.class b/src/main/resources/org/python/google/common/annotations/VisibleForTesting.class new file mode 100644 index 0000000000000000000000000000000000000000..96365e88f43f59f54ac97b25bc148aad2cca6863 Binary files /dev/null and b/src/main/resources/org/python/google/common/annotations/VisibleForTesting.class differ diff --git a/src/main/resources/org/python/google/common/base/Absent.class b/src/main/resources/org/python/google/common/base/Absent.class new file mode 100644 index 0000000000000000000000000000000000000000..70749380eb5d97cd468c7a0927c2c16bc3c0a4b8 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Absent.class differ diff --git a/src/main/resources/org/python/google/common/base/AbstractIterator$1.class b/src/main/resources/org/python/google/common/base/AbstractIterator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d899b50facec9e29295784fdc1c2712203f56a79 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/AbstractIterator$1.class differ diff --git a/src/main/resources/org/python/google/common/base/AbstractIterator$State.class b/src/main/resources/org/python/google/common/base/AbstractIterator$State.class new file mode 100644 index 0000000000000000000000000000000000000000..4b7f921946f2a9211bf036315b4116bea215e984 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/AbstractIterator$State.class differ diff --git a/src/main/resources/org/python/google/common/base/AbstractIterator.class b/src/main/resources/org/python/google/common/base/AbstractIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..b6f452c20e6bfb785227925a7e2db3287a779dc8 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/AbstractIterator.class differ diff --git a/src/main/resources/org/python/google/common/base/Ascii.class b/src/main/resources/org/python/google/common/base/Ascii.class new file mode 100644 index 0000000000000000000000000000000000000000..dcdb9a793d3bcd0f7cc9fc68c1298698ffea2454 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Ascii.class differ diff --git a/src/main/resources/org/python/google/common/base/CaseFormat$1.class b/src/main/resources/org/python/google/common/base/CaseFormat$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1e713713034f3a3a88945d0a905c3484f3e4e342 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CaseFormat$1.class differ diff --git a/src/main/resources/org/python/google/common/base/CaseFormat.class b/src/main/resources/org/python/google/common/base/CaseFormat.class new file mode 100644 index 0000000000000000000000000000000000000000..e737d9c235422f15988ff391995c56896992d679 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CaseFormat.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$1.class b/src/main/resources/org/python/google/common/base/CharMatcher$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0a04a85bb3fee19b5600418762cbd78cfafbea1f Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$1.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$10.class b/src/main/resources/org/python/google/common/base/CharMatcher$10.class new file mode 100644 index 0000000000000000000000000000000000000000..442e6e97d6b176881ce75a339e66d245cccb64c7 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$10.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$11.class b/src/main/resources/org/python/google/common/base/CharMatcher$11.class new file mode 100644 index 0000000000000000000000000000000000000000..b493a55cc2270a471bd2666b7f62a3332dabab69 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$11.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$12.class b/src/main/resources/org/python/google/common/base/CharMatcher$12.class new file mode 100644 index 0000000000000000000000000000000000000000..71e011d4ca83ff70cbbebbd4bf2dd76d3b30c18a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$12.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$13.class b/src/main/resources/org/python/google/common/base/CharMatcher$13.class new file mode 100644 index 0000000000000000000000000000000000000000..e9b0b6db3c6db44ceb4c116b86879b62a9997e4a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$13.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$14.class b/src/main/resources/org/python/google/common/base/CharMatcher$14.class new file mode 100644 index 0000000000000000000000000000000000000000..60ed0fc674087c7231ffe1e85ca0e6920b1f682f Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$14.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$15.class b/src/main/resources/org/python/google/common/base/CharMatcher$15.class new file mode 100644 index 0000000000000000000000000000000000000000..461390b3767f521d46c69ead2bf18a01d76d9c49 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$15.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$16.class b/src/main/resources/org/python/google/common/base/CharMatcher$16.class new file mode 100644 index 0000000000000000000000000000000000000000..a9b45c92b564bd9f8aec5376f99ec08956dc0d83 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$16.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$2.class b/src/main/resources/org/python/google/common/base/CharMatcher$2.class new file mode 100644 index 0000000000000000000000000000000000000000..f45be85d32f5c2c6ff3a8145e727bbb9b18e4853 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$2.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$3.class b/src/main/resources/org/python/google/common/base/CharMatcher$3.class new file mode 100644 index 0000000000000000000000000000000000000000..f7ef18506fec0bad5eae4cc33a642ec3a94948be Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$3.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$4.class b/src/main/resources/org/python/google/common/base/CharMatcher$4.class new file mode 100644 index 0000000000000000000000000000000000000000..d20c35112126f4c31da35227f2f49768715ac6ba Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$4.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$5.class b/src/main/resources/org/python/google/common/base/CharMatcher$5.class new file mode 100644 index 0000000000000000000000000000000000000000..dd016b5ea4d3aa4e6ab440c2d1aacb4f7e971557 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$5.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$6.class b/src/main/resources/org/python/google/common/base/CharMatcher$6.class new file mode 100644 index 0000000000000000000000000000000000000000..f33d40cd2eaa1803cd45efb28a7f63fa64a4437b Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$6.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$7.class b/src/main/resources/org/python/google/common/base/CharMatcher$7.class new file mode 100644 index 0000000000000000000000000000000000000000..0683ef436882b4dc57176f3cd8f444d0aacf2a53 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$7.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$8.class b/src/main/resources/org/python/google/common/base/CharMatcher$8.class new file mode 100644 index 0000000000000000000000000000000000000000..83c68af3e7877684250a865b7192051cb7c183e4 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$8.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$9.class b/src/main/resources/org/python/google/common/base/CharMatcher$9.class new file mode 100644 index 0000000000000000000000000000000000000000..ec3bde50e10bc47a71a26867236329e1fd4e964b Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$9.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$And.class b/src/main/resources/org/python/google/common/base/CharMatcher$And.class new file mode 100644 index 0000000000000000000000000000000000000000..197bc8a8ac9ef6cf6483d5985a270dd56d0560bb Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$And.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$LookupTable.class b/src/main/resources/org/python/google/common/base/CharMatcher$LookupTable.class new file mode 100644 index 0000000000000000000000000000000000000000..c1d63dd7c1f0f770eaa590af178426b6c669ea05 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$LookupTable.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher$Or.class b/src/main/resources/org/python/google/common/base/CharMatcher$Or.class new file mode 100644 index 0000000000000000000000000000000000000000..7f439b316f44182b647ab8f7ab9a1c56031cf745 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher$Or.class differ diff --git a/src/main/resources/org/python/google/common/base/CharMatcher.class b/src/main/resources/org/python/google/common/base/CharMatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..83e7083fecb6ec8a6f4073f3bceb7771a63c37fc Binary files /dev/null and b/src/main/resources/org/python/google/common/base/CharMatcher.class differ diff --git a/src/main/resources/org/python/google/common/base/Charsets.class b/src/main/resources/org/python/google/common/base/Charsets.class new file mode 100644 index 0000000000000000000000000000000000000000..2080efdfaeb0f2836f5d68c9aa498e9e8a214f2c Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Charsets.class differ diff --git a/src/main/resources/org/python/google/common/base/Defaults.class b/src/main/resources/org/python/google/common/base/Defaults.class new file mode 100644 index 0000000000000000000000000000000000000000..73f7a48c4f5a3a1287322ca5034e7dbbaa8c3e5a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Defaults.class differ diff --git a/src/main/resources/org/python/google/common/base/Enums$1.class b/src/main/resources/org/python/google/common/base/Enums$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6e3cbdba29a7f1cc40f2ca0a7daa544a327a13b3 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Enums$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Enums$ValueOfFunction.class b/src/main/resources/org/python/google/common/base/Enums$ValueOfFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..82b2e44ee50ebe33dbfca2325a538fb70a3e01e5 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Enums$ValueOfFunction.class differ diff --git a/src/main/resources/org/python/google/common/base/Enums.class b/src/main/resources/org/python/google/common/base/Enums.class new file mode 100644 index 0000000000000000000000000000000000000000..117e3cea86e429abe0e10257f9986c365b674df2 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Enums.class differ diff --git a/src/main/resources/org/python/google/common/base/Equivalence$1.class b/src/main/resources/org/python/google/common/base/Equivalence$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9441a5d6a8e38aecdb7ebc64699358c612132646 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Equivalence$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Equivalence$Equals.class b/src/main/resources/org/python/google/common/base/Equivalence$Equals.class new file mode 100644 index 0000000000000000000000000000000000000000..cd01796b2e18bfb25503040519e166d2026bd5a4 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Equivalence$Equals.class differ diff --git a/src/main/resources/org/python/google/common/base/Equivalence$EquivalentToPredicate.class b/src/main/resources/org/python/google/common/base/Equivalence$EquivalentToPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..3e3548a46a98d16fa93eb69621ce868d019baa0b Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Equivalence$EquivalentToPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Equivalence$Identity.class b/src/main/resources/org/python/google/common/base/Equivalence$Identity.class new file mode 100644 index 0000000000000000000000000000000000000000..2fccc0fda38b5475b8c099ff4edb874a0bc24aae Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Equivalence$Identity.class differ diff --git a/src/main/resources/org/python/google/common/base/Equivalence$Wrapper.class b/src/main/resources/org/python/google/common/base/Equivalence$Wrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..031062f65b5c4f686112e5c73db418b76302b058 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Equivalence$Wrapper.class differ diff --git a/src/main/resources/org/python/google/common/base/Equivalence.class b/src/main/resources/org/python/google/common/base/Equivalence.class new file mode 100644 index 0000000000000000000000000000000000000000..7697da83eed7bc9a3faeb0f600449af8d975e00b Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Equivalence.class differ diff --git a/src/main/resources/org/python/google/common/base/Equivalences.class b/src/main/resources/org/python/google/common/base/Equivalences.class new file mode 100644 index 0000000000000000000000000000000000000000..4a6ca717e1c7009eeab6b8fbe89feb6591f0fd00 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Equivalences.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizablePhantomReference.class b/src/main/resources/org/python/google/common/base/FinalizablePhantomReference.class new file mode 100644 index 0000000000000000000000000000000000000000..6d0769ca8e796924be4409696c7badb4e5782a49 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizablePhantomReference.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableReference.class b/src/main/resources/org/python/google/common/base/FinalizableReference.class new file mode 100644 index 0000000000000000000000000000000000000000..c581f32773a002b9b98038a10bfe196d287a491d Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableReference.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$DecoupledLoader.class b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$DecoupledLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..8a0221ba6c2beaed399820f32aea6b15b205678b Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$DecoupledLoader.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$DirectLoader.class b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$DirectLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..a88abac5d03a674329268f423f3d884561826300 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$DirectLoader.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$FinalizerLoader.class b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$FinalizerLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..519c48e4282a1026ef1b90d446245628c6879392 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$FinalizerLoader.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$SystemLoader.class b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$SystemLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..ca4bdce94c2ed98b0a4444e5e3e1e123572f2d8d Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue$SystemLoader.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue.class b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..e1ed04d9a50ecc34dda7ea5b5fcd717ad62476f2 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableReferenceQueue.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableSoftReference.class b/src/main/resources/org/python/google/common/base/FinalizableSoftReference.class new file mode 100644 index 0000000000000000000000000000000000000000..54be4418a7f65b9e0f9153a5492ff830a264677f Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableSoftReference.class differ diff --git a/src/main/resources/org/python/google/common/base/FinalizableWeakReference.class b/src/main/resources/org/python/google/common/base/FinalizableWeakReference.class new file mode 100644 index 0000000000000000000000000000000000000000..5db4b27427c70f5c67183b71e035973a6a470a47 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FinalizableWeakReference.class differ diff --git a/src/main/resources/org/python/google/common/base/Function.class b/src/main/resources/org/python/google/common/base/Function.class new file mode 100644 index 0000000000000000000000000000000000000000..174675645d639ddff2817dd0caf903b4d0873947 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Function.class differ diff --git a/src/main/resources/org/python/google/common/base/FunctionalEquivalence.class b/src/main/resources/org/python/google/common/base/FunctionalEquivalence.class new file mode 100644 index 0000000000000000000000000000000000000000..7139740d42ea401a839663f9d835ed6a365dadc8 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/FunctionalEquivalence.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$1.class b/src/main/resources/org/python/google/common/base/Functions$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9846a3885fd277923e2f8351d49d9e9b6a0625a2 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$ConstantFunction.class b/src/main/resources/org/python/google/common/base/Functions$ConstantFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..949ac796918c2493f9498d300e3a73c96be10f00 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$ConstantFunction.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$ForMapWithDefault.class b/src/main/resources/org/python/google/common/base/Functions$ForMapWithDefault.class new file mode 100644 index 0000000000000000000000000000000000000000..4a3b1a65e6937612cb8b0c61cd8670c5909c97c9 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$ForMapWithDefault.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$FunctionComposition.class b/src/main/resources/org/python/google/common/base/Functions$FunctionComposition.class new file mode 100644 index 0000000000000000000000000000000000000000..c15607858ab1bd8073d6e586df8c7a44d80f4cc0 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$FunctionComposition.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$FunctionForMapNoDefault.class b/src/main/resources/org/python/google/common/base/Functions$FunctionForMapNoDefault.class new file mode 100644 index 0000000000000000000000000000000000000000..a16dab34883dbc12bdcb637f88329788aad15b1d Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$FunctionForMapNoDefault.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$IdentityFunction.class b/src/main/resources/org/python/google/common/base/Functions$IdentityFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..fbdc3697a8cac4b3d049d77753a23110a32baf62 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$IdentityFunction.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$PredicateFunction.class b/src/main/resources/org/python/google/common/base/Functions$PredicateFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..472402bd4a8ee925ad6d49889e9ce8c3d86a0257 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$PredicateFunction.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$SupplierFunction.class b/src/main/resources/org/python/google/common/base/Functions$SupplierFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..eae29b2de317a5c1d5055012a1fa9c5724407e65 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$SupplierFunction.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions$ToStringFunction.class b/src/main/resources/org/python/google/common/base/Functions$ToStringFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..674d7d21aa9a1185dbee13ccba00aade60f87392 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions$ToStringFunction.class differ diff --git a/src/main/resources/org/python/google/common/base/Functions.class b/src/main/resources/org/python/google/common/base/Functions.class new file mode 100644 index 0000000000000000000000000000000000000000..95605f01ab27e30d450342c1b21dcec28cd40942 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Functions.class differ diff --git a/src/main/resources/org/python/google/common/base/Joiner$1.class b/src/main/resources/org/python/google/common/base/Joiner$1.class new file mode 100644 index 0000000000000000000000000000000000000000..aa65dbce592119a173a5219806e71fa1ebc700df Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Joiner$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Joiner$2.class b/src/main/resources/org/python/google/common/base/Joiner$2.class new file mode 100644 index 0000000000000000000000000000000000000000..e4c53c40b3a656165048666120d1b520e97abfe8 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Joiner$2.class differ diff --git a/src/main/resources/org/python/google/common/base/Joiner$3.class b/src/main/resources/org/python/google/common/base/Joiner$3.class new file mode 100644 index 0000000000000000000000000000000000000000..2a5bc9295c63a49afd21e32bbd4aff2e1b23464a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Joiner$3.class differ diff --git a/src/main/resources/org/python/google/common/base/Joiner$MapJoiner.class b/src/main/resources/org/python/google/common/base/Joiner$MapJoiner.class new file mode 100644 index 0000000000000000000000000000000000000000..e01baa543bd243db58a510c48eb61f784549be57 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Joiner$MapJoiner.class differ diff --git a/src/main/resources/org/python/google/common/base/Joiner.class b/src/main/resources/org/python/google/common/base/Joiner.class new file mode 100644 index 0000000000000000000000000000000000000000..d922340969c779fbe2858aee6d71cee0b42e8c01 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Joiner.class differ diff --git a/src/main/resources/org/python/google/common/base/MediumCharMatcher.class b/src/main/resources/org/python/google/common/base/MediumCharMatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..7ac5f2bd694e2fcbfe0929e8dd012ea264f51d70 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/MediumCharMatcher.class differ diff --git a/src/main/resources/org/python/google/common/base/Objects$1.class b/src/main/resources/org/python/google/common/base/Objects$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9670b71a992555ae37bc7fc2b74e94e4f9cb86da Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Objects$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Objects$ToStringHelper$ValueHolder.class b/src/main/resources/org/python/google/common/base/Objects$ToStringHelper$ValueHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..7e69f8703312f153705019a2d9f17f86883fdd34 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Objects$ToStringHelper$ValueHolder.class differ diff --git a/src/main/resources/org/python/google/common/base/Objects$ToStringHelper.class b/src/main/resources/org/python/google/common/base/Objects$ToStringHelper.class new file mode 100644 index 0000000000000000000000000000000000000000..e42aa57f32ab96bcff8a59ddcbe7a73e62cd0485 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Objects$ToStringHelper.class differ diff --git a/src/main/resources/org/python/google/common/base/Objects.class b/src/main/resources/org/python/google/common/base/Objects.class new file mode 100644 index 0000000000000000000000000000000000000000..1553d734fc2c44bc6810b1aa3cf6f5afe2641ecb Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Objects.class differ diff --git a/src/main/resources/org/python/google/common/base/Optional$1$1.class b/src/main/resources/org/python/google/common/base/Optional$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e977e3995eba9010f1db07e78d3b186f240cbc7b Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Optional$1$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Optional$1.class b/src/main/resources/org/python/google/common/base/Optional$1.class new file mode 100644 index 0000000000000000000000000000000000000000..927b31d860a2572a1deca8f35269b7a766c58d6a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Optional$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Optional.class b/src/main/resources/org/python/google/common/base/Optional.class new file mode 100644 index 0000000000000000000000000000000000000000..d6e6a0b18c17d3151301e07d4b1b64cd6856cf9a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Optional.class differ diff --git a/src/main/resources/org/python/google/common/base/PairwiseEquivalence.class b/src/main/resources/org/python/google/common/base/PairwiseEquivalence.class new file mode 100644 index 0000000000000000000000000000000000000000..467df3ed3fb799efe74f8f4d3646e7d61d03a27e Binary files /dev/null and b/src/main/resources/org/python/google/common/base/PairwiseEquivalence.class differ diff --git a/src/main/resources/org/python/google/common/base/Platform$1.class b/src/main/resources/org/python/google/common/base/Platform$1.class new file mode 100644 index 0000000000000000000000000000000000000000..afca56ec2ec036fc20558de77bf447bb929def7d Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Platform$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Platform.class b/src/main/resources/org/python/google/common/base/Platform.class new file mode 100644 index 0000000000000000000000000000000000000000..46b0d8f957e85ed8069cff1c3483912a89619493 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Platform.class differ diff --git a/src/main/resources/org/python/google/common/base/Preconditions.class b/src/main/resources/org/python/google/common/base/Preconditions.class new file mode 100644 index 0000000000000000000000000000000000000000..2d09eeb57cf4381eb5e0819cefe50b223dc212a2 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Preconditions.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicate.class b/src/main/resources/org/python/google/common/base/Predicate.class new file mode 100644 index 0000000000000000000000000000000000000000..3e0d2f89a01437507d070199316c66377f7e8839 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$1.class b/src/main/resources/org/python/google/common/base/Predicates$1.class new file mode 100644 index 0000000000000000000000000000000000000000..97b769cb98770ad2ddf6c877c0eb2c497864350d Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$AndPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$AndPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..5310a1407ff27ed9995295a2298489b38ea137aa Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$AndPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$AssignableFromPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$AssignableFromPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..e5349d465a9738e7c1cd4ee54aeea44f1d3d45fb Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$AssignableFromPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$CompositionPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$CompositionPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..ae8da7545cda88fe4709a6252bf02690747ab289 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$CompositionPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$ContainsPatternPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$ContainsPatternPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..43b13db11862f6b2b93b2786b1a00e7e8e69b982 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$ContainsPatternPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$InPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$InPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..5de33b959594f8d415ab57c05c7e3191f0c1b274 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$InPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$InstanceOfPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$InstanceOfPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..326c01cf73ab65dc60b1814cdb55b9bdaec11486 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$InstanceOfPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$IsEqualToPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$IsEqualToPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..644aa95fcbd5861dcdb6cdb0ec63becf814f32e3 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$IsEqualToPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$NotPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$NotPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..fc25f7fd70e98c722c2001de15fa902206d8bf35 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$NotPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$1.class b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e7b8b594557584497a9657e712842c537c54c20f Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$2.class b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$2.class new file mode 100644 index 0000000000000000000000000000000000000000..e7768b9843ca53fff3547f70bcc70190e4019e70 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$2.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$3.class b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$3.class new file mode 100644 index 0000000000000000000000000000000000000000..3c3b661d0a92a0607a5a6f4f2fadb01d19220426 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$3.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$4.class b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$4.class new file mode 100644 index 0000000000000000000000000000000000000000..cc66afbdceb6d6bdb3c83218d763ca531757904d Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate$4.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..611d070174fcff396217b517e3a9b2d6260461ba Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$ObjectPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates$OrPredicate.class b/src/main/resources/org/python/google/common/base/Predicates$OrPredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..8fdf64a16abeda4c64539fac9c6f1a00fced097c Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates$OrPredicate.class differ diff --git a/src/main/resources/org/python/google/common/base/Predicates.class b/src/main/resources/org/python/google/common/base/Predicates.class new file mode 100644 index 0000000000000000000000000000000000000000..35517e25a09e27f778109355be75452510f4e721 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Predicates.class differ diff --git a/src/main/resources/org/python/google/common/base/Present.class b/src/main/resources/org/python/google/common/base/Present.class new file mode 100644 index 0000000000000000000000000000000000000000..b470d66d67cb5e855d7da2e94592cea0572a94a1 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Present.class differ diff --git a/src/main/resources/org/python/google/common/base/SmallCharMatcher.class b/src/main/resources/org/python/google/common/base/SmallCharMatcher.class new file mode 100644 index 0000000000000000000000000000000000000000..2a204367586bcdc602dd64600680379e8133c58d Binary files /dev/null and b/src/main/resources/org/python/google/common/base/SmallCharMatcher.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$1$1.class b/src/main/resources/org/python/google/common/base/Splitter$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..eab5a3c0b0aa96e774219780a0c1a09d47b8c5c5 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$1$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$1.class b/src/main/resources/org/python/google/common/base/Splitter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5256949b3e447fc4fbead287ec53ff83e9b61416 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$2$1.class b/src/main/resources/org/python/google/common/base/Splitter$2$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4b63a96ff107f4c238e833bd77c4c44b945317d4 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$2$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$2.class b/src/main/resources/org/python/google/common/base/Splitter$2.class new file mode 100644 index 0000000000000000000000000000000000000000..78056854337e5237b7e0c3f86643d94fd33d690a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$2.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$3$1.class b/src/main/resources/org/python/google/common/base/Splitter$3$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2ecb53d991052b17b1dab0de48dd66f3bf359f09 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$3$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$3.class b/src/main/resources/org/python/google/common/base/Splitter$3.class new file mode 100644 index 0000000000000000000000000000000000000000..e69f4d6db9f7cba6577cd61dfe4e7307da8f79c3 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$3.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$4$1.class b/src/main/resources/org/python/google/common/base/Splitter$4$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5615c34d0211ae41bc6620d10e378a0affb8c91a Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$4$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$4.class b/src/main/resources/org/python/google/common/base/Splitter$4.class new file mode 100644 index 0000000000000000000000000000000000000000..71e4b826f96befc68739002be4c0550904c53e94 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$4.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$5.class b/src/main/resources/org/python/google/common/base/Splitter$5.class new file mode 100644 index 0000000000000000000000000000000000000000..7d5c3823f997fd7cc540ddd51a2a0f21cfbb32ce Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$5.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$MapSplitter.class b/src/main/resources/org/python/google/common/base/Splitter$MapSplitter.class new file mode 100644 index 0000000000000000000000000000000000000000..28c4cd7bff791520f9358ebbe51c796b664a18c0 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$MapSplitter.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$SplittingIterator.class b/src/main/resources/org/python/google/common/base/Splitter$SplittingIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..f82e55226f6e1bed6179bf3710aba031bd0942f5 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$SplittingIterator.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter$Strategy.class b/src/main/resources/org/python/google/common/base/Splitter$Strategy.class new file mode 100644 index 0000000000000000000000000000000000000000..ae34cb59b0bf733829e5b816cb556b6cc983106f Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter$Strategy.class differ diff --git a/src/main/resources/org/python/google/common/base/Splitter.class b/src/main/resources/org/python/google/common/base/Splitter.class new file mode 100644 index 0000000000000000000000000000000000000000..0bb83ab9889f9364627b3e3a019722d9df022df4 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Splitter.class differ diff --git a/src/main/resources/org/python/google/common/base/Stopwatch$1.class b/src/main/resources/org/python/google/common/base/Stopwatch$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e1ad9acf4e64005ccda9dcdfba06b74e072e38bf Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Stopwatch$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Stopwatch.class b/src/main/resources/org/python/google/common/base/Stopwatch.class new file mode 100644 index 0000000000000000000000000000000000000000..04f60a42f443609395624ab6781e33d464cbaa02 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Stopwatch.class differ diff --git a/src/main/resources/org/python/google/common/base/Strings.class b/src/main/resources/org/python/google/common/base/Strings.class new file mode 100644 index 0000000000000000000000000000000000000000..5d5d249f6a9f262fec90822ddbf2d2d20285c68e Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Strings.class differ diff --git a/src/main/resources/org/python/google/common/base/Supplier.class b/src/main/resources/org/python/google/common/base/Supplier.class new file mode 100644 index 0000000000000000000000000000000000000000..90d22a0d85867d2f3b4e09ec1e8b9610c9b92409 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Supplier.class differ diff --git a/src/main/resources/org/python/google/common/base/Suppliers$ExpiringMemoizingSupplier.class b/src/main/resources/org/python/google/common/base/Suppliers$ExpiringMemoizingSupplier.class new file mode 100644 index 0000000000000000000000000000000000000000..19977af50ea7ad4eced429b23361bd98c1df772f Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Suppliers$ExpiringMemoizingSupplier.class differ diff --git a/src/main/resources/org/python/google/common/base/Suppliers$MemoizingSupplier.class b/src/main/resources/org/python/google/common/base/Suppliers$MemoizingSupplier.class new file mode 100644 index 0000000000000000000000000000000000000000..5afd75deba240e595830570944f480c2de1a4439 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Suppliers$MemoizingSupplier.class differ diff --git a/src/main/resources/org/python/google/common/base/Suppliers$SupplierComposition.class b/src/main/resources/org/python/google/common/base/Suppliers$SupplierComposition.class new file mode 100644 index 0000000000000000000000000000000000000000..b11e3fcbbac6216b6750509d382ba0204620ffc0 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Suppliers$SupplierComposition.class differ diff --git a/src/main/resources/org/python/google/common/base/Suppliers$SupplierFunction.class b/src/main/resources/org/python/google/common/base/Suppliers$SupplierFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..de1ec1ef05681987344f0cc7f038af22e60928c1 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Suppliers$SupplierFunction.class differ diff --git a/src/main/resources/org/python/google/common/base/Suppliers$SupplierOfInstance.class b/src/main/resources/org/python/google/common/base/Suppliers$SupplierOfInstance.class new file mode 100644 index 0000000000000000000000000000000000000000..6d4d1a5ed0e4199fb6f5b86e9329361314a65096 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Suppliers$SupplierOfInstance.class differ diff --git a/src/main/resources/org/python/google/common/base/Suppliers$ThreadSafeSupplier.class b/src/main/resources/org/python/google/common/base/Suppliers$ThreadSafeSupplier.class new file mode 100644 index 0000000000000000000000000000000000000000..0e6b6b77d4a9c2b7779b2ff464b6b676a4d06c51 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Suppliers$ThreadSafeSupplier.class differ diff --git a/src/main/resources/org/python/google/common/base/Suppliers.class b/src/main/resources/org/python/google/common/base/Suppliers.class new file mode 100644 index 0000000000000000000000000000000000000000..8462aa545885745345aa1afa3da3d5c212a9d55c Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Suppliers.class differ diff --git a/src/main/resources/org/python/google/common/base/Throwables.class b/src/main/resources/org/python/google/common/base/Throwables.class new file mode 100644 index 0000000000000000000000000000000000000000..11b85c5ea0cf07c3d633ea837eb68b569a269103 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Throwables.class differ diff --git a/src/main/resources/org/python/google/common/base/Ticker$1.class b/src/main/resources/org/python/google/common/base/Ticker$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6c520cc5fa78c710562887b8f4192aaa52b30720 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Ticker$1.class differ diff --git a/src/main/resources/org/python/google/common/base/Ticker.class b/src/main/resources/org/python/google/common/base/Ticker.class new file mode 100644 index 0000000000000000000000000000000000000000..364b8f486b08ef91a2fe0003352c65dfdd525d5c Binary files /dev/null and b/src/main/resources/org/python/google/common/base/Ticker.class differ diff --git a/src/main/resources/org/python/google/common/base/internal/Finalizer$1.class b/src/main/resources/org/python/google/common/base/internal/Finalizer$1.class new file mode 100644 index 0000000000000000000000000000000000000000..90062bb3a7db44011ee145f34cf0f9b3e314ccae Binary files /dev/null and b/src/main/resources/org/python/google/common/base/internal/Finalizer$1.class differ diff --git a/src/main/resources/org/python/google/common/base/internal/Finalizer$ShutDown.class b/src/main/resources/org/python/google/common/base/internal/Finalizer$ShutDown.class new file mode 100644 index 0000000000000000000000000000000000000000..3b04c19a358bdb9cc5f9a23a49c41faae1659525 Binary files /dev/null and b/src/main/resources/org/python/google/common/base/internal/Finalizer$ShutDown.class differ diff --git a/src/main/resources/org/python/google/common/base/internal/Finalizer.class b/src/main/resources/org/python/google/common/base/internal/Finalizer.class new file mode 100644 index 0000000000000000000000000000000000000000..792a2a08ff61a0edcf28ac3016701322eadfdf7f Binary files /dev/null and b/src/main/resources/org/python/google/common/base/internal/Finalizer.class differ diff --git a/src/main/resources/org/python/google/common/cache/AbstractCache$SimpleStatsCounter.class b/src/main/resources/org/python/google/common/cache/AbstractCache$SimpleStatsCounter.class new file mode 100644 index 0000000000000000000000000000000000000000..89d49418c4f16fc3f1cf5a3e7aa992c10566d52d Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/AbstractCache$SimpleStatsCounter.class differ diff --git a/src/main/resources/org/python/google/common/cache/AbstractCache$StatsCounter.class b/src/main/resources/org/python/google/common/cache/AbstractCache$StatsCounter.class new file mode 100644 index 0000000000000000000000000000000000000000..5c9be8c4901f182f8007c8c317b0c581e602cce1 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/AbstractCache$StatsCounter.class differ diff --git a/src/main/resources/org/python/google/common/cache/AbstractCache.class b/src/main/resources/org/python/google/common/cache/AbstractCache.class new file mode 100644 index 0000000000000000000000000000000000000000..68b277ac968303556a1c5d2548c47879097fe6be Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/AbstractCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/AbstractLoadingCache.class b/src/main/resources/org/python/google/common/cache/AbstractLoadingCache.class new file mode 100644 index 0000000000000000000000000000000000000000..c8d4d4c1325b1c4349b0547111a627aa88a8c214 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/AbstractLoadingCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/Cache.class b/src/main/resources/org/python/google/common/cache/Cache.class new file mode 100644 index 0000000000000000000000000000000000000000..dc164a6c060193a455f5253beb609c9b92d8f107 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/Cache.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilder$1.class b/src/main/resources/org/python/google/common/cache/CacheBuilder$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e397d6446df97189f60e30826f8bc6c37198b0be Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilder$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilder$2.class b/src/main/resources/org/python/google/common/cache/CacheBuilder$2.class new file mode 100644 index 0000000000000000000000000000000000000000..afc2e0c19eacbbd1d2f34d206deb55cdf8f38920 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilder$2.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilder$3.class b/src/main/resources/org/python/google/common/cache/CacheBuilder$3.class new file mode 100644 index 0000000000000000000000000000000000000000..24ea0564e70a187bf371379ecb40174e40e969e3 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilder$3.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilder$NullListener.class b/src/main/resources/org/python/google/common/cache/CacheBuilder$NullListener.class new file mode 100644 index 0000000000000000000000000000000000000000..09a488bd9ddc0048a4625c6bb0db24b8d4aab54f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilder$NullListener.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilder$OneWeigher.class b/src/main/resources/org/python/google/common/cache/CacheBuilder$OneWeigher.class new file mode 100644 index 0000000000000000000000000000000000000000..affb6c98d8250d3de4f3f7a799a4d9554cbdafb5 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilder$OneWeigher.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilder.class b/src/main/resources/org/python/google/common/cache/CacheBuilder.class new file mode 100644 index 0000000000000000000000000000000000000000..621d1b4b3de6f0bf03b1d450c97a41d480d16b4d Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilder.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$1.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$1.class new file mode 100644 index 0000000000000000000000000000000000000000..654c3f02f67358c71b421b8d669eb24814e56850 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$AccessDurationParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$AccessDurationParser.class new file mode 100644 index 0000000000000000000000000000000000000000..36a762238337f0da35ef976b60decd09779cf8b9 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$AccessDurationParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ConcurrencyLevelParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ConcurrencyLevelParser.class new file mode 100644 index 0000000000000000000000000000000000000000..c3d4b95c000aafc6383e442f8c9af6b7f54350dd Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ConcurrencyLevelParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$DurationParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$DurationParser.class new file mode 100644 index 0000000000000000000000000000000000000000..7e0ce6b07b2cac07bd3f4911f5e8adb1052d8065 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$DurationParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$InitialCapacityParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$InitialCapacityParser.class new file mode 100644 index 0000000000000000000000000000000000000000..967b553cead62929463527c1eff752ef03d327f2 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$InitialCapacityParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$IntegerParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$IntegerParser.class new file mode 100644 index 0000000000000000000000000000000000000000..10a15d4cd8abd301dcf59114f1f9fefd91e2bfa5 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$IntegerParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$KeyStrengthParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$KeyStrengthParser.class new file mode 100644 index 0000000000000000000000000000000000000000..9655caa70f0ec8f26bf32bf19789693086fee2b1 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$KeyStrengthParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$LongParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$LongParser.class new file mode 100644 index 0000000000000000000000000000000000000000..34bfc765dcb04c4f758a6eba224209a698482e74 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$LongParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$MaximumSizeParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$MaximumSizeParser.class new file mode 100644 index 0000000000000000000000000000000000000000..7c10b3b492f1403088b3d476a268f98beca96ae4 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$MaximumSizeParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$MaximumWeightParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$MaximumWeightParser.class new file mode 100644 index 0000000000000000000000000000000000000000..8dd2c5de0431aec35aeb47d720f2ea788ce8094d Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$MaximumWeightParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$RefreshDurationParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$RefreshDurationParser.class new file mode 100644 index 0000000000000000000000000000000000000000..41319c3526a748fa67da63c8f9c5a0b282725f58 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$RefreshDurationParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ValueParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ValueParser.class new file mode 100644 index 0000000000000000000000000000000000000000..1ae350fbb4b4273da98f17319b4f3c52cc6b6590 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ValueParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ValueStrengthParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ValueStrengthParser.class new file mode 100644 index 0000000000000000000000000000000000000000..59052de5f590246e4bb1ae63430eadf2432a7757 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$ValueStrengthParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$WriteDurationParser.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$WriteDurationParser.class new file mode 100644 index 0000000000000000000000000000000000000000..2a45ee1b4902015959906e441b1e64c76397d483 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec$WriteDurationParser.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheBuilderSpec.class b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec.class new file mode 100644 index 0000000000000000000000000000000000000000..bb13402f2aae869d1fca03c867a610240f617e14 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheBuilderSpec.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheLoader$FunctionToCacheLoader.class b/src/main/resources/org/python/google/common/cache/CacheLoader$FunctionToCacheLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..934e632fcaeb0f60e2d8d6d47157a18c571d9ade Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheLoader$FunctionToCacheLoader.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheLoader$InvalidCacheLoadException.class b/src/main/resources/org/python/google/common/cache/CacheLoader$InvalidCacheLoadException.class new file mode 100644 index 0000000000000000000000000000000000000000..9d17bfd3948dd74c5420287155918f73cc219ab3 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheLoader$InvalidCacheLoadException.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheLoader$SupplierToCacheLoader.class b/src/main/resources/org/python/google/common/cache/CacheLoader$SupplierToCacheLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..160f2f351320b4138e05f04e3556eb4086fadf73 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheLoader$SupplierToCacheLoader.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheLoader$UnsupportedLoadingOperationException.class b/src/main/resources/org/python/google/common/cache/CacheLoader$UnsupportedLoadingOperationException.class new file mode 100644 index 0000000000000000000000000000000000000000..33c2b5881d5ad849030bc41225b1ea1035f0d931 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheLoader$UnsupportedLoadingOperationException.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheLoader.class b/src/main/resources/org/python/google/common/cache/CacheLoader.class new file mode 100644 index 0000000000000000000000000000000000000000..0b643ffe0944f8fe29bf8fcd41c5779ba9b85927 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheLoader.class differ diff --git a/src/main/resources/org/python/google/common/cache/CacheStats.class b/src/main/resources/org/python/google/common/cache/CacheStats.class new file mode 100644 index 0000000000000000000000000000000000000000..8a01eada883fad946b6328be729ee752a1c51934 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/CacheStats.class differ diff --git a/src/main/resources/org/python/google/common/cache/ForwardingCache$SimpleForwardingCache.class b/src/main/resources/org/python/google/common/cache/ForwardingCache$SimpleForwardingCache.class new file mode 100644 index 0000000000000000000000000000000000000000..508ccca7b519d42eae8abd9eff1d3cce110648d2 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/ForwardingCache$SimpleForwardingCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/ForwardingCache.class b/src/main/resources/org/python/google/common/cache/ForwardingCache.class new file mode 100644 index 0000000000000000000000000000000000000000..941f79dc2670b22e1de4fd2bbdad69d0226b223f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/ForwardingCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/ForwardingLoadingCache$SimpleForwardingLoadingCache.class b/src/main/resources/org/python/google/common/cache/ForwardingLoadingCache$SimpleForwardingLoadingCache.class new file mode 100644 index 0000000000000000000000000000000000000000..69db09520b15ae640befe411b39786344e98491f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/ForwardingLoadingCache$SimpleForwardingLoadingCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/ForwardingLoadingCache.class b/src/main/resources/org/python/google/common/cache/ForwardingLoadingCache.class new file mode 100644 index 0000000000000000000000000000000000000000..10208074bff2c5ad93ac3101ea527d6c6585312c Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/ForwardingLoadingCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/LoadingCache.class b/src/main/resources/org/python/google/common/cache/LoadingCache.class new file mode 100644 index 0000000000000000000000000000000000000000..f95f0b7f0e7ba47b2638e2113b0bcacedae6e587 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LoadingCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$1.class b/src/main/resources/org/python/google/common/cache/LocalCache$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8c2205787aa22fc0431aca3652523cad2b14f423 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$2.class b/src/main/resources/org/python/google/common/cache/LocalCache$2.class new file mode 100644 index 0000000000000000000000000000000000000000..9dc53021363f3308920312a503c07c820ab01ac0 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$2.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$AbstractReferenceEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$AbstractReferenceEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..0f0599c362551350e333dae534c12daf8e72b1ec Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$AbstractReferenceEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue$1.class b/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9fb513d6f8265e56d8da1a6371969594331931d8 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue$2.class b/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue$2.class new file mode 100644 index 0000000000000000000000000000000000000000..572c0221f282e9d8ed2befd2c37cda6dd740f0ff Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue$2.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue.class b/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..63c82d006536865db27337b99c529e9eaa8b2513 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$AccessQueue.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$1.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$1.class new file mode 100644 index 0000000000000000000000000000000000000000..eb2682be7f6e6f757cac7cf320cbc4b70acc0d92 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$2.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$2.class new file mode 100644 index 0000000000000000000000000000000000000000..42282ede62e2ccdd172d4d47d3783e9d8d987cc4 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$2.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$3.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$3.class new file mode 100644 index 0000000000000000000000000000000000000000..230dd8c596ecde4ba1771311d75e983cf5967a59 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$3.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$4.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$4.class new file mode 100644 index 0000000000000000000000000000000000000000..aaf7fffe0a73b66f892ed8ed692dfda23726887c Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$4.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$5.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$5.class new file mode 100644 index 0000000000000000000000000000000000000000..fe0fcdeb5aa9b6cdaa8428e035ecf093d4cf1545 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$5.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$6.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$6.class new file mode 100644 index 0000000000000000000000000000000000000000..0fd832335eafaaccfc5cbb50dc49522f1935bed7 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$6.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$7.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$7.class new file mode 100644 index 0000000000000000000000000000000000000000..b705af571929a660b50f9dbf53f9fa301fc88f67 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$7.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$8.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$8.class new file mode 100644 index 0000000000000000000000000000000000000000..583ae31a4b3350a20b13c4d3d8cdcb619d50e7ce Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory$8.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..d256cecb6d5644fbe305eeaf395fbfac657c80d6 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryFactory.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntryIterator.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntryIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..27051a0424dbefcc7f016a45063d01c6d58a7857 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntryIterator.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$EntrySet.class b/src/main/resources/org/python/google/common/cache/LocalCache$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..0781219be32aac138981f25a971a4c7becdb1474 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$HashIterator.class b/src/main/resources/org/python/google/common/cache/LocalCache$HashIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..6dfa306101ca781fa8998871fc5a3f9fba1cd446 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$HashIterator.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$KeyIterator.class b/src/main/resources/org/python/google/common/cache/LocalCache$KeyIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..069df75fa98841cdfd0c96d1d55fc5c8d55c2773 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$KeyIterator.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$KeySet.class b/src/main/resources/org/python/google/common/cache/LocalCache$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..fe8a0962ede3922a4027a4c4747af295b90136fb Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$LoadingSerializationProxy.class b/src/main/resources/org/python/google/common/cache/LocalCache$LoadingSerializationProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..c6969a6d36a83b04bc3dc8ee0d341cacc43fbdf5 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$LoadingSerializationProxy.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$LoadingValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$LoadingValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..9855bf083a0ef6d5f8d23a8904058f62a2373f39 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$LoadingValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$LocalLoadingCache.class b/src/main/resources/org/python/google/common/cache/LocalCache$LocalLoadingCache.class new file mode 100644 index 0000000000000000000000000000000000000000..7346181b2ae471c6bfa94cbf8c0d16be8aa68ed3 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$LocalLoadingCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$LocalManualCache$1.class b/src/main/resources/org/python/google/common/cache/LocalCache$LocalManualCache$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d168ccfa83e04af861b78ab0c51f65dd3a96d087 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$LocalManualCache$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$LocalManualCache.class b/src/main/resources/org/python/google/common/cache/LocalCache$LocalManualCache.class new file mode 100644 index 0000000000000000000000000000000000000000..3fba479c9c0c3bff0114bef6c03908a3591450c0 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$LocalManualCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$ManualSerializationProxy.class b/src/main/resources/org/python/google/common/cache/LocalCache$ManualSerializationProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..b99b5d71745ab7af565af4550bde6164846ef6ae Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$ManualSerializationProxy.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$NullEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$NullEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..2d353ff79d9b169b4e8fbbed990cf933ff479ca9 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$NullEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$ReferenceEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$ReferenceEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..f07b73b3e101a2b9185a86b74e3df57d2509c31f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$ReferenceEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$Segment$1.class b/src/main/resources/org/python/google/common/cache/LocalCache$Segment$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1f15483dcc3a87c83ed3f515d848382f986239d9 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$Segment$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$Segment.class b/src/main/resources/org/python/google/common/cache/LocalCache$Segment.class new file mode 100644 index 0000000000000000000000000000000000000000..6bc99d42d359ee4f7b70cd8bd68d9c4eee4d3800 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$Segment.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$SoftValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$SoftValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..d6a27de06635a7ec94d8cedeff508a5476a387be Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$SoftValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$Strength$1.class b/src/main/resources/org/python/google/common/cache/LocalCache$Strength$1.class new file mode 100644 index 0000000000000000000000000000000000000000..153ffc04ec959a721e35117c91d9cc0e20a4420c Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$Strength$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$Strength$2.class b/src/main/resources/org/python/google/common/cache/LocalCache$Strength$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c3c242796959b6d6b1c7a9267b01251725852d45 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$Strength$2.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$Strength$3.class b/src/main/resources/org/python/google/common/cache/LocalCache$Strength$3.class new file mode 100644 index 0000000000000000000000000000000000000000..353a82fc3d82d472b9996d047d787c1cc97659dd Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$Strength$3.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$Strength.class b/src/main/resources/org/python/google/common/cache/LocalCache$Strength.class new file mode 100644 index 0000000000000000000000000000000000000000..3e4cc363546b5ef4b6a830592483ca71b1991422 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$Strength.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$StrongAccessEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$StrongAccessEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..0dd563318df596a4ce7627ca7a173e9513f223d4 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$StrongAccessEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$StrongAccessWriteEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$StrongAccessWriteEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..a07e48c7bf4c4ffb1b2a10b525e7b4d26fed0d75 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$StrongAccessWriteEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$StrongEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$StrongEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..0634fb89e0bbaf50990a03f6a0f67417f08485ab Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$StrongEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$StrongValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$StrongValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..5f9d6426b9aba98f9df50fb890a8ca5f312ecc7e Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$StrongValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$StrongWriteEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$StrongWriteEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..481ad307fbd91835f0111a7bbc4c74bf37a7ebe6 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$StrongWriteEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$ValueIterator.class b/src/main/resources/org/python/google/common/cache/LocalCache$ValueIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..6f3b4fd44a24a777362dc3cd3b3f52bf0b1634d7 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$ValueIterator.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$ValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$ValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..59bf0874423f3a77d1105e14e4d1cd942a6463e8 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$ValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$Values.class b/src/main/resources/org/python/google/common/cache/LocalCache$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..270299803086c66808b700e8db19327a9eb165a5 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$Values.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeakAccessEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeakAccessEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..ab448b4e515fa23e8bef94a97239f77219c793b4 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeakAccessEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeakAccessWriteEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeakAccessWriteEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..d5c29865fae0d065ffa547ccea0b4f2c782fb2cb Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeakAccessWriteEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeakEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeakEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..1dc8ce9fb26429c251f8561acaa2a93db829398f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeakEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeakValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeakValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..1fb3b23a3ee3f4fa022b40b8d09a782ab517ca8f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeakValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeakWriteEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeakWriteEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..0601108d874e5f5a72d2043d075958a88e7252f1 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeakWriteEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeightedSoftValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeightedSoftValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..44f58cdd9aa2d0e76456cab4eb21a521570f0165 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeightedSoftValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeightedStrongValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeightedStrongValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..0354d21dd3f9f5c4f35c7018502e3e015d99f5d1 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeightedStrongValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WeightedWeakValueReference.class b/src/main/resources/org/python/google/common/cache/LocalCache$WeightedWeakValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..dcb4b3ad3baba68ed7b6d0c8ea1ca5f68f4102cd Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WeightedWeakValueReference.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue$1.class b/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue$1.class new file mode 100644 index 0000000000000000000000000000000000000000..78df33d44a8ba8d9a3da66b7e09104bd6e6afe9e Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue$2.class b/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue$2.class new file mode 100644 index 0000000000000000000000000000000000000000..6800fc5db8074033b7830de23ef04b974c6e2ba3 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue$2.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue.class b/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..7f3ef6cbf809f581da8facd4e4f9c1203dd6f1c1 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WriteQueue.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache$WriteThroughEntry.class b/src/main/resources/org/python/google/common/cache/LocalCache$WriteThroughEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..f23c859ebb4cc2805b6b8adb145be09a36e83e1b Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache$WriteThroughEntry.class differ diff --git a/src/main/resources/org/python/google/common/cache/LocalCache.class b/src/main/resources/org/python/google/common/cache/LocalCache.class new file mode 100644 index 0000000000000000000000000000000000000000..887d68c922731381ffced78d35af3cc4b9739c06 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LocalCache.class differ diff --git a/src/main/resources/org/python/google/common/cache/LongAdder.class b/src/main/resources/org/python/google/common/cache/LongAdder.class new file mode 100644 index 0000000000000000000000000000000000000000..701838234768fb24f0fe0839dc138f267ba96b00 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/LongAdder.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalCause$1.class b/src/main/resources/org/python/google/common/cache/RemovalCause$1.class new file mode 100644 index 0000000000000000000000000000000000000000..481651ec713dc0decd0d1a17fe25c38d170a8be3 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalCause$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalCause$2.class b/src/main/resources/org/python/google/common/cache/RemovalCause$2.class new file mode 100644 index 0000000000000000000000000000000000000000..e590bd80a165eb941a07bd04bb5a7da82238e6cc Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalCause$2.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalCause$3.class b/src/main/resources/org/python/google/common/cache/RemovalCause$3.class new file mode 100644 index 0000000000000000000000000000000000000000..60a29ce4e3cbf7069df13059902794f466502644 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalCause$3.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalCause$4.class b/src/main/resources/org/python/google/common/cache/RemovalCause$4.class new file mode 100644 index 0000000000000000000000000000000000000000..c8c22b5a469c642167920628ac2faa125eec44de Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalCause$4.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalCause$5.class b/src/main/resources/org/python/google/common/cache/RemovalCause$5.class new file mode 100644 index 0000000000000000000000000000000000000000..a5dc8ccda0bf297d0bb7679cc805a2f4e782c10d Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalCause$5.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalCause.class b/src/main/resources/org/python/google/common/cache/RemovalCause.class new file mode 100644 index 0000000000000000000000000000000000000000..ebc5cde39234acca2310305f867901fc97e92c27 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalCause.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalListener.class b/src/main/resources/org/python/google/common/cache/RemovalListener.class new file mode 100644 index 0000000000000000000000000000000000000000..537d647d7af4c5f90bdc3ca46546e3eb3f6b59fa Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalListener.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalListeners$1$1.class b/src/main/resources/org/python/google/common/cache/RemovalListeners$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8cd363711ac09402b0baff2016f17188a16876ec Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalListeners$1$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalListeners$1.class b/src/main/resources/org/python/google/common/cache/RemovalListeners$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a91883434088e04d4fe3f5756ace3c6891b4acae Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalListeners$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalListeners.class b/src/main/resources/org/python/google/common/cache/RemovalListeners.class new file mode 100644 index 0000000000000000000000000000000000000000..f3f94ef74a424da71ffcd5ac70524be555b40d24 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalListeners.class differ diff --git a/src/main/resources/org/python/google/common/cache/RemovalNotification.class b/src/main/resources/org/python/google/common/cache/RemovalNotification.class new file mode 100644 index 0000000000000000000000000000000000000000..4f2d1c9ddff67eaade372c63d029fdee2b077d34 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/RemovalNotification.class differ diff --git a/src/main/resources/org/python/google/common/cache/Striped64$1.class b/src/main/resources/org/python/google/common/cache/Striped64$1.class new file mode 100644 index 0000000000000000000000000000000000000000..efdb97366a828e6b09fd486cb43f71480fe8ec95 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/Striped64$1.class differ diff --git a/src/main/resources/org/python/google/common/cache/Striped64$Cell.class b/src/main/resources/org/python/google/common/cache/Striped64$Cell.class new file mode 100644 index 0000000000000000000000000000000000000000..c23fc26f77d7b3d337761e3a555e99a508c9ad53 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/Striped64$Cell.class differ diff --git a/src/main/resources/org/python/google/common/cache/Striped64$HashCode.class b/src/main/resources/org/python/google/common/cache/Striped64$HashCode.class new file mode 100644 index 0000000000000000000000000000000000000000..5922e661de110b887e110e556b9b5a4c1724881f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/Striped64$HashCode.class differ diff --git a/src/main/resources/org/python/google/common/cache/Striped64$ThreadHashCode.class b/src/main/resources/org/python/google/common/cache/Striped64$ThreadHashCode.class new file mode 100644 index 0000000000000000000000000000000000000000..94c70a5623b3fc44b01328628958a6aafd467c4f Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/Striped64$ThreadHashCode.class differ diff --git a/src/main/resources/org/python/google/common/cache/Striped64.class b/src/main/resources/org/python/google/common/cache/Striped64.class new file mode 100644 index 0000000000000000000000000000000000000000..221552ee2ec0182658ff64357de285c4fe7a2a59 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/Striped64.class differ diff --git a/src/main/resources/org/python/google/common/cache/Weigher.class b/src/main/resources/org/python/google/common/cache/Weigher.class new file mode 100644 index 0000000000000000000000000000000000000000..78105e97f0112f0ea7c160f3891f5b880764ad90 Binary files /dev/null and b/src/main/resources/org/python/google/common/cache/Weigher.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap$1.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4d1e8189041e738392281a7818c15ad6b42e18a9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet$1$1.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4d8d4bf309ed726b01837766a355cf9da9075c60 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c0ee0c377c76909e80cb45714e5a1afffe0cb6b6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..101ef1b430f46ba8d18bb587a2aa518afa374d4a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap$Inverse.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap$Inverse.class new file mode 100644 index 0000000000000000000000000000000000000000..2e3c28dab90dd5e5cbfb11e8cf6147aff44b1054 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap$Inverse.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap$KeySet.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..947ad5b7fc15976f8c3e75dc36f3c31ae41bbee6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap$ValueSet.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap$ValueSet.class new file mode 100644 index 0000000000000000000000000000000000000000..13d865d357dc4f96cd2ae4dd7ecf55f91c02c306 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap$ValueSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractBiMap.class b/src/main/resources/org/python/google/common/collect/AbstractBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..20d7024fcaef10020c6b958af1dba411ef08c3f0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractIndexedListIterator.class b/src/main/resources/org/python/google/common/collect/AbstractIndexedListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..228f51e6d9492f2de6f50714972282349be45155 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractIndexedListIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractIterator$1.class b/src/main/resources/org/python/google/common/collect/AbstractIterator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9b2cef041d0704e43f11b39782d8ef7074f9d8b0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractIterator$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractIterator$State.class b/src/main/resources/org/python/google/common/collect/AbstractIterator$State.class new file mode 100644 index 0000000000000000000000000000000000000000..82d8d09603403169e2763efa5d8ed5086894aecd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractIterator$State.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractIterator.class b/src/main/resources/org/python/google/common/collect/AbstractIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..81a64875515c86a684f678954d0bea7e68e249a2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractLinkedIterator.class b/src/main/resources/org/python/google/common/collect/AbstractLinkedIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..ecb758d4c7a23dc25d62370b1819c0a5345c413c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractLinkedIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractListMultimap.class b/src/main/resources/org/python/google/common/collect/AbstractListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..186aaf3ee0cad8ca05a56c8391b1f822d573761e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$1$1.class b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0abb004dc41eeb59693b92d17f6488181c552980 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$1.class b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1b128feaeeb56e6eee0aed060073a0e314e38fbc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$MapBasedElementSet.class b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$MapBasedElementSet.class new file mode 100644 index 0000000000000000000000000000000000000000..96229736cf7919ee3adf1e34c6edfee7d8a441ab Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$MapBasedElementSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$MapBasedMultisetIterator.class b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$MapBasedMultisetIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..f6894cf325d8996b46f928abe8cecb0e394ad1c0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset$MapBasedMultisetIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset.class b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..0857a85933ef7231b07e97b558e5010f65cb7b5e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMapBasedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMapEntry.class b/src/main/resources/org/python/google/common/collect/AbstractMapEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..aaa3b6f730fa395d0f63c539775907ac4849fa95 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMapEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$1.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a766fee5199346b410447c58d3d3dc1561796e34 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$2.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..d60e0c41e733fec8d1bcb3aca9c1f223899b70d2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$3.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$3.class new file mode 100644 index 0000000000000000000000000000000000000000..0399748a63e82dc3a664af8b66861a003c1a7c4f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$4.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$4.class new file mode 100644 index 0000000000000000000000000000000000000000..23c9a04013106d0a35c707217d45154d0243bcf2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap$AsMapEntries.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap$AsMapEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..7fd444f88789fa2e35de80be2981893b943eaad4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap$AsMapEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap$AsMapIterator.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap$AsMapIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..a8c3b4bcd83e1cade581a91dc81f91dee08e9738 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap$AsMapIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap.class new file mode 100644 index 0000000000000000000000000000000000000000..ae013f514b1da0025fb7b76f6ff1006bfbfbeca7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$AsMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$EntryIterator.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$EntryIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..a7e2d030d21e41c3f38c13d52ed48ccabdf41952 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$EntryIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$KeySet$1.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$KeySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fc54399fefd84acd25f4536a199aa99c556c1b6d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$KeySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$KeySet.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..28d7fc1d5a9d961c25a37fa88207b3153ae823c7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$RandomAccessWrappedList.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$RandomAccessWrappedList.class new file mode 100644 index 0000000000000000000000000000000000000000..08b8b01acbb283fbe00cc01bd54bcbbab961ab45 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$RandomAccessWrappedList.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$SortedAsMap.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$SortedAsMap.class new file mode 100644 index 0000000000000000000000000000000000000000..7eaf12080c360e14d40314a98d83e66c8038f2df Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$SortedAsMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$SortedKeySet.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$SortedKeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..a16243945d52ba2126150659166711fc378379b9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$SortedKeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedCollection$WrappedIterator.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedCollection$WrappedIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..d24dfa66c8613dabc0fb68b4a11a984dbfa14ffb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedCollection$WrappedIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedCollection.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..af5af6855eef210bf86d79b80f34bf5dcfde4684 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedList$WrappedListIterator.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedList$WrappedListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..daf18dff89072e9ceb87cf2d2642816cb87df6ba Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedList$WrappedListIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedList.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedList.class new file mode 100644 index 0000000000000000000000000000000000000000..5b91dee9334bc2a8a499c7748d8b32b1ab16de1c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedList.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedSet.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..f1540784f1a06ebc2eef8392eee637e1c276899e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedSortedSet.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..212d4ae35bf8ad33792f820e0dee34cda94d0142 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap$WrappedSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultimap.class b/src/main/resources/org/python/google/common/collect/AbstractMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..3bc015a2e5624210a28000efdd1e69b556ea636e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultiset$ElementSet.class b/src/main/resources/org/python/google/common/collect/AbstractMultiset$ElementSet.class new file mode 100644 index 0000000000000000000000000000000000000000..3fb173cf9fd28a59c9f35dcc3f558336bb039f31 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultiset$ElementSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultiset$EntrySet.class b/src/main/resources/org/python/google/common/collect/AbstractMultiset$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..9642f0027fa909ae18210907339f81e17fed75f3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultiset$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractMultiset.class b/src/main/resources/org/python/google/common/collect/AbstractMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..b57173c42052d765acb5b815b837502a2cd80b1d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractSequentialIterator.class b/src/main/resources/org/python/google/common/collect/AbstractSequentialIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..cc3af9e510f0095a66a73078f51c2f71a7336f41 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractSequentialIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractSetMultimap.class b/src/main/resources/org/python/google/common/collect/AbstractSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..95ab54f4db6e6dc95f76e28cc7b2f3a50d42eccb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset$1.class b/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2a974c8aad0c14fb65faaaf5b0cc647c9bb712d0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset$2.class b/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5f582a2dfe05077c9de76f38830327ad5fee427d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset.class b/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..8c5ead66d90c836369f55ba98a1d7d342982af60 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractSortedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/AbstractSortedSetMultimap.class b/src/main/resources/org/python/google/common/collect/AbstractSortedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..b05909c31548efcf542edbab05888b7d276efc99 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AbstractSortedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/AllEqualOrdering.class b/src/main/resources/org/python/google/common/collect/AllEqualOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..81880f72da244a64a0fb6a3d63cc6c80a38199c8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AllEqualOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayListMultimap.class b/src/main/resources/org/python/google/common/collect/ArrayListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..a9e2155985d0e89e4bcadf86b194d59fb81e3007 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$1.class b/src/main/resources/org/python/google/common/collect/ArrayTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c376b4016c8c00e6d88d6dec7324dfd95605d1e4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1$1$1.class b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c46be845bd42bad599081202414c340e8a649bdc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1$1.class b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b9527d92e661685cc5f075a4280c28a722880acf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1.class b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b8ead6df2292f6fc5f109bbd9e821314ed5af390 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap.class b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap.class new file mode 100644 index 0000000000000000000000000000000000000000..99d69b0d027cebd5e1301e88ae54408310dcc125 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$ArrayMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet$1$1.class b/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..72f647224aec736ce9fa4c4e2c8a5eb74a5af882 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet$1.class b/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9dcf1e2b75f4e5bade8ece5292b7a2241707f4fb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet.class b/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet.class new file mode 100644 index 0000000000000000000000000000000000000000..d2e219652b4cf066df1e1a386cbdcb878fc527a3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$CellSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$Column.class b/src/main/resources/org/python/google/common/collect/ArrayTable$Column.class new file mode 100644 index 0000000000000000000000000000000000000000..4d77a4e5afedb0ed799423b1bf953efed790b6c9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$Column.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$ColumnMap.class b/src/main/resources/org/python/google/common/collect/ArrayTable$ColumnMap.class new file mode 100644 index 0000000000000000000000000000000000000000..139f1b663550eadde5b5391bce3aef233661d14c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$ColumnMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$Row.class b/src/main/resources/org/python/google/common/collect/ArrayTable$Row.class new file mode 100644 index 0000000000000000000000000000000000000000..bfdd3aa90a90c252e2b1684ef50bf42945cb5b9c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$Row.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$RowMap.class b/src/main/resources/org/python/google/common/collect/ArrayTable$RowMap.class new file mode 100644 index 0000000000000000000000000000000000000000..69928c8c493124fb0b8d475365a0f1e16fd96e2a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$RowMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$Values$1.class b/src/main/resources/org/python/google/common/collect/ArrayTable$Values$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b1500fa9f104fbc64396c4185903da5be90edce5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$Values$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable$Values.class b/src/main/resources/org/python/google/common/collect/ArrayTable$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..8ae1e5042413fec6d335470d54f2b141aaf7f88a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/ArrayTable.class b/src/main/resources/org/python/google/common/collect/ArrayTable.class new file mode 100644 index 0000000000000000000000000000000000000000..2a986381f5cccca48b7ade08e4bb43514d920e12 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ArrayTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/AsynchronousComputationException.class b/src/main/resources/org/python/google/common/collect/AsynchronousComputationException.class new file mode 100644 index 0000000000000000000000000000000000000000..b2d6dde8e7e00014a41ebd0f77784853459853e9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/AsynchronousComputationException.class differ diff --git a/src/main/resources/org/python/google/common/collect/BiMap.class b/src/main/resources/org/python/google/common/collect/BiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..a8a5763066fe74c588a16ccf38d6bdf8d0e4f88e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/BiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/BoundType$1.class b/src/main/resources/org/python/google/common/collect/BoundType$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2f82dff4193b30c4cb9a338d898e5de25bd80dc7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/BoundType$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/BoundType$2.class b/src/main/resources/org/python/google/common/collect/BoundType$2.class new file mode 100644 index 0000000000000000000000000000000000000000..daa63e8d77a90be105c1d986e513b2e14380cad0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/BoundType$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/BoundType.class b/src/main/resources/org/python/google/common/collect/BoundType.class new file mode 100644 index 0000000000000000000000000000000000000000..c27e662b268594c36f0ea05a15caa472ba3bc1b1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/BoundType.class differ diff --git a/src/main/resources/org/python/google/common/collect/ByFunctionOrdering.class b/src/main/resources/org/python/google/common/collect/ByFunctionOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..afa4709c28edc651b7d37b6c9f03d166ed461835 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ByFunctionOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/ClassToInstanceMap.class b/src/main/resources/org/python/google/common/collect/ClassToInstanceMap.class new file mode 100644 index 0000000000000000000000000000000000000000..dc992fb7524c0922198524deb54a7acd65ef5acc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ClassToInstanceMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$1.class b/src/main/resources/org/python/google/common/collect/Collections2$1.class new file mode 100644 index 0000000000000000000000000000000000000000..838e19a2d74621390a9d60721b143a8e47387777 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection$1.class b/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ef6ea25a3d56542573167b32aede024eeb7dc0dc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection$2.class b/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection$2.class new file mode 100644 index 0000000000000000000000000000000000000000..3fed5221de64a487dd08cc325d9b083bfb452d95 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection.class b/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..3fc4b0c105da03f3d121d6204a514ca273bdeb2a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$FilteredCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$OrderedPermutationCollection.class b/src/main/resources/org/python/google/common/collect/Collections2$OrderedPermutationCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..0d69bafb9fcbd09ab97df37a4212bd8fce3a9a0e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$OrderedPermutationCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$OrderedPermutationIterator.class b/src/main/resources/org/python/google/common/collect/Collections2$OrderedPermutationIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..1689cdbd6168ae2672497d602fb6efdef88a4bb1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$OrderedPermutationIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$PermutationCollection.class b/src/main/resources/org/python/google/common/collect/Collections2$PermutationCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..133851e7b4998402ba4f2ff48a5d575f48cec140 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$PermutationCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$PermutationIterator.class b/src/main/resources/org/python/google/common/collect/Collections2$PermutationIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..96bb3c7e5a7d49a29bbf4a14553afaf3f981f1d3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$PermutationIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2$TransformedCollection.class b/src/main/resources/org/python/google/common/collect/Collections2$TransformedCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..17fa22a590a97bee408fa911243ce2fbc6443bd1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2$TransformedCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/Collections2.class b/src/main/resources/org/python/google/common/collect/Collections2.class new file mode 100644 index 0000000000000000000000000000000000000000..a547febf70d4ce475b5d1c3af22bef05697133ec Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Collections2.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComparatorOrdering.class b/src/main/resources/org/python/google/common/collect/ComparatorOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..c57f9a95172420e346d8612bf92383666b802aa1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComparatorOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComparisonChain$1.class b/src/main/resources/org/python/google/common/collect/ComparisonChain$1.class new file mode 100644 index 0000000000000000000000000000000000000000..66216abaefcc7fe7f5a769c61effba9ec9249c8b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComparisonChain$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComparisonChain$InactiveComparisonChain.class b/src/main/resources/org/python/google/common/collect/ComparisonChain$InactiveComparisonChain.class new file mode 100644 index 0000000000000000000000000000000000000000..283c0f8663b140f78f36ff50443b7c6dc105129e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComparisonChain$InactiveComparisonChain.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComparisonChain.class b/src/main/resources/org/python/google/common/collect/ComparisonChain.class new file mode 100644 index 0000000000000000000000000000000000000000..5396fde12080e342efd12466307d33a268085662 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComparisonChain.class differ diff --git a/src/main/resources/org/python/google/common/collect/CompoundOrdering.class b/src/main/resources/org/python/google/common/collect/CompoundOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..3a6ed8c262d4ef248de960f4c908367f560813aa Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/CompoundOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputationException.class b/src/main/resources/org/python/google/common/collect/ComputationException.class new file mode 100644 index 0000000000000000000000000000000000000000..595b61fe84d6ca48540656bf4e74531be820715e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputationException.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputationExceptionReference.class b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputationExceptionReference.class new file mode 100644 index 0000000000000000000000000000000000000000..9e7ba39feba29cb2ecfada0e8c898242c263bc7c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputationExceptionReference.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputedReference.class b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputedReference.class new file mode 100644 index 0000000000000000000000000000000000000000..283dee669e539a4a3792cb425244be3ef9c25048 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputedReference.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingMapAdapter.class b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingMapAdapter.class new file mode 100644 index 0000000000000000000000000000000000000000..244fcbb69fe63c59a340c58d34cd3fa181315a9c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingMapAdapter.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingSegment.class b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingSegment.class new file mode 100644 index 0000000000000000000000000000000000000000..fc38034580f59738461043929923b980308dd7cd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingSegment.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingSerializationProxy.class b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingSerializationProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..4ac50459c2c35d74048771d1180397b4a3319463 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingSerializationProxy.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingValueReference.class b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..c81dfe0951324ee7f628770b823ccda43bf86b76 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap$ComputingValueReference.class differ diff --git a/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap.class b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap.class new file mode 100644 index 0000000000000000000000000000000000000000..f6a2718c71a600376ea18f4f8996363cd9784727 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ComputingConcurrentHashMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$1.class b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..50290d5af5c4bc4c413eeaf8d0531f2b7d4f6631 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$2.class b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$2.class new file mode 100644 index 0000000000000000000000000000000000000000..36bd26a3be43a484a8f1d2dd1bbd691c000266f8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$3.class b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$3.class new file mode 100644 index 0000000000000000000000000000000000000000..e3f8bd0038f52c6c8e96e7fe2ea67b5be2d7bd17 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$EntrySet.class b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..b5b32e13301d881cf4b3910b46cd5968ff59039f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$FieldSettersHolder.class b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$FieldSettersHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..680e24a4033ad60a1fecf6a01073d3950c7ae68b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset$FieldSettersHolder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset.class b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..6dbb85953cb041ef05ea9979ae34d934dd7d0e0d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ConcurrentHashMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraint.class b/src/main/resources/org/python/google/common/collect/Constraint.class new file mode 100644 index 0000000000000000000000000000000000000000..f09637f245a9c0d8b152124b4a934d2a597e23c4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraint.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedCollection.class b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..fc05247b06394532ba53777aae341981a14aae86 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedList.class b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedList.class new file mode 100644 index 0000000000000000000000000000000000000000..4979f8fa297a77c541431dc44128c49f97a3fa73 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedListIterator.class b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..90dfdb768289c7120db9f2bafc7458f30ae59aee Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedListIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedMultiset.class b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..9ec7c0b2ac724a72bf4b895658eae7f3757b1fc0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedRandomAccessList.class b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedRandomAccessList.class new file mode 100644 index 0000000000000000000000000000000000000000..ad48aa2f7699e5fae030d612058e3f1f7b5a15b5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedRandomAccessList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedSet.class b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..2ee92f7385177cbcdff9adb9f5b0e132b6125c4a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedSortedSet.class b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..7ec858076194bb978355c7f0a14a176fff86454c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$ConstrainedSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints$NotNullConstraint.class b/src/main/resources/org/python/google/common/collect/Constraints$NotNullConstraint.class new file mode 100644 index 0000000000000000000000000000000000000000..52545d6a99bdfa0d07aab5c6f5b5c271245958b5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints$NotNullConstraint.class differ diff --git a/src/main/resources/org/python/google/common/collect/Constraints.class b/src/main/resources/org/python/google/common/collect/Constraints.class new file mode 100644 index 0000000000000000000000000000000000000000..58f97e958c214e95d208a2c9819547f1c91a2e7d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Constraints.class differ diff --git a/src/main/resources/org/python/google/common/collect/ContiguousSet.class b/src/main/resources/org/python/google/common/collect/ContiguousSet.class new file mode 100644 index 0000000000000000000000000000000000000000..83670790fb88db4cd0be1c20238fb34b7be0e5e1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ContiguousSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Count.class b/src/main/resources/org/python/google/common/collect/Count.class new file mode 100644 index 0000000000000000000000000000000000000000..b4002c317afbcd21eba81a5e968c055d31f8d22d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Count.class differ diff --git a/src/main/resources/org/python/google/common/collect/Cut$1.class b/src/main/resources/org/python/google/common/collect/Cut$1.class new file mode 100644 index 0000000000000000000000000000000000000000..86ac65e249046f3a828802bccbdb3772af39c831 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Cut$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Cut$AboveAll.class b/src/main/resources/org/python/google/common/collect/Cut$AboveAll.class new file mode 100644 index 0000000000000000000000000000000000000000..d5b96e1fc8b64029270ab8066a93e35f5832a417 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Cut$AboveAll.class differ diff --git a/src/main/resources/org/python/google/common/collect/Cut$AboveValue.class b/src/main/resources/org/python/google/common/collect/Cut$AboveValue.class new file mode 100644 index 0000000000000000000000000000000000000000..cb1c3d64533d3e425f02c80595ced2ca82754800 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Cut$AboveValue.class differ diff --git a/src/main/resources/org/python/google/common/collect/Cut$BelowAll.class b/src/main/resources/org/python/google/common/collect/Cut$BelowAll.class new file mode 100644 index 0000000000000000000000000000000000000000..6df4d8d6ba51cc675905f385a82f74c7301f992d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Cut$BelowAll.class differ diff --git a/src/main/resources/org/python/google/common/collect/Cut$BelowValue.class b/src/main/resources/org/python/google/common/collect/Cut$BelowValue.class new file mode 100644 index 0000000000000000000000000000000000000000..42a992b3c8cd6af41927b3d5475f4555f606406c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Cut$BelowValue.class differ diff --git a/src/main/resources/org/python/google/common/collect/Cut.class b/src/main/resources/org/python/google/common/collect/Cut.class new file mode 100644 index 0000000000000000000000000000000000000000..f0aa114834be359e2da6e7fca63c9274ccf480e3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Cut.class differ diff --git a/src/main/resources/org/python/google/common/collect/DescendingImmutableSortedMultiset$1.class b/src/main/resources/org/python/google/common/collect/DescendingImmutableSortedMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..737ef47e565472d7f466390f575f25d118d3fa5c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/DescendingImmutableSortedMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/DescendingImmutableSortedMultiset.class b/src/main/resources/org/python/google/common/collect/DescendingImmutableSortedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..46d35374b50bda14f830dbfd55af140ecbefc659 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/DescendingImmutableSortedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/DiscreteDomain.class b/src/main/resources/org/python/google/common/collect/DiscreteDomain.class new file mode 100644 index 0000000000000000000000000000000000000000..31688d5f4a26e50f999d346cfdbe16a7c679ecc4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/DiscreteDomain.class differ diff --git a/src/main/resources/org/python/google/common/collect/DiscreteDomains$BigIntegerDomain.class b/src/main/resources/org/python/google/common/collect/DiscreteDomains$BigIntegerDomain.class new file mode 100644 index 0000000000000000000000000000000000000000..f2ebe66f3ba9ac909542477f73a9ad2412421d85 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/DiscreteDomains$BigIntegerDomain.class differ diff --git a/src/main/resources/org/python/google/common/collect/DiscreteDomains$IntegerDomain.class b/src/main/resources/org/python/google/common/collect/DiscreteDomains$IntegerDomain.class new file mode 100644 index 0000000000000000000000000000000000000000..4dc0bc74a1e130b39611e3c343a83b83c7a38352 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/DiscreteDomains$IntegerDomain.class differ diff --git a/src/main/resources/org/python/google/common/collect/DiscreteDomains$LongDomain.class b/src/main/resources/org/python/google/common/collect/DiscreteDomains$LongDomain.class new file mode 100644 index 0000000000000000000000000000000000000000..4b92d8c6aa19cce4bac7f2b9444e3bbd96acea81 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/DiscreteDomains$LongDomain.class differ diff --git a/src/main/resources/org/python/google/common/collect/DiscreteDomains.class b/src/main/resources/org/python/google/common/collect/DiscreteDomains.class new file mode 100644 index 0000000000000000000000000000000000000000..d8babbc8ce5eb7a53389e2f0d9cccf758d71d3e9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/DiscreteDomains.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyContiguousSet$1.class b/src/main/resources/org/python/google/common/collect/EmptyContiguousSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c083ae0354b0deab1f6bdd0b5c80b77da47d19fb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyContiguousSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyContiguousSet$SerializedForm.class b/src/main/resources/org/python/google/common/collect/EmptyContiguousSet$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..43d02e07cbef57b9fb5b4a88436ae6eb5a60031c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyContiguousSet$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyContiguousSet.class b/src/main/resources/org/python/google/common/collect/EmptyContiguousSet.class new file mode 100644 index 0000000000000000000000000000000000000000..2b7cc8f87ac512ac9694ad20bd26fe4d9a636f59 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyContiguousSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableBiMap.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..4035fc4a6cd74ed6c28e3e768ecd8c2ed6c7c8bb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableList.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableList.class new file mode 100644 index 0000000000000000000000000000000000000000..c695c7c91584504b56cea4641d8befc458195489 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableList.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableListMultimap.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..e4b7b9be3dda9445a49e68f2789ca48b2d55123f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableMap.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..a0040cc803ca2ee311a6d13971c9f77da7bc5afd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableMultiset.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..bbd0dc947783bb681e787604be9f4f6b89d3d96b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableSet.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..d0170d64671a3c46ddae04628ca3dc58b20edb86 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableSetMultimap.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..b85b6a77870ca70e75abffcf129061a0ec3fdc40 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedMap.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..a5d2819ea968b6ba51abb5d6d7a505e3df8e5756 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedMultiset.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..f61c9f9f8a00d10f69d7b08042b41506e009caff Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedSet.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..44df59a2a12d8dabea3519541f3f811b47f4dd1a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/EmptyImmutableTable.class b/src/main/resources/org/python/google/common/collect/EmptyImmutableTable.class new file mode 100644 index 0000000000000000000000000000000000000000..f9d5e2f77f4422128d5455b8bd9d3e5cd0715295 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EmptyImmutableTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/EnumBiMap.class b/src/main/resources/org/python/google/common/collect/EnumBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..17dedda35daf8b150f1e86027a0c8078d132e576 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EnumBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/EnumHashBiMap.class b/src/main/resources/org/python/google/common/collect/EnumHashBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..ca73ea9c8fdbd21bae0cf908fed81c1b991db235 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EnumHashBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/EnumMultiset.class b/src/main/resources/org/python/google/common/collect/EnumMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..4dd12c4bee389e08c87e942e7fc5df9a12ba0a58 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/EnumMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/ExplicitOrdering.class b/src/main/resources/org/python/google/common/collect/ExplicitOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..a6d7fdc07e3f2a916339f98cfbecda0c8e8dc0b3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ExplicitOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/FluentIterable$1.class b/src/main/resources/org/python/google/common/collect/FluentIterable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0d4472fd2f81bc0f80ca4c81ad03f10b19cec015 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/FluentIterable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/FluentIterable$FromIterableFunction.class b/src/main/resources/org/python/google/common/collect/FluentIterable$FromIterableFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..a688373e41802a501039deb525e4c018b3b458ba Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/FluentIterable$FromIterableFunction.class differ diff --git a/src/main/resources/org/python/google/common/collect/FluentIterable.class b/src/main/resources/org/python/google/common/collect/FluentIterable.class new file mode 100644 index 0000000000000000000000000000000000000000..c6b1b409362ee9431bd18722a8e63ddd26e4be94 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/FluentIterable.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingCollection.class b/src/main/resources/org/python/google/common/collect/ForwardingCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..9ecbe79cb5d284a315fe3fd1283a63a9a0b9a58e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingConcurrentMap.class b/src/main/resources/org/python/google/common/collect/ForwardingConcurrentMap.class new file mode 100644 index 0000000000000000000000000000000000000000..2c8355f361d9c1381b120fea3b82cea585a823fa Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingConcurrentMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingDeque.class b/src/main/resources/org/python/google/common/collect/ForwardingDeque.class new file mode 100644 index 0000000000000000000000000000000000000000..f381edbfa4f1aaa37af9b9e98a13bc03f077c09a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingDeque.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingImmutableList.class b/src/main/resources/org/python/google/common/collect/ForwardingImmutableList.class new file mode 100644 index 0000000000000000000000000000000000000000..c2097c91996ba175f8d2a7e5edd49110edb2081b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingImmutableList.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingImmutableMap.class b/src/main/resources/org/python/google/common/collect/ForwardingImmutableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..2edc394e73424386bf1e90abf167a55cb5c8078a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingImmutableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingImmutableSet.class b/src/main/resources/org/python/google/common/collect/ForwardingImmutableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..4b6a5e7bc61dae3b740df96b14d828b1a8b93797 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingImmutableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingIterator.class b/src/main/resources/org/python/google/common/collect/ForwardingIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..30906319941301982984ac73a78d70feb194f331 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingList.class b/src/main/resources/org/python/google/common/collect/ForwardingList.class new file mode 100644 index 0000000000000000000000000000000000000000..a96db0747d93e8aa81572c44aaf0742cb444000f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingList.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingListIterator.class b/src/main/resources/org/python/google/common/collect/ForwardingListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..01213b3450b9bc06a3181e422c1a1b65b96e6468 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingListIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingListMultimap.class b/src/main/resources/org/python/google/common/collect/ForwardingListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..7b471430077f15728f4c9a81a4552aa6de53ffc9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardEntrySet.class b/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..3c1d8fafb9b40556c40408e5ad2c5c97610d619c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardKeySet.class b/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardKeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..64ab3a7c09791540fce1eb8c1f7f551431ac0c8c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardKeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardValues.class b/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardValues.class new file mode 100644 index 0000000000000000000000000000000000000000..0ccdb1e24344d0775044d0259d4d1014caf54f0f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMap$StandardValues.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMap.class b/src/main/resources/org/python/google/common/collect/ForwardingMap.class new file mode 100644 index 0000000000000000000000000000000000000000..7de32c4bad13ae3c4ee7dfa498f9de05360f07e0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMapEntry.class b/src/main/resources/org/python/google/common/collect/ForwardingMapEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..96f168f37448037c4347eb51770c3a0c6e358b2a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMapEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMultimap.class b/src/main/resources/org/python/google/common/collect/ForwardingMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..1836dfc1f7d57a6fa065f8112d1b66cf194d1441 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMultiset$StandardElementSet.class b/src/main/resources/org/python/google/common/collect/ForwardingMultiset$StandardElementSet.class new file mode 100644 index 0000000000000000000000000000000000000000..f3fb1daf8f5baa0c3097930248825a92faf2babd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMultiset$StandardElementSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingMultiset.class b/src/main/resources/org/python/google/common/collect/ForwardingMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..3e24d759e7929678b531fbd75b347bac37698830 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardDescendingMap$1.class b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardDescendingMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d729aa65eb1a10a38bc2ba323dc48d2de6d9ac43 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardDescendingMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardDescendingMap.class b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardDescendingMap.class new file mode 100644 index 0000000000000000000000000000000000000000..420ea5b1d14729d9645125491eb9ecb5646ef8ee Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardDescendingMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardNavigableKeySet.class b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardNavigableKeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..8fc5fdbb9420a66d362a1821b3bed279be6800ca Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap$StandardNavigableKeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap.class b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..b5d50c27e3e8622b3961e6d2907a2bf3852473a6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingNavigableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingNavigableSet$StandardDescendingSet.class b/src/main/resources/org/python/google/common/collect/ForwardingNavigableSet$StandardDescendingSet.class new file mode 100644 index 0000000000000000000000000000000000000000..45bf66deed9365f8f64cee20ae6b5227d27981d4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingNavigableSet$StandardDescendingSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingNavigableSet.class b/src/main/resources/org/python/google/common/collect/ForwardingNavigableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..8f45076520aa69a5af1b4ecf020f6ed5e0064690 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingNavigableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingObject.class b/src/main/resources/org/python/google/common/collect/ForwardingObject.class new file mode 100644 index 0000000000000000000000000000000000000000..61ef2454bd4a3bc776706bf88733ba3c2025e5d9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingObject.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingQueue.class b/src/main/resources/org/python/google/common/collect/ForwardingQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..c794ec9db5cc08b490fcb107e3eddffb7ac3a24d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingQueue.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingSet.class b/src/main/resources/org/python/google/common/collect/ForwardingSet.class new file mode 100644 index 0000000000000000000000000000000000000000..a420039f622d95bb33af1c9a5bbc096b491ad03d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingSetMultimap.class b/src/main/resources/org/python/google/common/collect/ForwardingSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..d63de8c3689187b6efcdf032b74431a829e28cdf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingSortedMap.class b/src/main/resources/org/python/google/common/collect/ForwardingSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..3ad5349daa69e463f04a08d95b1e230ee9fe8f55 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingSortedSet.class b/src/main/resources/org/python/google/common/collect/ForwardingSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..a6ff8510bca4eea461d571499cd673d76b201ce2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingSortedSetMultimap.class b/src/main/resources/org/python/google/common/collect/ForwardingSortedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..dfaf7828ced07ef030b0811b6f46192bf36c440b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingSortedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ForwardingTable.class b/src/main/resources/org/python/google/common/collect/ForwardingTable.class new file mode 100644 index 0000000000000000000000000000000000000000..42926ec5b754b980a7c240dc30e671e7c8e309cf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ForwardingTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/GeneralRange$1.class b/src/main/resources/org/python/google/common/collect/GeneralRange$1.class new file mode 100644 index 0000000000000000000000000000000000000000..891557c54cfb8d3fcd33b73730440d8730f6ad86 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/GeneralRange$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/GeneralRange.class b/src/main/resources/org/python/google/common/collect/GeneralRange.class new file mode 100644 index 0000000000000000000000000000000000000000..814e9606947ef6c969d8b1d4346f7f5011167343 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/GeneralRange.class differ diff --git a/src/main/resources/org/python/google/common/collect/GenericMapMaker$NullListener.class b/src/main/resources/org/python/google/common/collect/GenericMapMaker$NullListener.class new file mode 100644 index 0000000000000000000000000000000000000000..6f59adc9726066db8b42d0f86b99002c58e5fc1f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/GenericMapMaker$NullListener.class differ diff --git a/src/main/resources/org/python/google/common/collect/GenericMapMaker.class b/src/main/resources/org/python/google/common/collect/GenericMapMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..0503fb46b191a7412f4c0238bef5956d936c178a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/GenericMapMaker.class differ diff --git a/src/main/resources/org/python/google/common/collect/GwtTransient.class b/src/main/resources/org/python/google/common/collect/GwtTransient.class new file mode 100644 index 0000000000000000000000000000000000000000..46c9b0be582ccb8aa5b54a1b2fc57c19d8b89bc3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/GwtTransient.class differ diff --git a/src/main/resources/org/python/google/common/collect/HashBasedTable$Factory.class b/src/main/resources/org/python/google/common/collect/HashBasedTable$Factory.class new file mode 100644 index 0000000000000000000000000000000000000000..a5520f2ca39172487308452ef57b22a5f5a09ca0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/HashBasedTable$Factory.class differ diff --git a/src/main/resources/org/python/google/common/collect/HashBasedTable.class b/src/main/resources/org/python/google/common/collect/HashBasedTable.class new file mode 100644 index 0000000000000000000000000000000000000000..0c1f9e3886d1e5d0568a6577f0c92279f4695054 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/HashBasedTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/HashBiMap.class b/src/main/resources/org/python/google/common/collect/HashBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..1261d02cd67c88fb3b5f55c18dd53295c1599af3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/HashBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/HashMultimap.class b/src/main/resources/org/python/google/common/collect/HashMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..60878c29666ed7c3c25231eee835e3e5a667d020 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/HashMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/HashMultiset.class b/src/main/resources/org/python/google/common/collect/HashMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..5d1d3d04685ef8cfecb0190b82c5d24f80324bd4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/HashMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Hashing.class b/src/main/resources/org/python/google/common/collect/Hashing.class new file mode 100644 index 0000000000000000000000000000000000000000..feadaf9f6fba1fb342f026852c4f440f34dd68cb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Hashing.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableAsList$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableAsList$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..0255601384a075289d0e5f6191fbad1430d119b2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableAsList$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableAsList.class b/src/main/resources/org/python/google/common/collect/ImmutableAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..15676391c8fffcd6ead2f5e102bda6eb13681634 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableAsList.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableBiMap$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableBiMap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..38296f277ca930489de13fb98fa051eb469f9bcc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableBiMap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableBiMap$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableBiMap$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..3f60a0d502b676441d84c9afa5f90b6c5ca40216 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableBiMap$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableBiMap.class b/src/main/resources/org/python/google/common/collect/ImmutableBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..6e508c2df47c3ab54c7c53cb22ba92baedaa88d6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap$1.class b/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fca703d6756046aab86e154d1a92ee72c7d2e063 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..1ce100d03bb9cbd4ccdf5a933070b67a8e6ffe8f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap.class b/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap.class new file mode 100644 index 0000000000000000000000000000000000000000..3468b838a1e1d24defbbfe9dd68eb82af60a4dfc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableClassToInstanceMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableCollection$1.class b/src/main/resources/org/python/google/common/collect/ImmutableCollection$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4c2c93e2daba36fa10d1e7f50f53c163875aa0aa Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableCollection$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableCollection$ArrayImmutableCollection.class b/src/main/resources/org/python/google/common/collect/ImmutableCollection$ArrayImmutableCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..a875f2ea42d366dd9cdeb1be0ea6d4a03aee5ab1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableCollection$ArrayImmutableCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableCollection$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableCollection$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..f1ebdf60bf55f8dd29170ef6aa3dc071a8f65c2c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableCollection$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableCollection$EmptyImmutableCollection.class b/src/main/resources/org/python/google/common/collect/ImmutableCollection$EmptyImmutableCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..d456291d0c703a87c5204fa4ac0f666be8efae26 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableCollection$EmptyImmutableCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableCollection$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableCollection$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..75a2aa3233aedaf28504c7e6127309b37b66f74e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableCollection$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableCollection.class b/src/main/resources/org/python/google/common/collect/ImmutableCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..4a173d8e1353d40b7a9dbd7c4f0c49eb883d67e5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableEntry.class b/src/main/resources/org/python/google/common/collect/ImmutableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..e0d3248ca39c7e82d832116bd0c4ca989ab192d9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableEnumSet$EnumSerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableEnumSet$EnumSerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..04a40c375f7fcb404e3de83f2deee073ed56c51d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableEnumSet$EnumSerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableEnumSet.class b/src/main/resources/org/python/google/common/collect/ImmutableEnumSet.class new file mode 100644 index 0000000000000000000000000000000000000000..78edd4eeb34a0194534561a0ec7a2854d8d3a488 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableEnumSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableList$1.class b/src/main/resources/org/python/google/common/collect/ImmutableList$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fc306bf955e405964306615b456880cdb76726ab Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableList$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableList$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableList$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..5282c1ee776dbc347c2023b89796220f60536ad1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableList$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableList$ReverseImmutableList$1.class b/src/main/resources/org/python/google/common/collect/ImmutableList$ReverseImmutableList$1.class new file mode 100644 index 0000000000000000000000000000000000000000..665fb9db52d16163fc7d43257bb61b2db3917fd3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableList$ReverseImmutableList$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableList$ReverseImmutableList.class b/src/main/resources/org/python/google/common/collect/ImmutableList$ReverseImmutableList.class new file mode 100644 index 0000000000000000000000000000000000000000..b487784f72a2f45f1e8907366bf3453e7ff20f8b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableList$ReverseImmutableList.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableList$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableList$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..1f9016ac8c6033fe345b80ef57c6eb260b35bec5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableList$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableList$SubList.class b/src/main/resources/org/python/google/common/collect/ImmutableList$SubList.class new file mode 100644 index 0000000000000000000000000000000000000000..bceecd884515aa81184fdd56aa52ca5e329fe077 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableList$SubList.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableList.class b/src/main/resources/org/python/google/common/collect/ImmutableList.class new file mode 100644 index 0000000000000000000000000000000000000000..138467296a8c6ae719cc2007467a8e8e1d0d6a1a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableList.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableListMultimap$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableListMultimap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..5817dc8e95f0ebde9f08a33938e7e66591d7d5a0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableListMultimap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableListMultimap.class b/src/main/resources/org/python/google/common/collect/ImmutableListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..8979d395961db09d3ad0942f06b827001d9dc68e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMap$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c02aa282d1e7bfbe0b48e01c758d88cd97902c05 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMap$2.class b/src/main/resources/org/python/google/common/collect/ImmutableMap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..ba8cb89ce549617bb8b2716010baa0e4f6a3ce0a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMap$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableMap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..a75e1d690e1e5b6aa89ccc20e10e4abe9870c28e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMap$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableMap$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..78ca73d063f2851f8a1526efe231a9f8b6e5f207 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMap$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMap.class b/src/main/resources/org/python/google/common/collect/ImmutableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..501b1e8ec73961be108d7324f1b42c8acbc06880 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapEntrySet$EntrySetSerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableMapEntrySet$EntrySetSerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..1ba0a4244fbb9815580390173525533b8427929f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapEntrySet$EntrySetSerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapEntrySet.class b/src/main/resources/org/python/google/common/collect/ImmutableMapEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..88c615a500ff52575afb3364fe73613196f50dd4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..40cd4e2c1b791db7d6dfa826a5337724a25f5ea6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet$KeySetSerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet$KeySetSerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..6b553f10eea6c4021aa78f45ef72068dbbf18140 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet$KeySetSerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet.class b/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..9f590b971d66c296bc3959a3963bd51964ac5e8c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapKeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapValues$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMapValues$1.class new file mode 100644 index 0000000000000000000000000000000000000000..35e50019419c0d1223c0b1b444583fd86055c8f8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapValues$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapValues$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableMapValues$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..f643c7921f295d9a5a13990d1cb720c5d897c3f9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapValues$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMapValues.class b/src/main/resources/org/python/google/common/collect/ImmutableMapValues.class new file mode 100644 index 0000000000000000000000000000000000000000..5c304feca55247946e1348c8a019265f153ce68a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMapValues.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..66f5095629880d6158075f14433a72cb8eb88822 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Builder$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Builder$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8765ba8e08d1440be17baeba921b0cf4a2075aa3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Builder$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..3faed4d300cb48832c28450a36be7bad91921f6a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$BuilderMultimap.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$BuilderMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..b949f1427bd536cb3c3dbf2f96ac7938e875368b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$BuilderMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$EntryCollection$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$EntryCollection$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0384ef62c78f8da746e12b063ddc28fd23da7376 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$EntryCollection$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$EntryCollection.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$EntryCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..37fea93708ce9188d9ba27f72865775ae3943938 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$EntryCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$FieldSettersHolder.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$FieldSettersHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..da18ce2d6adc145b90f8b7c586d21e57e4171a3a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$FieldSettersHolder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys$KeysEntrySet$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys$KeysEntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..046338953ba85d1c0681824190b4ca4843a9165c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys$KeysEntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys$KeysEntrySet.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys$KeysEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..a4128da10e2147208b3b03fc7a0c03fab2c942ef Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys$KeysEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys.class new file mode 100644 index 0000000000000000000000000000000000000000..d825250fec76717a1a54e8b2b6f9e4a82e3ecbd9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Keys.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Values.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..f08273034ba9ad57db0c1a6031c0882f7f565d2d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultimap.class b/src/main/resources/org/python/google/common/collect/ImmutableMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..0bd9abe3ff7f330421c6b7b93beb2b9cc4c56154 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultiset$1.class b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..63692f119b610d998e801a65d7da28a4e6f555d9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultiset$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..9635bc3abd338f9cd50200d5c9077e4367162489 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultiset$EntrySet.class b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..a666d373fc0862714fb5f8317c8f74cf84e77755 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultiset$EntrySetSerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$EntrySetSerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..0477c7420e25b6e0738dc21ac587107934387d8e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$EntrySetSerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultiset$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..c05913e174ff05c07c3fef24759cf138ce883dc9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultiset$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableMultiset.class b/src/main/resources/org/python/google/common/collect/ImmutableMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..4f95febfdd08bd3c521b1af21269e9ec704dedb6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSet$ArrayImmutableSet.class b/src/main/resources/org/python/google/common/collect/ImmutableSet$ArrayImmutableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..43d6828973ab8bce291137d7a3a3f7c7f962c4ff Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSet$ArrayImmutableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSet$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableSet$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..546608d71b80ff6041135726244df43754ce942c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSet$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSet$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableSet$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..68134c37f17b21672e62ef29050a5c0f83a681ad Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSet$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSet.class b/src/main/resources/org/python/google/common/collect/ImmutableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..3f8ba811e5202c9a9c98e537e6d1e1f2b16d17d4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$Builder$1.class b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$Builder$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4b37ca8551d981506d099481a4629502a2ae713e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$Builder$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..01b0dd1928c5f53c2aa484229c86880f61b091f4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$BuilderMultimap.class b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$BuilderMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..41875ddeb2a52fe569f63cdb956b86be20fb1270 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$BuilderMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$SortedKeyBuilderMultimap.class b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$SortedKeyBuilderMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..eaf1c63ffce41d6e8b89d94ed39b9c375a355760 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap$SortedKeyBuilderMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap.class b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..12f1a3f38851ca23e00ddb19b3d53220f4b4c792 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedAsList.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..7d38826e591b238d0315659a3f234ba88ecdf011 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedAsList.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$1.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..464ae55fea24cebee7565ff4155b444229e170bb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..f6c56e9ce3fbb3d019092e2a5e7c0a6115618b2d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..e0b346954253241057d6458e73d3c6dcae0e480b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMap.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..eaa9db817099a6e8614e649758bda79ee28557ce Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMapFauxverideShim.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMapFauxverideShim.class new file mode 100644 index 0000000000000000000000000000000000000000..6ee1695c198cc2975df213ac0d196b9cf741185f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMapFauxverideShim.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..829b2384dfeed389192e10f1c0604c25c7f5ece0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..d5ebd775c8a2788ecdc1e026f68d5914bc6673af Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..9655cafe7f39b9afbb2cef6262689e42e2568592 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedMultisetFauxverideShim.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultisetFauxverideShim.class new file mode 100644 index 0000000000000000000000000000000000000000..7a898ac3aa8cbdfda5f93231dc8a06d7f46bb916 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedMultisetFauxverideShim.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedSet$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedSet$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..758c685091e8a1fafad450761473034fbb542b38 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedSet$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedSet$SerializedForm.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedSet$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..b67a126e26bea5397a956253c0f61cba381a1513 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedSet$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedSet.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..b7b5431159a0e503643eea8f89dbe2046f7c487e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableSortedSetFauxverideShim.class b/src/main/resources/org/python/google/common/collect/ImmutableSortedSetFauxverideShim.class new file mode 100644 index 0000000000000000000000000000000000000000..949eb6b489c9f9f8ef270fdd1c39c8faa361ae13 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableSortedSetFauxverideShim.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableTable$Builder.class b/src/main/resources/org/python/google/common/collect/ImmutableTable$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..1eebc948bce148727052207efe252d9b5cb7ef82 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableTable$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/ImmutableTable.class b/src/main/resources/org/python/google/common/collect/ImmutableTable.class new file mode 100644 index 0000000000000000000000000000000000000000..8bc2759c41e02bcfd75475870a56cd523ed20c56 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ImmutableTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/Interner.class b/src/main/resources/org/python/google/common/collect/Interner.class new file mode 100644 index 0000000000000000000000000000000000000000..312259c91fadf96df5f2b23a139af9d5662e15ff Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Interner.class differ diff --git a/src/main/resources/org/python/google/common/collect/Interners$1.class b/src/main/resources/org/python/google/common/collect/Interners$1.class new file mode 100644 index 0000000000000000000000000000000000000000..20dceba65f84c125f5a15687d9d3c6676537854c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Interners$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Interners$InternerFunction.class b/src/main/resources/org/python/google/common/collect/Interners$InternerFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..da5aa946dd27b58ce05a3052686c160fd8f9618c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Interners$InternerFunction.class differ diff --git a/src/main/resources/org/python/google/common/collect/Interners$WeakInterner$Dummy.class b/src/main/resources/org/python/google/common/collect/Interners$WeakInterner$Dummy.class new file mode 100644 index 0000000000000000000000000000000000000000..bec9c1ec412d7d6c98f94b58a0d6a485bca2ff7e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Interners$WeakInterner$Dummy.class differ diff --git a/src/main/resources/org/python/google/common/collect/Interners$WeakInterner.class b/src/main/resources/org/python/google/common/collect/Interners$WeakInterner.class new file mode 100644 index 0000000000000000000000000000000000000000..50ae3440f1f0ce2ab3e7877f0dfe2e159de8dc41 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Interners$WeakInterner.class differ diff --git a/src/main/resources/org/python/google/common/collect/Interners.class b/src/main/resources/org/python/google/common/collect/Interners.class new file mode 100644 index 0000000000000000000000000000000000000000..97ddf7ff1063202d86acffcef491a9aba6aac773 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Interners.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$1.class b/src/main/resources/org/python/google/common/collect/Iterables$1.class new file mode 100644 index 0000000000000000000000000000000000000000..22c1c669c0b12d68f73502c4a1ecddbe0cca42d3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$10$1.class b/src/main/resources/org/python/google/common/collect/Iterables$10$1.class new file mode 100644 index 0000000000000000000000000000000000000000..927a57a5b98f6dd78bc89c987fd573288e4f8496 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$10$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$10.class b/src/main/resources/org/python/google/common/collect/Iterables$10.class new file mode 100644 index 0000000000000000000000000000000000000000..491dc6e5e86e879e08acb264a3174a928e0b6840 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$10.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$11.class b/src/main/resources/org/python/google/common/collect/Iterables$11.class new file mode 100644 index 0000000000000000000000000000000000000000..019fb29854c9cd3ba626e54ee08c2bfdcba32624 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$11.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$12.class b/src/main/resources/org/python/google/common/collect/Iterables$12.class new file mode 100644 index 0000000000000000000000000000000000000000..533ed3448ef54baac3bebe215c448c0ce1871105 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$12.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$13.class b/src/main/resources/org/python/google/common/collect/Iterables$13.class new file mode 100644 index 0000000000000000000000000000000000000000..aaf4578f04e99be83138943b9356a4c87c8aa880 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$13.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$14.class b/src/main/resources/org/python/google/common/collect/Iterables$14.class new file mode 100644 index 0000000000000000000000000000000000000000..4f2bf9e3bb07fc07a9eda13132aadda2d29f2be8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$14.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$15.class b/src/main/resources/org/python/google/common/collect/Iterables$15.class new file mode 100644 index 0000000000000000000000000000000000000000..a74c4e8ae80a32fee9e5b912fff950822fc55e70 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$15.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$2.class b/src/main/resources/org/python/google/common/collect/Iterables$2.class new file mode 100644 index 0000000000000000000000000000000000000000..396ad4c1eb149b06294f00a0498821e8e39a4aa3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$3.class b/src/main/resources/org/python/google/common/collect/Iterables$3.class new file mode 100644 index 0000000000000000000000000000000000000000..9408ab99118debb7da98da2125976c70b3d2c77b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$4.class b/src/main/resources/org/python/google/common/collect/Iterables$4.class new file mode 100644 index 0000000000000000000000000000000000000000..de6137d3f037daa12a31e786ce4480d3a45ff360 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$5.class b/src/main/resources/org/python/google/common/collect/Iterables$5.class new file mode 100644 index 0000000000000000000000000000000000000000..23591cfdc2de3b1101822709b993061d0ebabbd8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$6.class b/src/main/resources/org/python/google/common/collect/Iterables$6.class new file mode 100644 index 0000000000000000000000000000000000000000..f8a264e768ec75c903c681f46ec0ef6206612d13 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$6.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$7.class b/src/main/resources/org/python/google/common/collect/Iterables$7.class new file mode 100644 index 0000000000000000000000000000000000000000..d02dd04adfc1f3c89b47c88b70e05f376f44f49b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$7.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$8.class b/src/main/resources/org/python/google/common/collect/Iterables$8.class new file mode 100644 index 0000000000000000000000000000000000000000..7f6e3c11586429f6ae01e6a030f62a8633f21dd3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$8.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$9.class b/src/main/resources/org/python/google/common/collect/Iterables$9.class new file mode 100644 index 0000000000000000000000000000000000000000..c0a8083352ceb239685a620475b585a6ca894788 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$9.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$ConsumingQueueIterator.class b/src/main/resources/org/python/google/common/collect/Iterables$ConsumingQueueIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..6713f1952590ec2ee3a8de357866946abcfdf7a5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$ConsumingQueueIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables$UnmodifiableIterable.class b/src/main/resources/org/python/google/common/collect/Iterables$UnmodifiableIterable.class new file mode 100644 index 0000000000000000000000000000000000000000..4717be65b8c1ca55f2c4cb7857c1f4376f945533 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables$UnmodifiableIterable.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterables.class b/src/main/resources/org/python/google/common/collect/Iterables.class new file mode 100644 index 0000000000000000000000000000000000000000..2d10189b828d44695113b87fdd040b451213e02f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterables.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$1.class b/src/main/resources/org/python/google/common/collect/Iterators$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8bcdeca93cdf4d268b7abde1a8c23fc4b8a896b4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$10.class b/src/main/resources/org/python/google/common/collect/Iterators$10.class new file mode 100644 index 0000000000000000000000000000000000000000..e44ccc3d240bf45eb9c569fce5f121175e3b15f7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$10.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$11.class b/src/main/resources/org/python/google/common/collect/Iterators$11.class new file mode 100644 index 0000000000000000000000000000000000000000..fc3e78fb81bd017fff665238ac9f6565e85f42b6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$11.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$12.class b/src/main/resources/org/python/google/common/collect/Iterators$12.class new file mode 100644 index 0000000000000000000000000000000000000000..1208fcfe5966e113f11f609b53ed21d373f0b7fb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$12.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$13.class b/src/main/resources/org/python/google/common/collect/Iterators$13.class new file mode 100644 index 0000000000000000000000000000000000000000..ef87bbe8ae7142f6baebccc5ae308b43c1814855 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$13.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$14.class b/src/main/resources/org/python/google/common/collect/Iterators$14.class new file mode 100644 index 0000000000000000000000000000000000000000..c2fcc9aba8bbcf7cbb4b0707fb8fbc49ce7c0a89 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$14.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$15.class b/src/main/resources/org/python/google/common/collect/Iterators$15.class new file mode 100644 index 0000000000000000000000000000000000000000..48e9740dc30da993ea714ae25cf24de729d753af Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$15.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$16.class b/src/main/resources/org/python/google/common/collect/Iterators$16.class new file mode 100644 index 0000000000000000000000000000000000000000..8dc9a87d23db66fac5a3ed88738416ae2e308742 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$16.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$2.class b/src/main/resources/org/python/google/common/collect/Iterators$2.class new file mode 100644 index 0000000000000000000000000000000000000000..1c7a6c326e03b9ddc5ceb5e906c94fc879e5b6a4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$3.class b/src/main/resources/org/python/google/common/collect/Iterators$3.class new file mode 100644 index 0000000000000000000000000000000000000000..59c0af6a7db032b2f175e6fcf84a8e1b835a2f2f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$4.class b/src/main/resources/org/python/google/common/collect/Iterators$4.class new file mode 100644 index 0000000000000000000000000000000000000000..b081a837bd24df49a6b30b360d4da0ad3a2373ea Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$5.class b/src/main/resources/org/python/google/common/collect/Iterators$5.class new file mode 100644 index 0000000000000000000000000000000000000000..875bc1b2f586e1ccc7bbe48e705ad8538974ec47 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$6.class b/src/main/resources/org/python/google/common/collect/Iterators$6.class new file mode 100644 index 0000000000000000000000000000000000000000..0dd150cdf0362ea9ba96bee869bb230ba7fecb02 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$6.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$7.class b/src/main/resources/org/python/google/common/collect/Iterators$7.class new file mode 100644 index 0000000000000000000000000000000000000000..5093c865a0574008f17ef85208abebc2ba3594aa Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$7.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$8.class b/src/main/resources/org/python/google/common/collect/Iterators$8.class new file mode 100644 index 0000000000000000000000000000000000000000..783fb42a9031bcf21140fd0833055c154a85dbd7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$8.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$9.class b/src/main/resources/org/python/google/common/collect/Iterators$9.class new file mode 100644 index 0000000000000000000000000000000000000000..dbd965d7e36992b02a8c96e76256a7b892dbbc74 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$9.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$MergingIterator$1.class b/src/main/resources/org/python/google/common/collect/Iterators$MergingIterator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3d97faec154cecc8c29c0b50156841a87b2627cc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$MergingIterator$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$MergingIterator.class b/src/main/resources/org/python/google/common/collect/Iterators$MergingIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..05ec86a9f36c68f08d510faac583f1fb85ecd125 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$MergingIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators$PeekingImpl.class b/src/main/resources/org/python/google/common/collect/Iterators$PeekingImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..b270db7a84506faf20788ca14ac7b35b00e7edcb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators$PeekingImpl.class differ diff --git a/src/main/resources/org/python/google/common/collect/Iterators.class b/src/main/resources/org/python/google/common/collect/Iterators.class new file mode 100644 index 0000000000000000000000000000000000000000..d4178b68042bd149d5245e927017bbb1a0ffa508 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Iterators.class differ diff --git a/src/main/resources/org/python/google/common/collect/LexicographicalOrdering.class b/src/main/resources/org/python/google/common/collect/LexicographicalOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..ca290fcd8a08146ff6d51b7ae36487de57417559 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LexicographicalOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$1.class b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3cdf95770f2284e1548b108c173f3b10dbea05ad Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueEntry.class b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..47596f630d039e79f1eff0451932c15ef32c98a9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSet$1.class b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..310a4cc0ca6b2a82cc8958450e1eaf0fba32c547 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSet.class b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSet.class new file mode 100644 index 0000000000000000000000000000000000000000..1c038387cc0a4aed4463aceede0d22c4533cfe53 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSetLink.class b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSetLink.class new file mode 100644 index 0000000000000000000000000000000000000000..8cde605cec1c86153c9042167d2e97c19a000e54 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap$ValueSetLink.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedHashMultimap.class b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..333fd658868f4ad5992792ad19df1fe55a2ff3ed Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedHashMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedHashMultiset.class b/src/main/resources/org/python/google/common/collect/LinkedHashMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..dc17a0d0242f781beb0b6b359dd43f4251b1cae8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedHashMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$1.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a679a67908b74c1bb5f9bf5f0ee8e9aa00d661d6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$2.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..1d45f54b413fbed6ca92b3750d468de296fcfb2a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$3$1.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$3$1.class new file mode 100644 index 0000000000000000000000000000000000000000..031a06bbea319c1452da0f91cf1303da5d86ef22 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$3$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$3.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$3.class new file mode 100644 index 0000000000000000000000000000000000000000..9295a862c0164bcacc8e08a11367ae69b522ab3f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$4.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$4.class new file mode 100644 index 0000000000000000000000000000000000000000..79e3dc369b996ef5da85e99683ea090729546db2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$5$1.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$5$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1aab7cfceb35c0d1d95014efc9deb33ffa55b8b8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$5$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$5.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$5.class new file mode 100644 index 0000000000000000000000000000000000000000..af656e4170ce0fff75e9e1d43963d1bdd7f1e86b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6$1$1.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8aa4a75caf8c73de8f494b2c9b5556e91ab9f010 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6$1.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1c6199cae89db5d95e1d689900e407d268a8e31e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6.class new file mode 100644 index 0000000000000000000000000000000000000000..9180a0bb1409189288af9ff02ac330a7b4481440 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$6.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$DistinctKeyIterator.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$DistinctKeyIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..d1533fd52c33f2655b29c46a742671b8589d0004 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$DistinctKeyIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$1$1.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f8d146dbc7627999c5cdd651fd21d7963d0f6122 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$1.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e90fd99f695e0007c3769f31967ca445b77e82a3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$2.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$2.class new file mode 100644 index 0000000000000000000000000000000000000000..d30da1152d2d70a43d9a982f05d17e03e91a3776 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView.class new file mode 100644 index 0000000000000000000000000000000000000000..57de665c2c4887cf16d56b9bdf794ba919d2be33 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$MultisetView.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$Node.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$Node.class new file mode 100644 index 0000000000000000000000000000000000000000..22325cbf776a9a590608946c335d4fdebafa1d99 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$Node.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$NodeIterator.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$NodeIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..6488858ddb074f9aaabb4de5cf45c40e466b0706 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$NodeIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap$ValueForKeyIterator.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$ValueForKeyIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..1a8615bb9c09d47904475bd3a312e738dbfe802b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap$ValueForKeyIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/LinkedListMultimap.class b/src/main/resources/org/python/google/common/collect/LinkedListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..4b5402de055497e48c5d84aec2ded519c21ee62f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/LinkedListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/ListMultimap.class b/src/main/resources/org/python/google/common/collect/ListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..26bc53468efe3cc307f6dd4afc00f4cef480fa0b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$1.class b/src/main/resources/org/python/google/common/collect/Lists$1.class new file mode 100644 index 0000000000000000000000000000000000000000..03f373c649cad2a0117536b30b386507769300bd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$2.class b/src/main/resources/org/python/google/common/collect/Lists$2.class new file mode 100644 index 0000000000000000000000000000000000000000..6dbd216be24dfe0a943bf4c7d84664fd47fc79fb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$AbstractListWrapper.class b/src/main/resources/org/python/google/common/collect/Lists$AbstractListWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..d352b8bd8050ce18cb920934e4ae0d7c714ec3f4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$AbstractListWrapper.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$CharSequenceAsList.class b/src/main/resources/org/python/google/common/collect/Lists$CharSequenceAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..c1da28fad083907f59e76fbc8c29ed6086854165 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$CharSequenceAsList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$OnePlusArrayList.class b/src/main/resources/org/python/google/common/collect/Lists$OnePlusArrayList.class new file mode 100644 index 0000000000000000000000000000000000000000..8d7a04430ce2417c14b6461b72d653dce8390531 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$OnePlusArrayList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$Partition.class b/src/main/resources/org/python/google/common/collect/Lists$Partition.class new file mode 100644 index 0000000000000000000000000000000000000000..dac08a6e11d66a43f60f1ace1bc9ad8d49ad23d8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$Partition.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$RandomAccessListWrapper.class b/src/main/resources/org/python/google/common/collect/Lists$RandomAccessListWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..b84ed51ea36de748fdf40d0e3cb13b276bee54ce Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$RandomAccessListWrapper.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$RandomAccessPartition.class b/src/main/resources/org/python/google/common/collect/Lists$RandomAccessPartition.class new file mode 100644 index 0000000000000000000000000000000000000000..44c6b8e505a436985d65b3544c9a27f055ccf10d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$RandomAccessPartition.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$RandomAccessReverseList.class b/src/main/resources/org/python/google/common/collect/Lists$RandomAccessReverseList.class new file mode 100644 index 0000000000000000000000000000000000000000..f15b3339ec3f230e758f40b0c8a68d7e596b76f8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$RandomAccessReverseList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$ReverseList$1.class b/src/main/resources/org/python/google/common/collect/Lists$ReverseList$1.class new file mode 100644 index 0000000000000000000000000000000000000000..84bba6c52ed851c911ead23f62115a7cde2a65a2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$ReverseList$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$ReverseList.class b/src/main/resources/org/python/google/common/collect/Lists$ReverseList.class new file mode 100644 index 0000000000000000000000000000000000000000..ed0f14f3c1232c87fab74e08ac13f6772a50c2e9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$ReverseList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$StringAsImmutableList.class b/src/main/resources/org/python/google/common/collect/Lists$StringAsImmutableList.class new file mode 100644 index 0000000000000000000000000000000000000000..7e1ce9f813c5115f9e62e3920e504383df4b5193 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$StringAsImmutableList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$TransformingRandomAccessList.class b/src/main/resources/org/python/google/common/collect/Lists$TransformingRandomAccessList.class new file mode 100644 index 0000000000000000000000000000000000000000..e96caf77b5910a2654f5137578f47fcc8af10adc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$TransformingRandomAccessList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$TransformingSequentialList$1.class b/src/main/resources/org/python/google/common/collect/Lists$TransformingSequentialList$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ca4b48a714675b2e02ff6b971ab21ed511bb2efb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$TransformingSequentialList$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$TransformingSequentialList.class b/src/main/resources/org/python/google/common/collect/Lists$TransformingSequentialList.class new file mode 100644 index 0000000000000000000000000000000000000000..9bc1799e7a9e624c0d4abd8f7745c1eeb8ea74a7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$TransformingSequentialList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists$TwoPlusArrayList.class b/src/main/resources/org/python/google/common/collect/Lists$TwoPlusArrayList.class new file mode 100644 index 0000000000000000000000000000000000000000..711ab52966af7184adc47aa07fde8b0126801243 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists$TwoPlusArrayList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Lists.class b/src/main/resources/org/python/google/common/collect/Lists.class new file mode 100644 index 0000000000000000000000000000000000000000..26ecc1a8fb001346a9ea1809198fef39a036235a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Lists.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraint.class b/src/main/resources/org/python/google/common/collect/MapConstraint.class new file mode 100644 index 0000000000000000000000000000000000000000..8db59e80bc5536219e21c0e3caddd69639dac979 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraint.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$1.class b/src/main/resources/org/python/google/common/collect/MapConstraints$1.class new file mode 100644 index 0000000000000000000000000000000000000000..77d8ee5365d2b0cc356774c300a8b9db0ba227f6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$2$1.class b/src/main/resources/org/python/google/common/collect/MapConstraints$2$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1a682114015d897978686d7e6f4b5f31c92e2dd6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$2$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$2.class b/src/main/resources/org/python/google/common/collect/MapConstraints$2.class new file mode 100644 index 0000000000000000000000000000000000000000..1accaa4184a4a50fcf08ac46d533083a472fa761 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapEntries$1.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapEntries$1.class new file mode 100644 index 0000000000000000000000000000000000000000..903a2d95c6e85411e89d353a9c6c6c846dca2f76 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapEntries$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapEntries.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..6b1ab09e7826e03df6e195e11691e6b3143bfaee Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapValues$1.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapValues$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0e79a4bbec7ddc281964f72ace8cdad990a97359 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapValues$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapValues.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapValues.class new file mode 100644 index 0000000000000000000000000000000000000000..c8d218f078627d6f0c7e50fe2949e2b4461c2689 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedAsMapValues.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedBiMap.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..ae2c4f924bac7f49854d3f24e657e9727b5ef823 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntries$1.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntries$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9a2a0fb998f501e1c0fa419a9f8bd6dab404909f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntries$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntries.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..38aa438c1c956ea3824c488646d9f81ff02a017a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntrySet.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..699df4784da93907b3abc1c9d3a3a480c6881fd7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedListMultimap.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..435d6600e6f9eada9539af503d1d49822c95319f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMap.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..249ccb64d79924186712c69d6a0a32701324325c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap$1.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b3e6969b85beec10b12334b522132ddcba8ed545 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap$2.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..8b78d26676ff6c9e66f22817136c9260cbba6457 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..c7b021737d808309f82d4919e841c874ae5f84bd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedSetMultimap.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..5d71026674d30ab74031d19718507d81b184a5b5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedSortedSetMultimap.class b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedSortedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..de76b29e04c965e536d71695a8064a10ca986f73 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$ConstrainedSortedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$InverseConstraint.class b/src/main/resources/org/python/google/common/collect/MapConstraints$InverseConstraint.class new file mode 100644 index 0000000000000000000000000000000000000000..102489c9f272f8820a3c06a43ef84bac9f093df1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$InverseConstraint.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints$NotNullMapConstraint.class b/src/main/resources/org/python/google/common/collect/MapConstraints$NotNullMapConstraint.class new file mode 100644 index 0000000000000000000000000000000000000000..b46c0d6f988eac9692480ed3909cc23eef220987 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints$NotNullMapConstraint.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapConstraints.class b/src/main/resources/org/python/google/common/collect/MapConstraints.class new file mode 100644 index 0000000000000000000000000000000000000000..92fba84e53a5b6ea43e6278a90a73963e811635c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapConstraints.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapDifference$ValueDifference.class b/src/main/resources/org/python/google/common/collect/MapDifference$ValueDifference.class new file mode 100644 index 0000000000000000000000000000000000000000..c54ba1860a9f89f4396b3583b4e54e9d8cb77bcb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapDifference$ValueDifference.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapDifference.class b/src/main/resources/org/python/google/common/collect/MapDifference.class new file mode 100644 index 0000000000000000000000000000000000000000..02a6d26144b2b31be2049bbc6755c4ae1b8929af Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapDifference.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$1.class b/src/main/resources/org/python/google/common/collect/MapMaker$1.class new file mode 100644 index 0000000000000000000000000000000000000000..58678e018abb74ed49e39326291c72c9b5307858 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$NullComputingConcurrentMap.class b/src/main/resources/org/python/google/common/collect/MapMaker$NullComputingConcurrentMap.class new file mode 100644 index 0000000000000000000000000000000000000000..43958833ac942c5911638584d1102fe44bab6728 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$NullComputingConcurrentMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$NullConcurrentMap.class b/src/main/resources/org/python/google/common/collect/MapMaker$NullConcurrentMap.class new file mode 100644 index 0000000000000000000000000000000000000000..54c6d8d41321e4ad2d173f404780019eca03a5e6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$NullConcurrentMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$1.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c0b2778118fe7a0f101e5de6e7ed922765d57860 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$2.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$2.class new file mode 100644 index 0000000000000000000000000000000000000000..0b043789a9704d3650ea49cec6999bfc06b4f1e9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$3.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$3.class new file mode 100644 index 0000000000000000000000000000000000000000..c599272f6fc00408051299326dcb36495f142222 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$4.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$4.class new file mode 100644 index 0000000000000000000000000000000000000000..068975965b9f6d59aff76d48ef4726a13a9d8007 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$5.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$5.class new file mode 100644 index 0000000000000000000000000000000000000000..6d28ebbd58f8eabc02ee519ef75b6427d3799ece Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause.class new file mode 100644 index 0000000000000000000000000000000000000000..a1fda4c7183bb8ff0bb033d9f4e4707bd66118e5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalCause.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalListener.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalListener.class new file mode 100644 index 0000000000000000000000000000000000000000..23c081db817b8592b8a2272ecba9852f57310708 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalListener.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker$RemovalNotification.class b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalNotification.class new file mode 100644 index 0000000000000000000000000000000000000000..ee6ad10fa353368bacb03351531e253256034e39 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker$RemovalNotification.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMaker.class b/src/main/resources/org/python/google/common/collect/MapMaker.class new file mode 100644 index 0000000000000000000000000000000000000000..ab6346fb31fe294629e36b26b50026f92f7b855b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMaker.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$1.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..78c3f86db8f588a388990ce4ddc5468b89823dfd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$2.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..bb1bb993cc942ec27858955d0e6dea9f566dd980 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$AbstractReferenceEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$AbstractReferenceEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..37785a675e34f11fd3c77064d767470df66e40d0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$AbstractReferenceEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$AbstractSerializationProxy.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$AbstractSerializationProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..d9388092150d38654833993fbca164656c0e55f9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$AbstractSerializationProxy.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$CleanupMapTask.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$CleanupMapTask.class new file mode 100644 index 0000000000000000000000000000000000000000..7986b6a57209b7f4848a0074f436255d3bbe8c88 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$CleanupMapTask.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$1.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1d7085098fde34fb9b21b89c94223035fe00812b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$10.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$10.class new file mode 100644 index 0000000000000000000000000000000000000000..0483a2e4d412cbbd3ef71b2ab9be467febb998cb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$10.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$11.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$11.class new file mode 100644 index 0000000000000000000000000000000000000000..b5f9916a7cee2423d90c55ae71e2d4ad931aaf7b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$11.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$12.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$12.class new file mode 100644 index 0000000000000000000000000000000000000000..802e2b3d9f9de23d9538baaa134ea779a8bd643a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$12.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$2.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$2.class new file mode 100644 index 0000000000000000000000000000000000000000..164a2ce7ccb862b0b94e01ae8ebc72cc8f05244b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$3.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$3.class new file mode 100644 index 0000000000000000000000000000000000000000..4e23c4dd7b09181925ef4c6752cf849f0661a021 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$4.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$4.class new file mode 100644 index 0000000000000000000000000000000000000000..36280ed74ff0051e99629dbea85366dc620efbd4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$5.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$5.class new file mode 100644 index 0000000000000000000000000000000000000000..03cc7dc69d972845cad7177e8e46ec1c6dde94f6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$6.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$6.class new file mode 100644 index 0000000000000000000000000000000000000000..4a75bef1ea0004e3cb15bb9d72b5b794ec4f08a3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$6.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$7.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$7.class new file mode 100644 index 0000000000000000000000000000000000000000..750304f19872bf9735491a99b93eca9b2bce6511 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$7.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$8.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$8.class new file mode 100644 index 0000000000000000000000000000000000000000..d10319074b98ac6bb8c1a1400cf26868df3d0a79 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$8.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$9.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$9.class new file mode 100644 index 0000000000000000000000000000000000000000..71a127ea76789904cc0f21e2dec275560883cfde Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory$9.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory.class new file mode 100644 index 0000000000000000000000000000000000000000..701ecf52ca9b85d5c71eea1e62e44172760f89e4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryFactory.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryIterator.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..09ec679635e64c22035ddde1c351661a089f0ecb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntryIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..95598db9ff366d5c0c236ab1f4786d4a7aad0b3b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue$1.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue$1.class new file mode 100644 index 0000000000000000000000000000000000000000..49aeaf15cdc28277d12b51cfcd608fdc46ccbacf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue$2.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5f3e4f14003e6662f91be44143c76b8345e66fc1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..c96683dfe2cb2f13c7b4a0a44747d825f7fae7d4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$EvictionQueue.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue$1.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e5c53466e70dd9f1f23c3c78595ba4fd3c88bc0f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue$2.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue$2.class new file mode 100644 index 0000000000000000000000000000000000000000..7b8fc36d2099fde970fffd162f93b8759417fd22 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..083cadc0ce0a6f5291e6a81edafb58763068f557 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ExpirationQueue.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$HashIterator.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$HashIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..62ed43b65b2129cc3b433b745ed76b8e43684430 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$HashIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$KeyIterator.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$KeyIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..c11b5a0b07e33d671c5546f402607170e8f98d73 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$KeyIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$KeySet.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..abc3c85f3ea29b02cb0b4a99a9c6d72fb637d380 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$NullEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$NullEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..5385e90352a0f3f4bced65343243d7be3f87f049 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$NullEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ReferenceEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ReferenceEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..e806b4ce9e765aa07bcc55919f57bcccdfbf18a5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ReferenceEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Segment.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Segment.class new file mode 100644 index 0000000000000000000000000000000000000000..3b60f7496306ac0b464c6f671e4fc6c97fc49897 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Segment.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SerializationProxy.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SerializationProxy.class new file mode 100644 index 0000000000000000000000000000000000000000..8508f391eb3d4fe6504fe502bb0fb4539acc2bdb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SerializationProxy.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..681aa91286aad6288f7648cb3758a8f3578d5c10 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftEvictableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftEvictableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..6a73e6b455c6e00d9be1c02db15dc37ac19855af Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftEvictableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftExpirableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftExpirableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..3955c45657e31c4b7016c76ad16e315e0af87ade Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftExpirableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftExpirableEvictableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftExpirableEvictableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..049687c1e90887ee3e3d8931c7cfe8cb30ebf7eb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftExpirableEvictableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftValueReference.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..2b01622c12f9fccb9a59bd69a6ef7606bc923674 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$SoftValueReference.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$1.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$1.class new file mode 100644 index 0000000000000000000000000000000000000000..27512d3ad7228ab72409bd023c5f8e9dfbab682b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$2.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$2.class new file mode 100644 index 0000000000000000000000000000000000000000..0474f0a4f33abd4c568ee9f8dd07a3cd3c6e3c19 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$3.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$3.class new file mode 100644 index 0000000000000000000000000000000000000000..8aeed866e7c1a8643fee32b79aed2c4340b9cefe Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength.class new file mode 100644 index 0000000000000000000000000000000000000000..9fd77687cc9ad5a5c474ab83df8132defa5aa579 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Strength.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..096ac32b899a60c51656049f9542ccf1add937f8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongEvictableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongEvictableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..36d71888932cf591c9f4e4b2316ecbcd9839cd4e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongEvictableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongExpirableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongExpirableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..83131e5f4258ddb4b10ef47f9dbf608655544a82 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongExpirableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongExpirableEvictableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongExpirableEvictableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..59b176b2ba07d41117500ebd8b8550b5087a62a2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongExpirableEvictableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongValueReference.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..356da45d26afcea3404f6f33456a0763292a35c1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$StrongValueReference.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ValueIterator.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ValueIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..4bacd97b3d174bdff24ae672a8c3fab0d78c8797 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ValueIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ValueReference.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..db2de853e6d165cdb31a79f64f1ece6c6a94592c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$ValueReference.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Values.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..9de3586d1ce20654a2f991e3e055df89ff2e16d8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..3854ebaecc0d0af7e554b30fb878227e3d7dfaf7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakEvictableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakEvictableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..4804c1cb447d30737d7b555c8b0f4d5725e8dda5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakEvictableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakExpirableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakExpirableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..7fee5529f3895aad0863fe620a99915782aedb8f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakExpirableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakExpirableEvictableEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakExpirableEvictableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..a79c51df91cab82602ea00cddf0f13f7af37f20a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakExpirableEvictableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakValueReference.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakValueReference.class new file mode 100644 index 0000000000000000000000000000000000000000..cb973cdb0dba4c27b4ab67091eae946668c8b1f5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WeakValueReference.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WriteThroughEntry.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WriteThroughEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..7b6cd166bd825642aeece0bef71734610d4d42f6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap$WriteThroughEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/MapMakerInternalMap.class b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap.class new file mode 100644 index 0000000000000000000000000000000000000000..41d934262d73ef4c141d63d3a349073109ae645a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MapMakerInternalMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$1.class b/src/main/resources/org/python/google/common/collect/Maps$1.class new file mode 100644 index 0000000000000000000000000000000000000000..922daf21d623fbd80541b32c07fbfee37ac6a830 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$2.class b/src/main/resources/org/python/google/common/collect/Maps$2.class new file mode 100644 index 0000000000000000000000000000000000000000..3c7f8a91bfbfd1173ad972f3d73d908383e31c8f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$3.class b/src/main/resources/org/python/google/common/collect/Maps$3.class new file mode 100644 index 0000000000000000000000000000000000000000..0d05aaf1c65adf6e3d008c222b6dbf96c457fc4e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$4.class b/src/main/resources/org/python/google/common/collect/Maps$4.class new file mode 100644 index 0000000000000000000000000000000000000000..4c8c4be43de13579614e0214c774c54038656523 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$5.class b/src/main/resources/org/python/google/common/collect/Maps$5.class new file mode 100644 index 0000000000000000000000000000000000000000..a176c41387572b5845c6a95dc818fcd2042856d0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$6.class b/src/main/resources/org/python/google/common/collect/Maps$6.class new file mode 100644 index 0000000000000000000000000000000000000000..b75619bcb42b962b7d203ecd2c6ec91db91cd3a5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$6.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$7.class b/src/main/resources/org/python/google/common/collect/Maps$7.class new file mode 100644 index 0000000000000000000000000000000000000000..dce30f07df38bd09fb6221ad2446b5c1ffff108f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$7.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$8.class b/src/main/resources/org/python/google/common/collect/Maps$8.class new file mode 100644 index 0000000000000000000000000000000000000000..165d3e1595c83558744a45b059cdc7c017adcefe Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$8.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$9.class b/src/main/resources/org/python/google/common/collect/Maps$9.class new file mode 100644 index 0000000000000000000000000000000000000000..41383f289de07126b951821ca9adbdf4ecb1017e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$9.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap$Values$1.class b/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap$Values$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e7943923da25d2e3d5567a723961553c09892c32 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap$Values$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap$Values.class b/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..46334874f6e0040c1203d978b6d922aeba62602c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap.class b/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap.class new file mode 100644 index 0000000000000000000000000000000000000000..8316481666011e44790d35f47181353d56b3d622 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$AbstractFilteredMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$AsMapView$1.class b/src/main/resources/org/python/google/common/collect/Maps$AsMapView$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e2ef8392996048c5c352e8f91b922e435fcbaf35 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$AsMapView$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$AsMapView$2$1.class b/src/main/resources/org/python/google/common/collect/Maps$AsMapView$2$1.class new file mode 100644 index 0000000000000000000000000000000000000000..71e31cd948eeb9b9476d5fecaadbb03dfc1c1817 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$AsMapView$2$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$AsMapView$2.class b/src/main/resources/org/python/google/common/collect/Maps$AsMapView$2.class new file mode 100644 index 0000000000000000000000000000000000000000..cfd6eee73501f4d9d10a49031ccf5e3b3566155d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$AsMapView$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$AsMapView.class b/src/main/resources/org/python/google/common/collect/Maps$AsMapView.class new file mode 100644 index 0000000000000000000000000000000000000000..afa56e234e7df51c0ce847f708aef98d87aa7856 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$AsMapView.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$1.class b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f8c5bcda86563b10d57e2053a73215ac85fd35d9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$2.class b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..1fd14afdea900e7b9309bf7e6a55b3228cfac299 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$3.class b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$3.class new file mode 100644 index 0000000000000000000000000000000000000000..5c040069adc81754ebd53e445753e1c1230cfa71 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$DescendingMap.class b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap.class new file mode 100644 index 0000000000000000000000000000000000000000..6d4fdba2c1a94dc5b4ef035e7661d96eceed0646 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$DescendingMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$EntrySet.class b/src/main/resources/org/python/google/common/collect/Maps$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..65ec99622b40e4d573965f81ab043df4f1f3174c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$EntryTransformer.class b/src/main/resources/org/python/google/common/collect/Maps$EntryTransformer.class new file mode 100644 index 0000000000000000000000000000000000000000..850d15e2208691951820b043ab76722e07ab83fe Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$EntryTransformer.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet$1$1.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..084d65ef9fd1c7a24d6392e96c6cb5410ad31f09 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a134a4b13b3edfb0e0c2d72b4009c63f6d6d8d29 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..37600130811a217352d2894689ab0d0ffc19f1da Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$KeySet$1.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$KeySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ecf960f5a984f6dd983921a6b6821e317f5c3b6e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$KeySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$KeySet.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..0164fbef7740f99161fa587f4057e16a0482e412 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap.class new file mode 100644 index 0000000000000000000000000000000000000000..6d9f2ac48afa9b3c7d5db6d5d676f79c9b812888 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntryMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredEntrySortedMap.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntrySortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..36a79450ceb73a8658ffdd6dcb3d43577240f9df Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredEntrySortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$FilteredKeyMap.class b/src/main/resources/org/python/google/common/collect/Maps$FilteredKeyMap.class new file mode 100644 index 0000000000000000000000000000000000000000..e2af6c56bd4163273f8417870f83ada5b54cf62b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$FilteredKeyMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap$1.class b/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..371db6ed637d9b72f7ca34ebafe22249e347cb48 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap$2.class b/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..59e6955e09d986212d463d50f885fab98a122275 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap.class b/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap.class new file mode 100644 index 0000000000000000000000000000000000000000..d923b9605062a1d77195925670a72bb62218ef49 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$ImprovedAbstractMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$KeySet.class b/src/main/resources/org/python/google/common/collect/Maps$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..2a321a819ba0fd5a336955e8c1c217fd06b693f6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$MapDifferenceImpl.class b/src/main/resources/org/python/google/common/collect/Maps$MapDifferenceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..162ead3ee17b92a531b277e197511fc963c09d0c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$MapDifferenceImpl.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$NavigableKeySet.class b/src/main/resources/org/python/google/common/collect/Maps$NavigableKeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..12f1179adbd94e89acf3a501fe7b8b4949f91c4f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$NavigableKeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$SortedAsMapView.class b/src/main/resources/org/python/google/common/collect/Maps$SortedAsMapView.class new file mode 100644 index 0000000000000000000000000000000000000000..28443f913ec71138f017c3a2f406bf7ccdba5060 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$SortedAsMapView.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$SortedMapDifferenceImpl.class b/src/main/resources/org/python/google/common/collect/Maps$SortedMapDifferenceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..f75958d678bcb84d3fc8c198593b4b0452e3e36f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$SortedMapDifferenceImpl.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1$1$1.class b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..dfe9d71c0c6a5bdb191f77c101865d3da9af2218 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1$1.class b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cae9224b8f4c36ab2139d024d0205e6f97d60ebc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1.class b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5218629aa4a791e2386eedeaab9daf5ea7615675 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$2.class b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..0507b17d9be3ed19a9478bff0244c3bb2ade227e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap.class b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap.class new file mode 100644 index 0000000000000000000000000000000000000000..22a33408c5cc93db2e3105bdf8c5abcbc3253373 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesNavigableMap.class b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesNavigableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..5147c6e83644d9e1245e828574653f41000c2c65 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesNavigableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesSortedMap.class b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..50f8dcf115b316a86f903402730690cade3f1679 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$TransformedEntriesSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableBiMap.class b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..8102ab497fa8de05c8ae92dcba94c3531e549cde Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntries$1.class b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntries$1.class new file mode 100644 index 0000000000000000000000000000000000000000..676e354fc9e2c79e761137005864704ef42ed43a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntries$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntries.class b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..5ad4b7b3194a991ee6b330960386d4d4bedd9a42 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntrySet.class b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..8fdd9fdaddda9bc1593b971a102b143969fbf478 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableNavigableMap.class b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableNavigableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..7084e23bd0bc73fb22e25c6573e76560e64a59e9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$UnmodifiableNavigableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$ValueDifferenceImpl.class b/src/main/resources/org/python/google/common/collect/Maps$ValueDifferenceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..87e48830c9c752ee44d9e0ecda9df397a85ea899 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$ValueDifferenceImpl.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps$Values.class b/src/main/resources/org/python/google/common/collect/Maps$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..f82627d81414b31f1b8f77ed941ac1d8869e65b7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/Maps.class b/src/main/resources/org/python/google/common/collect/Maps.class new file mode 100644 index 0000000000000000000000000000000000000000..05cf420219bd65a01d0631e0b37d9a3b9f98c9b0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Maps.class differ diff --git a/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$1.class b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0e3564afa9f8516ab9ccbd0ecd240c2fdfdd9398 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$Builder.class b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..c29479a267a3c2c2ce7f8354a92318c48af58f80 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$Builder.class differ diff --git a/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$Heap.class b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$Heap.class new file mode 100644 index 0000000000000000000000000000000000000000..1dd42acc751d610bcf107053812893971b02dd0c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$Heap.class differ diff --git a/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$MoveDesc.class b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$MoveDesc.class new file mode 100644 index 0000000000000000000000000000000000000000..9d0932c5f96e6788d4b7a37d6f6a002d35590179 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$MoveDesc.class differ diff --git a/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$QueueIterator.class b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$QueueIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..15203d0f4c07cb1d4667f6b31419904f56bfdcfa Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue$QueueIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue.class b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue.class new file mode 100644 index 0000000000000000000000000000000000000000..560933721e8e7654bf3b7f1aeb620f1527eba627 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MinMaxPriorityQueue.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimap.class b/src/main/resources/org/python/google/common/collect/Multimap.class new file mode 100644 index 0000000000000000000000000000000000000000..b8c6fd92172fa23e970e761a8e783ed4c899643e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3a21bbaf243c9ee98802d3bd8aa0c93e829c024e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$2.class b/src/main/resources/org/python/google/common/collect/Multimaps$2.class new file mode 100644 index 0000000000000000000000000000000000000000..44c4faea51a67a3a29f64e55fed6f6dff4c87516 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$3.class b/src/main/resources/org/python/google/common/collect/Multimaps$3.class new file mode 100644 index 0000000000000000000000000000000000000000..6e83f592e50e468a2e9fc65cea42b706d1903026 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$4.class b/src/main/resources/org/python/google/common/collect/Multimaps$4.class new file mode 100644 index 0000000000000000000000000000000000000000..9e46d467056c585998cad4a6b631905a70b266b9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$5.class b/src/main/resources/org/python/google/common/collect/Multimaps$5.class new file mode 100644 index 0000000000000000000000000000000000000000..ab828502f98c05f1985c84bde957db3ae29fb064 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$AsMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/Multimaps$AsMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..bea2537787822cb3d5dfe17151ca924700724028 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$AsMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$AsMap.class b/src/main/resources/org/python/google/common/collect/Multimaps$AsMap.class new file mode 100644 index 0000000000000000000000000000000000000000..a723baf36dfbe64be063db29ee1abb3a550e140a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$AsMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$CustomListMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$CustomListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..54e2ba5ae5cc8ebff3d243a40416d387cc25e8db Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$CustomListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$CustomMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$CustomMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..d9681f258ed17fd2816535d17b5d2b0133bc292b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$CustomMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$CustomSetMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$CustomSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..92380a67b7b9f8106e82680d0bbb67137eb103b4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$CustomSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$CustomSortedSetMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$CustomSortedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..b0764477e66038a71c9dfffbfd3b80345c97b909 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$CustomSortedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$Entries.class b/src/main/resources/org/python/google/common/collect/Multimaps$Entries.class new file mode 100644 index 0000000000000000000000000000000000000000..48e374d3cb3d5064607371e4678d2c7b2158f135 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$Entries.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$EntrySet.class b/src/main/resources/org/python/google/common/collect/Multimaps$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..1c4b6f533afa352c75b28d10a373e3c1e8796569 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4187d9930112c46de8ca7de44e382ff9242f57a2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$2.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..3b6ef9757fdbdf394e0371d074dcf20bbc56d81c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..aa3bb680d788cc5bb6b9347c6f581e5e2942813f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..f08bc8541c6f6c05ab627c1688195ab604f000f2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$KeySet$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$KeySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..926f3b6b98e1cc20350960bfdfae5326d8bc00e7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$KeySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$KeySet.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..52af95a0a9903237b493d202abf9269421483903 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6933f28a705f9dc6bdac40a0a954addb33ef2539 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values$2.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values$2.class new file mode 100644 index 0000000000000000000000000000000000000000..4b402b7dfad39513689c259a2ee601f180869f30 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..366ab1bca26bdbd19858441f16d09cd09c918dd8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap.class new file mode 100644 index 0000000000000000000000000000000000000000..1bd919add85e83251cbd672e4ea7c95b5ba40b2a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$AsMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f61dc9f58098a993193b7e59543b22ede78e3894 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys$EntrySet.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..bbc76023086d1d62212b12f6c1d6a37a08989cf0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys.class new file mode 100644 index 0000000000000000000000000000000000000000..2c3dec67d88c651d2056113ccea4ffff4bfdc61d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Keys.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$ValuePredicate.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$ValuePredicate.class new file mode 100644 index 0000000000000000000000000000000000000000..1545bdecf08616fedabea86014c736f5bd39a770 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$ValuePredicate.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Values.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..4a6140e1c9941749189c280a53c66f2a069fdd7e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..05ec518dc60ae9ea9ef50d880c39feb1b7f49f9a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$FilteredMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$Keys$1$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$Keys$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a44d9b860300f970bb87f3905e1ac34baf7dc0c0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$Keys$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$Keys$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$Keys$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e653ddb8f0db20e4bb02deabc625f51c8638dc17 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$Keys$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$Keys$KeysEntrySet.class b/src/main/resources/org/python/google/common/collect/Multimaps$Keys$KeysEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..4dbe5720137a84da1c2a6dbffe30feef2f913ef3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$Keys$KeysEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$Keys.class b/src/main/resources/org/python/google/common/collect/Multimaps$Keys.class new file mode 100644 index 0000000000000000000000000000000000000000..80a97f051457e47e3bf732b9f9ed2694ff13d16a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$Keys.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$1$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..51e533a99407c9885228455f51066ffe7935ed01 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3c8bda3d2d8cff211adebc0c8588c409cfa9450c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMap.class b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMap.class new file mode 100644 index 0000000000000000000000000000000000000000..39e827f55f5d4e9a84fbe1553b167ca07cd8c704 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries$1$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..568bbbb8b27d185eaabe3a47d7ba7a538f762cdc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries$1.class new file mode 100644 index 0000000000000000000000000000000000000000..79e1c562108fe1d86675dedb5bc075a9b743dbd2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries.class b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..79a2a0edbc92d8f72159c5e7ce2963305b9b2923 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap$AsMapEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..77a67083d03cdb2e58fc5b3ac65e366a5271cdba Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$MapMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesListMultimap$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesListMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..24c048a1bd4d21d7f78862239d251f696afebe06 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesListMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesListMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..5020662a4deafd4c18e167d1267d961be7cd5257 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0cb1e80d52594868aa3d7bc7355d0e3059d692bf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$2.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5746c0e85e4bd2dfe7c30eaa6378d64aeb07e776 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$3.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$3.class new file mode 100644 index 0000000000000000000000000000000000000000..26a73676954afc7f3566e8e14d377ec174dbdb4a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries$1$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..73b0eca41004040286a6247395fb73688adbb2e2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b6604522e7c5f2e2d187449b836c84dc333528b6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..f402ccf8fd8ce9ce0ead10e00adb12d9304b438c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap$TransformedEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..953e227b33879970a061aaf5ee6076d2cff82c19 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$TransformedEntriesMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapEntries$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapEntries$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ba6d62b7dc1515c67fedc2827e1a7952e7ff9b69 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapEntries$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapEntries.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..6511f746a9b3acfcfdc6138fd818343a40b936c7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapValues$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapValues$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e33b1a1c0dff65dd415e4a65ab7b4cde809d9145 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapValues$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapValues.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapValues.class new file mode 100644 index 0000000000000000000000000000000000000000..651e1e37b5b540bc2b65a45b067d0fd3a4d47de3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableAsMapValues.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableListMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..9328b7f5a421ff3ff25faa9f51fa6b03d0353cfe Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableMultimap$1.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableMultimap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cd60bda161695fb10e84eece49db379e413846d2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableMultimap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..0188e1a198795c8e1b49b18cc56d1813202611d7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableSetMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..3e8da8fbaa720136e201e379ba2ef15cd906b5db Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableSortedSetMultimap.class b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableSortedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..3a5276f4ee5a9b14d280da37e866f37a0dae63d0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$UnmodifiableSortedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps$Values.class b/src/main/resources/org/python/google/common/collect/Multimaps$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..8fdad4a4dd34c627c1c7dec683d16f1c7860fadd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multimaps.class b/src/main/resources/org/python/google/common/collect/Multimaps.class new file mode 100644 index 0000000000000000000000000000000000000000..63be2fad9cd905b1179012cb2186ac55f47e7013 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multimaps.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multiset$Entry.class b/src/main/resources/org/python/google/common/collect/Multiset$Entry.class new file mode 100644 index 0000000000000000000000000000000000000000..6599492089236e53c32446a930ba4016dfef7683 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multiset$Entry.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multiset.class b/src/main/resources/org/python/google/common/collect/Multiset.class new file mode 100644 index 0000000000000000000000000000000000000000..9a0437ac9f798b815b63709154078f6c450ec8bd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$1$1.class b/src/main/resources/org/python/google/common/collect/Multisets$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..773ccd9d3ad94f19d4989cc2fe52d4551eb80f1e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$1.class b/src/main/resources/org/python/google/common/collect/Multisets$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b3e70cc0fa4d3f5bf54adc46606263c203c58da1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$2.class b/src/main/resources/org/python/google/common/collect/Multisets$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c68ca3d29b26503dc521f95d3493addf7265581f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$AbstractEntry.class b/src/main/resources/org/python/google/common/collect/Multisets$AbstractEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..87ea7c40c1d0998692698342f2088f731639dd95 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$AbstractEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$ElementSet$1.class b/src/main/resources/org/python/google/common/collect/Multisets$ElementSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a96a3dc062e5795ccca6234d80014b860727274f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$ElementSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$ElementSet.class b/src/main/resources/org/python/google/common/collect/Multisets$ElementSet.class new file mode 100644 index 0000000000000000000000000000000000000000..feb187fb55e2683985ecf98b21a7808ec2b1b99a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$ElementSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$EntrySet.class b/src/main/resources/org/python/google/common/collect/Multisets$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..97f5d2863f6242aa24ea92390cc21fde27bae1af Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$ImmutableEntry.class b/src/main/resources/org/python/google/common/collect/Multisets$ImmutableEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..0f85415e4aef6b38caf80d58d97ed124abf022dc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$ImmutableEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$MultisetIteratorImpl.class b/src/main/resources/org/python/google/common/collect/Multisets$MultisetIteratorImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..58ededdd4ddfd5c271632fe0a402b3288edff8eb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$MultisetIteratorImpl.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$1$1.class b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f3a25c56188e978a17c0311088c6dfd399b75fc8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$1.class b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..294b7bd67e8a2447d3b3b8c35ad4bf5c2a85e69b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$ElementSet.class b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$ElementSet.class new file mode 100644 index 0000000000000000000000000000000000000000..b5e9742c95cf3b3c391fbdba50e26af6da615792 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset$ElementSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset.class b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..97834d6d4c92a0a719ca1191a356b26d82cff67f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$SetMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$UnmodifiableMultiset.class b/src/main/resources/org/python/google/common/collect/Multisets$UnmodifiableMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..2310196f941363a1c655fe5a83bd471b0a922645 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$UnmodifiableMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets$UnmodifiableSortedMultiset.class b/src/main/resources/org/python/google/common/collect/Multisets$UnmodifiableSortedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..9e198b06f7507c82bb1489235ff4d854fe9d5eca Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets$UnmodifiableSortedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Multisets.class b/src/main/resources/org/python/google/common/collect/Multisets.class new file mode 100644 index 0000000000000000000000000000000000000000..8bb7c291c19569af217d6b7f0598637a2fda8ec3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Multisets.class differ diff --git a/src/main/resources/org/python/google/common/collect/MutableClassToInstanceMap$1.class b/src/main/resources/org/python/google/common/collect/MutableClassToInstanceMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6e23d60fc6dab28c75ec7dde2fd32c86fe872790 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MutableClassToInstanceMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/MutableClassToInstanceMap.class b/src/main/resources/org/python/google/common/collect/MutableClassToInstanceMap.class new file mode 100644 index 0000000000000000000000000000000000000000..583f1003d90f63b36e5c47dfa0ce49f88b4f70e5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/MutableClassToInstanceMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/NaturalOrdering.class b/src/main/resources/org/python/google/common/collect/NaturalOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..cb23b811eabaf73078d14d9072387276b260678c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/NaturalOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/NullsFirstOrdering.class b/src/main/resources/org/python/google/common/collect/NullsFirstOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..a594df2525f4e4558ed077ab6bedb01c13bf548d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/NullsFirstOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/NullsLastOrdering.class b/src/main/resources/org/python/google/common/collect/NullsLastOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..c930ff9e8a82e52bbbca6ddac70a023c5ad17952 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/NullsLastOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/ObjectArrays.class b/src/main/resources/org/python/google/common/collect/ObjectArrays.class new file mode 100644 index 0000000000000000000000000000000000000000..0a0da04e0c693194c2af115bf056b7724dd77419 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ObjectArrays.class differ diff --git a/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrdering$1.class b/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrdering$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a8ef2469077e5729238d9b8ca38fb03db48e4cca Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrdering$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrdering.class b/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..2a7eb4095afec3ce332b2e46d5b7da85c87b2df5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrderingHolder.class b/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrderingHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..e772d780c85b4402c4713c25d7c071283cbab779 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Ordering$ArbitraryOrderingHolder.class differ diff --git a/src/main/resources/org/python/google/common/collect/Ordering$IncomparableValueException.class b/src/main/resources/org/python/google/common/collect/Ordering$IncomparableValueException.class new file mode 100644 index 0000000000000000000000000000000000000000..6dafc8745fca26215a32847d337a846f9e219bec Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Ordering$IncomparableValueException.class differ diff --git a/src/main/resources/org/python/google/common/collect/Ordering.class b/src/main/resources/org/python/google/common/collect/Ordering.class new file mode 100644 index 0000000000000000000000000000000000000000..47c9ea5118060c2cacf3f28cb4bc023e8a2a802a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Ordering.class differ diff --git a/src/main/resources/org/python/google/common/collect/PeekingIterator.class b/src/main/resources/org/python/google/common/collect/PeekingIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..cfa7f2bc3d7bdc82f2ad0e342f24242f793d425e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/PeekingIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/Platform.class b/src/main/resources/org/python/google/common/collect/Platform.class new file mode 100644 index 0000000000000000000000000000000000000000..96df37a396751296df622d8cf368d317b8f55467 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Platform.class differ diff --git a/src/main/resources/org/python/google/common/collect/Queues.class b/src/main/resources/org/python/google/common/collect/Queues.class new file mode 100644 index 0000000000000000000000000000000000000000..7bd4dcbc6ea3366149f8e16d590411493473e9ee Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Queues.class differ diff --git a/src/main/resources/org/python/google/common/collect/Range.class b/src/main/resources/org/python/google/common/collect/Range.class new file mode 100644 index 0000000000000000000000000000000000000000..0cc5337f87706610d1d4a93dcbf3f011dfc68bf0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Range.class differ diff --git a/src/main/resources/org/python/google/common/collect/RangeMap$RangeValue.class b/src/main/resources/org/python/google/common/collect/RangeMap$RangeValue.class new file mode 100644 index 0000000000000000000000000000000000000000..db4b88c01e80a7d76c537d7def5ee64c64bbf3f1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RangeMap$RangeValue.class differ diff --git a/src/main/resources/org/python/google/common/collect/RangeMap.class b/src/main/resources/org/python/google/common/collect/RangeMap.class new file mode 100644 index 0000000000000000000000000000000000000000..7be1fe858eceea24eb6c06172e0353cdd46c2cfa Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RangeMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement$1$1.class b/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f4731c4f4cd9ec1e6ab0b8494672589f80536b82 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement$1.class b/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement$1.class new file mode 100644 index 0000000000000000000000000000000000000000..37fa71aae4a14a65fb69a264c3e2827e153ade7d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement.class b/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement.class new file mode 100644 index 0000000000000000000000000000000000000000..001383c16df90eb7d5de3ff9379bdeb541cec8c6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RangeSet$StandardComplement.class differ diff --git a/src/main/resources/org/python/google/common/collect/RangeSet.class b/src/main/resources/org/python/google/common/collect/RangeSet.class new file mode 100644 index 0000000000000000000000000000000000000000..0eac740ec7a389a09663ff0e67a5d15d0e1658cd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RangeSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Ranges$1.class b/src/main/resources/org/python/google/common/collect/Ranges$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9b45ae213fd4fd3f2ade8934de7a46967135aa7a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Ranges$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Ranges.class b/src/main/resources/org/python/google/common/collect/Ranges.class new file mode 100644 index 0000000000000000000000000000000000000000..723116dc370759d8810e8e64d454b4b0f50075da Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Ranges.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularContiguousSet$1.class b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b8bf710dae8638b13e996b853062a2a2c0bed4d7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularContiguousSet$DescendingContiguousSet$1.class b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$DescendingContiguousSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ea142736d02703c4c38fd6e070e0c0b5cf50ce68 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$DescendingContiguousSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularContiguousSet$DescendingContiguousSet.class b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$DescendingContiguousSet.class new file mode 100644 index 0000000000000000000000000000000000000000..24d54ae393c60e672273a5c30b724120693512b1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$DescendingContiguousSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularContiguousSet$SerializedForm.class b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$SerializedForm.class new file mode 100644 index 0000000000000000000000000000000000000000..31eb577962359b4d72ea75633705247014a3fa78 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularContiguousSet$SerializedForm.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularContiguousSet.class b/src/main/resources/org/python/google/common/collect/RegularContiguousSet.class new file mode 100644 index 0000000000000000000000000000000000000000..46c380f3b2b8cff01f0b1741d10ca83b757fbd48 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularContiguousSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableAsList.class b/src/main/resources/org/python/google/common/collect/RegularImmutableAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..048cd63faeacf9756ca6f3670c193fa9a5557189 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableAsList.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableBiMap.class b/src/main/resources/org/python/google/common/collect/RegularImmutableBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..37ae85dded75e66f6c35ba61ec520680c037a5cd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableList.class b/src/main/resources/org/python/google/common/collect/RegularImmutableList.class new file mode 100644 index 0000000000000000000000000000000000000000..49fce3d8d0332aa4c00ba481dc2b8b842423e81b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableList.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMap$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..80d973ccd75e8b79069bb85786cca27d0875e0f2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..c43cc57e01f83874b7c4535f983e8efbfb3d1812 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMap$LinkedEntry.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$LinkedEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..b4d9de03919d1af99b4bf3572b31640778e7ee13 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$LinkedEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMap$NonTerminalEntry.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$NonTerminalEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..de310afa986549012f15c3ffee335b51bf54a6a5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$NonTerminalEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMap$TerminalEntry.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$TerminalEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..90c31e2936ee1af026c6b75cb434df656e98cf2e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMap$TerminalEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMap.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..79ed4a13416fee9af1d03059e104095651eaaed9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..edf5ec05b8d5b369dbb3573d15e046a0016eec34 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a54c9745b778fac0c69e853a03a7ccab75356612 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$EntrySet.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..5434fc3a4f4de1f89367ec07cb7958b431b955c0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset.class b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..02273df2170c5d63dfc5f649fcaf356b457ee1f1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSet.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..47c19c897456e221a3b7c090c052092335e60afc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..dd8c4803b1117434bc2ee01bb67da30d9981d1f8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3f2f790afe8eb544bcfa321c48b646c871c8b56d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..22885c08c338b5bda5989fbbe688715c19b787ba Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..da401100a3057e6a4c09e382b45b855d8a58ea5e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e05d2b9fd07fc198516d31d489e68d08d754b8f0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6a5aca13723c96264a6ea8bc92d5f5cfef23f409 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$EntrySet.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..93ea9d1560b779ac602eeb31404b7f07e6884232 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..2ecbd9a45f6eabc51ba65a060ce653b4871665d7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableSortedSet.class b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..407821718d937e8d9c8ff4610a1dbb9ab327bd92 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f6d8fce2e84e3494fcdc137fa2f5f2afd34ac6e5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$2.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$2.class new file mode 100644 index 0000000000000000000000000000000000000000..c6ba0192253c98cc212b767506dceb44aa9a8850 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$Column.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$Column.class new file mode 100644 index 0000000000000000000000000000000000000000..2657357a110a443cb83bb323f32aefe5ff35a551 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$Column.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$ColumnMap.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$ColumnMap.class new file mode 100644 index 0000000000000000000000000000000000000000..e1cd92ba93d005ff8a570762f9465ff75bccdf6f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$ColumnMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$Row.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$Row.class new file mode 100644 index 0000000000000000000000000000000000000000..068c0b2d62508304a3766f70df8cd1642755fd33 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$Row.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$RowMap.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$RowMap.class new file mode 100644 index 0000000000000000000000000000000000000000..149bca5176a5776a3bdf7331608a42b336d23ade Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable$RowMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable.class new file mode 100644 index 0000000000000000000000000000000000000000..2499870cddfa47142cea785b4919377b376e5570 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$DenseImmutableTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$1$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e06bf208f61d80486b95dcc809cbc017166a43e4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..60b9f3549223f9947d1a4b1dee3c1ba321918a83 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$2$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$2$1.class new file mode 100644 index 0000000000000000000000000000000000000000..682ff36ece531e357aaa583d8636a969c8285d7f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$2$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$2.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5270904618ce92c388a234ab51ce5252713caef2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap.class new file mode 100644 index 0000000000000000000000000000000000000000..957e9f6bc1799d659fb81fd644abff48b9f4992f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$ImmutableArrayMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$SparseImmutableTable$1.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$SparseImmutableTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..4cc348d5d1973d4a12102b75ed3f4811c050ef1b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$SparseImmutableTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable$SparseImmutableTable.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$SparseImmutableTable.class new file mode 100644 index 0000000000000000000000000000000000000000..f0c459bc332870dcd37a8158617feb15933e6ab4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable$SparseImmutableTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/RegularImmutableTable.class b/src/main/resources/org/python/google/common/collect/RegularImmutableTable.class new file mode 100644 index 0000000000000000000000000000000000000000..32ae9f80cef1a53cd1aed9f979b299a64f5149fc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RegularImmutableTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/ReverseNaturalOrdering.class b/src/main/resources/org/python/google/common/collect/ReverseNaturalOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..518353e7f98561d39564dfc52eceeda2a5e79fac Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ReverseNaturalOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/ReverseOrdering.class b/src/main/resources/org/python/google/common/collect/ReverseOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..2e0c5057168ebc9ab82d2ee954737db6caf96952 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/ReverseOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/RowSortedTable.class b/src/main/resources/org/python/google/common/collect/RowSortedTable.class new file mode 100644 index 0000000000000000000000000000000000000000..b19f69c78408dd28b588bc28f30b7ff2d61dbc16 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/RowSortedTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/Serialization$1.class b/src/main/resources/org/python/google/common/collect/Serialization$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c7a1bf14588835fa1857fc0d13470a35715c844a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Serialization$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Serialization$FieldSetter.class b/src/main/resources/org/python/google/common/collect/Serialization$FieldSetter.class new file mode 100644 index 0000000000000000000000000000000000000000..7b33864aa7d86ad9c0fb369f2ff472df2dea5f84 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Serialization$FieldSetter.class differ diff --git a/src/main/resources/org/python/google/common/collect/Serialization.class b/src/main/resources/org/python/google/common/collect/Serialization.class new file mode 100644 index 0000000000000000000000000000000000000000..d74b2d66a191655e9f48c2b546bcbfb9ea5a22f3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Serialization.class differ diff --git a/src/main/resources/org/python/google/common/collect/SetMultimap.class b/src/main/resources/org/python/google/common/collect/SetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..d66d3c99c22bbdf004a44877f2cf8727b7cad817 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$1.class b/src/main/resources/org/python/google/common/collect/Sets$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0d5d9e44417a677f428a0c99c825a67ca5422f8f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$2.class b/src/main/resources/org/python/google/common/collect/Sets$2.class new file mode 100644 index 0000000000000000000000000000000000000000..33ad30239bb72415dfbd52eb89ec62f18bbe408b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$3.class b/src/main/resources/org/python/google/common/collect/Sets$3.class new file mode 100644 index 0000000000000000000000000000000000000000..7b4179a300d1f0172ed08a0d50f9398478e6b00a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$CartesianSet$1.class b/src/main/resources/org/python/google/common/collect/Sets$CartesianSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..bc544502a02cb7c8d6d2c4e2a3288394f88b1780 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$CartesianSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$CartesianSet$Axis.class b/src/main/resources/org/python/google/common/collect/Sets$CartesianSet$Axis.class new file mode 100644 index 0000000000000000000000000000000000000000..dc76806a7fe23ecfe1367494280f17b1565aa0bf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$CartesianSet$Axis.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$CartesianSet.class b/src/main/resources/org/python/google/common/collect/Sets$CartesianSet.class new file mode 100644 index 0000000000000000000000000000000000000000..eda1a39960bd7226774c22d0acf916f301da9eeb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$CartesianSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$DescendingSet.class b/src/main/resources/org/python/google/common/collect/Sets$DescendingSet.class new file mode 100644 index 0000000000000000000000000000000000000000..ff67555da95cb15fd2bea8df12028b8645dcafaf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$DescendingSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$FilteredSet.class b/src/main/resources/org/python/google/common/collect/Sets$FilteredSet.class new file mode 100644 index 0000000000000000000000000000000000000000..2ff473d3df5f504bfa898442ae20e606ef34b600 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$FilteredSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$FilteredSortedSet.class b/src/main/resources/org/python/google/common/collect/Sets$FilteredSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..817cf6497b2e2732ef1d96c5fb72358e4700a56c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$FilteredSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$ImprovedAbstractSet.class b/src/main/resources/org/python/google/common/collect/Sets$ImprovedAbstractSet.class new file mode 100644 index 0000000000000000000000000000000000000000..d3eed402845f133da37ed8884fb918f7a66421dd Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$ImprovedAbstractSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$PowerSet$1$1.class b/src/main/resources/org/python/google/common/collect/Sets$PowerSet$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..33c87fa63a8ab2826173f2fb704fbe6081880802 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$PowerSet$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$PowerSet$1.class b/src/main/resources/org/python/google/common/collect/Sets$PowerSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5a7d75801c6bc8ae9503e4d2531b7d1048de0ee4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$PowerSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$PowerSet$BitFilteredSetIterator.class b/src/main/resources/org/python/google/common/collect/Sets$PowerSet$BitFilteredSetIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..b4a63715633be8d37e018d38081e2ae4352f5278 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$PowerSet$BitFilteredSetIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$PowerSet.class b/src/main/resources/org/python/google/common/collect/Sets$PowerSet.class new file mode 100644 index 0000000000000000000000000000000000000000..ccf1f514c3e0946537617b791ecc59c2b120a793 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$PowerSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$SetFromMap.class b/src/main/resources/org/python/google/common/collect/Sets$SetFromMap.class new file mode 100644 index 0000000000000000000000000000000000000000..e5e25e8533d776a32ddc8939fe268f7dcf5f48a0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$SetFromMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$SetView.class b/src/main/resources/org/python/google/common/collect/Sets$SetView.class new file mode 100644 index 0000000000000000000000000000000000000000..49b6f0d45352094c7df8fcdf9cefcbb77538f5e3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$SetView.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets$UnmodifiableNavigableSet.class b/src/main/resources/org/python/google/common/collect/Sets$UnmodifiableNavigableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..3f907efc3f92cea9ff4bc1e517aabbd7e603f356 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets$UnmodifiableNavigableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Sets.class b/src/main/resources/org/python/google/common/collect/Sets.class new file mode 100644 index 0000000000000000000000000000000000000000..7feb12030b00d54a6ff5eba023c15e7771592290 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Sets.class differ diff --git a/src/main/resources/org/python/google/common/collect/SingletonImmutableList.class b/src/main/resources/org/python/google/common/collect/SingletonImmutableList.class new file mode 100644 index 0000000000000000000000000000000000000000..8841960b348fb27b719da8a0c697d5a2aec3492e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SingletonImmutableList.class differ diff --git a/src/main/resources/org/python/google/common/collect/SingletonImmutableMap.class b/src/main/resources/org/python/google/common/collect/SingletonImmutableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..eec2da7c176f4f625e89b570ab0d7330794d5273 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SingletonImmutableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/SingletonImmutableSet.class b/src/main/resources/org/python/google/common/collect/SingletonImmutableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..eab07a6ab9f0993204867079eb518981e3b4abde Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SingletonImmutableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/SingletonImmutableTable.class b/src/main/resources/org/python/google/common/collect/SingletonImmutableTable.class new file mode 100644 index 0000000000000000000000000000000000000000..1942352d1d4e7137643c1b7cb514acb093c0f69f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SingletonImmutableTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedIterable.class b/src/main/resources/org/python/google/common/collect/SortedIterable.class new file mode 100644 index 0000000000000000000000000000000000000000..e930d038eb56acb13f6b8b18e67aaeea593f0f2d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedIterable.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedIterables.class b/src/main/resources/org/python/google/common/collect/SortedIterables.class new file mode 100644 index 0000000000000000000000000000000000000000..8bff407f9ad78236358a03ae2b5d09bb76db0d37 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedIterables.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$1.class b/src/main/resources/org/python/google/common/collect/SortedLists$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0ca87ed162e65a05c96559ba532608ff233ce37d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$1.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$1.class new file mode 100644 index 0000000000000000000000000000000000000000..92bfd947da9429c6fd3cd53c16a906ffb587b1b3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$2.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$2.class new file mode 100644 index 0000000000000000000000000000000000000000..898987ce68ee5a8414406f568e2b501432218080 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$3.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$3.class new file mode 100644 index 0000000000000000000000000000000000000000..a4235dbb04a4554c365b898b23123d213f39fa01 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior.class new file mode 100644 index 0000000000000000000000000000000000000000..9097292965e6ba1bffd527412750c9955c2f2f09 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyAbsentBehavior.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$1.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e921e6f22a309532e43b96142c189cc3fa6de933 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$2.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$2.class new file mode 100644 index 0000000000000000000000000000000000000000..11853a458cbf9b8891a69c3e9f217bab7b7a0e9c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$3.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$3.class new file mode 100644 index 0000000000000000000000000000000000000000..d643e77d383da0cabb0dbad2ec4675e8b1d26c0d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$4.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$4.class new file mode 100644 index 0000000000000000000000000000000000000000..141eb30e5220020a4474d8b11114eb62a02e93ea Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$5.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$5.class new file mode 100644 index 0000000000000000000000000000000000000000..e657106156e046f1eb68604a9b4249eebff79c4b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior$5.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior.class b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior.class new file mode 100644 index 0000000000000000000000000000000000000000..5e1614620a6c0b84cebae3bf3df8f18c45de9339 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists$KeyPresentBehavior.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedLists.class b/src/main/resources/org/python/google/common/collect/SortedLists.class new file mode 100644 index 0000000000000000000000000000000000000000..4694f4380f1d8f569da60cbf1d3823a0b9b927c1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedLists.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedMapDifference.class b/src/main/resources/org/python/google/common/collect/SortedMapDifference.class new file mode 100644 index 0000000000000000000000000000000000000000..7f0cac1e2c7d073ad5ad45125cb1631f3f159268 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedMapDifference.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedMultiset.class b/src/main/resources/org/python/google/common/collect/SortedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..9ef038f895264c718aee921cdc9c34872cc7edf8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset$1.class b/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..165e5095707b5ad50f26e2338ff2bfc324e142e0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset$2.class b/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset$2.class new file mode 100644 index 0000000000000000000000000000000000000000..f4010df07970366d6eec6a9b362319f7044f94e8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset.class b/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..f2b6f9386f356d5aa7f72ff315d3b8d1820f2265 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedMultisets$DescendingMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedMultisets$ElementSet.class b/src/main/resources/org/python/google/common/collect/SortedMultisets$ElementSet.class new file mode 100644 index 0000000000000000000000000000000000000000..70173a674f0116757725ae455e6cfc09332238b0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedMultisets$ElementSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedMultisets.class b/src/main/resources/org/python/google/common/collect/SortedMultisets.class new file mode 100644 index 0000000000000000000000000000000000000000..d578e6128af20f24f716f3a16fc710dc04546b9e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedMultisets.class differ diff --git a/src/main/resources/org/python/google/common/collect/SortedSetMultimap.class b/src/main/resources/org/python/google/common/collect/SortedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..daf26415446dc10d81808930f5a524ba20703492 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/SortedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$1.class b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2812c15ff07611e9306b97bca5bdc24e320c6b65 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$RowKeySortedSet.class b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$RowKeySortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..89527df1f71d33a2e3204e08d55c8d26cae38e9c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$RowKeySortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$RowSortedMap.class b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$RowSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..6648b353019874ffb8c8793540b25cc89d35cd22 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable$RowSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardRowSortedTable.class b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable.class new file mode 100644 index 0000000000000000000000000000000000000000..e8c2cbdc94f4fc47f04392c430c2a014717942cf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardRowSortedTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2fff7fea4c6e8a4f7e8dc1979c8cb09fc0f803e3 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$CellIterator.class b/src/main/resources/org/python/google/common/collect/StandardTable$CellIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..15d3f328d56bcdd619636e46082c6a994ce60ad2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$CellIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$CellSet.class b/src/main/resources/org/python/google/common/collect/StandardTable$CellSet.class new file mode 100644 index 0000000000000000000000000000000000000000..2a2f81e14fe56f660e7e46d89bf2e66ae29fb228 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$CellSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySet.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..92942972a61ea2e55e38ee8c82356d138dbc03f9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySetIterator$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySetIterator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fd47bcd71cdaf7f161bba2e9a8891fc1f5eeca4b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySetIterator$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySetIterator.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySetIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..7ee33d64bbfd3d08e06c2c570dcdefd63fd02b66 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$EntrySetIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$KeySet$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$KeySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d0195ec1be8e32b9961d16650d1493a369188036 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$KeySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$KeySet.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$KeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..78c1903105b7b97944f61d0ab5266fc9b18722b9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$KeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3f1d59ca57ea6f8f246093eb625956da6e38c55c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values$2.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values$2.class new file mode 100644 index 0000000000000000000000000000000000000000..14eba697720aa0700defecb921d6bff19837f140 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..dffef33d5c06d4c146b8a998df4d07df9c724b23 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Column.class b/src/main/resources/org/python/google/common/collect/StandardTable$Column.class new file mode 100644 index 0000000000000000000000000000000000000000..590352fc28eeeb2131184bd8b1ea41824f80194d Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Column.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$ColumnKeyIterator.class b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnKeyIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..288c85659c3a5ee1c7a9cfaafaf603c4abbb7782 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnKeyIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$ColumnKeySet.class b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnKeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..4b9c46e79d203fe433d1b8b394ad846b66afb2b4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnKeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapEntrySet$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapEntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..87ab8bc98c55563a1538988edabe6104ce66297c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapEntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapEntrySet.class b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..e5e9ce35bb58acc0a1c42873fc5beda1123d0626 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapValues.class b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapValues.class new file mode 100644 index 0000000000000000000000000000000000000000..883dcd8f84589f70e4d6ca6639aa187fe896e539 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap$ColumnMapValues.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap.class b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap.class new file mode 100644 index 0000000000000000000000000000000000000000..8dc9008ec794487ad6ef728a2876742494b46e1f Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$ColumnMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Row$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$Row$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ba5556de2fa4adcf3bcf477decd0292c6c0e437b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Row$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet$1$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c4d5903ac062d4243effc66d510cbfbe4dff12dc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5ea66b4d8b0095971e391f69baf3827579e259e8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet.class b/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..e3dcae3a82768eae351eff4cda327392e8a11489 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Row$RowEntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Row.class b/src/main/resources/org/python/google/common/collect/StandardTable$Row.class new file mode 100644 index 0000000000000000000000000000000000000000..225b5e28708ea0c04dded8546e6dc7bf9cd63560 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Row.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$RowKeySet.class b/src/main/resources/org/python/google/common/collect/StandardTable$RowKeySet.class new file mode 100644 index 0000000000000000000000000000000000000000..ccacf9abab9eee2287bcdb81222d2d014dc6c3a4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$RowKeySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$RowMap$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$RowMap$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0c37c2cda018a0accbf4cbbe5775292c850eaa4b Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$RowMap$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$RowMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/StandardTable$RowMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..fb0986ab948a6cc6971e42550cb0c41b12a21ea0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$RowMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$RowMap.class b/src/main/resources/org/python/google/common/collect/StandardTable$RowMap.class new file mode 100644 index 0000000000000000000000000000000000000000..1fae315223f55f2c0174b7073a2ef503b884b4df Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$RowMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$TableCollection.class b/src/main/resources/org/python/google/common/collect/StandardTable$TableCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..8e1de2009d1ba6801d202135f1e669d1e8226fb4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$TableCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$TableSet.class b/src/main/resources/org/python/google/common/collect/StandardTable$TableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..f09a8343eea1ba94f7a5b363412af3464be3a8e5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$TableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Values$1.class b/src/main/resources/org/python/google/common/collect/StandardTable$Values$1.class new file mode 100644 index 0000000000000000000000000000000000000000..47a5dfc331333f6932a3e6a13273750423715914 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Values$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable$Values.class b/src/main/resources/org/python/google/common/collect/StandardTable$Values.class new file mode 100644 index 0000000000000000000000000000000000000000..8845a59947dc5fc3fbd65e8b3090f19f0d56de7c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable$Values.class differ diff --git a/src/main/resources/org/python/google/common/collect/StandardTable.class b/src/main/resources/org/python/google/common/collect/StandardTable.class new file mode 100644 index 0000000000000000000000000000000000000000..bbbd0e4436858069290c9b3849886055413ecf3c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/StandardTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$1.class b/src/main/resources/org/python/google/common/collect/Synchronized$1.class new file mode 100644 index 0000000000000000000000000000000000000000..91e0b7c5b6a74dde5740804706e7249c62b29785 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMap.class new file mode 100644 index 0000000000000000000000000000000000000000..5be42037b770e5907a239a7a156624ba0e5a38bb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries$1$1.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6eff1059b90ecaf58abd83b02153a97536c264cb Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries$1.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5de8ff4fabcca439aaa9298719c63bac28e43083 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries.class new file mode 100644 index 0000000000000000000000000000000000000000..bb60caeab26e4f6b718084e7ebc14352c35f4577 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapEntries.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapValues$1.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapValues$1.class new file mode 100644 index 0000000000000000000000000000000000000000..60bc80670c7e3b5d09a443e8db5f73349a235f47 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapValues$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapValues.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapValues.class new file mode 100644 index 0000000000000000000000000000000000000000..3a9cb8c1c4ffa5a0c5ad49546e8d2927bbd5ed6c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedAsMapValues.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedBiMap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedBiMap.class new file mode 100644 index 0000000000000000000000000000000000000000..7e12e60bb18c4120d4d3d723745fa1aac5a85c27 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedBiMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedCollection.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedCollection.class new file mode 100644 index 0000000000000000000000000000000000000000..6e4dce12a7d4d85072058211a8c099cd555ab09a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedCollection.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedEntry.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..f329199716d244a5660e798d9eca38bb018d4df2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedEntry.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedList.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedList.class new file mode 100644 index 0000000000000000000000000000000000000000..c1e98b6e1ef814b909d375542c6447894007f2df Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedListMultimap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedListMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..3c0f8c1e1e19b8c0df9496aea7b7e84bfc9541e8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedListMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..b4379829a3dbf6c4d8109037d9c01cad7fa5e7ab Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMultimap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..aa411df5ca67dc3274aaf0696caa393b42e20c98 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMultiset.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..0ad4ea1e3417c5283e10aff78c4faf7d7f36c5cc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedNavigableMap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedNavigableMap.class new file mode 100644 index 0000000000000000000000000000000000000000..924de3b7e92fa26155ebfbf5f0a03bea490bde04 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedNavigableMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedNavigableSet.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedNavigableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..285b0ac56db35dc8cd83b3a47ea8fcf0cc059a41 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedNavigableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedObject.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedObject.class new file mode 100644 index 0000000000000000000000000000000000000000..72db82b63dc2d386dbfd66da0944122f438f4ef0 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedObject.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedRandomAccessList.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedRandomAccessList.class new file mode 100644 index 0000000000000000000000000000000000000000..5dc6a435a8a113f13e3bdbfe756dac16dc3e85a7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedRandomAccessList.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSet.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..7b43248b68daca01716a9e985638fe1fbebd3fe7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSetMultimap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..9975c97ae56ec4fafe098400f87390bfd6cfe320 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedMap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..61f70db0fdd9ef4b8751bf61b4d01f20a12c8416 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedSet.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedSet.class new file mode 100644 index 0000000000000000000000000000000000000000..063ce58746f19ceab1c41607f69f771a6a5c29c5 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedSetMultimap.class b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedSetMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..bdbc1550c1141b8339f77ed91a0940c25193952e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized$SynchronizedSortedSetMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Synchronized.class b/src/main/resources/org/python/google/common/collect/Synchronized.class new file mode 100644 index 0000000000000000000000000000000000000000..87cf8d0ae44813f1e42a849851bcd0ca97b8f1da Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Synchronized.class differ diff --git a/src/main/resources/org/python/google/common/collect/Table$Cell.class b/src/main/resources/org/python/google/common/collect/Table$Cell.class new file mode 100644 index 0000000000000000000000000000000000000000..27237d6d18dc795ce3e94641320c310495ea98b1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Table$Cell.class differ diff --git a/src/main/resources/org/python/google/common/collect/Table.class b/src/main/resources/org/python/google/common/collect/Table.class new file mode 100644 index 0000000000000000000000000000000000000000..d4faabe2383e1e0dd1a6acbe33591128e2913097 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Table.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$1.class b/src/main/resources/org/python/google/common/collect/Tables$1.class new file mode 100644 index 0000000000000000000000000000000000000000..dc431db0bd88a6114986547ffe5c73ca2dd6661c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$AbstractCell.class b/src/main/resources/org/python/google/common/collect/Tables$AbstractCell.class new file mode 100644 index 0000000000000000000000000000000000000000..556d08bd888f2d7dac1f92fce2ba95de9e7b4ed7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$AbstractCell.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$ImmutableCell.class b/src/main/resources/org/python/google/common/collect/Tables$ImmutableCell.class new file mode 100644 index 0000000000000000000000000000000000000000..33530b6f79802c2037175df13da65ec2c1c55351 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$ImmutableCell.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$1.class b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..35fd1831baecabf08a326a6b5f081d0b6818acff Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$2.class b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$2.class new file mode 100644 index 0000000000000000000000000000000000000000..a6eb683d466aa0358ff37d063503ac1df65f9078 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$3.class b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$3.class new file mode 100644 index 0000000000000000000000000000000000000000..8e0aeaddc774ad68cee28d9db06099ccdfefab52 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$CellSet.class b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$CellSet.class new file mode 100644 index 0000000000000000000000000000000000000000..5ca2e45e9b00eec043add3d7bf905f05304bd707 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable$CellSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransformedTable.class b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable.class new file mode 100644 index 0000000000000000000000000000000000000000..185c06cf00ffa938def93ce90981362218c18c60 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransformedTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransposeTable$1.class b/src/main/resources/org/python/google/common/collect/Tables$TransposeTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ac3491b4f0c8e1d7e2e34240ab19bb86ff81abaf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransposeTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransposeTable$CellSet.class b/src/main/resources/org/python/google/common/collect/Tables$TransposeTable$CellSet.class new file mode 100644 index 0000000000000000000000000000000000000000..8cf05d8cd6db50c23fb648deb419353a7801d9ef Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransposeTable$CellSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$TransposeTable.class b/src/main/resources/org/python/google/common/collect/Tables$TransposeTable.class new file mode 100644 index 0000000000000000000000000000000000000000..412201d37357d54a5a247343b64a15242941ce82 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$TransposeTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$UnmodifiableRowSortedMap.class b/src/main/resources/org/python/google/common/collect/Tables$UnmodifiableRowSortedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..3605df696b9189445e5462ac818f2c9ce68448e1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$UnmodifiableRowSortedMap.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables$UnmodifiableTable.class b/src/main/resources/org/python/google/common/collect/Tables$UnmodifiableTable.class new file mode 100644 index 0000000000000000000000000000000000000000..e7709916caa51614fc5d8edb02c71621a6f725a8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables$UnmodifiableTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/Tables.class b/src/main/resources/org/python/google/common/collect/Tables.class new file mode 100644 index 0000000000000000000000000000000000000000..667b6df6314928bc1f8d1ab9b39027e3b2e6f3a6 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/Tables.class differ diff --git a/src/main/resources/org/python/google/common/collect/TransformedImmutableSet$1.class b/src/main/resources/org/python/google/common/collect/TransformedImmutableSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c42fb79fc75235c5c0141d6028ef62845cec0baf Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TransformedImmutableSet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/TransformedImmutableSet.class b/src/main/resources/org/python/google/common/collect/TransformedImmutableSet.class new file mode 100644 index 0000000000000000000000000000000000000000..c928495827add6d1081ad8c9d9ba47c0075ba833 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TransformedImmutableSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/TransformedIterator.class b/src/main/resources/org/python/google/common/collect/TransformedIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..f19fdc35e35665b5c26adc893377531b6214fbd7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TransformedIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/TransformedListIterator.class b/src/main/resources/org/python/google/common/collect/TransformedListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..346587e7f9b2f3ef64304ff2aeb3b27a54320056 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TransformedListIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeBasedTable$1.class b/src/main/resources/org/python/google/common/collect/TreeBasedTable$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0021e44c2f25c34891e03d74fb0b7036be5118bc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeBasedTable$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeBasedTable$2.class b/src/main/resources/org/python/google/common/collect/TreeBasedTable$2.class new file mode 100644 index 0000000000000000000000000000000000000000..8607c62a761cdd3902516a5276a5925974d618e1 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeBasedTable$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeBasedTable$Factory.class b/src/main/resources/org/python/google/common/collect/TreeBasedTable$Factory.class new file mode 100644 index 0000000000000000000000000000000000000000..c41b5f84ae777863e2b8739a07b687d15a7f1137 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeBasedTable$Factory.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeBasedTable$TreeRow.class b/src/main/resources/org/python/google/common/collect/TreeBasedTable$TreeRow.class new file mode 100644 index 0000000000000000000000000000000000000000..2bced65044585bceb8c851057be4ca150ae75f2e Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeBasedTable$TreeRow.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeBasedTable.class b/src/main/resources/org/python/google/common/collect/TreeBasedTable.class new file mode 100644 index 0000000000000000000000000000000000000000..467cad4b15b956254337fe4db350d8f5772c9a62 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeBasedTable.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultimap.class b/src/main/resources/org/python/google/common/collect/TreeMultimap.class new file mode 100644 index 0000000000000000000000000000000000000000..ba5a30a0a4eb3278ae1f35a59e641dd2044513e7 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultimap.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$1.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3444d9857cabe3628e2a61407a9cfc79a2003055 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$2.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$2.class new file mode 100644 index 0000000000000000000000000000000000000000..23f2dc55378ede7e983f988ae5cde7d849dd5136 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$3.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$3.class new file mode 100644 index 0000000000000000000000000000000000000000..d5ba2b04f69d4990bdb687cf724d4abc45a59682 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$3.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$4.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$4.class new file mode 100644 index 0000000000000000000000000000000000000000..24d25100d6944809b0c59f2b18f8262fb2ee9fbc Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$4.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate$1.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2ee49897bb2c35dd33fb28525e0b91fda5ad6ed9 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate$2.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate$2.class new file mode 100644 index 0000000000000000000000000000000000000000..19aa508a6980b679bfbcfdb0100278ed3e404d39 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate$2.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate.class new file mode 100644 index 0000000000000000000000000000000000000000..c869dfcacbc4682624b64b6df526d62a237eb48c Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$Aggregate.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$AvlNode.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$AvlNode.class new file mode 100644 index 0000000000000000000000000000000000000000..ba69dd6fa44ca0d7d23d1d444a8e3ef81fefef05 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$AvlNode.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset$Reference.class b/src/main/resources/org/python/google/common/collect/TreeMultiset$Reference.class new file mode 100644 index 0000000000000000000000000000000000000000..3d4e0d713e8ef37c7af0ed1decd9efdcc42d0724 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset$Reference.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeMultiset.class b/src/main/resources/org/python/google/common/collect/TreeMultiset.class new file mode 100644 index 0000000000000000000000000000000000000000..7d6329eb9e6646f4e8be5952b10c1f9208eadd66 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeMultiset.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeRangeSet$AsRanges.class b/src/main/resources/org/python/google/common/collect/TreeRangeSet$AsRanges.class new file mode 100644 index 0000000000000000000000000000000000000000..cc6e6b6f066ea101583ec08f4dfb1176007f4f77 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeRangeSet$AsRanges.class differ diff --git a/src/main/resources/org/python/google/common/collect/TreeRangeSet.class b/src/main/resources/org/python/google/common/collect/TreeRangeSet.class new file mode 100644 index 0000000000000000000000000000000000000000..e05e731053f4366d9a7e5a6dd2f94a5a6f496218 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/TreeRangeSet.class differ diff --git a/src/main/resources/org/python/google/common/collect/UnmodifiableIterator.class b/src/main/resources/org/python/google/common/collect/UnmodifiableIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..5f1e747d5a151de1e438463b39a3092db8f7021a Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/UnmodifiableIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/UnmodifiableListIterator.class b/src/main/resources/org/python/google/common/collect/UnmodifiableListIterator.class new file mode 100644 index 0000000000000000000000000000000000000000..29c6509a7720918a4d9a62b8c9bef5d39e3044e8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/UnmodifiableListIterator.class differ diff --git a/src/main/resources/org/python/google/common/collect/UsingToStringOrdering.class b/src/main/resources/org/python/google/common/collect/UsingToStringOrdering.class new file mode 100644 index 0000000000000000000000000000000000000000..9ac0f68c8beba16d32ea5da42779a46c801bc4a4 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/UsingToStringOrdering.class differ diff --git a/src/main/resources/org/python/google/common/collect/WellBehavedMap$1.class b/src/main/resources/org/python/google/common/collect/WellBehavedMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..aef6e8d31665fcbf5cab9ec65b0126211d5f66ee Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/WellBehavedMap$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet$1$1.class b/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8db3bfce236fcba15e35f6d0ec071d9fa894bc95 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet$1$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet$1.class b/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8c871dcff002df4c89b2a8e1abcad0d33ccf96c2 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet$1.class differ diff --git a/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet.class b/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet.class new file mode 100644 index 0000000000000000000000000000000000000000..0d75bdbb6c7850e33d14b9c21ce8e71a4ffd8095 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/WellBehavedMap$EntrySet.class differ diff --git a/src/main/resources/org/python/google/common/collect/WellBehavedMap.class b/src/main/resources/org/python/google/common/collect/WellBehavedMap.class new file mode 100644 index 0000000000000000000000000000000000000000..952daec2dba4ec0a0fb4610eac81a73e1a5f9ee8 Binary files /dev/null and b/src/main/resources/org/python/google/common/collect/WellBehavedMap.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/AllowConcurrentEvents.class b/src/main/resources/org/python/google/common/eventbus/AllowConcurrentEvents.class new file mode 100644 index 0000000000000000000000000000000000000000..5a1800026b62465f7980a95640db2fb6fda59fa3 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/AllowConcurrentEvents.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/AnnotatedHandlerFinder.class b/src/main/resources/org/python/google/common/eventbus/AnnotatedHandlerFinder.class new file mode 100644 index 0000000000000000000000000000000000000000..02d961344b426b3413c9fa8bbe52aa872a518350 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/AnnotatedHandlerFinder.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/AsyncEventBus$1.class b/src/main/resources/org/python/google/common/eventbus/AsyncEventBus$1.class new file mode 100644 index 0000000000000000000000000000000000000000..77354dbe34267136dd0a565d99b3403b4d1779f6 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/AsyncEventBus$1.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/AsyncEventBus.class b/src/main/resources/org/python/google/common/eventbus/AsyncEventBus.class new file mode 100644 index 0000000000000000000000000000000000000000..6402d725b129620b6fb06d0330a30a2969c7adda Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/AsyncEventBus.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/DeadEvent.class b/src/main/resources/org/python/google/common/eventbus/DeadEvent.class new file mode 100644 index 0000000000000000000000000000000000000000..72741cbe381425bce1de66bb8f25c74f900f59ca Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/DeadEvent.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/EventBus$1.class b/src/main/resources/org/python/google/common/eventbus/EventBus$1.class new file mode 100644 index 0000000000000000000000000000000000000000..1a5b83f606295949e21dc9488648b07686c271a3 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/EventBus$1.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/EventBus$2.class b/src/main/resources/org/python/google/common/eventbus/EventBus$2.class new file mode 100644 index 0000000000000000000000000000000000000000..d55ec48b07b05922b4d2eabec3387999c0fd3a6f Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/EventBus$2.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/EventBus$3.class b/src/main/resources/org/python/google/common/eventbus/EventBus$3.class new file mode 100644 index 0000000000000000000000000000000000000000..93a91c76f3e5151f3dbf26ced997b6d861d3cc18 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/EventBus$3.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/EventBus$4.class b/src/main/resources/org/python/google/common/eventbus/EventBus$4.class new file mode 100644 index 0000000000000000000000000000000000000000..00a90159f24089c29589070d98d33a61e4ab459a Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/EventBus$4.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/EventBus$EventWithHandler.class b/src/main/resources/org/python/google/common/eventbus/EventBus$EventWithHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..f64a7e8ad33396abb0ba865cb727f1a0c61a498d Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/EventBus$EventWithHandler.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/EventBus.class b/src/main/resources/org/python/google/common/eventbus/EventBus.class new file mode 100644 index 0000000000000000000000000000000000000000..0a592f6f16cf8323766ac550f8b0ed6730badb8c Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/EventBus.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/EventHandler.class b/src/main/resources/org/python/google/common/eventbus/EventHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..453360eeb83024274b056de6d810e398d9aeb705 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/EventHandler.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/HandlerFindingStrategy.class b/src/main/resources/org/python/google/common/eventbus/HandlerFindingStrategy.class new file mode 100644 index 0000000000000000000000000000000000000000..729fdae523b87668bf2c341454e20d9bdfcb51cd Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/HandlerFindingStrategy.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/Subscribe.class b/src/main/resources/org/python/google/common/eventbus/Subscribe.class new file mode 100644 index 0000000000000000000000000000000000000000..332429b43e1af733e90b1631e52d8559103676b0 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/Subscribe.class differ diff --git a/src/main/resources/org/python/google/common/eventbus/SynchronizedEventHandler.class b/src/main/resources/org/python/google/common/eventbus/SynchronizedEventHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..cf7e3b5829fd717290e961aaa7fd7f0ab49d51c5 Binary files /dev/null and b/src/main/resources/org/python/google/common/eventbus/SynchronizedEventHandler.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractCompositeHashFunction$1.class b/src/main/resources/org/python/google/common/hash/AbstractCompositeHashFunction$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2b9cb8e52a4b2b6b947bd2828023dc8c59a48536 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractCompositeHashFunction$1.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractCompositeHashFunction.class b/src/main/resources/org/python/google/common/hash/AbstractCompositeHashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..9c863dce1e6341674803ce366402de4810757f35 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractCompositeHashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractHasher.class b/src/main/resources/org/python/google/common/hash/AbstractHasher.class new file mode 100644 index 0000000000000000000000000000000000000000..ef5c4c24d3b25a0f5aaadb4a70ca08f8b66b63e8 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractHasher.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction$BufferingHasher.class b/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction$BufferingHasher.class new file mode 100644 index 0000000000000000000000000000000000000000..0df7cf9a0a9eb4b97d2a6e543b07939501ea9d07 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction$BufferingHasher.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction$ExposedByteArrayOutputStream.class b/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction$ExposedByteArrayOutputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..e0e6849dfbdd29ed3875131fb0f60729ed3c7f3c Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction$ExposedByteArrayOutputStream.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction.class b/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..8fb28a020092d20f55daecc12096a126d2ddbff2 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractNonStreamingHashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractStreamingHashFunction$AbstractStreamingHasher.class b/src/main/resources/org/python/google/common/hash/AbstractStreamingHashFunction$AbstractStreamingHasher.class new file mode 100644 index 0000000000000000000000000000000000000000..0009ed0cb44bb40b6e95032c6e813a339f989585 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractStreamingHashFunction$AbstractStreamingHasher.class differ diff --git a/src/main/resources/org/python/google/common/hash/AbstractStreamingHashFunction.class b/src/main/resources/org/python/google/common/hash/AbstractStreamingHashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..579b8326d7da830c4556db6ec6c011b66a371fbe Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/AbstractStreamingHashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/BloomFilter$1.class b/src/main/resources/org/python/google/common/hash/BloomFilter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3b94c70f9f232f291715f04e866c1680632af361 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/BloomFilter$1.class differ diff --git a/src/main/resources/org/python/google/common/hash/BloomFilter$SerialForm.class b/src/main/resources/org/python/google/common/hash/BloomFilter$SerialForm.class new file mode 100644 index 0000000000000000000000000000000000000000..e2835d84aacb16999d7e5efff3d84cf05e310e9f Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/BloomFilter$SerialForm.class differ diff --git a/src/main/resources/org/python/google/common/hash/BloomFilter$Strategy.class b/src/main/resources/org/python/google/common/hash/BloomFilter$Strategy.class new file mode 100644 index 0000000000000000000000000000000000000000..8e28e940354f0340ca22f8200570487a40c23c0f Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/BloomFilter$Strategy.class differ diff --git a/src/main/resources/org/python/google/common/hash/BloomFilter.class b/src/main/resources/org/python/google/common/hash/BloomFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..99cfc3ba00cd40a22de736c01afb7ad6c8973ce6 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/BloomFilter.class differ diff --git a/src/main/resources/org/python/google/common/hash/BloomFilterStrategies$1.class b/src/main/resources/org/python/google/common/hash/BloomFilterStrategies$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3c96fd214fdbdb204f577c2c060d2e05228ca0d9 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/BloomFilterStrategies$1.class differ diff --git a/src/main/resources/org/python/google/common/hash/BloomFilterStrategies$BitArray.class b/src/main/resources/org/python/google/common/hash/BloomFilterStrategies$BitArray.class new file mode 100644 index 0000000000000000000000000000000000000000..d8ab2fc378d50f1ccff71abc60283f79e4a3977a Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/BloomFilterStrategies$BitArray.class differ diff --git a/src/main/resources/org/python/google/common/hash/BloomFilterStrategies.class b/src/main/resources/org/python/google/common/hash/BloomFilterStrategies.class new file mode 100644 index 0000000000000000000000000000000000000000..7d49d4ce6218f542ebf584c8a4bf859628d93fa2 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/BloomFilterStrategies.class differ diff --git a/src/main/resources/org/python/google/common/hash/Funnel.class b/src/main/resources/org/python/google/common/hash/Funnel.class new file mode 100644 index 0000000000000000000000000000000000000000..3c0bc9aeb888c19a8a6e20792e6374760700aa5a Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Funnel.class differ diff --git a/src/main/resources/org/python/google/common/hash/Funnels$ByteArrayFunnel.class b/src/main/resources/org/python/google/common/hash/Funnels$ByteArrayFunnel.class new file mode 100644 index 0000000000000000000000000000000000000000..d205284d032246964c787386ccc1cb1086297558 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Funnels$ByteArrayFunnel.class differ diff --git a/src/main/resources/org/python/google/common/hash/Funnels$IntegerFunnel.class b/src/main/resources/org/python/google/common/hash/Funnels$IntegerFunnel.class new file mode 100644 index 0000000000000000000000000000000000000000..816b5c9fdabf6a2aa6c399d5f777f968e6905beb Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Funnels$IntegerFunnel.class differ diff --git a/src/main/resources/org/python/google/common/hash/Funnels$LongFunnel.class b/src/main/resources/org/python/google/common/hash/Funnels$LongFunnel.class new file mode 100644 index 0000000000000000000000000000000000000000..4d08cb1533e1e6ebbeebdad0c08354c773551dfb Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Funnels$LongFunnel.class differ diff --git a/src/main/resources/org/python/google/common/hash/Funnels$SinkAsStream.class b/src/main/resources/org/python/google/common/hash/Funnels$SinkAsStream.class new file mode 100644 index 0000000000000000000000000000000000000000..cc760ba992fdfa9d01271e4c2be2936e280c1800 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Funnels$SinkAsStream.class differ diff --git a/src/main/resources/org/python/google/common/hash/Funnels$StringFunnel.class b/src/main/resources/org/python/google/common/hash/Funnels$StringFunnel.class new file mode 100644 index 0000000000000000000000000000000000000000..05f25820fc52714ea05fa58b6ec460eab17a3407 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Funnels$StringFunnel.class differ diff --git a/src/main/resources/org/python/google/common/hash/Funnels.class b/src/main/resources/org/python/google/common/hash/Funnels.class new file mode 100644 index 0000000000000000000000000000000000000000..fe4ddfe5ce912dcc346041016e113baaf9c4e1ea Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Funnels.class differ diff --git a/src/main/resources/org/python/google/common/hash/HashCode.class b/src/main/resources/org/python/google/common/hash/HashCode.class new file mode 100644 index 0000000000000000000000000000000000000000..741225597910650d56ae1389c4268bb27065e033 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/HashCode.class differ diff --git a/src/main/resources/org/python/google/common/hash/HashCodes$BytesHashCode.class b/src/main/resources/org/python/google/common/hash/HashCodes$BytesHashCode.class new file mode 100644 index 0000000000000000000000000000000000000000..b2fa2fc7e519515ac2317cdc3508a53dc9076bcb Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/HashCodes$BytesHashCode.class differ diff --git a/src/main/resources/org/python/google/common/hash/HashCodes$IntHashCode.class b/src/main/resources/org/python/google/common/hash/HashCodes$IntHashCode.class new file mode 100644 index 0000000000000000000000000000000000000000..88c2070b32a7f3806fc8769d3d55f7473771865f Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/HashCodes$IntHashCode.class differ diff --git a/src/main/resources/org/python/google/common/hash/HashCodes$LongHashCode.class b/src/main/resources/org/python/google/common/hash/HashCodes$LongHashCode.class new file mode 100644 index 0000000000000000000000000000000000000000..933edbf4d669cc1adc18eb7cdb5f277f23a2a694 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/HashCodes$LongHashCode.class differ diff --git a/src/main/resources/org/python/google/common/hash/HashCodes.class b/src/main/resources/org/python/google/common/hash/HashCodes.class new file mode 100644 index 0000000000000000000000000000000000000000..3fb6dfb2b4825225f6f07bae32532913cf828cf0 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/HashCodes.class differ diff --git a/src/main/resources/org/python/google/common/hash/HashFunction.class b/src/main/resources/org/python/google/common/hash/HashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..98d18725c9f3dc4f13aad844d3665b0b95376959 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/HashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/Hasher.class b/src/main/resources/org/python/google/common/hash/Hasher.class new file mode 100644 index 0000000000000000000000000000000000000000..47e5f4ce709a7c1d22215bee45cfae91d5de6321 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Hasher.class differ diff --git a/src/main/resources/org/python/google/common/hash/Hashing$ConcatenatedHashFunction.class b/src/main/resources/org/python/google/common/hash/Hashing$ConcatenatedHashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..426f54e9cffa4c1ede3b8016323d14dc86aca5ad Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Hashing$ConcatenatedHashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/Hashing$LinearCongruentialGenerator.class b/src/main/resources/org/python/google/common/hash/Hashing$LinearCongruentialGenerator.class new file mode 100644 index 0000000000000000000000000000000000000000..2d84ead602f41e5b49f4a0cf2326c0b40055b6d6 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Hashing$LinearCongruentialGenerator.class differ diff --git a/src/main/resources/org/python/google/common/hash/Hashing.class b/src/main/resources/org/python/google/common/hash/Hashing.class new file mode 100644 index 0000000000000000000000000000000000000000..3e38a1e35932ab5605144d84c0fe71e5b20bd81c Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Hashing.class differ diff --git a/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction$1.class b/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction$1.class new file mode 100644 index 0000000000000000000000000000000000000000..91345ae25aff699cb97e3b3346c1280547902146 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction$1.class differ diff --git a/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction$MessageDigestHasher.class b/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction$MessageDigestHasher.class new file mode 100644 index 0000000000000000000000000000000000000000..1acde7005c2dfcd68071865a3197a71d4a9a5bba Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction$MessageDigestHasher.class differ diff --git a/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction.class b/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..338a9534fa68a6029b0ad2809d2ca93df180b1ae Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/MessageDigestHashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/Murmur3_128HashFunction$Murmur3_128Hasher.class b/src/main/resources/org/python/google/common/hash/Murmur3_128HashFunction$Murmur3_128Hasher.class new file mode 100644 index 0000000000000000000000000000000000000000..3928492c09ead0e961fc1ba6a87b983dc8889bec Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Murmur3_128HashFunction$Murmur3_128Hasher.class differ diff --git a/src/main/resources/org/python/google/common/hash/Murmur3_128HashFunction.class b/src/main/resources/org/python/google/common/hash/Murmur3_128HashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..e3bc282c5848a8ab67ea87554a7b9d930f631f66 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Murmur3_128HashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/Murmur3_32HashFunction$Murmur3_32Hasher.class b/src/main/resources/org/python/google/common/hash/Murmur3_32HashFunction$Murmur3_32Hasher.class new file mode 100644 index 0000000000000000000000000000000000000000..0904db23df55f79c76fe88ff0a12e538433c0680 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Murmur3_32HashFunction$Murmur3_32Hasher.class differ diff --git a/src/main/resources/org/python/google/common/hash/Murmur3_32HashFunction.class b/src/main/resources/org/python/google/common/hash/Murmur3_32HashFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..704156ec016420daeb525ff6f335752ddbbb41ba Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/Murmur3_32HashFunction.class differ diff --git a/src/main/resources/org/python/google/common/hash/PrimitiveSink.class b/src/main/resources/org/python/google/common/hash/PrimitiveSink.class new file mode 100644 index 0000000000000000000000000000000000000000..a7a391a4b93a89821933a3f79438b82812352111 Binary files /dev/null and b/src/main/resources/org/python/google/common/hash/PrimitiveSink.class differ diff --git a/src/main/resources/org/python/google/common/io/AppendableWriter.class b/src/main/resources/org/python/google/common/io/AppendableWriter.class new file mode 100644 index 0000000000000000000000000000000000000000..5a93f43af1b6d5d811ec59f689bd76349624e51d Binary files /dev/null and b/src/main/resources/org/python/google/common/io/AppendableWriter.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteArrayDataInput.class b/src/main/resources/org/python/google/common/io/ByteArrayDataInput.class new file mode 100644 index 0000000000000000000000000000000000000000..a76c0a7b438d1ed0e51fa080ac33114c8b583387 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteArrayDataInput.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteArrayDataOutput.class b/src/main/resources/org/python/google/common/io/ByteArrayDataOutput.class new file mode 100644 index 0000000000000000000000000000000000000000..dc9c48d74e00e5c3d41b0fdcf036a27112deed35 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteArrayDataOutput.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteProcessor.class b/src/main/resources/org/python/google/common/io/ByteProcessor.class new file mode 100644 index 0000000000000000000000000000000000000000..713043b7a6ce5352d244255566b01d4d48cac0f8 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteProcessor.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteStreams$1.class b/src/main/resources/org/python/google/common/io/ByteStreams$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0798f1eca2b3f2fff9cca7bebe1b9dc6a98d0bcd Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteStreams$1.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteStreams$2.class b/src/main/resources/org/python/google/common/io/ByteStreams$2.class new file mode 100644 index 0000000000000000000000000000000000000000..013fee5e1869a7d1bb669875c221bfac59bab3b0 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteStreams$2.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteStreams$3.class b/src/main/resources/org/python/google/common/io/ByteStreams$3.class new file mode 100644 index 0000000000000000000000000000000000000000..41014b4d5ded6fcd62c5b7a78b264c2aaac20da1 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteStreams$3.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteStreams$4.class b/src/main/resources/org/python/google/common/io/ByteStreams$4.class new file mode 100644 index 0000000000000000000000000000000000000000..9216c77182dcb8200f3390b72fae8c1d4c244b36 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteStreams$4.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteStreams$ByteArrayDataInputStream.class b/src/main/resources/org/python/google/common/io/ByteStreams$ByteArrayDataInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..ecbd61602bfcd9529443291b836b17fb6e972b46 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteStreams$ByteArrayDataInputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteStreams$ByteArrayDataOutputStream.class b/src/main/resources/org/python/google/common/io/ByteStreams$ByteArrayDataOutputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..9ccf3b5f87b01a44d8dac29da44c47a937d8e11a Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteStreams$ByteArrayDataOutputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/ByteStreams.class b/src/main/resources/org/python/google/common/io/ByteStreams.class new file mode 100644 index 0000000000000000000000000000000000000000..3d668227ef2475bfae522a0974435a80c51c295d Binary files /dev/null and b/src/main/resources/org/python/google/common/io/ByteStreams.class differ diff --git a/src/main/resources/org/python/google/common/io/CharStreams$1.class b/src/main/resources/org/python/google/common/io/CharStreams$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5908760bd13e63a35f0ab0892b850262f840cedc Binary files /dev/null and b/src/main/resources/org/python/google/common/io/CharStreams$1.class differ diff --git a/src/main/resources/org/python/google/common/io/CharStreams$2.class b/src/main/resources/org/python/google/common/io/CharStreams$2.class new file mode 100644 index 0000000000000000000000000000000000000000..35325125429040e2e71ed721b9cd7687c3201987 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/CharStreams$2.class differ diff --git a/src/main/resources/org/python/google/common/io/CharStreams$3.class b/src/main/resources/org/python/google/common/io/CharStreams$3.class new file mode 100644 index 0000000000000000000000000000000000000000..693a74f2522303ad0f82ecb3c2d67765cf39ddbd Binary files /dev/null and b/src/main/resources/org/python/google/common/io/CharStreams$3.class differ diff --git a/src/main/resources/org/python/google/common/io/CharStreams$4.class b/src/main/resources/org/python/google/common/io/CharStreams$4.class new file mode 100644 index 0000000000000000000000000000000000000000..9b54264c31b4dbadeef56683aedab7bf30b25b4b Binary files /dev/null and b/src/main/resources/org/python/google/common/io/CharStreams$4.class differ diff --git a/src/main/resources/org/python/google/common/io/CharStreams.class b/src/main/resources/org/python/google/common/io/CharStreams.class new file mode 100644 index 0000000000000000000000000000000000000000..4dc080caca998418c47bba17d19e9de367a4bcb7 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/CharStreams.class differ diff --git a/src/main/resources/org/python/google/common/io/Closeables.class b/src/main/resources/org/python/google/common/io/Closeables.class new file mode 100644 index 0000000000000000000000000000000000000000..5aa8e89364781ea9180f72dc643723a26a2cf381 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/Closeables.class differ diff --git a/src/main/resources/org/python/google/common/io/CountingInputStream.class b/src/main/resources/org/python/google/common/io/CountingInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..9db8d0eda6df3a3027f50a574027e921cd1c3505 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/CountingInputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/CountingOutputStream.class b/src/main/resources/org/python/google/common/io/CountingOutputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..9376c9c97aa0bd4da7dca29dc170198dc0ccac57 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/CountingOutputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/FileBackedOutputStream$1.class b/src/main/resources/org/python/google/common/io/FileBackedOutputStream$1.class new file mode 100644 index 0000000000000000000000000000000000000000..3d5d72b804f5176b25ad3058381a819c17f26636 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/FileBackedOutputStream$1.class differ diff --git a/src/main/resources/org/python/google/common/io/FileBackedOutputStream$2.class b/src/main/resources/org/python/google/common/io/FileBackedOutputStream$2.class new file mode 100644 index 0000000000000000000000000000000000000000..ba5a81c5a200ac91b6691f427fceefae6ea2c9bc Binary files /dev/null and b/src/main/resources/org/python/google/common/io/FileBackedOutputStream$2.class differ diff --git a/src/main/resources/org/python/google/common/io/FileBackedOutputStream$MemoryOutput.class b/src/main/resources/org/python/google/common/io/FileBackedOutputStream$MemoryOutput.class new file mode 100644 index 0000000000000000000000000000000000000000..d493bd490a33dbe3235dc3bbd0321d8d42989099 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/FileBackedOutputStream$MemoryOutput.class differ diff --git a/src/main/resources/org/python/google/common/io/FileBackedOutputStream.class b/src/main/resources/org/python/google/common/io/FileBackedOutputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..c74cd828f3e3a6e655ad75a0898c9a09f6641cd5 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/FileBackedOutputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/Files$1.class b/src/main/resources/org/python/google/common/io/Files$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f898a468b43ae8e03abba7b0f205141d3c44c9c3 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/Files$1.class differ diff --git a/src/main/resources/org/python/google/common/io/Files$2.class b/src/main/resources/org/python/google/common/io/Files$2.class new file mode 100644 index 0000000000000000000000000000000000000000..6a9d2c5b6aefda8a7d0aba603af7e946f8e78136 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/Files$2.class differ diff --git a/src/main/resources/org/python/google/common/io/Files.class b/src/main/resources/org/python/google/common/io/Files.class new file mode 100644 index 0000000000000000000000000000000000000000..b765a30beee2302f2f687eab8e9ab6fc01647518 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/Files.class differ diff --git a/src/main/resources/org/python/google/common/io/Flushables.class b/src/main/resources/org/python/google/common/io/Flushables.class new file mode 100644 index 0000000000000000000000000000000000000000..5e61052283a6201659a2649c26c5bd12513a2a70 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/Flushables.class differ diff --git a/src/main/resources/org/python/google/common/io/InputSupplier.class b/src/main/resources/org/python/google/common/io/InputSupplier.class new file mode 100644 index 0000000000000000000000000000000000000000..fdd113521babe4343653d565f99088a731ee462b Binary files /dev/null and b/src/main/resources/org/python/google/common/io/InputSupplier.class differ diff --git a/src/main/resources/org/python/google/common/io/LimitInputStream.class b/src/main/resources/org/python/google/common/io/LimitInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..7047a248f7b3a0b0300cf1bf7b15348c537818ce Binary files /dev/null and b/src/main/resources/org/python/google/common/io/LimitInputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/LineBuffer.class b/src/main/resources/org/python/google/common/io/LineBuffer.class new file mode 100644 index 0000000000000000000000000000000000000000..13df316854d9a905118c7822d35b294527e21211 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/LineBuffer.class differ diff --git a/src/main/resources/org/python/google/common/io/LineProcessor.class b/src/main/resources/org/python/google/common/io/LineProcessor.class new file mode 100644 index 0000000000000000000000000000000000000000..707a2c1174aa9644e8d786a4ba6a0eb64758ef65 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/LineProcessor.class differ diff --git a/src/main/resources/org/python/google/common/io/LineReader$1.class b/src/main/resources/org/python/google/common/io/LineReader$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0805a85598899f433b6b2f2e714b5119d9271d24 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/LineReader$1.class differ diff --git a/src/main/resources/org/python/google/common/io/LineReader.class b/src/main/resources/org/python/google/common/io/LineReader.class new file mode 100644 index 0000000000000000000000000000000000000000..e9aa63856399a0469903a81cb80028303f5419e1 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/LineReader.class differ diff --git a/src/main/resources/org/python/google/common/io/LittleEndianDataInputStream.class b/src/main/resources/org/python/google/common/io/LittleEndianDataInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..d6bbff381dab9e13ba084a24d96d178b4cf9cc4e Binary files /dev/null and b/src/main/resources/org/python/google/common/io/LittleEndianDataInputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/LittleEndianDataOutputStream.class b/src/main/resources/org/python/google/common/io/LittleEndianDataOutputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..3c0a6c4796eec839e75c21de22217d6c0ae70c3d Binary files /dev/null and b/src/main/resources/org/python/google/common/io/LittleEndianDataOutputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/MultiInputStream.class b/src/main/resources/org/python/google/common/io/MultiInputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..d8c8f010855bb236839f26f25653271d96e300b4 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/MultiInputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/MultiReader.class b/src/main/resources/org/python/google/common/io/MultiReader.class new file mode 100644 index 0000000000000000000000000000000000000000..71357b3a75c6fe75fcc9727103a3feaebfd4d2ca Binary files /dev/null and b/src/main/resources/org/python/google/common/io/MultiReader.class differ diff --git a/src/main/resources/org/python/google/common/io/NullOutputStream.class b/src/main/resources/org/python/google/common/io/NullOutputStream.class new file mode 100644 index 0000000000000000000000000000000000000000..61f534748f606babd1a3f8cfdb502ed134b7db1b Binary files /dev/null and b/src/main/resources/org/python/google/common/io/NullOutputStream.class differ diff --git a/src/main/resources/org/python/google/common/io/OutputSupplier.class b/src/main/resources/org/python/google/common/io/OutputSupplier.class new file mode 100644 index 0000000000000000000000000000000000000000..0c3f292dec3c6e4621ae368ba452d37a31b1d0ac Binary files /dev/null and b/src/main/resources/org/python/google/common/io/OutputSupplier.class differ diff --git a/src/main/resources/org/python/google/common/io/PatternFilenameFilter.class b/src/main/resources/org/python/google/common/io/PatternFilenameFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..571f283025a7f7fadefeff7ca03dc23f18b7786a Binary files /dev/null and b/src/main/resources/org/python/google/common/io/PatternFilenameFilter.class differ diff --git a/src/main/resources/org/python/google/common/io/Resources$1.class b/src/main/resources/org/python/google/common/io/Resources$1.class new file mode 100644 index 0000000000000000000000000000000000000000..fc00bb112e6cff393d2dfc4631dbdd180fe6e474 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/Resources$1.class differ diff --git a/src/main/resources/org/python/google/common/io/Resources.class b/src/main/resources/org/python/google/common/io/Resources.class new file mode 100644 index 0000000000000000000000000000000000000000..92152be59974ab4ed62e8c894b33095b85e49aa5 Binary files /dev/null and b/src/main/resources/org/python/google/common/io/Resources.class differ diff --git a/src/main/resources/org/python/google/common/math/BigIntegerMath$1.class b/src/main/resources/org/python/google/common/math/BigIntegerMath$1.class new file mode 100644 index 0000000000000000000000000000000000000000..dcc29aa88e23d656836a32352feb6a81e0c178ed Binary files /dev/null and b/src/main/resources/org/python/google/common/math/BigIntegerMath$1.class differ diff --git a/src/main/resources/org/python/google/common/math/BigIntegerMath.class b/src/main/resources/org/python/google/common/math/BigIntegerMath.class new file mode 100644 index 0000000000000000000000000000000000000000..822afd8f188a8e32b43800284993f9a999ad09e8 Binary files /dev/null and b/src/main/resources/org/python/google/common/math/BigIntegerMath.class differ diff --git a/src/main/resources/org/python/google/common/math/DoubleMath$1.class b/src/main/resources/org/python/google/common/math/DoubleMath$1.class new file mode 100644 index 0000000000000000000000000000000000000000..f6c56743cc5eeb7a355d60a82a3fc3625d935d4c Binary files /dev/null and b/src/main/resources/org/python/google/common/math/DoubleMath$1.class differ diff --git a/src/main/resources/org/python/google/common/math/DoubleMath.class b/src/main/resources/org/python/google/common/math/DoubleMath.class new file mode 100644 index 0000000000000000000000000000000000000000..726f3ee0365fbebdd4f9d862442ea62bb7623188 Binary files /dev/null and b/src/main/resources/org/python/google/common/math/DoubleMath.class differ diff --git a/src/main/resources/org/python/google/common/math/DoubleUtils.class b/src/main/resources/org/python/google/common/math/DoubleUtils.class new file mode 100644 index 0000000000000000000000000000000000000000..0b76821aa8e52e088e692449df27f8bb1daf76f5 Binary files /dev/null and b/src/main/resources/org/python/google/common/math/DoubleUtils.class differ diff --git a/src/main/resources/org/python/google/common/math/IntMath$1.class b/src/main/resources/org/python/google/common/math/IntMath$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0165fe1002da86c610889b558d8d7c53cbd5eeed Binary files /dev/null and b/src/main/resources/org/python/google/common/math/IntMath$1.class differ diff --git a/src/main/resources/org/python/google/common/math/IntMath.class b/src/main/resources/org/python/google/common/math/IntMath.class new file mode 100644 index 0000000000000000000000000000000000000000..397c2bd585447823b5e146f5496128a7063cc1d5 Binary files /dev/null and b/src/main/resources/org/python/google/common/math/IntMath.class differ diff --git a/src/main/resources/org/python/google/common/math/LongMath$1.class b/src/main/resources/org/python/google/common/math/LongMath$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cf227c969c25ae24e32479643e5f766ea8a7d0e1 Binary files /dev/null and b/src/main/resources/org/python/google/common/math/LongMath$1.class differ diff --git a/src/main/resources/org/python/google/common/math/LongMath.class b/src/main/resources/org/python/google/common/math/LongMath.class new file mode 100644 index 0000000000000000000000000000000000000000..e48edba6f46cb8f1adac2f3774f8c323be2c2ecc Binary files /dev/null and b/src/main/resources/org/python/google/common/math/LongMath.class differ diff --git a/src/main/resources/org/python/google/common/math/MathPreconditions.class b/src/main/resources/org/python/google/common/math/MathPreconditions.class new file mode 100644 index 0000000000000000000000000000000000000000..dbd358a1dd9c3b36c074ee07f16ed22ff5f533b4 Binary files /dev/null and b/src/main/resources/org/python/google/common/math/MathPreconditions.class differ diff --git a/src/main/resources/org/python/google/common/net/HostAndPort.class b/src/main/resources/org/python/google/common/net/HostAndPort.class new file mode 100644 index 0000000000000000000000000000000000000000..da4de1ab37b0908b30bfbf3ef0e35d24ec02b68f Binary files /dev/null and b/src/main/resources/org/python/google/common/net/HostAndPort.class differ diff --git a/src/main/resources/org/python/google/common/net/HostSpecifier.class b/src/main/resources/org/python/google/common/net/HostSpecifier.class new file mode 100644 index 0000000000000000000000000000000000000000..0cc2cb86d7b07721d4a3677f1d6799262ba5e2b1 Binary files /dev/null and b/src/main/resources/org/python/google/common/net/HostSpecifier.class differ diff --git a/src/main/resources/org/python/google/common/net/HttpHeaders.class b/src/main/resources/org/python/google/common/net/HttpHeaders.class new file mode 100644 index 0000000000000000000000000000000000000000..67200738b44001f571c7fc218436fe594d271ea9 Binary files /dev/null and b/src/main/resources/org/python/google/common/net/HttpHeaders.class differ diff --git a/src/main/resources/org/python/google/common/net/InetAddresses$TeredoInfo.class b/src/main/resources/org/python/google/common/net/InetAddresses$TeredoInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..49d79186a6d86771601f357b4612aebf2ecccecf Binary files /dev/null and b/src/main/resources/org/python/google/common/net/InetAddresses$TeredoInfo.class differ diff --git a/src/main/resources/org/python/google/common/net/InetAddresses.class b/src/main/resources/org/python/google/common/net/InetAddresses.class new file mode 100644 index 0000000000000000000000000000000000000000..6cec7807424d93e31085d5ec435b0f172bfe3b42 Binary files /dev/null and b/src/main/resources/org/python/google/common/net/InetAddresses.class differ diff --git a/src/main/resources/org/python/google/common/net/InternetDomainName.class b/src/main/resources/org/python/google/common/net/InternetDomainName.class new file mode 100644 index 0000000000000000000000000000000000000000..c412e780ef5fd1d634d59e1220d8b9d02269d59c Binary files /dev/null and b/src/main/resources/org/python/google/common/net/InternetDomainName.class differ diff --git a/src/main/resources/org/python/google/common/net/MediaType$1.class b/src/main/resources/org/python/google/common/net/MediaType$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b3398a6156f1d050dafe601134dcfcb8ab90cdc5 Binary files /dev/null and b/src/main/resources/org/python/google/common/net/MediaType$1.class differ diff --git a/src/main/resources/org/python/google/common/net/MediaType$2.class b/src/main/resources/org/python/google/common/net/MediaType$2.class new file mode 100644 index 0000000000000000000000000000000000000000..eb5f4d8acb5ab4ed1e42317cd37cfb0d2702def2 Binary files /dev/null and b/src/main/resources/org/python/google/common/net/MediaType$2.class differ diff --git a/src/main/resources/org/python/google/common/net/MediaType$Tokenizer.class b/src/main/resources/org/python/google/common/net/MediaType$Tokenizer.class new file mode 100644 index 0000000000000000000000000000000000000000..463c50892a201f590ea7461fa4a1083aa966a1ee Binary files /dev/null and b/src/main/resources/org/python/google/common/net/MediaType$Tokenizer.class differ diff --git a/src/main/resources/org/python/google/common/net/MediaType.class b/src/main/resources/org/python/google/common/net/MediaType.class new file mode 100644 index 0000000000000000000000000000000000000000..f9aafa0431e0d05bd4b51edfc6ac9ce2d921a7e5 Binary files /dev/null and b/src/main/resources/org/python/google/common/net/MediaType.class differ diff --git a/src/main/resources/org/python/google/common/net/TldPatterns.class b/src/main/resources/org/python/google/common/net/TldPatterns.class new file mode 100644 index 0000000000000000000000000000000000000000..b53ec9a869dccdbc67eaec6d0f0d1f9ae5aecd5e Binary files /dev/null and b/src/main/resources/org/python/google/common/net/TldPatterns.class differ diff --git a/src/main/resources/org/python/google/common/primitives/AndroidInteger.class b/src/main/resources/org/python/google/common/primitives/AndroidInteger.class new file mode 100644 index 0000000000000000000000000000000000000000..1a39b261983cd9aaede6de7dbd09f65855df7503 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/AndroidInteger.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Booleans$BooleanArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Booleans$BooleanArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..0c31b7dfee4b92ab8532b584920b69d9ed5e9643 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Booleans$BooleanArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Booleans$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/Booleans$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..d60c5be4baca255997ec870066f6be080b7e26b0 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Booleans$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Booleans.class b/src/main/resources/org/python/google/common/primitives/Booleans.class new file mode 100644 index 0000000000000000000000000000000000000000..9b39cc9b14b1e262b3ec63382646191e8ca06455 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Booleans.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Bytes$ByteArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Bytes$ByteArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..e92e281a352a56f177e104e0fb801faadc01f40a Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Bytes$ByteArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Bytes.class b/src/main/resources/org/python/google/common/primitives/Bytes.class new file mode 100644 index 0000000000000000000000000000000000000000..30fd97a05965bd1180f504adc7b12eadf77c549f Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Bytes.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Chars$CharArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Chars$CharArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..634dc42c2f7d7a320239df572f5f6ac3de8d6e56 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Chars$CharArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Chars$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/Chars$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..4e2f50420d3025511e5c4e125634b1ba5931bf2e Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Chars$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Chars.class b/src/main/resources/org/python/google/common/primitives/Chars.class new file mode 100644 index 0000000000000000000000000000000000000000..98bda21c5682accac2cdf739d8d6e17014d846b2 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Chars.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Doubles$DoubleArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Doubles$DoubleArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..3b06d96b2ad1896729b35500695ae014b33a3e18 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Doubles$DoubleArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Doubles$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/Doubles$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..91157b6f6b249ac07be70b29d892e0e6997b31f6 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Doubles$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Doubles.class b/src/main/resources/org/python/google/common/primitives/Doubles.class new file mode 100644 index 0000000000000000000000000000000000000000..68d524f8f375c10d1a12d8f2a97ed7cf69cf6583 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Doubles.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Floats$FloatArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Floats$FloatArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..a940839a97c714e64b565e913f8bfe92a10613fb Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Floats$FloatArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Floats$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/Floats$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..1f67ce39fdca97638fa37ff42b6567340c281cde Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Floats$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Floats.class b/src/main/resources/org/python/google/common/primitives/Floats.class new file mode 100644 index 0000000000000000000000000000000000000000..0646981774ae7bfaaa182055b28b768b30856ff1 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Floats.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Ints$IntArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Ints$IntArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..81051237e87dce8deff45516eb82d57c88a4911b Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Ints$IntArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Ints$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/Ints$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..3108f91d709afa326a252b0207dd0a902eb0e211 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Ints$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Ints.class b/src/main/resources/org/python/google/common/primitives/Ints.class new file mode 100644 index 0000000000000000000000000000000000000000..8256e510fd5a8dfb88a3b719697993023e1d48e1 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Ints.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Longs$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/Longs$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..23396fb0fa7a78417582bad82d8a423666cb7a60 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Longs$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Longs$LongArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Longs$LongArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..859a4a98d7ef14db8ddbfcb60325daaec4ad7813 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Longs$LongArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Longs.class b/src/main/resources/org/python/google/common/primitives/Longs.class new file mode 100644 index 0000000000000000000000000000000000000000..547250c9e1bdf6e685f30f41581df749fb1f9203 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Longs.class differ diff --git a/src/main/resources/org/python/google/common/primitives/ParseRequest.class b/src/main/resources/org/python/google/common/primitives/ParseRequest.class new file mode 100644 index 0000000000000000000000000000000000000000..ce06babc5fdd320f926b67da8348d2da0cf4acc7 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/ParseRequest.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Primitives.class b/src/main/resources/org/python/google/common/primitives/Primitives.class new file mode 100644 index 0000000000000000000000000000000000000000..b3928d70f1c7e9bc45ea7e95504103c6885aaad3 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Primitives.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Shorts$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/Shorts$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..b21a33c15cc9f6e7f22db63cfb0eea35a20b5c6a Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Shorts$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Shorts$ShortArrayAsList.class b/src/main/resources/org/python/google/common/primitives/Shorts$ShortArrayAsList.class new file mode 100644 index 0000000000000000000000000000000000000000..3fe685f2847568eac0d7ab37f058f925319c804f Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Shorts$ShortArrayAsList.class differ diff --git a/src/main/resources/org/python/google/common/primitives/Shorts.class b/src/main/resources/org/python/google/common/primitives/Shorts.class new file mode 100644 index 0000000000000000000000000000000000000000..2c0770dab1ac1a27067d80de72b650f61345c149 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/Shorts.class differ diff --git a/src/main/resources/org/python/google/common/primitives/SignedBytes$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/SignedBytes$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..6f01ec24218ae7cdaec942fa28e89c2bff2c11a0 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/SignedBytes$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/SignedBytes.class b/src/main/resources/org/python/google/common/primitives/SignedBytes.class new file mode 100644 index 0000000000000000000000000000000000000000..e45903aa2f1014b2bb9a5a9aadaed3b0dc94f0dc Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/SignedBytes.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$PureJavaComparator.class b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$PureJavaComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..ede688f9c183fa8e04faa58195ee3be2f619fa10 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$PureJavaComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator$1.class b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator$1.class new file mode 100644 index 0000000000000000000000000000000000000000..997dc2c9dfb3d8f29b042fbfeee83b05f850624e Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator$1.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator.class b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..49d723abc564d7ad0cab4a3312ff778b572a69eb Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder.class b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder.class new file mode 100644 index 0000000000000000000000000000000000000000..fa0c524cd94aef563d91e9f3b2fe4e6e05a06979 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedBytes$LexicographicalComparatorHolder.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedBytes.class b/src/main/resources/org/python/google/common/primitives/UnsignedBytes.class new file mode 100644 index 0000000000000000000000000000000000000000..236168365ef4cd7f29c35aa788227bb5305e3bd7 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedBytes.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedInteger.class b/src/main/resources/org/python/google/common/primitives/UnsignedInteger.class new file mode 100644 index 0000000000000000000000000000000000000000..6fb7acb9c30ecb43a76fde1847a316d8edc520ac Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedInteger.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedInts$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/UnsignedInts$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..52b94b314877a0288774159e1923743cca6d3f7b Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedInts$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedInts.class b/src/main/resources/org/python/google/common/primitives/UnsignedInts.class new file mode 100644 index 0000000000000000000000000000000000000000..bf42f8ca3b72a832dd8afe15e6335073587d3ade Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedInts.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedLong.class b/src/main/resources/org/python/google/common/primitives/UnsignedLong.class new file mode 100644 index 0000000000000000000000000000000000000000..d26d7b0eefc05e631bd270be91e8d5e9218c8f0f Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedLong.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedLongs$LexicographicalComparator.class b/src/main/resources/org/python/google/common/primitives/UnsignedLongs$LexicographicalComparator.class new file mode 100644 index 0000000000000000000000000000000000000000..98d562906ff78f5fc64de1e401ff6f5036505ffe Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedLongs$LexicographicalComparator.class differ diff --git a/src/main/resources/org/python/google/common/primitives/UnsignedLongs.class b/src/main/resources/org/python/google/common/primitives/UnsignedLongs.class new file mode 100644 index 0000000000000000000000000000000000000000..889a6b9ef2be62508a9179e61987b3cb50ab2891 Binary files /dev/null and b/src/main/resources/org/python/google/common/primitives/UnsignedLongs.class differ diff --git a/src/main/resources/org/python/google/common/reflect/AbstractInvocationHandler.class b/src/main/resources/org/python/google/common/reflect/AbstractInvocationHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..0ee00aa2f13c45408a06774aed86aea8bfe9981e Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/AbstractInvocationHandler.class differ diff --git a/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap$1.class b/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ecd732e7a19a4117f3a98aa96c8dadca519872cf Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap$Builder.class b/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap$Builder.class new file mode 100644 index 0000000000000000000000000000000000000000..8183ab2422d98fa31ed6027a6a0781552ef471d1 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap$Builder.class differ diff --git a/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap.class b/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap.class new file mode 100644 index 0000000000000000000000000000000000000000..341ed0b3089d9694b04722ca57df910fce97f44d Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/ImmutableTypeToInstanceMap.class differ diff --git a/src/main/resources/org/python/google/common/reflect/MutableTypeToInstanceMap.class b/src/main/resources/org/python/google/common/reflect/MutableTypeToInstanceMap.class new file mode 100644 index 0000000000000000000000000000000000000000..2603e2062b0f4d39c0d63ddc67bba8c1ae43ddf5 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/MutableTypeToInstanceMap.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Reflection.class b/src/main/resources/org/python/google/common/reflect/Reflection.class new file mode 100644 index 0000000000000000000000000000000000000000..efe14446dea4874ab0ca4cab0b78de988aff6657 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Reflection.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeCapture.class b/src/main/resources/org/python/google/common/reflect/TypeCapture.class new file mode 100644 index 0000000000000000000000000000000000000000..2a1f0fa98ca37c25adb5501a76c4ca34d046f6a3 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeCapture.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeParameter.class b/src/main/resources/org/python/google/common/reflect/TypeParameter.class new file mode 100644 index 0000000000000000000000000000000000000000..85f9021eef9dd0ee4d743257a88d045c0d441780 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeParameter.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeResolver$1.class b/src/main/resources/org/python/google/common/reflect/TypeResolver$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0e34e092082806d964df89041341872371c8661e Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeResolver$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeResolver$TypeMappingIntrospector.class b/src/main/resources/org/python/google/common/reflect/TypeResolver$TypeMappingIntrospector.class new file mode 100644 index 0000000000000000000000000000000000000000..e5ebd17be5d50b4366cf6db72ce9eb776cd294b5 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeResolver$TypeMappingIntrospector.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeResolver$WildcardCapturer.class b/src/main/resources/org/python/google/common/reflect/TypeResolver$WildcardCapturer.class new file mode 100644 index 0000000000000000000000000000000000000000..f88996997362e6caea0cc30bd38e415149980f86 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeResolver$WildcardCapturer.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeResolver.class b/src/main/resources/org/python/google/common/reflect/TypeResolver.class new file mode 100644 index 0000000000000000000000000000000000000000..5022ef053842d32f12512a269ebc63813be3a024 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeResolver.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToInstanceMap.class b/src/main/resources/org/python/google/common/reflect/TypeToInstanceMap.class new file mode 100644 index 0000000000000000000000000000000000000000..2368db5c1456a59833d510f36cc61886686b0828 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToInstanceMap.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$1.class b/src/main/resources/org/python/google/common/reflect/TypeToken$1.class new file mode 100644 index 0000000000000000000000000000000000000000..cbd8ec2cdbff60fbdc0b1867a6a3ab06564470fb Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$ClassSet.class b/src/main/resources/org/python/google/common/reflect/TypeToken$ClassSet.class new file mode 100644 index 0000000000000000000000000000000000000000..c066d9bb770d09f367a8a721af0bb5dfabfdfa0f Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$ClassSet.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$InterfaceSet$1.class b/src/main/resources/org/python/google/common/reflect/TypeToken$InterfaceSet$1.class new file mode 100644 index 0000000000000000000000000000000000000000..8982a7772357343a4a81e8efce0f1574f89011c3 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$InterfaceSet$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$InterfaceSet.class b/src/main/resources/org/python/google/common/reflect/TypeToken$InterfaceSet.class new file mode 100644 index 0000000000000000000000000000000000000000..93e60e86315bc4b372d607f0612f19dabde51062 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$InterfaceSet.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$SimpleTypeToken.class b/src/main/resources/org/python/google/common/reflect/TypeToken$SimpleTypeToken.class new file mode 100644 index 0000000000000000000000000000000000000000..da538d44e2eded7deb00fb114879f5e151111fe7 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$SimpleTypeToken.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$1.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2a5e5c0ea5aa56c8d8606134d3fa2d2bb8796b05 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$2.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$2.class new file mode 100644 index 0000000000000000000000000000000000000000..7ad88ea9f63b1a1d848ab3de9656e27873aa2a23 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$2.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$3.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$3.class new file mode 100644 index 0000000000000000000000000000000000000000..45e2643febc6a76d618af43eafbaae621f6a03bc Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$3.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$4.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$4.class new file mode 100644 index 0000000000000000000000000000000000000000..1d7d64b351ecb30458f19af9379ce02f697af0c8 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$4.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$ForwardingTypeCollector.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$ForwardingTypeCollector.class new file mode 100644 index 0000000000000000000000000000000000000000..fc0d36d3062279279f0924e764efbe81b9484ed8 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector$ForwardingTypeCollector.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector.class new file mode 100644 index 0000000000000000000000000000000000000000..b60050a87d3d1ecfe3ce750530735138aa1d5659 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeCollector.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter$1.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b8f2208ec1f6dfb5f245802d8f6c8465d40bd557 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter$2.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter$2.class new file mode 100644 index 0000000000000000000000000000000000000000..53b159597254bbc9fe1aa33fdbfa52c869bd3c06 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter$2.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter.class new file mode 100644 index 0000000000000000000000000000000000000000..ea42a16c5890221a202c7d5a349f25cf78ef1ec7 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeFilter.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken$TypeSet.class b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeSet.class new file mode 100644 index 0000000000000000000000000000000000000000..91ea04f0c5525b46b3a42b8284f8d0bbc8c1d96d Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken$TypeSet.class differ diff --git a/src/main/resources/org/python/google/common/reflect/TypeToken.class b/src/main/resources/org/python/google/common/reflect/TypeToken.class new file mode 100644 index 0000000000000000000000000000000000000000..09e02fa4d7701776f83ee4e8aac57cd502c9c99c Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/TypeToken.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$1.class b/src/main/resources/org/python/google/common/reflect/Types$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6c80b0d9d5bd31ead91c1bdf174344bc75fd68d5 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$1.class b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2c7a69ecab56928a99803d20b3937900b1b1b318 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$1LocalClass.class b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$1LocalClass.class new file mode 100644 index 0000000000000000000000000000000000000000..86418ce8b9ab2558fa72c5c041c5605eaebea6fd Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$1LocalClass.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$2.class b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$2.class new file mode 100644 index 0000000000000000000000000000000000000000..246218b4a07dc799cb0f5c52310d37aedf583db8 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$2.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$3.class b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$3.class new file mode 100644 index 0000000000000000000000000000000000000000..a0eb49cc34166752fd33a55b41c2361ea4452e17 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership$3.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership.class b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership.class new file mode 100644 index 0000000000000000000000000000000000000000..1181901e8cf10ad87a453b10d84a6755c3793c5e Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$ClassOwnership.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$GenericArrayTypeImpl.class b/src/main/resources/org/python/google/common/reflect/Types$GenericArrayTypeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1dbc41f529ea5af995ca53d2a1975c58d5fb67a5 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$GenericArrayTypeImpl.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$1.class b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5b1c0f0fef2aff85fe02848c1e7da99e7501fce9 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$1.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$2.class b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$2.class new file mode 100644 index 0000000000000000000000000000000000000000..b0aa268d6ace791bf1577f2a7259fefe56193035 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$2.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$3.class b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$3.class new file mode 100644 index 0000000000000000000000000000000000000000..3db52b1ed4440821eb99c7466025b75b44cb2b65 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion$3.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$JavaVersion.class b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion.class new file mode 100644 index 0000000000000000000000000000000000000000..3c7c83fb5a67b1de9327977fd24ffe7ffbdca63b Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$JavaVersion.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$ParameterizedTypeImpl.class b/src/main/resources/org/python/google/common/reflect/Types$ParameterizedTypeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..02d205addd5b74d0bbf40da92b1df5c5f2887a94 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$ParameterizedTypeImpl.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$TypeVariableImpl.class b/src/main/resources/org/python/google/common/reflect/Types$TypeVariableImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..7909c66e0912c6d86c0305e09a29defe3d557287 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$TypeVariableImpl.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types$WildcardTypeImpl.class b/src/main/resources/org/python/google/common/reflect/Types$WildcardTypeImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..1346ed39b23b3cb92a8014b43dbaaa2d5b54dd97 Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types$WildcardTypeImpl.class differ diff --git a/src/main/resources/org/python/google/common/reflect/Types.class b/src/main/resources/org/python/google/common/reflect/Types.class new file mode 100644 index 0000000000000000000000000000000000000000..1e61f42f18b753aa47c61f55255fbc728ea37aea Binary files /dev/null and b/src/main/resources/org/python/google/common/reflect/Types.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractCheckedFuture.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractCheckedFuture.class new file mode 100644 index 0000000000000000000000000000000000000000..053fc6767a6c55695cb5059dc6069ffa32ffcb95 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractCheckedFuture.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$1$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..2a31c2878cd64ae043e3fa01fd6dc4b0328bb3fa Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$1$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d181ce0fa6017cd1cdb0c314991b8ae0982be4a4 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$2.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$2.class new file mode 100644 index 0000000000000000000000000000000000000000..a54c743482113359c39adeb1faf60787059df57a Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService$2.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService.class new file mode 100644 index 0000000000000000000000000000000000000000..ff58c83fa0d267ee8a4e87adec90e51f2c548529 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractExecutionThreadService.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractFuture$Sync.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractFuture$Sync.class new file mode 100644 index 0000000000000000000000000000000000000000..5b90a57697a1e2823ea75e2753783b0f25e434ea Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractFuture$Sync.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractFuture.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractFuture.class new file mode 100644 index 0000000000000000000000000000000000000000..841924bbc5c5255d021a5cf453f752e7acdb30ae Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractFuture.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..356c969e68acbea0937485c985d33f9477b1faa4 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1$2.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1$2.class new file mode 100644 index 0000000000000000000000000000000000000000..450b8a77a3f6f4ff342980edca0021b82064aa39 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1$2.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1.class new file mode 100644 index 0000000000000000000000000000000000000000..69bd8a015a9ab4d4bcf07db5d52cf04e4b7aa0d5 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$2.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$2.class new file mode 100644 index 0000000000000000000000000000000000000000..e6efaf6ae2842043b1e9e077ebecb928663a55f2 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService$2.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService.class new file mode 100644 index 0000000000000000000000000000000000000000..0e648a80909217a2ebe3a43bdb58e56c5967c902 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractIdleService.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractListeningExecutorService.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractListeningExecutorService.class new file mode 100644 index 0000000000000000000000000000000000000000..df7f80a67e05f3e721cc6a6af66ad15b4d7d92f5 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractListeningExecutorService.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$1.class new file mode 100644 index 0000000000000000000000000000000000000000..7fe032671d88468eb3f8c9188ebe4c689bdab8ae Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$2.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$2.class new file mode 100644 index 0000000000000000000000000000000000000000..84e0ea701d39550f7e156851349304aef577a0fc Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$2.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$3.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$3.class new file mode 100644 index 0000000000000000000000000000000000000000..3ce961715b25b49eec08d5fade87d93dadf178ca Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1$3.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d4297c82193a40b7b97526a1cb46d109b192d39b Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler$ReschedulableCallable.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler$ReschedulableCallable.class new file mode 100644 index 0000000000000000000000000000000000000000..66ce99b6f80aa9a892f5d0bb56d25a88e0f20e76 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler$ReschedulableCallable.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler$Schedule.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler$Schedule.class new file mode 100644 index 0000000000000000000000000000000000000000..77881a7baa10ecd85b807072d19495596802d20f Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler$Schedule.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler.class new file mode 100644 index 0000000000000000000000000000000000000000..6e9274836a98d54784ee075fb0857bbb8ad96e32 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$CustomScheduler.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler$1.class new file mode 100644 index 0000000000000000000000000000000000000000..49d9a90bc5c980413a76a614a3c480606fc282be Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler$2.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler$2.class new file mode 100644 index 0000000000000000000000000000000000000000..38279170bcecf561e1900407c5c5b6b3fc78d7c7 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler$2.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler.class new file mode 100644 index 0000000000000000000000000000000000000000..08dca32040fa908fdeacd03cf341e133ce047017 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService$Scheduler.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService.class new file mode 100644 index 0000000000000000000000000000000000000000..6e6e29b9eb8a2356667ceec510f3d0c15e590d87 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractScheduledService.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$1.class new file mode 100644 index 0000000000000000000000000000000000000000..775d3c3406a9a86a7fc8df9abf83d61ced4e3eb2 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$2$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$2$1.class new file mode 100644 index 0000000000000000000000000000000000000000..a29db1b2852180ff4a577c2e74165cf89ff3b702 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$2$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$2.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$2.class new file mode 100644 index 0000000000000000000000000000000000000000..bc522b9b2fab5f6c259e335de160f85b586ce835 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$2.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$3$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$3$1.class new file mode 100644 index 0000000000000000000000000000000000000000..923418a5c0fd088dabcccd176c6e4ddf4f7e9b94 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$3$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$3.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$3.class new file mode 100644 index 0000000000000000000000000000000000000000..83d359d457067b79292aa659420d954390def2b2 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$3.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$4$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$4$1.class new file mode 100644 index 0000000000000000000000000000000000000000..aa350f608822aee40fb164b23a9e094a85e79979 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$4$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$4.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$4.class new file mode 100644 index 0000000000000000000000000000000000000000..5c110fa5426825b2422ab4b49a12670b2e177a61 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$4.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$5$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$5$1.class new file mode 100644 index 0000000000000000000000000000000000000000..0cbdfd9640d34e71e49fcabe9a66ccad3a29a325 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$5$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$5.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$5.class new file mode 100644 index 0000000000000000000000000000000000000000..83c4a97caa3d436c3979ae80f8c75c4bd8c5b28e Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$5.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$6$1.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$6$1.class new file mode 100644 index 0000000000000000000000000000000000000000..6821d22aaeb5d0df18d1d82cdb1f2fff03148111 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$6$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$6.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$6.class new file mode 100644 index 0000000000000000000000000000000000000000..68725e065bc0de9368c936b6cc5f68165a1a56e1 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$6.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$7.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$7.class new file mode 100644 index 0000000000000000000000000000000000000000..63ee9fa2a66cbbeea801908ee794d233f535a0fd Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$7.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$ListenerExecutorPair.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$ListenerExecutorPair.class new file mode 100644 index 0000000000000000000000000000000000000000..aae3ab60a8c90bf445647c21eea0e095be871b27 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$ListenerExecutorPair.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$StateSnapshot.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$StateSnapshot.class new file mode 100644 index 0000000000000000000000000000000000000000..550d9f6dcbb99bd4b380e370d0a280ce491b81b6 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$StateSnapshot.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService$Transition.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$Transition.class new file mode 100644 index 0000000000000000000000000000000000000000..8413b4dd1ebb2f491904257264b81010a816c11c Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService$Transition.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AbstractService.class b/src/main/resources/org/python/google/common/util/concurrent/AbstractService.class new file mode 100644 index 0000000000000000000000000000000000000000..a98a57fbc806355025315135a48aa27e54474225 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AbstractService.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AsyncFunction.class b/src/main/resources/org/python/google/common/util/concurrent/AsyncFunction.class new file mode 100644 index 0000000000000000000000000000000000000000..c1970f6ac58435c2f6cae0228d773c04308c3e76 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AsyncFunction.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AtomicDouble.class b/src/main/resources/org/python/google/common/util/concurrent/AtomicDouble.class new file mode 100644 index 0000000000000000000000000000000000000000..6d18a8717418f2151c5c4b5261cdd68ad5905143 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AtomicDouble.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AtomicDoubleArray.class b/src/main/resources/org/python/google/common/util/concurrent/AtomicDoubleArray.class new file mode 100644 index 0000000000000000000000000000000000000000..3867af7e2a32281b0f3f139157853511bf0e6f76 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AtomicDoubleArray.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AtomicLongMap$1.class b/src/main/resources/org/python/google/common/util/concurrent/AtomicLongMap$1.class new file mode 100644 index 0000000000000000000000000000000000000000..68cd46f30a088cfd90a31451ebf42a623af3a6e3 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AtomicLongMap$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/AtomicLongMap.class b/src/main/resources/org/python/google/common/util/concurrent/AtomicLongMap.class new file mode 100644 index 0000000000000000000000000000000000000000..0d61694902bacb475187de08ec44a4b7552736c2 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/AtomicLongMap.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/Atomics.class b/src/main/resources/org/python/google/common/util/concurrent/Atomics.class new file mode 100644 index 0000000000000000000000000000000000000000..e8c8018592afe7ec2d91f3d73be45975edb334db Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/Atomics.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/Callables$1.class b/src/main/resources/org/python/google/common/util/concurrent/Callables$1.class new file mode 100644 index 0000000000000000000000000000000000000000..ccee81bee108bfd20328dcabd843fb1cd52be0d2 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/Callables$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/Callables.class b/src/main/resources/org/python/google/common/util/concurrent/Callables.class new file mode 100644 index 0000000000000000000000000000000000000000..9cb042ef533dda0031f50fd6fc0e3a6914c9b5f1 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/Callables.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CheckedFuture.class b/src/main/resources/org/python/google/common/util/concurrent/CheckedFuture.class new file mode 100644 index 0000000000000000000000000000000000000000..04228e15a81c730164528194ed1245a90002626d Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CheckedFuture.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$1.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$1.class new file mode 100644 index 0000000000000000000000000000000000000000..c9affcbb924d769a65f5b0636c1b7535f6c059c7 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingLock.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingLock.class new file mode 100644 index 0000000000000000000000000000000000000000..b268ab819df4feb8a01850b3eec04497021435f4 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingLock.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantLock.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantLock.class new file mode 100644 index 0000000000000000000000000000000000000000..2a3d21bd8becfa91b2d1cf8fd2b898093cde5a2a Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantLock.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantReadLock.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantReadLock.class new file mode 100644 index 0000000000000000000000000000000000000000..b2f3e8507f5e79507345a9a461e349d3428bf712 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantReadLock.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantReadWriteLock.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantReadWriteLock.class new file mode 100644 index 0000000000000000000000000000000000000000..5b845220f866bfd627981a80aafdb8ab19af929c Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantReadWriteLock.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantWriteLock.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantWriteLock.class new file mode 100644 index 0000000000000000000000000000000000000000..346aff7e143fecdddda2c7916a41126c52841241 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$CycleDetectingReentrantWriteLock.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$ExampleStackTrace.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$ExampleStackTrace.class new file mode 100644 index 0000000000000000000000000000000000000000..be81431237c330da5c426cc9526f91dba10ed1b6 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$ExampleStackTrace.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$LockGraphNode.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$LockGraphNode.class new file mode 100644 index 0000000000000000000000000000000000000000..3aad7f02a79836a0d3dee0808a9e91a7bfaeb82f Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$LockGraphNode.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$OrderedLockGraphNodesCreator.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$OrderedLockGraphNodesCreator.class new file mode 100644 index 0000000000000000000000000000000000000000..c25f2545cab7f567602cf704375d49e8a30f2bc3 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$OrderedLockGraphNodesCreator.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$1.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$1.class new file mode 100644 index 0000000000000000000000000000000000000000..74271675c579919f3e22951c38b9024f262b4f0b Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$1.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$2.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$2.class new file mode 100644 index 0000000000000000000000000000000000000000..5f83efc821d785cbfdd88d40f5009a5ecd12a6db Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$2.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$3.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$3.class new file mode 100644 index 0000000000000000000000000000000000000000..df18251f8d01b0fb4beda98b67e66dfe3ceeb45c Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies$3.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies.class new file mode 100644 index 0000000000000000000000000000000000000000..e8305147e8bb0f0b3de0070d100a4c3946f498df Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policies.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policy.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policy.class new file mode 100644 index 0000000000000000000000000000000000000000..13975d4846813ff1891ad51310a5d942756ee9b0 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$Policy.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$PotentialDeadlockException.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$PotentialDeadlockException.class new file mode 100644 index 0000000000000000000000000000000000000000..e13a953dbcd5e07d46d0ae3ae3e1217306c32eb1 Binary files /dev/null and b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$PotentialDeadlockException.class differ diff --git a/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$WithExplicitOrdering.class b/src/main/resources/org/python/google/common/util/concurrent/CycleDetectingLockFactory$WithExplicitOrdering.class new file mode 100644 index